Initial commit
This commit is contained in:
3
core/vendor/symfony/cache/.gitignore
vendored
Normal file
3
core/vendor/symfony/cache/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
vendor/
|
||||
316
core/vendor/symfony/cache/Adapter/AbstractAdapter.php
vendored
Normal file
316
core/vendor/symfony/cache/Adapter/AbstractAdapter.php
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\AbstractTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const NS_SEPARATOR = ':';
|
||||
|
||||
use AbstractTrait;
|
||||
|
||||
private static $apcuSupported;
|
||||
private static $phpFilesSupported;
|
||||
|
||||
private $createCacheItem;
|
||||
private $mergeByLifetime;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
protected function __construct($namespace = '', $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 = $value;
|
||||
$item->isHit = $isHit;
|
||||
$item->defaultLifetime = $defaultLifetime;
|
||||
|
||||
return $item;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
$getId = function ($key) { return $this->getId((string) $key); };
|
||||
$this->mergeByLifetime = \Closure::bind(
|
||||
static function ($deferred, $namespace, &$expiredIds) use ($getId) {
|
||||
$byLifetime = [];
|
||||
$now = time();
|
||||
$expiredIds = [];
|
||||
|
||||
foreach ($deferred as $key => $item) {
|
||||
if (null === $item->expiry) {
|
||||
$byLifetime[0 < $item->defaultLifetime ? $item->defaultLifetime : 0][$getId($key)] = $item->value;
|
||||
} elseif ($item->expiry > $now) {
|
||||
$byLifetime[$item->expiry - $now][$getId($key)] = $item->value;
|
||||
} else {
|
||||
$expiredIds[] = $getId($key);
|
||||
}
|
||||
}
|
||||
|
||||
return $byLifetime;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
if (null === self::$apcuSupported) {
|
||||
self::$apcuSupported = ApcuAdapter::isSupported();
|
||||
}
|
||||
|
||||
if (!self::$apcuSupported && null === self::$phpFilesSupported) {
|
||||
self::$phpFilesSupported = PhpFilesAdapter::isSupported();
|
||||
}
|
||||
|
||||
if (self::$phpFilesSupported) {
|
||||
$opcache = new PhpFilesAdapter($namespace, $defaultLifetime, $directory);
|
||||
if (null !== $logger) {
|
||||
$opcache->setLogger($logger);
|
||||
}
|
||||
|
||||
return $opcache;
|
||||
}
|
||||
|
||||
$fs = new FilesystemAdapter($namespace, $defaultLifetime, $directory);
|
||||
if (null !== $logger) {
|
||||
$fs->setLogger($logger);
|
||||
}
|
||||
if (!self::$apcuSupported) {
|
||||
return $fs;
|
||||
}
|
||||
|
||||
$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, $fs]);
|
||||
}
|
||||
|
||||
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://')) {
|
||||
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 getItem($key)
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
$id = $this->getId($key);
|
||||
|
||||
$f = $this->createCacheItem;
|
||||
$isHit = false;
|
||||
$value = null;
|
||||
|
||||
try {
|
||||
foreach ($this->doFetch([$id]) as $value) {
|
||||
$isHit = true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
}
|
||||
|
||||
return $f($key, $value, $isHit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
$ids = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$ids[] = $this->getId($key);
|
||||
}
|
||||
try {
|
||||
$items = $this->doFetch($ids);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => $keys, 'exception' => $e]);
|
||||
$items = [];
|
||||
}
|
||||
$ids = array_combine($ids, $keys);
|
||||
|
||||
return $this->generateItems($items, $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
if (!$item instanceof CacheItem) {
|
||||
return false;
|
||||
}
|
||||
$this->deferred[$item->getKey()] = $item;
|
||||
|
||||
return $this->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
if (!$item instanceof CacheItem) {
|
||||
return false;
|
||||
}
|
||||
$this->deferred[$item->getKey()] = $item;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$ok = true;
|
||||
$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);
|
||||
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, '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);
|
||||
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
}
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
}
|
||||
|
||||
private function generateItems($items, &$keys)
|
||||
{
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
try {
|
||||
foreach ($items as $id => $value) {
|
||||
if (!isset($keys[$id])) {
|
||||
$id = key($keys);
|
||||
}
|
||||
$key = $keys[$id];
|
||||
unset($keys[$id]);
|
||||
yield $key => $f($key, $value, true);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => array_values($keys), 'exception' => $e]);
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $f($key, null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
core/vendor/symfony/cache/Adapter/AdapterInterface.php
vendored
Normal file
37
core/vendor/symfony/cache/Adapter/AdapterInterface.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
|
||||
/**
|
||||
* Interface for adapters managing instances of Symfony's CacheItem.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface AdapterInterface extends CacheItemPoolInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return CacheItem
|
||||
*/
|
||||
public function getItem($key);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return \Traversable|CacheItem[]
|
||||
*/
|
||||
public function getItems(array $keys = []);
|
||||
}
|
||||
31
core/vendor/symfony/cache/Adapter/ApcuAdapter.php
vendored
Normal file
31
core/vendor/symfony/cache/Adapter/ApcuAdapter.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Traits\ApcuTrait;
|
||||
|
||||
class ApcuAdapter extends AbstractAdapter
|
||||
{
|
||||
use ApcuTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $version
|
||||
*
|
||||
* @throws CacheException if APCu is not enabled
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $version = null)
|
||||
{
|
||||
$this->init($namespace, $defaultLifetime, $version);
|
||||
}
|
||||
}
|
||||
155
core/vendor/symfony/cache/Adapter/ArrayAdapter.php
vendored
Normal file
155
core/vendor/symfony/cache/Adapter/ArrayAdapter.php
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ArrayTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use ArrayTrait;
|
||||
|
||||
private $createCacheItem;
|
||||
|
||||
/**
|
||||
* @param int $defaultLifetime
|
||||
* @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise
|
||||
*/
|
||||
public function __construct($defaultLifetime = 0, $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 getItem($key)
|
||||
{
|
||||
$isHit = $this->hasItem($key);
|
||||
try {
|
||||
if (!$isHit) {
|
||||
$this->values[$key] = $value = null;
|
||||
} elseif (!$this->storeSerialized) {
|
||||
$value = $this->values[$key];
|
||||
} elseif ('b:0;' === $value = $this->values[$key]) {
|
||||
$value = false;
|
||||
} elseif (false === $value = unserialize($value)) {
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
return $f($key, $value, $isHit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
CacheItem::validateKey($key);
|
||||
}
|
||||
|
||||
return $this->generateItems($keys, time(), $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 <= time()) {
|
||||
$this->deleteItem($key);
|
||||
|
||||
return true;
|
||||
}
|
||||
if ($this->storeSerialized) {
|
||||
try {
|
||||
$value = serialize($value);
|
||||
} catch (\Exception $e) {
|
||||
$type = \is_object($value) ? \get_class($value) : \gettype($value);
|
||||
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (null === $expiry && 0 < $item["\0*\0defaultLifetime"]) {
|
||||
$expiry = time() + $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;
|
||||
}
|
||||
}
|
||||
273
core/vendor/symfony/cache/Adapter/ChainAdapter.php
vendored
Normal file
273
core/vendor/symfony/cache/Adapter/ChainAdapter.php
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\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;
|
||||
|
||||
/**
|
||||
* 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 <dunglas@gmail.com>
|
||||
*/
|
||||
class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $adapters = [];
|
||||
private $adapterCount;
|
||||
private $syncItem;
|
||||
|
||||
/**
|
||||
* @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items
|
||||
* @param int $defaultLifetime The default lifetime of items propagated from lower adapters to upper ones
|
||||
*/
|
||||
public function __construct(array $adapters, $defaultLifetime = 0)
|
||||
{
|
||||
if (!$adapters) {
|
||||
throw new InvalidArgumentException('At least one adapter must be specified.');
|
||||
}
|
||||
|
||||
foreach ($adapters as $adapter) {
|
||||
if (!$adapter instanceof CacheItemPoolInterface) {
|
||||
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($adapter), CacheItemPoolInterface::class));
|
||||
}
|
||||
|
||||
if ($adapter instanceof AdapterInterface) {
|
||||
$this->adapters[] = $adapter;
|
||||
} else {
|
||||
$this->adapters[] = new ProxyAdapter($adapter);
|
||||
}
|
||||
}
|
||||
$this->adapterCount = \count($this->adapters);
|
||||
|
||||
$this->syncItem = \Closure::bind(
|
||||
static function ($sourceItem, $item) use ($defaultLifetime) {
|
||||
$item->value = $sourceItem->value;
|
||||
$item->expiry = $sourceItem->expiry;
|
||||
$item->isHit = $sourceItem->isHit;
|
||||
|
||||
if (0 < $sourceItem->defaultLifetime && $sourceItem->defaultLifetime < $defaultLifetime) {
|
||||
$defaultLifetime = $sourceItem->defaultLifetime;
|
||||
}
|
||||
if (0 < $defaultLifetime && ($item->defaultLifetime <= 0 || $defaultLifetime < $item->defaultLifetime)) {
|
||||
$item->defaultLifetime = $defaultLifetime;
|
||||
}
|
||||
|
||||
return $item;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItem($key)
|
||||
{
|
||||
$syncItem = $this->syncItem;
|
||||
$misses = [];
|
||||
|
||||
foreach ($this->adapters as $i => $adapter) {
|
||||
$item = $adapter->getItem($key);
|
||||
|
||||
if ($item->isHit()) {
|
||||
while (0 <= --$i) {
|
||||
$this->adapters[$i]->save($syncItem($item, $misses[$i]));
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
$misses[$i] = $item;
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
return $this->generateItems($this->adapters[0]->getItems($keys), 0);
|
||||
}
|
||||
|
||||
private function generateItems($items, $adapterIndex)
|
||||
{
|
||||
$missing = [];
|
||||
$misses = [];
|
||||
$nextAdapterIndex = $adapterIndex + 1;
|
||||
$nextAdapter = isset($this->adapters[$nextAdapterIndex]) ? $this->adapters[$nextAdapterIndex] : null;
|
||||
|
||||
foreach ($items as $k => $item) {
|
||||
if (!$nextAdapter || $item->isHit()) {
|
||||
yield $k => $item;
|
||||
} else {
|
||||
$missing[] = $k;
|
||||
$misses[$k] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if ($missing) {
|
||||
$syncItem = $this->syncItem;
|
||||
$adapter = $this->adapters[$adapterIndex];
|
||||
$items = $this->generateItems($nextAdapter->getItems($missing), $nextAdapterIndex);
|
||||
|
||||
foreach ($items as $k => $item) {
|
||||
if ($item->isHit()) {
|
||||
$adapter->save($syncItem($item, $misses[$k]));
|
||||
}
|
||||
|
||||
yield $k => $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
foreach ($this->adapters as $adapter) {
|
||||
if ($adapter->hasItem($key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$cleared = true;
|
||||
$i = $this->adapterCount;
|
||||
|
||||
while ($i--) {
|
||||
$cleared = $this->adapters[$i]->clear() && $cleared;
|
||||
}
|
||||
|
||||
return $cleared;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
$deleted = true;
|
||||
$i = $this->adapterCount;
|
||||
|
||||
while ($i--) {
|
||||
$deleted = $this->adapters[$i]->deleteItem($key) && $deleted;
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
$deleted = true;
|
||||
$i = $this->adapterCount;
|
||||
|
||||
while ($i--) {
|
||||
$deleted = $this->adapters[$i]->deleteItems($keys) && $deleted;
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
$saved = true;
|
||||
$i = $this->adapterCount;
|
||||
|
||||
while ($i--) {
|
||||
$saved = $this->adapters[$i]->save($item) && $saved;
|
||||
}
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
$saved = true;
|
||||
$i = $this->adapterCount;
|
||||
|
||||
while ($i--) {
|
||||
$saved = $this->adapters[$i]->saveDeferred($item) && $saved;
|
||||
}
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$committed = true;
|
||||
$i = $this->adapterCount;
|
||||
|
||||
while ($i--) {
|
||||
$committed = $this->adapters[$i]->commit() && $committed;
|
||||
}
|
||||
|
||||
return $committed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prune()
|
||||
{
|
||||
$pruned = true;
|
||||
|
||||
foreach ($this->adapters as $adapter) {
|
||||
if ($adapter instanceof PruneableInterface) {
|
||||
$pruned = $adapter->prune() && $pruned;
|
||||
}
|
||||
}
|
||||
|
||||
return $pruned;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
foreach ($this->adapters as $adapter) {
|
||||
if ($adapter instanceof ResettableInterface) {
|
||||
$adapter->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
core/vendor/symfony/cache/Adapter/DoctrineAdapter.php
vendored
Normal file
31
core/vendor/symfony/cache/Adapter/DoctrineAdapter.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Symfony\Component\Cache\Traits\DoctrineTrait;
|
||||
|
||||
class DoctrineAdapter extends AbstractAdapter
|
||||
{
|
||||
use DoctrineTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct(CacheProvider $provider, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->provider = $provider;
|
||||
$provider->setNamespace($namespace);
|
||||
}
|
||||
}
|
||||
31
core/vendor/symfony/cache/Adapter/FilesystemAdapter.php
vendored
Normal file
31
core/vendor/symfony/cache/Adapter/FilesystemAdapter.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\FilesystemTrait;
|
||||
|
||||
class FilesystemAdapter extends AbstractAdapter implements PruneableInterface
|
||||
{
|
||||
use FilesystemTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $directory
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $directory = null)
|
||||
{
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
}
|
||||
}
|
||||
36
core/vendor/symfony/cache/Adapter/MemcachedAdapter.php
vendored
Normal file
36
core/vendor/symfony/cache/Adapter/MemcachedAdapter.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Traits\MemcachedTrait;
|
||||
|
||||
class MemcachedAdapter extends AbstractAdapter
|
||||
{
|
||||
use MemcachedTrait;
|
||||
|
||||
protected $maxIdLength = 250;
|
||||
|
||||
/**
|
||||
* Using a MemcachedAdapter with a TagAwareAdapter for storing tags is discouraged.
|
||||
* Using a RedisAdapter is recommended instead. If you cannot do otherwise, be aware that:
|
||||
* - the Memcached::OPT_BINARY_PROTOCOL must be enabled
|
||||
* (that's the default when using MemcachedAdapter::createConnection());
|
||||
* - tags eviction by Memcached's LRU algorithm will break by-tags invalidation;
|
||||
* your Memcached memory should be large enough to never trigger LRU.
|
||||
*
|
||||
* Using a MemcachedAdapter as a pure items store is fine.
|
||||
*/
|
||||
public function __construct(\Memcached $client, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->init($client, $namespace, $defaultLifetime);
|
||||
}
|
||||
}
|
||||
121
core/vendor/symfony/cache/Adapter/NullAdapter.php
vendored
Normal file
121
core/vendor/symfony/cache/Adapter/NullAdapter.php
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
|
||||
/**
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
*/
|
||||
class NullAdapter implements AdapterInterface
|
||||
{
|
||||
private $createCacheItem;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->createCacheItem = \Closure::bind(
|
||||
function ($key) {
|
||||
$item = new CacheItem();
|
||||
$item->key = $key;
|
||||
$item->isHit = false;
|
||||
|
||||
return $item;
|
||||
},
|
||||
$this,
|
||||
CacheItem::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItem($key)
|
||||
{
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
return $f($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
return $this->generateItems($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteItem($key)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private function generateItems(array $keys)
|
||||
{
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $f($key);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
core/vendor/symfony/cache/Adapter/PdoAdapter.php
vendored
Normal file
53
core/vendor/symfony/cache/Adapter/PdoAdapter.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\PdoTrait;
|
||||
|
||||
class PdoAdapter extends AbstractAdapter 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.
|
||||
*
|
||||
* 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
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param array $options An associative array of options
|
||||
*
|
||||
* @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, $namespace = '', $defaultLifetime = 0, array $options = [])
|
||||
{
|
||||
$this->init($connOrDsn, $namespace, $defaultLifetime, $options);
|
||||
}
|
||||
}
|
||||
303
core/vendor/symfony/cache/Adapter/PhpArrayAdapter.php
vendored
Normal file
303
core/vendor/symfony/cache/Adapter/PhpArrayAdapter.php
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\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\PhpArrayTrait;
|
||||
|
||||
/**
|
||||
* Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0.
|
||||
* Warmed up items are read-only and run-time discovered items are cached using a fallback adapter.
|
||||
*
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PhpArrayAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use PhpArrayTrait;
|
||||
|
||||
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($file, AdapterInterface $fallbackPool)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->pool = $fallbackPool;
|
||||
$this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), FILTER_VALIDATE_BOOLEAN);
|
||||
$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 should only be used on PHP 7.0+ to take advantage of how PHP
|
||||
* stores arrays in its latest versions. This factory method decorates the given
|
||||
* fallback pool with this adapter only if the current PHP version is supported.
|
||||
*
|
||||
* @param string $file The PHP file were values are cached
|
||||
* @param CacheItemPoolInterface $fallbackPool Fallback for old PHP versions or opcache disabled
|
||||
*
|
||||
* @return CacheItemPoolInterface
|
||||
*/
|
||||
public static function create($file, CacheItemPoolInterface $fallbackPool)
|
||||
{
|
||||
// Shared memory is available in PHP 7.0+ with OPCache enabled and in HHVM
|
||||
if ((\PHP_VERSION_ID >= 70000 && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) || \defined('HHVM_VERSION')) {
|
||||
if (!$fallbackPool instanceof AdapterInterface) {
|
||||
$fallbackPool = new ProxyAdapter($fallbackPool);
|
||||
}
|
||||
|
||||
return new static($file, $fallbackPool);
|
||||
}
|
||||
|
||||
return $fallbackPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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->values[$key])) {
|
||||
return $this->pool->getItem($key);
|
||||
}
|
||||
|
||||
$value = $this->values[$key];
|
||||
$isHit = true;
|
||||
|
||||
if ('N;' === $value) {
|
||||
$value = null;
|
||||
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
$e = null;
|
||||
$value = unserialize($value);
|
||||
} catch (\Error $e) {
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
if (null !== $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->values[$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->values[$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->values[$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->values[$item->getKey()]) && $this->pool->save($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
if (null === $this->values) {
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->values[$item->getKey()]) && $this->pool->saveDeferred($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->pool->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Generator
|
||||
*/
|
||||
private function generateItems(array $keys)
|
||||
{
|
||||
$f = $this->createCacheItem;
|
||||
$fallbackKeys = [];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (isset($this->values[$key])) {
|
||||
$value = $this->values[$key];
|
||||
|
||||
if ('N;' === $value) {
|
||||
yield $key => $f($key, null, true);
|
||||
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
yield $key => $f($key, unserialize($value), true);
|
||||
} catch (\Error $e) {
|
||||
yield $key => $f($key, null, false);
|
||||
} catch (\Exception $e) {
|
||||
yield $key => $f($key, null, false);
|
||||
}
|
||||
} else {
|
||||
yield $key => $f($key, $value, true);
|
||||
}
|
||||
} else {
|
||||
$fallbackKeys[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fallbackKeys) {
|
||||
foreach ($this->pool->getItems($fallbackKeys) as $key => $item) {
|
||||
yield $key => $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
41
core/vendor/symfony/cache/Adapter/PhpFilesAdapter.php
vendored
Normal file
41
core/vendor/symfony/cache/Adapter/PhpFilesAdapter.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Exception\CacheException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\PhpFilesTrait;
|
||||
|
||||
class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
|
||||
{
|
||||
use PhpFilesTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $directory
|
||||
*
|
||||
* @throws CacheException if OPcache is not enabled
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $directory = null)
|
||||
{
|
||||
if (!static::isSupported()) {
|
||||
throw new CacheException('OPcache is not enabled');
|
||||
}
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
|
||||
$e = new \Exception();
|
||||
$this->includeHandler = function () use ($e) { throw $e; };
|
||||
$this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
}
|
||||
198
core/vendor/symfony/cache/Adapter/ProxyAdapter.php
vendored
Normal file
198
core/vendor/symfony/cache/Adapter/ProxyAdapter.php
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\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\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ProxyAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ProxyTrait;
|
||||
|
||||
private $namespace;
|
||||
private $namespaceLen;
|
||||
private $createCacheItem;
|
||||
private $poolHash;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct(CacheItemPoolInterface $pool, $namespace = '', $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;
|
||||
$item->defaultLifetime = $defaultLifetime;
|
||||
$item->poolHash = $poolHash;
|
||||
|
||||
if (null !== $innerItem) {
|
||||
$item->value = $innerItem->get();
|
||||
$item->isHit = $innerItem->isHit();
|
||||
$item->innerItem = $innerItem;
|
||||
$innerItem->set(null);
|
||||
}
|
||||
|
||||
return $item;
|
||||
},
|
||||
null,
|
||||
CacheItem::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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;
|
||||
$expiry = $item["\0*\0expiry"];
|
||||
if (null === $expiry && 0 < $item["\0*\0defaultLifetime"]) {
|
||||
$expiry = time() + $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"]);
|
||||
}
|
||||
|
||||
$innerItem->set($item["\0*\0value"]);
|
||||
$innerItem->expiresAt(null !== $expiry ? \DateTime::createFromFormat('U', $expiry) : null);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
29
core/vendor/symfony/cache/Adapter/RedisAdapter.php
vendored
Normal file
29
core/vendor/symfony/cache/Adapter/RedisAdapter.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\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, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->init($redisClient, $namespace, $defaultLifetime);
|
||||
}
|
||||
}
|
||||
83
core/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php
vendored
Normal file
83
core/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const NS_SEPARATOR = '_';
|
||||
|
||||
use ProxyTrait;
|
||||
|
||||
private $miss;
|
||||
|
||||
public function __construct(CacheInterface $pool, $namespace = '', $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);
|
||||
}
|
||||
}
|
||||
395
core/vendor/symfony/cache/Adapter/TagAwareAdapter.php
vendored
Normal file
395
core/vendor/symfony/cache/Adapter/TagAwareAdapter.php
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
const TAGS_PREFIX = "\0tags\0";
|
||||
|
||||
use ProxyTrait;
|
||||
|
||||
private $deferred = [];
|
||||
private $createCacheItem;
|
||||
private $setCacheItemTags;
|
||||
private $getTagsByKey;
|
||||
private $invalidateTags;
|
||||
private $tags;
|
||||
private $knownTagVersions = [];
|
||||
private $knownTagVersionsTtl;
|
||||
|
||||
public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null, $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) {
|
||||
if (!$item->isHit) {
|
||||
return $item;
|
||||
}
|
||||
if (isset($itemTags[$key])) {
|
||||
foreach ($itemTags[$key] as $tag => $version) {
|
||||
$item->prevTags[$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->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;
|
||||
}
|
||||
|
||||
$itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key);
|
||||
|
||||
if (!$itemTags->isHit()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$itemTags = $itemTags->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 __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
if ($item->isHit()) {
|
||||
$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) || $now - $this->knownTagVersions[$tag][0] >= $this->knownTagVersionsTtl) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
33
core/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php
vendored
Normal file
33
core/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Interface for invalidating cached items using tags.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
233
core/vendor/symfony/cache/Adapter/TraceableAdapter.php
vendored
Normal file
233
core/vendor/symfony/cache/Adapter/TraceableAdapter.php
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* An adapter that collects data about all cache calls.
|
||||
*
|
||||
* @author Aaron Scherer <aequasi@gmail.com>
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TraceableAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
protected $pool;
|
||||
private $calls = [];
|
||||
|
||||
public function __construct(AdapterInterface $pool)
|
||||
{
|
||||
$this->pool = $pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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 ResettableInterface) {
|
||||
return;
|
||||
}
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
$this->pool->reset();
|
||||
} 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;
|
||||
}
|
||||
36
core/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php
vendored
Normal file
36
core/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
/**
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface
|
||||
{
|
||||
public function __construct(TagAwareAdapterInterface $pool)
|
||||
{
|
||||
parent::__construct($pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function invalidateTags(array $tags)
|
||||
{
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
return $event->result = $this->pool->invalidateTags($tags);
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
core/vendor/symfony/cache/CHANGELOG.md
vendored
Normal file
36
core/vendor/symfony/cache/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* added using options from Memcached DSN
|
||||
* added PruneableInterface so PSR-6 or PSR-16 cache implementations can declare support for manual stale cache pruning
|
||||
* added prune logic to FilesystemTrait, PhpFilesTrait, PdoTrait, TagAwareAdapter and ChainTrait
|
||||
* now FilesystemAdapter, PhpFilesAdapter, FilesystemCache, PhpFilesCache, PdoAdapter, PdoCache, ChainAdapter, and
|
||||
ChainCache implement PruneableInterface and support manual stale cache pruning
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* [EXPERIMENTAL] added CacheItem::getPreviousTags() to get bound tags coming from the pool storage if any
|
||||
* added PSR-16 "Simple Cache" implementations for all existing PSR-6 adapters
|
||||
* added Psr6Cache and SimpleCacheAdapter for bidirectional interoperability between PSR-6 and PSR-16
|
||||
* added MemcachedAdapter (PSR-6) and MemcachedCache (PSR-16)
|
||||
* added TraceableAdapter (PSR-6) and TraceableCache (PSR-16)
|
||||
|
||||
3.2.0
|
||||
-----
|
||||
|
||||
* added TagAwareAdapter for tags-based invalidation
|
||||
* added PdoAdapter with PDO and Doctrine DBAL support
|
||||
* added PhpArrayAdapter and PhpFilesAdapter for OPcache-backed shared memory storage (PHP 7+ only)
|
||||
* added NullAdapter
|
||||
|
||||
3.1.0
|
||||
-----
|
||||
|
||||
* added the component with strict PSR-6 implementations
|
||||
* added ApcuAdapter, ArrayAdapter, FilesystemAdapter and RedisAdapter
|
||||
* added AbstractAdapter, ChainAdapter and ProxyAdapter
|
||||
* added DoctrineAdapter and DoctrineProvider for bidirectional interoperability with Doctrine Cache
|
||||
193
core/vendor/symfony/cache/CacheItem.php
vendored
Normal file
193
core/vendor/symfony/cache/CacheItem.php
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
final class CacheItem implements CacheItemInterface
|
||||
{
|
||||
protected $key;
|
||||
protected $value;
|
||||
protected $isHit = false;
|
||||
protected $expiry;
|
||||
protected $defaultLifetime;
|
||||
protected $tags = [];
|
||||
protected $prevTags = [];
|
||||
protected $innerItem;
|
||||
protected $poolHash;
|
||||
|
||||
/**
|
||||
* {@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 ? time() + $this->defaultLifetime : null;
|
||||
} elseif ($expiration instanceof \DateTimeInterface) {
|
||||
$this->expiry = (int) $expiration->format('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 ? time() + $this->defaultLifetime : null;
|
||||
} elseif ($time instanceof \DateInterval) {
|
||||
$this->expiry = (int) \DateTime::createFromFormat('U', time())->add($time)->format('U');
|
||||
} elseif (\is_int($time)) {
|
||||
$this->expiry = $time + time();
|
||||
} 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag to a cache item.
|
||||
*
|
||||
* @param string|string[] $tags A tag or array of tags
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException When $tag is not valid
|
||||
*/
|
||||
public function tag($tags)
|
||||
{
|
||||
if (!\is_array($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->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->tags[$tag] = $tag;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of tags bound to the value coming from the pool storage if any.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPreviousTags()
|
||||
{
|
||||
return $this->prevTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
188
core/vendor/symfony/cache/DataCollector/CacheDataCollector.php
vendored
Normal file
188
core/vendor/symfony/cache/DataCollector/CacheDataCollector.php
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\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 <aequasi@gmail.com>
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class CacheDataCollector extends DataCollector implements LateDataCollectorInterface
|
||||
{
|
||||
/**
|
||||
* @var TraceableAdapter[]
|
||||
*/
|
||||
private $instances = [];
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function addInstance($name, TraceableAdapter $instance)
|
||||
{
|
||||
$this->instances[$name] = $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
$empty = ['calls' => [], 'config' => [], 'options' => [], 'statistics' => []];
|
||||
$this->data = ['instances' => $empty, 'total' => $empty];
|
||||
foreach ($this->instances as $name => $instance) {
|
||||
$this->data['instances']['calls'][$name] = $instance->getCalls();
|
||||
}
|
||||
|
||||
$this->data['instances']['statistics'] = $this->calculateStatistics();
|
||||
$this->data['total']['statistics'] = $this->calculateTotalStatistics();
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->data = [];
|
||||
foreach ($this->instances as $instance) {
|
||||
$instance->clearCalls();
|
||||
}
|
||||
}
|
||||
|
||||
public function lateCollect()
|
||||
{
|
||||
$this->data = $this->cloneVar($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* Method returns amount of logged Cache reads: "get" calls.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getStatistics()
|
||||
{
|
||||
return $this->data['instances']['statistics'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method returns the statistic totals.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTotals()
|
||||
{
|
||||
return $this->data['total']['statistics'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method returns all logged Cache call objects.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCalls()
|
||||
{
|
||||
return $this->data['instances']['calls'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function calculateStatistics()
|
||||
{
|
||||
$statistics = [];
|
||||
foreach ($this->data['instances']['calls'] as $name => $calls) {
|
||||
$statistics[$name] = [
|
||||
'calls' => 0,
|
||||
'time' => 0,
|
||||
'reads' => 0,
|
||||
'writes' => 0,
|
||||
'deletes' => 0,
|
||||
'hits' => 0,
|
||||
'misses' => 0,
|
||||
];
|
||||
/** @var TraceableAdapterEvent $call */
|
||||
foreach ($calls as $call) {
|
||||
++$statistics[$name]['calls'];
|
||||
$statistics[$name]['time'] += $call->end - $call->start;
|
||||
if ('getItem' === $call->name) {
|
||||
++$statistics[$name]['reads'];
|
||||
if ($call->hits) {
|
||||
++$statistics[$name]['hits'];
|
||||
} else {
|
||||
++$statistics[$name]['misses'];
|
||||
}
|
||||
} elseif ('getItems' === $call->name) {
|
||||
$statistics[$name]['reads'] += $call->hits + $call->misses;
|
||||
$statistics[$name]['hits'] += $call->hits;
|
||||
$statistics[$name]['misses'] += $call->misses;
|
||||
} elseif ('hasItem' === $call->name) {
|
||||
++$statistics[$name]['reads'];
|
||||
if (false === $call->result) {
|
||||
++$statistics[$name]['misses'];
|
||||
} else {
|
||||
++$statistics[$name]['hits'];
|
||||
}
|
||||
} elseif ('save' === $call->name) {
|
||||
++$statistics[$name]['writes'];
|
||||
} elseif ('deleteItem' === $call->name) {
|
||||
++$statistics[$name]['deletes'];
|
||||
}
|
||||
}
|
||||
if ($statistics[$name]['reads']) {
|
||||
$statistics[$name]['hit_read_ratio'] = round(100 * $statistics[$name]['hits'] / $statistics[$name]['reads'], 2);
|
||||
} else {
|
||||
$statistics[$name]['hit_read_ratio'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $statistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function calculateTotalStatistics()
|
||||
{
|
||||
$statistics = $this->getStatistics();
|
||||
$totals = [
|
||||
'calls' => 0,
|
||||
'time' => 0,
|
||||
'reads' => 0,
|
||||
'writes' => 0,
|
||||
'deletes' => 0,
|
||||
'hits' => 0,
|
||||
'misses' => 0,
|
||||
];
|
||||
foreach ($statistics as $name => $values) {
|
||||
foreach ($totals as $key => $value) {
|
||||
$totals[$key] += $statistics[$name][$key];
|
||||
}
|
||||
}
|
||||
if ($totals['reads']) {
|
||||
$totals['hit_read_ratio'] = round(100 * $totals['hits'] / $totals['reads'], 2);
|
||||
} else {
|
||||
$totals['hit_read_ratio'] = null;
|
||||
}
|
||||
|
||||
return $totals;
|
||||
}
|
||||
}
|
||||
103
core/vendor/symfony/cache/DoctrineProvider.php
vendored
Normal file
103
core/vendor/symfony/cache/DoctrineProvider.php
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
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 ResettableInterface) {
|
||||
$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;
|
||||
}
|
||||
}
|
||||
19
core/vendor/symfony/cache/Exception/CacheException.php
vendored
Normal file
19
core/vendor/symfony/cache/Exception/CacheException.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Exception;
|
||||
|
||||
use Psr\Cache\CacheException as Psr6CacheInterface;
|
||||
use Psr\SimpleCache\CacheException as SimpleCacheInterface;
|
||||
|
||||
class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
|
||||
{
|
||||
}
|
||||
19
core/vendor/symfony/cache/Exception/InvalidArgumentException.php
vendored
Normal file
19
core/vendor/symfony/cache/Exception/InvalidArgumentException.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Exception;
|
||||
|
||||
use Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
|
||||
{
|
||||
}
|
||||
19
core/vendor/symfony/cache/LICENSE
vendored
Normal file
19
core/vendor/symfony/cache/LICENSE
vendored
Normal file
@@ -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.
|
||||
23
core/vendor/symfony/cache/PruneableInterface.php
vendored
Normal file
23
core/vendor/symfony/cache/PruneableInterface.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
18
core/vendor/symfony/cache/README.md
vendored
Normal file
18
core/vendor/symfony/cache/README.md
vendored
Normal file
@@ -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)
|
||||
20
core/vendor/symfony/cache/ResettableInterface.php
vendored
Normal file
20
core/vendor/symfony/cache/ResettableInterface.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
/**
|
||||
* Resets a pool's local state.
|
||||
*/
|
||||
interface ResettableInterface
|
||||
{
|
||||
public function reset();
|
||||
}
|
||||
190
core/vendor/symfony/cache/Simple/AbstractCache.php
vendored
Normal file
190
core/vendor/symfony/cache/Simple/AbstractCache.php
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\AbstractTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const NS_SEPARATOR = ':';
|
||||
|
||||
use AbstractTrait {
|
||||
deleteItems as private;
|
||||
AbstractTrait::deleteItem as delete;
|
||||
AbstractTrait::hasItem as has;
|
||||
}
|
||||
|
||||
private $defaultLifetime;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
protected function __construct($namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->defaultLifetime = max(0, (int) $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}"', ['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 requested values', ['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));
|
||||
}
|
||||
CacheItem::log($this->logger, 'Failed to save values', ['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 requested values', ['keys' => array_values($keys), 'exception' => $e]);
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $default;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
core/vendor/symfony/cache/Simple/ApcuCache.php
vendored
Normal file
29
core/vendor/symfony/cache/Simple/ApcuCache.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Traits\ApcuTrait;
|
||||
|
||||
class ApcuCache extends AbstractCache
|
||||
{
|
||||
use ApcuTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $version
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $version = null)
|
||||
{
|
||||
$this->init($namespace, $defaultLifetime, $version);
|
||||
}
|
||||
}
|
||||
148
core/vendor/symfony/cache/Simple/ArrayCache.php
vendored
Normal file
148
core/vendor/symfony/cache/Simple/ArrayCache.php
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ArrayTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use ArrayTrait {
|
||||
ArrayTrait::deleteItem as delete;
|
||||
ArrayTrait::hasItem as has;
|
||||
}
|
||||
|
||||
private $defaultLifetime;
|
||||
|
||||
/**
|
||||
* @param int $defaultLifetime
|
||||
* @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise
|
||||
*/
|
||||
public function __construct($defaultLifetime = 0, $storeSerialized = true)
|
||||
{
|
||||
$this->defaultLifetime = (int) $defaultLifetime;
|
||||
$this->storeSerialized = $storeSerialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
foreach ($this->getMultiple([$key], $default) as $v) {
|
||||
return $v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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) {
|
||||
CacheItem::validateKey($key);
|
||||
}
|
||||
|
||||
return $this->generateItems($keys, time(), 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)
|
||||
{
|
||||
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) {
|
||||
\is_int($key) || CacheItem::validateKey($key);
|
||||
$valuesArray[$key] = $value;
|
||||
}
|
||||
if (false === $ttl = $this->normalizeTtl($ttl)) {
|
||||
return $this->deleteMultiple(array_keys($valuesArray));
|
||||
}
|
||||
if ($this->storeSerialized) {
|
||||
foreach ($valuesArray as $key => $value) {
|
||||
try {
|
||||
$valuesArray[$key] = serialize($value);
|
||||
} catch (\Exception $e) {
|
||||
$type = \is_object($value) ? \get_class($value) : \gettype($value);
|
||||
CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$expiry = 0 < $ttl ? time() + $ttl : PHP_INT_MAX;
|
||||
|
||||
foreach ($valuesArray as $key => $value) {
|
||||
$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)));
|
||||
}
|
||||
}
|
||||
252
core/vendor/symfony/cache/Simple/ChainCache.php
vendored
Normal file
252
core/vendor/symfony/cache/Simple/ChainCache.php
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* Chains several caches together.
|
||||
*
|
||||
* Cached items are fetched from the first cache having them in its data store.
|
||||
* They are saved and deleted in all caches at once.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ChainCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $miss;
|
||||
private $caches = [];
|
||||
private $defaultLifetime;
|
||||
private $cacheCount;
|
||||
|
||||
/**
|
||||
* @param CacheInterface[] $caches The ordered list of caches used to fetch cached items
|
||||
* @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones
|
||||
*/
|
||||
public function __construct(array $caches, $defaultLifetime = 0)
|
||||
{
|
||||
if (!$caches) {
|
||||
throw new InvalidArgumentException('At least one cache must be specified.');
|
||||
}
|
||||
|
||||
foreach ($caches as $cache) {
|
||||
if (!$cache instanceof CacheInterface) {
|
||||
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), CacheInterface::class));
|
||||
}
|
||||
}
|
||||
|
||||
$this->miss = new \stdClass();
|
||||
$this->caches = array_values($caches);
|
||||
$this->cacheCount = \count($this->caches);
|
||||
$this->defaultLifetime = 0 < $defaultLifetime ? (int) $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 ResettableInterface) {
|
||||
$cache->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
core/vendor/symfony/cache/Simple/DoctrineCache.php
vendored
Normal file
31
core/vendor/symfony/cache/Simple/DoctrineCache.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Symfony\Component\Cache\Traits\DoctrineTrait;
|
||||
|
||||
class DoctrineCache extends AbstractCache
|
||||
{
|
||||
use DoctrineTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct(CacheProvider $provider, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->provider = $provider;
|
||||
$provider->setNamespace($namespace);
|
||||
}
|
||||
}
|
||||
31
core/vendor/symfony/cache/Simple/FilesystemCache.php
vendored
Normal file
31
core/vendor/symfony/cache/Simple/FilesystemCache.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\FilesystemTrait;
|
||||
|
||||
class FilesystemCache extends AbstractCache implements PruneableInterface
|
||||
{
|
||||
use FilesystemTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $directory
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $directory = null)
|
||||
{
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
}
|
||||
}
|
||||
30
core/vendor/symfony/cache/Simple/MemcachedCache.php
vendored
Normal file
30
core/vendor/symfony/cache/Simple/MemcachedCache.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Traits\MemcachedTrait;
|
||||
|
||||
class MemcachedCache extends AbstractCache
|
||||
{
|
||||
use MemcachedTrait;
|
||||
|
||||
protected $maxIdLength = 250;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct(\Memcached $client, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->init($client, $namespace, $defaultLifetime);
|
||||
}
|
||||
}
|
||||
86
core/vendor/symfony/cache/Simple/NullCache.php
vendored
Normal file
86
core/vendor/symfony/cache/Simple/NullCache.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class NullCache implements CacheInterface
|
||||
{
|
||||
/**
|
||||
* {@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;
|
||||
}
|
||||
}
|
||||
51
core/vendor/symfony/cache/Simple/PdoCache.php
vendored
Normal file
51
core/vendor/symfony/cache/Simple/PdoCache.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\PdoTrait;
|
||||
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param array $options An associative array of options
|
||||
*
|
||||
* @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, $namespace = '', $defaultLifetime = 0, array $options = [])
|
||||
{
|
||||
$this->init($connOrDsn, $namespace, $defaultLifetime, $options);
|
||||
}
|
||||
}
|
||||
259
core/vendor/symfony/cache/Simple/PhpArrayCache.php
vendored
Normal file
259
core/vendor/symfony/cache/Simple/PhpArrayCache.php
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\PhpArrayTrait;
|
||||
|
||||
/**
|
||||
* Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0.
|
||||
* Warmed up items are read-only and run-time discovered items are cached using a fallback adapter.
|
||||
*
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use PhpArrayTrait;
|
||||
|
||||
/**
|
||||
* @param string $file The PHP file were values are cached
|
||||
* @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit
|
||||
*/
|
||||
public function __construct($file, CacheInterface $fallbackPool)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->pool = $fallbackPool;
|
||||
$this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* This adapter should only be used on PHP 7.0+ to take advantage of how PHP
|
||||
* stores arrays in its latest versions. This factory method decorates the given
|
||||
* fallback pool with this adapter only if the current PHP version is supported.
|
||||
*
|
||||
* @param string $file The PHP file were values are cached
|
||||
*
|
||||
* @return CacheInterface
|
||||
*/
|
||||
public static function create($file, CacheInterface $fallbackPool)
|
||||
{
|
||||
// Shared memory is available in PHP 7.0+ with OPCache enabled and in HHVM
|
||||
if ((\PHP_VERSION_ID >= 70000 && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) || \defined('HHVM_VERSION')) {
|
||||
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->values[$key])) {
|
||||
return $this->pool->get($key, $default);
|
||||
}
|
||||
|
||||
$value = $this->values[$key];
|
||||
|
||||
if ('N;' === $value) {
|
||||
$value = null;
|
||||
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
$e = null;
|
||||
$value = unserialize($value);
|
||||
} catch (\Error $e) {
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
if (null !== $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->values[$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->values[$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->values[$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->values[$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->values[$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->values[$key])) {
|
||||
$value = $this->values[$key];
|
||||
|
||||
if ('N;' === $value) {
|
||||
yield $key => null;
|
||||
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||
try {
|
||||
yield $key => unserialize($value);
|
||||
} catch (\Error $e) {
|
||||
yield $key => $default;
|
||||
} catch (\Exception $e) {
|
||||
yield $key => $default;
|
||||
}
|
||||
} else {
|
||||
yield $key => $value;
|
||||
}
|
||||
} else {
|
||||
$fallbackKeys[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fallbackKeys) {
|
||||
foreach ($this->pool->getMultiple($fallbackKeys, $default) as $key => $item) {
|
||||
yield $key => $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
core/vendor/symfony/cache/Simple/PhpFilesCache.php
vendored
Normal file
41
core/vendor/symfony/cache/Simple/PhpFilesCache.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Exception\CacheException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Traits\PhpFilesTrait;
|
||||
|
||||
class PhpFilesCache extends AbstractCache implements PruneableInterface
|
||||
{
|
||||
use PhpFilesTrait;
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
* @param string|null $directory
|
||||
*
|
||||
* @throws CacheException if OPcache is not enabled
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $directory = null)
|
||||
{
|
||||
if (!static::isSupported()) {
|
||||
throw new CacheException('OPcache is not enabled');
|
||||
}
|
||||
parent::__construct('', $defaultLifetime);
|
||||
$this->init($namespace, $directory);
|
||||
|
||||
$e = new \Exception();
|
||||
$this->includeHandler = function () use ($e) { throw $e; };
|
||||
$this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
}
|
||||
241
core/vendor/symfony/cache/Simple/Psr6Cache.php
vendored
Normal file
241
core/vendor/symfony/cache/Simple/Psr6Cache.php
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\Cache\CacheException as Psr6CacheException;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\SimpleCache\CacheException as SimpleCacheException;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use ProxyTrait;
|
||||
|
||||
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, $value, $allowInt);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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 = [];
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
$values[$key] = $item->isHit() ? $item->get() : $default;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
core/vendor/symfony/cache/Simple/RedisCache.php
vendored
Normal file
29
core/vendor/symfony/cache/Simple/RedisCache.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Traits\RedisTrait;
|
||||
|
||||
class RedisCache extends AbstractCache
|
||||
{
|
||||
use RedisTrait;
|
||||
|
||||
/**
|
||||
* @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient
|
||||
* @param string $namespace
|
||||
* @param int $defaultLifetime
|
||||
*/
|
||||
public function __construct($redisClient, $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->init($redisClient, $namespace, $defaultLifetime);
|
||||
}
|
||||
}
|
||||
241
core/vendor/symfony/cache/Simple/TraceableCache.php
vendored
Normal file
241
core/vendor/symfony/cache/Simple/TraceableCache.php
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* An adapter that collects data about all cache calls.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TraceableCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $pool;
|
||||
private $miss;
|
||||
private $calls = [];
|
||||
|
||||
public function __construct(CacheInterface $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 ResettableInterface) {
|
||||
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;
|
||||
}
|
||||
46
core/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php
vendored
Normal file
46
core/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
self::$redis = null;
|
||||
}
|
||||
}
|
||||
175
core/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php
vendored
Normal file
175
core/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Cache\IntegrationTests\CachePoolTest;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
|
||||
abstract class AdapterTestCase extends CachePoolTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (!\array_key_exists('testDeferredSaveWithoutCommit', $this->skippedTests) && \defined('HHVM_VERSION')) {
|
||||
$this->skippedTests['testDeferredSaveWithoutCommit'] = 'Destructors are called late on HHVM.';
|
||||
}
|
||||
|
||||
if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) {
|
||||
$this->skippedTests['testPrune'] = 'Not a pruneable cache pool.';
|
||||
}
|
||||
}
|
||||
|
||||
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'));
|
||||
}
|
||||
}
|
||||
|
||||
class NotUnserializable implements \Serializable
|
||||
{
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(123);
|
||||
}
|
||||
|
||||
public function unserialize($ser)
|
||||
{
|
||||
throw new \Exception(__CLASS__);
|
||||
}
|
||||
}
|
||||
124
core/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php
vendored
Normal file
124
core/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
56
core/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php
vendored
Normal file
56
core/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class ArrayAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'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']);
|
||||
}
|
||||
}
|
||||
115
core/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php
vendored
Normal file
115
core/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use 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 <dunglas@gmail.com>
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class ChainAdapterTest extends AdapterTestCase
|
||||
{
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter(), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime);
|
||||
}
|
||||
|
||||
public function testEmptyAdaptersException()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('At least one adapter must be specified.');
|
||||
new ChainAdapter([]);
|
||||
}
|
||||
|
||||
public function testInvalidAdapterException()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('The class "stdClass" does not implement');
|
||||
new ChainAdapter([new \stdClass()]);
|
||||
}
|
||||
|
||||
public function testPrune()
|
||||
{
|
||||
if (isset($this->skippedTests[__FUNCTION__])) {
|
||||
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
|
||||
}
|
||||
|
||||
$cache = new ChainAdapter([
|
||||
$this->getPruneableMock(),
|
||||
$this->getNonPruneableMock(),
|
||||
$this->getPruneableMock(),
|
||||
]);
|
||||
$this->assertTrue($cache->prune());
|
||||
|
||||
$cache = new ChainAdapter([
|
||||
$this->getPruneableMock(),
|
||||
$this->getFailingPruneableMock(),
|
||||
$this->getPruneableMock(),
|
||||
]);
|
||||
$this->assertFalse($cache->prune());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|PruneableCacheInterface
|
||||
*/
|
||||
private function getPruneableMock()
|
||||
{
|
||||
$pruneable = $this
|
||||
->getMockBuilder(PruneableCacheInterface::class)
|
||||
->getMock();
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
->method('prune')
|
||||
->willReturn(true);
|
||||
|
||||
return $pruneable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|PruneableCacheInterface
|
||||
*/
|
||||
private function getFailingPruneableMock()
|
||||
{
|
||||
$pruneable = $this
|
||||
->getMockBuilder(PruneableCacheInterface::class)
|
||||
->getMock();
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
->method('prune')
|
||||
->willReturn(false);
|
||||
|
||||
return $pruneable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|AdapterInterface
|
||||
*/
|
||||
private function getNonPruneableMock()
|
||||
{
|
||||
return $this
|
||||
->getMockBuilder(AdapterInterface::class)
|
||||
->getMock();
|
||||
}
|
||||
}
|
||||
|
||||
interface PruneableCacheInterface extends PruneableInterface, AdapterInterface
|
||||
{
|
||||
}
|
||||
32
core/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php
vendored
Normal file
32
core/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
|
||||
use Symfony\Component\Cache\Tests\Fixtures\ArrayCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class DoctrineAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayCache is not.',
|
||||
'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayCache is not.',
|
||||
'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize',
|
||||
];
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new DoctrineAdapter(new ArrayCache($defaultLifetime), '', $defaultLifetime);
|
||||
}
|
||||
}
|
||||
61
core/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php
vendored
Normal file
61
core/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class FilesystemAdapterTest extends AdapterTestCase
|
||||
{
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new FilesystemAdapter('', $defaultLifetime);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
self::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
|
||||
public static function rmdir($dir)
|
||||
{
|
||||
if (!file_exists($dir)) {
|
||||
return;
|
||||
}
|
||||
if (!$dir || 0 !== strpos(\dirname($dir), sys_get_temp_dir())) {
|
||||
throw new \Exception(__METHOD__."() operates only on subdirs of system's temp dir");
|
||||
}
|
||||
$children = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
\RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
foreach ($children as $child) {
|
||||
if ($child->isDir()) {
|
||||
rmdir($child);
|
||||
} else {
|
||||
unlink($child);
|
||||
}
|
||||
}
|
||||
rmdir($dir);
|
||||
}
|
||||
|
||||
protected function isPruned(CacheItemPoolInterface $cache, $name)
|
||||
{
|
||||
$getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile');
|
||||
$getFileMethod->setAccessible(true);
|
||||
|
||||
return !file_exists($getFileMethod->invoke($cache, $name));
|
||||
}
|
||||
}
|
||||
87
core/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php
vendored
Normal file
87
core/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
|
||||
class MaxIdLengthAdapterTest extends TestCase
|
||||
{
|
||||
public function testLongKey()
|
||||
{
|
||||
$cache = $this->getMockBuilder(MaxIdLengthAdapter::class)
|
||||
->setConstructorArgs([str_repeat('-', 10)])
|
||||
->setMethods(['doHave', 'doFetch', 'doDelete', 'doSave', 'doClear'])
|
||||
->getMock();
|
||||
|
||||
$cache->expects($this->exactly(2))
|
||||
->method('doHave')
|
||||
->withConsecutive(
|
||||
[$this->equalTo('----------:0GTYWa9n4ed8vqNlOT2iEr:')],
|
||||
[$this->equalTo('----------:---------------------------------------')]
|
||||
);
|
||||
|
||||
$cache->hasItem(str_repeat('-', 40));
|
||||
$cache->hasItem(str_repeat('-', 39));
|
||||
}
|
||||
|
||||
public function testLongKeyVersioning()
|
||||
{
|
||||
$cache = $this->getMockBuilder(MaxIdLengthAdapter::class)
|
||||
->setConstructorArgs([str_repeat('-', 26)])
|
||||
->getMock();
|
||||
|
||||
$cache
|
||||
->method('doFetch')
|
||||
->willReturn(['2:']);
|
||||
|
||||
$reflectionClass = new \ReflectionClass(AbstractAdapter::class);
|
||||
|
||||
$reflectionMethod = $reflectionClass->getMethod('getId');
|
||||
$reflectionMethod->setAccessible(true);
|
||||
|
||||
// No versioning enabled
|
||||
$this->assertEquals('--------------------------:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]));
|
||||
$this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])));
|
||||
$this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)])));
|
||||
$this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)])));
|
||||
|
||||
$reflectionProperty = $reflectionClass->getProperty('versioningIsEnabled');
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$reflectionProperty->setValue($cache, true);
|
||||
|
||||
// Versioning enabled
|
||||
$this->assertEquals('--------------------------:2:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]));
|
||||
$this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])));
|
||||
$this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)])));
|
||||
$this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)])));
|
||||
}
|
||||
|
||||
public function testTooLongNamespace()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Namespace must be 26 chars max, 40 given ("----------------------------------------")');
|
||||
$this->getMockBuilder(MaxIdLengthAdapter::class)
|
||||
->setConstructorArgs([str_repeat('-', 40)])
|
||||
->getMock();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class MaxIdLengthAdapter extends AbstractAdapter
|
||||
{
|
||||
protected $maxIdLength = 50;
|
||||
|
||||
public function __construct($ns)
|
||||
{
|
||||
parent::__construct($ns);
|
||||
}
|
||||
}
|
||||
198
core/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php
vendored
Normal file
198
core/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
|
||||
|
||||
class MemcachedAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite',
|
||||
'testDefaultLifeTime' => 'Testing expiration slows down the test suite',
|
||||
];
|
||||
|
||||
protected static $client;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!MemcachedAdapter::isSupported()) {
|
||||
self::markTestSkipped('Extension memcached >=2.2.0 required.');
|
||||
}
|
||||
self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]);
|
||||
self::$client->get('foo');
|
||||
$code = self::$client->getResultCode();
|
||||
|
||||
if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) {
|
||||
self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
$client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST')) : self::$client;
|
||||
|
||||
return new MemcachedAdapter($client, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||
}
|
||||
|
||||
public function testOptions()
|
||||
{
|
||||
$client = MemcachedAdapter::createConnection([], [
|
||||
'libketama_compatible' => false,
|
||||
'distribution' => 'modula',
|
||||
'compression' => true,
|
||||
'serializer' => 'php',
|
||||
'hash' => 'md5',
|
||||
]);
|
||||
|
||||
$this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER));
|
||||
$this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH));
|
||||
$this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION));
|
||||
$this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE));
|
||||
$this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideBadOptions
|
||||
*/
|
||||
public function testBadOptions($name, $value)
|
||||
{
|
||||
$this->expectException('ErrorException');
|
||||
$this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::');
|
||||
MemcachedAdapter::createConnection([], [$name => $value]);
|
||||
}
|
||||
|
||||
public function provideBadOptions()
|
||||
{
|
||||
return [
|
||||
['foo', 'bar'],
|
||||
['hash', 'zyx'],
|
||||
['serializer', 'zyx'],
|
||||
['distribution', 'zyx'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testDefaultOptions()
|
||||
{
|
||||
$this->assertTrue(MemcachedAdapter::isSupported());
|
||||
|
||||
$client = MemcachedAdapter::createConnection([]);
|
||||
|
||||
$this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION));
|
||||
$this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL));
|
||||
$this->assertSame(1, $client->getOption(\Memcached::OPT_TCP_NODELAY));
|
||||
$this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE));
|
||||
}
|
||||
|
||||
public function testOptionSerializer()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\CacheException');
|
||||
$this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
|
||||
if (!\Memcached::HAVE_JSON) {
|
||||
$this->markTestSkipped('Memcached::HAVE_JSON required');
|
||||
}
|
||||
|
||||
new MemcachedAdapter(MemcachedAdapter::createConnection([], ['serializer' => 'json']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideServersSetting
|
||||
*/
|
||||
public function testServersSetting($dsn, $host, $port)
|
||||
{
|
||||
$client1 = MemcachedAdapter::createConnection($dsn);
|
||||
$client2 = MemcachedAdapter::createConnection([$dsn]);
|
||||
$client3 = MemcachedAdapter::createConnection([[$host, $port]]);
|
||||
$expect = [
|
||||
'host' => $host,
|
||||
'port' => $port,
|
||||
];
|
||||
|
||||
$f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; };
|
||||
$this->assertSame([$expect], array_map($f, $client1->getServerList()));
|
||||
$this->assertSame([$expect], array_map($f, $client2->getServerList()));
|
||||
$this->assertSame([$expect], array_map($f, $client3->getServerList()));
|
||||
}
|
||||
|
||||
public function provideServersSetting()
|
||||
{
|
||||
yield [
|
||||
'memcached://127.0.0.1/50',
|
||||
'127.0.0.1',
|
||||
11211,
|
||||
];
|
||||
yield [
|
||||
'memcached://localhost:11222?weight=25',
|
||||
'localhost',
|
||||
11222,
|
||||
];
|
||||
if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) {
|
||||
yield [
|
||||
'memcached://user:password@127.0.0.1?weight=50',
|
||||
'127.0.0.1',
|
||||
11211,
|
||||
];
|
||||
}
|
||||
yield [
|
||||
'memcached:///var/run/memcached.sock?weight=25',
|
||||
'/var/run/memcached.sock',
|
||||
0,
|
||||
];
|
||||
yield [
|
||||
'memcached:///var/local/run/memcached.socket?weight=25',
|
||||
'/var/local/run/memcached.socket',
|
||||
0,
|
||||
];
|
||||
if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) {
|
||||
yield [
|
||||
'memcached://user:password@/var/local/run/memcached.socket?weight=25',
|
||||
'/var/local/run/memcached.socket',
|
||||
0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDsnWithOptions
|
||||
*/
|
||||
public function testDsnWithOptions($dsn, array $options, array $expectedOptions)
|
||||
{
|
||||
$client = MemcachedAdapter::createConnection($dsn, $options);
|
||||
|
||||
foreach ($expectedOptions as $option => $expect) {
|
||||
$this->assertSame($expect, $client->getOption($option));
|
||||
}
|
||||
}
|
||||
|
||||
public function provideDsnWithOptions()
|
||||
{
|
||||
if (!class_exists('\Memcached')) {
|
||||
self::markTestSkipped('Extension memcached required.');
|
||||
}
|
||||
|
||||
yield [
|
||||
'memcached://localhost:11222?retry_timeout=10',
|
||||
[\Memcached::OPT_RETRY_TIMEOUT => 8],
|
||||
[\Memcached::OPT_RETRY_TIMEOUT => 10],
|
||||
];
|
||||
yield [
|
||||
'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2',
|
||||
[\Memcached::OPT_RETRY_TIMEOUT => 8],
|
||||
[\Memcached::OPT_SOCKET_RECV_SIZE => 1, \Memcached::OPT_SOCKET_SEND_SIZE => 2, \Memcached::OPT_RETRY_TIMEOUT => 8],
|
||||
];
|
||||
}
|
||||
|
||||
public function testClear()
|
||||
{
|
||||
$this->assertTrue($this->createCachePool()->clear());
|
||||
}
|
||||
}
|
||||
26
core/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php
vendored
Normal file
26
core/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class NamespacedProxyAdapterTest extends ProxyAdapterTest
|
||||
{
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new ProxyAdapter(new ArrayAdapter($defaultLifetime), 'foo', $defaultLifetime);
|
||||
}
|
||||
}
|
||||
128
core/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php
vendored
Normal file
128
core/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\Adapter\NullAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class NullAdapterTest extends TestCase
|
||||
{
|
||||
public function createCachePool()
|
||||
{
|
||||
return new NullAdapter();
|
||||
}
|
||||
|
||||
public function testGetItem()
|
||||
{
|
||||
$adapter = $this->createCachePool();
|
||||
|
||||
$item = $adapter->getItem('key');
|
||||
$this->assertFalse($item->isHit());
|
||||
$this->assertNull($item->get(), "Item's value must be null when isHit is false.");
|
||||
}
|
||||
|
||||
public function testHasItem()
|
||||
{
|
||||
$this->assertFalse($this->createCachePool()->hasItem('key'));
|
||||
}
|
||||
|
||||
public function testGetItems()
|
||||
{
|
||||
$adapter = $this->createCachePool();
|
||||
|
||||
$keys = ['foo', 'bar', 'baz', 'biz'];
|
||||
|
||||
/** @var CacheItemInterface[] $items */
|
||||
$items = $adapter->getItems($keys);
|
||||
$count = 0;
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
$itemKey = $item->getKey();
|
||||
|
||||
$this->assertEquals($itemKey, $key, 'Keys must be preserved when fetching multiple items');
|
||||
$this->assertContains($key, $keys, 'Cache key can not change.');
|
||||
$this->assertFalse($item->isHit());
|
||||
|
||||
// Remove $key for $keys
|
||||
foreach ($keys as $k => $v) {
|
||||
if ($v === $key) {
|
||||
unset($keys[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
++$count;
|
||||
}
|
||||
|
||||
$this->assertSame(4, $count);
|
||||
}
|
||||
|
||||
public function testIsHit()
|
||||
{
|
||||
$adapter = $this->createCachePool();
|
||||
|
||||
$item = $adapter->getItem('key');
|
||||
$this->assertFalse($item->isHit());
|
||||
}
|
||||
|
||||
public function testClear()
|
||||
{
|
||||
$this->assertTrue($this->createCachePool()->clear());
|
||||
}
|
||||
|
||||
public function testDeleteItem()
|
||||
{
|
||||
$this->assertTrue($this->createCachePool()->deleteItem('key'));
|
||||
}
|
||||
|
||||
public function testDeleteItems()
|
||||
{
|
||||
$this->assertTrue($this->createCachePool()->deleteItems(['key', 'foo', 'bar']));
|
||||
}
|
||||
|
||||
public function testSave()
|
||||
{
|
||||
$adapter = $this->createCachePool();
|
||||
|
||||
$item = $adapter->getItem('key');
|
||||
$this->assertFalse($item->isHit());
|
||||
$this->assertNull($item->get(), "Item's value must be null when isHit is false.");
|
||||
|
||||
$this->assertFalse($adapter->save($item));
|
||||
}
|
||||
|
||||
public function testDeferredSave()
|
||||
{
|
||||
$adapter = $this->createCachePool();
|
||||
|
||||
$item = $adapter->getItem('key');
|
||||
$this->assertFalse($item->isHit());
|
||||
$this->assertNull($item->get(), "Item's value must be null when isHit is false.");
|
||||
|
||||
$this->assertFalse($adapter->saveDeferred($item));
|
||||
}
|
||||
|
||||
public function testCommit()
|
||||
{
|
||||
$adapter = $this->createCachePool();
|
||||
|
||||
$item = $adapter->getItem('key');
|
||||
$this->assertFalse($item->isHit());
|
||||
$this->assertNull($item->get(), "Item's value must be null when isHit is false.");
|
||||
|
||||
$this->assertFalse($adapter->saveDeferred($item));
|
||||
$this->assertFalse($this->createCachePool()->commit());
|
||||
}
|
||||
}
|
||||
73
core/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php
vendored
Normal file
73
core/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\PdoAdapter;
|
||||
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PdoAdapterTest extends AdapterTestCase
|
||||
{
|
||||
use PdoPruneableTrait;
|
||||
|
||||
protected static $dbFile;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!\extension_loaded('pdo_sqlite')) {
|
||||
self::markTestSkipped('Extension pdo_sqlite required.');
|
||||
}
|
||||
|
||||
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
|
||||
|
||||
$pool = new PdoAdapter('sqlite:'.self::$dbFile);
|
||||
$pool->createTable();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
@unlink(self::$dbFile);
|
||||
}
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new PdoAdapter('sqlite:'.self::$dbFile, 'ns', $defaultLifetime);
|
||||
}
|
||||
|
||||
public function testCleanupExpiredItems()
|
||||
{
|
||||
$pdo = new \PDO('sqlite:'.self::$dbFile);
|
||||
|
||||
$getCacheItemCount = function () use ($pdo) {
|
||||
return (int) $pdo->query('SELECT COUNT(*) FROM cache_items')->fetch(\PDO::FETCH_COLUMN);
|
||||
};
|
||||
|
||||
$this->assertSame(0, $getCacheItemCount());
|
||||
|
||||
$cache = $this->createCachePool();
|
||||
|
||||
$item = $cache->getItem('some_nice_key');
|
||||
$item->expiresAfter(1);
|
||||
$item->set(1);
|
||||
|
||||
$cache->save($item);
|
||||
$this->assertSame(1, $getCacheItemCount());
|
||||
|
||||
sleep(2);
|
||||
|
||||
$newItem = $cache->getItem($item->getKey());
|
||||
$this->assertFalse($newItem->isHit());
|
||||
$this->assertSame(0, $getCacheItemCount(), 'PDOAdapter must clean up expired items');
|
||||
}
|
||||
}
|
||||
48
core/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php
vendored
Normal file
48
core/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Symfony\Component\Cache\Adapter\PdoAdapter;
|
||||
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PdoDbalAdapterTest extends AdapterTestCase
|
||||
{
|
||||
use PdoPruneableTrait;
|
||||
|
||||
protected static $dbFile;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!\extension_loaded('pdo_sqlite')) {
|
||||
self::markTestSkipped('Extension pdo_sqlite required.');
|
||||
}
|
||||
|
||||
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
|
||||
|
||||
$pool = new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]));
|
||||
$pool->createTable();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
@unlink(self::$dbFile);
|
||||
}
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime);
|
||||
}
|
||||
}
|
||||
133
core/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php
vendored
Normal file
133
core/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\Adapter\NullAdapter;
|
||||
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PhpArrayAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testBasicUsage' => 'PhpArrayAdapter is read-only.',
|
||||
'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.',
|
||||
'testClear' => 'PhpArrayAdapter is read-only.',
|
||||
'testClearWithDeferredItems' => 'PhpArrayAdapter is read-only.',
|
||||
'testDeleteItem' => 'PhpArrayAdapter is read-only.',
|
||||
'testSaveExpired' => 'PhpArrayAdapter is read-only.',
|
||||
'testSaveWithoutExpire' => 'PhpArrayAdapter is read-only.',
|
||||
'testDeferredSave' => 'PhpArrayAdapter is read-only.',
|
||||
'testDeferredSaveWithoutCommit' => 'PhpArrayAdapter is read-only.',
|
||||
'testDeleteItems' => 'PhpArrayAdapter is read-only.',
|
||||
'testDeleteDeferredItem' => 'PhpArrayAdapter is read-only.',
|
||||
'testCommit' => 'PhpArrayAdapter is read-only.',
|
||||
'testSaveDeferredWhenChangingValues' => 'PhpArrayAdapter is read-only.',
|
||||
'testSaveDeferredOverwrite' => 'PhpArrayAdapter is read-only.',
|
||||
'testIsHitDeferred' => 'PhpArrayAdapter is read-only.',
|
||||
|
||||
'testExpiresAt' => 'PhpArrayAdapter does not support expiration.',
|
||||
'testExpiresAtWithNull' => 'PhpArrayAdapter does not support expiration.',
|
||||
'testExpiresAfterWithNull' => 'PhpArrayAdapter does not support expiration.',
|
||||
'testDeferredExpired' => 'PhpArrayAdapter does not support expiration.',
|
||||
'testExpiration' => 'PhpArrayAdapter does not support expiration.',
|
||||
|
||||
'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
|
||||
'testDefaultLifeTime' => 'PhpArrayAdapter does not allow configuring a default lifetime.',
|
||||
'testPrune' => 'PhpArrayAdapter just proxies',
|
||||
];
|
||||
|
||||
protected static $file;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php';
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
|
||||
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
}
|
||||
|
||||
public function createCachePool()
|
||||
{
|
||||
return new PhpArrayAdapterWrapper(self::$file, new NullAdapter());
|
||||
}
|
||||
|
||||
public function testStore()
|
||||
{
|
||||
$arrayWithRefs = [];
|
||||
$arrayWithRefs[0] = 123;
|
||||
$arrayWithRefs[1] = &$arrayWithRefs[0];
|
||||
|
||||
$object = (object) [
|
||||
'foo' => 'bar',
|
||||
'foo2' => 'bar2',
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'null' => null,
|
||||
'serializedString' => serialize($object),
|
||||
'arrayWithRefs' => $arrayWithRefs,
|
||||
'object' => $object,
|
||||
'arrayWithObject' => ['bar' => $object],
|
||||
];
|
||||
|
||||
$adapter = $this->createCachePool();
|
||||
$adapter->warmUp($expected);
|
||||
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertSame(serialize($value), serialize($adapter->getItem($key)->get()), 'Warm up should create a PHP file that OPCache can load in memory');
|
||||
}
|
||||
}
|
||||
|
||||
public function testStoredFile()
|
||||
{
|
||||
$expected = [
|
||||
'integer' => 42,
|
||||
'float' => 42.42,
|
||||
'boolean' => true,
|
||||
'array_simple' => ['foo', 'bar'],
|
||||
'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'],
|
||||
];
|
||||
|
||||
$adapter = $this->createCachePool();
|
||||
$adapter->warmUp($expected);
|
||||
|
||||
$values = eval(substr(file_get_contents(self::$file), 6));
|
||||
|
||||
$this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory');
|
||||
}
|
||||
}
|
||||
|
||||
class PhpArrayAdapterWrapper extends PhpArrayAdapter
|
||||
{
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
\call_user_func(\Closure::bind(function () use ($item) {
|
||||
$this->values[$item->getKey()] = $item->get();
|
||||
$this->warmUp($this->values);
|
||||
$this->values = eval(substr(file_get_contents($this->file), 6));
|
||||
}, $this, PhpArrayAdapter::class));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
49
core/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php
vendored
Normal file
49
core/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PhpArrayAdapterWithFallbackTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testPrune' => 'PhpArrayAdapter just proxies',
|
||||
];
|
||||
|
||||
protected static $file;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php';
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
|
||||
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
}
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new PhpArrayAdapter(self::$file, new FilesystemAdapter('php-array-fallback', $defaultLifetime));
|
||||
}
|
||||
}
|
||||
47
core/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php
vendored
Normal file
47
core/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PhpFilesAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testDefaultLifeTime' => 'PhpFilesAdapter does not allow configuring a default lifetime.',
|
||||
];
|
||||
|
||||
public function createCachePool()
|
||||
{
|
||||
if (!PhpFilesAdapter::isSupported()) {
|
||||
$this->markTestSkipped('OPcache extension is not enabled.');
|
||||
}
|
||||
|
||||
return new PhpFilesAdapter('sf-cache');
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
|
||||
protected function isPruned(CacheItemPoolInterface $cache, $name)
|
||||
{
|
||||
$getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile');
|
||||
$getFileMethod->setAccessible(true);
|
||||
|
||||
return !file_exists($getFileMethod->invoke($cache, $name));
|
||||
}
|
||||
}
|
||||
53
core/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php
vendored
Normal file
53
core/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Predis\Connection\StreamConnection;
|
||||
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
||||
|
||||
class PredisAdapterTest extends AbstractRedisAdapterTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')]);
|
||||
}
|
||||
|
||||
public function testCreateConnection()
|
||||
{
|
||||
$redisHost = getenv('REDIS_HOST');
|
||||
|
||||
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'/1', ['class' => \Predis\Client::class, 'timeout' => 3]);
|
||||
$this->assertInstanceOf(\Predis\Client::class, $redis);
|
||||
|
||||
$connection = $redis->getConnection();
|
||||
$this->assertInstanceOf(StreamConnection::class, $connection);
|
||||
|
||||
$params = [
|
||||
'scheme' => 'tcp',
|
||||
'host' => $redisHost,
|
||||
'path' => '',
|
||||
'dbindex' => '1',
|
||||
'port' => 6379,
|
||||
'class' => 'Predis\Client',
|
||||
'timeout' => 3,
|
||||
'persistent' => 0,
|
||||
'persistent_id' => null,
|
||||
'read_timeout' => 0,
|
||||
'retry_interval' => 0,
|
||||
'lazy' => false,
|
||||
'database' => '1',
|
||||
'password' => null,
|
||||
];
|
||||
$this->assertSame($params, $connection->getParameters()->toArray());
|
||||
}
|
||||
}
|
||||
26
core/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php
vendored
Normal file
26
core/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
class PredisClusterAdapterTest extends AbstractRedisAdapterTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]]);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
self::$redis = null;
|
||||
}
|
||||
}
|
||||
28
core/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php
vendored
Normal file
28
core/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
class PredisRedisClusterAdapterTest extends AbstractRedisAdapterTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) {
|
||||
self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
|
||||
}
|
||||
self::$redis = new \Predis\Client(explode(' ', $hosts), ['cluster' => 'redis']);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
self::$redis = null;
|
||||
}
|
||||
}
|
||||
69
core/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php
vendored
Normal file
69
core/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class ProxyAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.',
|
||||
'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.',
|
||||
'testPrune' => 'ProxyAdapter just proxies',
|
||||
];
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new ProxyAdapter(new ArrayAdapter(), '', $defaultLifetime);
|
||||
}
|
||||
|
||||
public function testProxyfiedItem()
|
||||
{
|
||||
$this->expectException('Exception');
|
||||
$this->expectExceptionMessage('OK bar');
|
||||
$item = new CacheItem();
|
||||
$pool = new ProxyAdapter(new TestingArrayAdapter($item));
|
||||
|
||||
$proxyItem = $pool->getItem('foo');
|
||||
|
||||
$this->assertNotSame($item, $proxyItem);
|
||||
$pool->save($proxyItem->set('bar'));
|
||||
}
|
||||
}
|
||||
|
||||
class TestingArrayAdapter extends ArrayAdapter
|
||||
{
|
||||
private $item;
|
||||
|
||||
public function __construct(CacheItemInterface $item)
|
||||
{
|
||||
$this->item = $item;
|
||||
}
|
||||
|
||||
public function getItem($key)
|
||||
{
|
||||
return $this->item;
|
||||
}
|
||||
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
if ($item === $this->item) {
|
||||
throw new \Exception('OK '.$item->get());
|
||||
}
|
||||
}
|
||||
}
|
||||
92
core/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php
vendored
Normal file
92
core/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
||||
use Symfony\Component\Cache\Traits\RedisProxy;
|
||||
|
||||
class RedisAdapterTest extends AbstractRedisAdapterTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]);
|
||||
}
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
$adapter = parent::createCachePool($defaultLifetime);
|
||||
$this->assertInstanceOf(RedisProxy::class, self::$redis);
|
||||
|
||||
return $adapter;
|
||||
}
|
||||
|
||||
public function testCreateConnection()
|
||||
{
|
||||
$redisHost = getenv('REDIS_HOST');
|
||||
|
||||
$redis = RedisAdapter::createConnection('redis://'.$redisHost);
|
||||
$this->assertInstanceOf(\Redis::class, $redis);
|
||||
$this->assertTrue($redis->isConnected());
|
||||
$this->assertSame(0, $redis->getDbNum());
|
||||
|
||||
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2');
|
||||
$this->assertSame(2, $redis->getDbNum());
|
||||
|
||||
$redis = RedisAdapter::createConnection('redis://'.$redisHost, ['timeout' => 3]);
|
||||
$this->assertEquals(3, $redis->getTimeout());
|
||||
|
||||
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4');
|
||||
$this->assertEquals(4, $redis->getTimeout());
|
||||
|
||||
$redis = RedisAdapter::createConnection('redis://'.$redisHost, ['read_timeout' => 5]);
|
||||
$this->assertEquals(5, $redis->getReadTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFailedCreateConnection
|
||||
*/
|
||||
public function testFailedCreateConnection($dsn)
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Redis connection failed');
|
||||
RedisAdapter::createConnection($dsn);
|
||||
}
|
||||
|
||||
public function provideFailedCreateConnection()
|
||||
{
|
||||
return [
|
||||
['redis://localhost:1234'],
|
||||
['redis://foo@localhost'],
|
||||
['redis://localhost/123'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidCreateConnection
|
||||
*/
|
||||
public function testInvalidCreateConnection($dsn)
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Invalid Redis DSN');
|
||||
RedisAdapter::createConnection($dsn);
|
||||
}
|
||||
|
||||
public function provideInvalidCreateConnection()
|
||||
{
|
||||
return [
|
||||
['foo://localhost'],
|
||||
['redis://'],
|
||||
];
|
||||
}
|
||||
}
|
||||
24
core/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php
vendored
Normal file
24
core/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
class RedisArrayAdapterTest extends AbstractRedisAdapterTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setupBeforeClass();
|
||||
if (!class_exists('RedisArray')) {
|
||||
self::markTestSkipped('The RedisArray class is required.');
|
||||
}
|
||||
self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]);
|
||||
}
|
||||
}
|
||||
27
core/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php
vendored
Normal file
27
core/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
class RedisClusterAdapterTest extends AbstractRedisAdapterTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!class_exists('RedisCluster')) {
|
||||
self::markTestSkipped('The RedisCluster class is required.');
|
||||
}
|
||||
if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) {
|
||||
self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
|
||||
}
|
||||
|
||||
self::$redis = new \RedisCluster(null, explode(' ', $hosts));
|
||||
}
|
||||
}
|
||||
41
core/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php
vendored
Normal file
41
core/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\SimpleCacheAdapter;
|
||||
use Symfony\Component\Cache\Simple\ArrayCache;
|
||||
use Symfony\Component\Cache\Simple\FilesystemCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class SimpleCacheAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testPrune' => 'SimpleCache just proxies',
|
||||
];
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime);
|
||||
}
|
||||
|
||||
public function testValidCacheKeyWithNamespace()
|
||||
{
|
||||
$cache = new SimpleCacheAdapter(new ArrayCache(), 'some_namespace', 0);
|
||||
$item = $cache->getItem('my_key');
|
||||
$item->set('someValue');
|
||||
$cache->save($item);
|
||||
|
||||
$this->assertTrue($cache->getItem('my_key')->isHit(), 'Stored item is successfully retrieved.');
|
||||
}
|
||||
}
|
||||
318
core/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php
vendored
Normal file
318
core/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class TagAwareAdapterTest extends AdapterTestCase
|
||||
{
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new TagAwareAdapter(new FilesystemAdapter('', $defaultLifetime));
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
|
||||
public function testInvalidTag()
|
||||
{
|
||||
$this->expectException('Psr\Cache\InvalidArgumentException');
|
||||
$pool = $this->createCachePool();
|
||||
$item = $pool->getItem('foo');
|
||||
$item->tag(':');
|
||||
}
|
||||
|
||||
public function testInvalidateTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$i0 = $pool->getItem('i0');
|
||||
$i1 = $pool->getItem('i1');
|
||||
$i2 = $pool->getItem('i2');
|
||||
$i3 = $pool->getItem('i3');
|
||||
$foo = $pool->getItem('foo');
|
||||
|
||||
$pool->save($i0->tag('bar'));
|
||||
$pool->save($i1->tag('foo'));
|
||||
$pool->save($i2->tag('foo')->tag('bar'));
|
||||
$pool->save($i3->tag('foo')->tag('baz'));
|
||||
$pool->save($foo);
|
||||
|
||||
$pool->invalidateTags(['bar']);
|
||||
|
||||
$this->assertFalse($pool->getItem('i0')->isHit());
|
||||
$this->assertTrue($pool->getItem('i1')->isHit());
|
||||
$this->assertFalse($pool->getItem('i2')->isHit());
|
||||
$this->assertTrue($pool->getItem('i3')->isHit());
|
||||
$this->assertTrue($pool->getItem('foo')->isHit());
|
||||
|
||||
$pool->invalidateTags(['foo']);
|
||||
|
||||
$this->assertFalse($pool->getItem('i1')->isHit());
|
||||
$this->assertFalse($pool->getItem('i3')->isHit());
|
||||
$this->assertTrue($pool->getItem('foo')->isHit());
|
||||
|
||||
$anotherPoolInstance = $this->createCachePool();
|
||||
|
||||
$this->assertFalse($anotherPoolInstance->getItem('i1')->isHit());
|
||||
$this->assertFalse($anotherPoolInstance->getItem('i3')->isHit());
|
||||
$this->assertTrue($anotherPoolInstance->getItem('foo')->isHit());
|
||||
}
|
||||
|
||||
public function testInvalidateCommits()
|
||||
{
|
||||
$pool1 = $this->createCachePool();
|
||||
|
||||
$foo = $pool1->getItem('foo');
|
||||
$foo->tag('tag');
|
||||
|
||||
$pool1->saveDeferred($foo->set('foo'));
|
||||
$pool1->invalidateTags(['tag']);
|
||||
|
||||
$pool2 = $this->createCachePool();
|
||||
$foo = $pool2->getItem('foo');
|
||||
|
||||
$this->assertTrue($foo->isHit());
|
||||
}
|
||||
|
||||
public function testTagsAreCleanedOnSave()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$i = $pool->getItem('k');
|
||||
$pool->save($i->tag('foo'));
|
||||
|
||||
$i = $pool->getItem('k');
|
||||
$pool->save($i->tag('bar'));
|
||||
|
||||
$pool->invalidateTags(['foo']);
|
||||
$this->assertTrue($pool->getItem('k')->isHit());
|
||||
}
|
||||
|
||||
public function testTagsAreCleanedOnDelete()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$i = $pool->getItem('k');
|
||||
$pool->save($i->tag('foo'));
|
||||
$pool->deleteItem('k');
|
||||
|
||||
$pool->save($pool->getItem('k'));
|
||||
$pool->invalidateTags(['foo']);
|
||||
|
||||
$this->assertTrue($pool->getItem('k')->isHit());
|
||||
}
|
||||
|
||||
public function testTagItemExpiry()
|
||||
{
|
||||
$pool = $this->createCachePool(10);
|
||||
|
||||
$item = $pool->getItem('foo');
|
||||
$item->tag(['baz']);
|
||||
$item->expiresAfter(100);
|
||||
|
||||
$pool->save($item);
|
||||
$pool->invalidateTags(['baz']);
|
||||
$this->assertFalse($pool->getItem('foo')->isHit());
|
||||
|
||||
sleep(20);
|
||||
|
||||
$this->assertFalse($pool->getItem('foo')->isHit());
|
||||
}
|
||||
|
||||
public function testGetPreviousTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$i = $pool->getItem('k');
|
||||
$pool->save($i->tag('foo'));
|
||||
|
||||
$i = $pool->getItem('k');
|
||||
$this->assertSame(['foo' => 'foo'], $i->getPreviousTags());
|
||||
}
|
||||
|
||||
public function testPrune()
|
||||
{
|
||||
$cache = new TagAwareAdapter($this->getPruneableMock());
|
||||
$this->assertTrue($cache->prune());
|
||||
|
||||
$cache = new TagAwareAdapter($this->getNonPruneableMock());
|
||||
$this->assertFalse($cache->prune());
|
||||
|
||||
$cache = new TagAwareAdapter($this->getFailingPruneableMock());
|
||||
$this->assertFalse($cache->prune());
|
||||
}
|
||||
|
||||
public function testKnownTagVersionsTtl()
|
||||
{
|
||||
$itemsPool = new FilesystemAdapter('', 10);
|
||||
$tagsPool = $this
|
||||
->getMockBuilder(AdapterInterface::class)
|
||||
->getMock();
|
||||
|
||||
$pool = new TagAwareAdapter($itemsPool, $tagsPool, 10);
|
||||
|
||||
$item = $pool->getItem('foo');
|
||||
$item->tag(['baz']);
|
||||
$item->expiresAfter(100);
|
||||
|
||||
$tag = $this->getMockBuilder(CacheItemInterface::class)->getMock();
|
||||
$tag->expects(self::exactly(2))->method('get')->willReturn(10);
|
||||
|
||||
$tagsPool->expects(self::exactly(2))->method('getItems')->willReturn([
|
||||
'baz'.TagAwareAdapter::TAGS_PREFIX => $tag,
|
||||
]);
|
||||
|
||||
$pool->save($item);
|
||||
$this->assertTrue($pool->getItem('foo')->isHit());
|
||||
$this->assertTrue($pool->getItem('foo')->isHit());
|
||||
|
||||
sleep(20);
|
||||
|
||||
$this->assertTrue($pool->getItem('foo')->isHit());
|
||||
|
||||
sleep(5);
|
||||
|
||||
$this->assertTrue($pool->getItem('foo')->isHit());
|
||||
}
|
||||
|
||||
public function testTagEntryIsCreatedForItemWithoutTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$this->assertTrue($adapter->hasItem(TagAwareAdapter::TAGS_PREFIX.$itemKey));
|
||||
}
|
||||
|
||||
public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$anotherPool = $this->createCachePool();
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair
|
||||
|
||||
$this->assertFalse($anotherPool->hasItem($itemKey));
|
||||
}
|
||||
|
||||
public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$anotherPool = $this->createCachePool();
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair
|
||||
|
||||
$item = $anotherPool->getItem($itemKey);
|
||||
$this->assertFalse($item->isHit());
|
||||
}
|
||||
|
||||
public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemAndOnlyHasTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$anotherPool = $this->createCachePool();
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$adapter->deleteItem($itemKey); //simulate losing item but keeping tags
|
||||
|
||||
$this->assertFalse($anotherPool->hasItem($itemKey));
|
||||
}
|
||||
|
||||
public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
|
||||
$itemKey = 'foo';
|
||||
$item = $pool->getItem($itemKey);
|
||||
$pool->save($item);
|
||||
|
||||
$anotherPool = $this->createCachePool();
|
||||
|
||||
$adapter = new FilesystemAdapter();
|
||||
$adapter->deleteItem($itemKey); //simulate losing item but keeping tags
|
||||
|
||||
$item = $anotherPool->getItem($itemKey);
|
||||
$this->assertFalse($item->isHit());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|PruneableCacheInterface
|
||||
*/
|
||||
private function getPruneableMock()
|
||||
{
|
||||
$pruneable = $this
|
||||
->getMockBuilder(PruneableCacheInterface::class)
|
||||
->getMock();
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
->method('prune')
|
||||
->willReturn(true);
|
||||
|
||||
return $pruneable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|PruneableCacheInterface
|
||||
*/
|
||||
private function getFailingPruneableMock()
|
||||
{
|
||||
$pruneable = $this
|
||||
->getMockBuilder(PruneableCacheInterface::class)
|
||||
->getMock();
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
->method('prune')
|
||||
->willReturn(false);
|
||||
|
||||
return $pruneable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|AdapterInterface
|
||||
*/
|
||||
private function getNonPruneableMock()
|
||||
{
|
||||
return $this
|
||||
->getMockBuilder(AdapterInterface::class)
|
||||
->getMock();
|
||||
}
|
||||
}
|
||||
38
core/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php
vendored
Normal file
38
core/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
|
||||
use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
|
||||
|
||||
class TagAwareAndProxyAdapterIntegrationTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider dataProvider
|
||||
*/
|
||||
public function testIntegrationUsingProxiedAdapter(CacheItemPoolInterface $proxiedAdapter)
|
||||
{
|
||||
$cache = new TagAwareAdapter(new ProxyAdapter($proxiedAdapter));
|
||||
|
||||
$item = $cache->getItem('foo');
|
||||
$item->tag(['tag1', 'tag2']);
|
||||
$item->set('bar');
|
||||
$cache->save($item);
|
||||
|
||||
$this->assertSame('bar', $cache->getItem('foo')->get());
|
||||
}
|
||||
|
||||
public function dataProvider()
|
||||
{
|
||||
return [
|
||||
[new ArrayAdapter()],
|
||||
// also testing with a non-AdapterInterface implementation
|
||||
// because the ProxyAdapter behaves slightly different for those
|
||||
[new ExternalAdapter()],
|
||||
];
|
||||
}
|
||||
}
|
||||
191
core/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php
vendored
Normal file
191
core/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class TraceableAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testPrune' => 'TraceableAdapter just proxies',
|
||||
];
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new TraceableAdapter(new FilesystemAdapter('', $defaultLifetime));
|
||||
}
|
||||
|
||||
public function testGetItemMissTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$pool->getItem('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('getItem', $call->name);
|
||||
$this->assertSame(['k' => false], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(1, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testGetItemHitTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$item = $pool->getItem('k')->set('foo');
|
||||
$pool->save($item);
|
||||
$pool->getItem('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(3, $calls);
|
||||
|
||||
$call = $calls[2];
|
||||
$this->assertSame(1, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
}
|
||||
|
||||
public function testGetItemsMissTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$arg = ['k0', 'k1'];
|
||||
$items = $pool->getItems($arg);
|
||||
foreach ($items as $item) {
|
||||
}
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('getItems', $call->name);
|
||||
$this->assertSame(['k0' => false, 'k1' => false], $call->result);
|
||||
$this->assertSame(2, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testHasItemMissTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$pool->hasItem('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('hasItem', $call->name);
|
||||
$this->assertSame(['k' => false], $call->result);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testHasItemHitTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$item = $pool->getItem('k')->set('foo');
|
||||
$pool->save($item);
|
||||
$pool->hasItem('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(3, $calls);
|
||||
|
||||
$call = $calls[2];
|
||||
$this->assertSame('hasItem', $call->name);
|
||||
$this->assertSame(['k' => true], $call->result);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testDeleteItemTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$pool->deleteItem('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('deleteItem', $call->name);
|
||||
$this->assertSame(['k' => true], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testDeleteItemsTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$arg = ['k0', 'k1'];
|
||||
$pool->deleteItems($arg);
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('deleteItems', $call->name);
|
||||
$this->assertSame(['keys' => $arg, 'result' => true], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testSaveTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$item = $pool->getItem('k')->set('foo');
|
||||
$pool->save($item);
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(2, $calls);
|
||||
|
||||
$call = $calls[1];
|
||||
$this->assertSame('save', $call->name);
|
||||
$this->assertSame(['k' => true], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testSaveDeferredTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$item = $pool->getItem('k')->set('foo');
|
||||
$pool->saveDeferred($item);
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(2, $calls);
|
||||
|
||||
$call = $calls[1];
|
||||
$this->assertSame('saveDeferred', $call->name);
|
||||
$this->assertSame(['k' => true], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testCommitTrace()
|
||||
{
|
||||
$pool = $this->createCachePool();
|
||||
$pool->commit();
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('commit', $call->name);
|
||||
$this->assertTrue($call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
}
|
||||
37
core/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php
vendored
Normal file
37
core/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class TraceableTagAwareAdapterTest extends TraceableAdapterTest
|
||||
{
|
||||
public function testInvalidateTags()
|
||||
{
|
||||
$pool = new TraceableTagAwareAdapter(new TagAwareAdapter(new FilesystemAdapter()));
|
||||
$pool->invalidateTags(['foo']);
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('invalidateTags', $call->name);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
}
|
||||
77
core/vendor/symfony/cache/Tests/CacheItemTest.php
vendored
Normal file
77
core/vendor/symfony/cache/Tests/CacheItemTest.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
|
||||
class CacheItemTest extends TestCase
|
||||
{
|
||||
public function testValidKey()
|
||||
{
|
||||
$this->assertSame('foo', CacheItem::validateKey('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidKey
|
||||
*/
|
||||
public function testInvalidKey($key)
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Cache key');
|
||||
CacheItem::validateKey($key);
|
||||
}
|
||||
|
||||
public function provideInvalidKey()
|
||||
{
|
||||
return [
|
||||
[''],
|
||||
['{'],
|
||||
['}'],
|
||||
['('],
|
||||
[')'],
|
||||
['/'],
|
||||
['\\'],
|
||||
['@'],
|
||||
[':'],
|
||||
[true],
|
||||
[null],
|
||||
[1],
|
||||
[1.1],
|
||||
[[[]]],
|
||||
[new \Exception('foo')],
|
||||
];
|
||||
}
|
||||
|
||||
public function testTag()
|
||||
{
|
||||
$item = new CacheItem();
|
||||
|
||||
$this->assertSame($item, $item->tag('foo'));
|
||||
$this->assertSame($item, $item->tag(['bar', 'baz']));
|
||||
|
||||
\call_user_func(\Closure::bind(function () use ($item) {
|
||||
$this->assertSame(['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'], $item->tags);
|
||||
}, $this, CacheItem::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidKey
|
||||
*/
|
||||
public function testInvalidTag($tag)
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Cache tag');
|
||||
$item = new CacheItem();
|
||||
$item->tag($tag);
|
||||
}
|
||||
}
|
||||
45
core/vendor/symfony/cache/Tests/DoctrineProviderTest.php
vendored
Normal file
45
core/vendor/symfony/cache/Tests/DoctrineProviderTest.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests;
|
||||
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\DoctrineProvider;
|
||||
|
||||
class DoctrineProviderTest extends TestCase
|
||||
{
|
||||
public function testProvider()
|
||||
{
|
||||
$pool = new ArrayAdapter();
|
||||
$cache = new DoctrineProvider($pool);
|
||||
|
||||
$this->assertInstanceOf(CacheProvider::class, $cache);
|
||||
|
||||
$key = '{}()/\@:';
|
||||
|
||||
$this->assertTrue($cache->delete($key));
|
||||
$this->assertFalse($cache->contains($key));
|
||||
|
||||
$this->assertTrue($cache->save($key, 'bar'));
|
||||
$this->assertTrue($cache->contains($key));
|
||||
$this->assertSame('bar', $cache->fetch($key));
|
||||
|
||||
$this->assertTrue($cache->delete($key));
|
||||
$this->assertFalse($cache->fetch($key));
|
||||
$this->assertTrue($cache->save($key, 'bar'));
|
||||
|
||||
$cache->flushAll();
|
||||
$this->assertFalse($cache->fetch($key));
|
||||
$this->assertFalse($cache->contains($key));
|
||||
}
|
||||
}
|
||||
52
core/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php
vendored
Normal file
52
core/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Fixtures;
|
||||
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
|
||||
class ArrayCache extends CacheProvider
|
||||
{
|
||||
private $data = [];
|
||||
|
||||
protected function doFetch($id)
|
||||
{
|
||||
return $this->doContains($id) ? $this->data[$id][0] : false;
|
||||
}
|
||||
|
||||
protected function doContains($id)
|
||||
{
|
||||
if (!isset($this->data[$id])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$expiry = $this->data[$id][1];
|
||||
|
||||
return !$expiry || time() < $expiry || !$this->doDelete($id);
|
||||
}
|
||||
|
||||
protected function doSave($id, $data, $lifeTime = 0)
|
||||
{
|
||||
$this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doDelete($id)
|
||||
{
|
||||
unset($this->data[$id]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doFlush()
|
||||
{
|
||||
$this->data = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doGetStats()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
76
core/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php
vendored
Normal file
76
core/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Fixtures;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
|
||||
/**
|
||||
* Adapter not implementing the {@see \Symfony\Component\Cache\Adapter\AdapterInterface}.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ExternalAdapter implements CacheItemPoolInterface
|
||||
{
|
||||
private $cache;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->cache = new ArrayAdapter();
|
||||
}
|
||||
|
||||
public function getItem($key)
|
||||
{
|
||||
return $this->cache->getItem($key);
|
||||
}
|
||||
|
||||
public function getItems(array $keys = [])
|
||||
{
|
||||
return $this->cache->getItems($keys);
|
||||
}
|
||||
|
||||
public function hasItem($key)
|
||||
{
|
||||
return $this->cache->hasItem($key);
|
||||
}
|
||||
|
||||
public function clear()
|
||||
{
|
||||
return $this->cache->clear();
|
||||
}
|
||||
|
||||
public function deleteItem($key)
|
||||
{
|
||||
return $this->cache->deleteItem($key);
|
||||
}
|
||||
|
||||
public function deleteItems(array $keys)
|
||||
{
|
||||
return $this->cache->deleteItems($keys);
|
||||
}
|
||||
|
||||
public function save(CacheItemInterface $item)
|
||||
{
|
||||
return $this->cache->save($item);
|
||||
}
|
||||
|
||||
public function saveDeferred(CacheItemInterface $item)
|
||||
{
|
||||
return $this->cache->saveDeferred($item);
|
||||
}
|
||||
|
||||
public function commit()
|
||||
{
|
||||
return $this->cache->commit();
|
||||
}
|
||||
}
|
||||
46
core/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php
vendored
Normal file
46
core/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\RedisCache;
|
||||
|
||||
abstract class AbstractRedisCacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testSetTtl' => 'Testing expiration slows down the test suite',
|
||||
'testSetMultipleTtl' => 'Testing expiration slows down the test suite',
|
||||
'testDefaultLifeTime' => 'Testing expiration slows down the test suite',
|
||||
];
|
||||
|
||||
protected static $redis;
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new RedisCache(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||
}
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
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()
|
||||
{
|
||||
self::$redis = null;
|
||||
}
|
||||
}
|
||||
35
core/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php
vendored
Normal file
35
core/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\ApcuCache;
|
||||
|
||||
class ApcuCacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testSetTtl' => 'Testing expiration slows down the test suite',
|
||||
'testSetMultipleTtl' => 'Testing expiration slows down the test suite',
|
||||
'testDefaultLifeTime' => 'Testing expiration slows down the test suite',
|
||||
];
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) || ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN))) {
|
||||
$this->markTestSkipped('APCu extension is required.');
|
||||
}
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$this->markTestSkipped('Fails transiently on Windows.');
|
||||
}
|
||||
|
||||
return new ApcuCache(str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||
}
|
||||
}
|
||||
25
core/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php
vendored
Normal file
25
core/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\ArrayCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class ArrayCacheTest extends CacheTestCase
|
||||
{
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new ArrayCache($defaultLifetime);
|
||||
}
|
||||
}
|
||||
150
core/vendor/symfony/cache/Tests/Simple/CacheTestCase.php
vendored
Normal file
150
core/vendor/symfony/cache/Tests/Simple/CacheTestCase.php
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Cache\IntegrationTests\SimpleCacheTest;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
|
||||
abstract class CacheTestCase extends SimpleCacheTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createSimpleCache() instanceof PruneableInterface) {
|
||||
$this->skippedTests['testPrune'] = 'Not a pruneable cache pool.';
|
||||
}
|
||||
}
|
||||
|
||||
public static function validKeys()
|
||||
{
|
||||
if (\defined('HHVM_VERSION')) {
|
||||
return parent::validKeys();
|
||||
}
|
||||
|
||||
return array_merge(parent::validKeys(), [["a\0b"]]);
|
||||
}
|
||||
|
||||
public function testDefaultLifeTime()
|
||||
{
|
||||
if (isset($this->skippedTests[__FUNCTION__])) {
|
||||
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
|
||||
}
|
||||
|
||||
$cache = $this->createSimpleCache(2);
|
||||
$cache->clear();
|
||||
|
||||
$cache->set('key.dlt', 'value');
|
||||
sleep(1);
|
||||
|
||||
$this->assertSame('value', $cache->get('key.dlt'));
|
||||
|
||||
sleep(2);
|
||||
$this->assertNull($cache->get('key.dlt'));
|
||||
|
||||
$cache->clear();
|
||||
}
|
||||
|
||||
public function testNotUnserializable()
|
||||
{
|
||||
if (isset($this->skippedTests[__FUNCTION__])) {
|
||||
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
|
||||
}
|
||||
|
||||
$cache = $this->createSimpleCache();
|
||||
$cache->clear();
|
||||
|
||||
$cache->set('foo', new NotUnserializable());
|
||||
|
||||
$this->assertNull($cache->get('foo'));
|
||||
|
||||
$cache->setMultiple(['foo' => new NotUnserializable()]);
|
||||
|
||||
foreach ($cache->getMultiple(['foo']) as $value) {
|
||||
}
|
||||
$this->assertNull($value);
|
||||
|
||||
$cache->clear();
|
||||
}
|
||||
|
||||
public function testPrune()
|
||||
{
|
||||
if (isset($this->skippedTests[__FUNCTION__])) {
|
||||
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
|
||||
}
|
||||
|
||||
if (!method_exists($this, 'isPruned')) {
|
||||
$this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.');
|
||||
}
|
||||
|
||||
/** @var PruneableInterface|CacheInterface $cache */
|
||||
$cache = $this->createSimpleCache();
|
||||
$cache->clear();
|
||||
|
||||
$cache->set('foo', 'foo-val', new \DateInterval('PT05S'));
|
||||
$cache->set('bar', 'bar-val', new \DateInterval('PT10S'));
|
||||
$cache->set('baz', 'baz-val', new \DateInterval('PT15S'));
|
||||
$cache->set('qux', 'qux-val', new \DateInterval('PT20S'));
|
||||
|
||||
sleep(30);
|
||||
$cache->prune();
|
||||
$this->assertTrue($this->isPruned($cache, 'foo'));
|
||||
$this->assertTrue($this->isPruned($cache, 'bar'));
|
||||
$this->assertTrue($this->isPruned($cache, 'baz'));
|
||||
$this->assertTrue($this->isPruned($cache, 'qux'));
|
||||
|
||||
$cache->set('foo', 'foo-val');
|
||||
$cache->set('bar', 'bar-val', new \DateInterval('PT20S'));
|
||||
$cache->set('baz', 'baz-val', new \DateInterval('PT40S'));
|
||||
$cache->set('qux', 'qux-val', new \DateInterval('PT80S'));
|
||||
|
||||
$cache->prune();
|
||||
$this->assertFalse($this->isPruned($cache, 'foo'));
|
||||
$this->assertFalse($this->isPruned($cache, 'bar'));
|
||||
$this->assertFalse($this->isPruned($cache, 'baz'));
|
||||
$this->assertFalse($this->isPruned($cache, 'qux'));
|
||||
|
||||
sleep(30);
|
||||
$cache->prune();
|
||||
$this->assertFalse($this->isPruned($cache, 'foo'));
|
||||
$this->assertTrue($this->isPruned($cache, 'bar'));
|
||||
$this->assertFalse($this->isPruned($cache, 'baz'));
|
||||
$this->assertFalse($this->isPruned($cache, 'qux'));
|
||||
|
||||
sleep(30);
|
||||
$cache->prune();
|
||||
$this->assertFalse($this->isPruned($cache, 'foo'));
|
||||
$this->assertTrue($this->isPruned($cache, 'baz'));
|
||||
$this->assertFalse($this->isPruned($cache, 'qux'));
|
||||
|
||||
sleep(30);
|
||||
$cache->prune();
|
||||
$this->assertFalse($this->isPruned($cache, 'foo'));
|
||||
$this->assertTrue($this->isPruned($cache, 'qux'));
|
||||
|
||||
$cache->clear();
|
||||
}
|
||||
}
|
||||
|
||||
class NotUnserializable implements \Serializable
|
||||
{
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(123);
|
||||
}
|
||||
|
||||
public function unserialize($ser)
|
||||
{
|
||||
throw new \Exception(__CLASS__);
|
||||
}
|
||||
}
|
||||
113
core/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php
vendored
Normal file
113
core/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Simple\ArrayCache;
|
||||
use Symfony\Component\Cache\Simple\ChainCache;
|
||||
use Symfony\Component\Cache\Simple\FilesystemCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class ChainCacheTest extends CacheTestCase
|
||||
{
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new ChainCache([new ArrayCache($defaultLifetime), new FilesystemCache('', $defaultLifetime)], $defaultLifetime);
|
||||
}
|
||||
|
||||
public function testEmptyCachesException()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('At least one cache must be specified.');
|
||||
new ChainCache([]);
|
||||
}
|
||||
|
||||
public function testInvalidCacheException()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('The class "stdClass" does not implement');
|
||||
new ChainCache([new \stdClass()]);
|
||||
}
|
||||
|
||||
public function testPrune()
|
||||
{
|
||||
if (isset($this->skippedTests[__FUNCTION__])) {
|
||||
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
|
||||
}
|
||||
|
||||
$cache = new ChainCache([
|
||||
$this->getPruneableMock(),
|
||||
$this->getNonPruneableMock(),
|
||||
$this->getPruneableMock(),
|
||||
]);
|
||||
$this->assertTrue($cache->prune());
|
||||
|
||||
$cache = new ChainCache([
|
||||
$this->getPruneableMock(),
|
||||
$this->getFailingPruneableMock(),
|
||||
$this->getPruneableMock(),
|
||||
]);
|
||||
$this->assertFalse($cache->prune());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|PruneableCacheInterface
|
||||
*/
|
||||
private function getPruneableMock()
|
||||
{
|
||||
$pruneable = $this
|
||||
->getMockBuilder(PruneableCacheInterface::class)
|
||||
->getMock();
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
->method('prune')
|
||||
->willReturn(true);
|
||||
|
||||
return $pruneable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|PruneableCacheInterface
|
||||
*/
|
||||
private function getFailingPruneableMock()
|
||||
{
|
||||
$pruneable = $this
|
||||
->getMockBuilder(PruneableCacheInterface::class)
|
||||
->getMock();
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
->method('prune')
|
||||
->willReturn(false);
|
||||
|
||||
return $pruneable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MockObject|CacheInterface
|
||||
*/
|
||||
private function getNonPruneableMock()
|
||||
{
|
||||
return $this
|
||||
->getMockBuilder(CacheInterface::class)
|
||||
->getMock();
|
||||
}
|
||||
}
|
||||
|
||||
interface PruneableCacheInterface extends PruneableInterface, CacheInterface
|
||||
{
|
||||
}
|
||||
31
core/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php
vendored
Normal file
31
core/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\DoctrineCache;
|
||||
use Symfony\Component\Cache\Tests\Fixtures\ArrayCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class DoctrineCacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testObjectDoesNotChangeInCache' => 'ArrayCache does not use serialize/unserialize',
|
||||
'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize',
|
||||
];
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new DoctrineCache(new ArrayCache($defaultLifetime), '', $defaultLifetime);
|
||||
}
|
||||
}
|
||||
34
core/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php
vendored
Normal file
34
core/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Simple\FilesystemCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class FilesystemCacheTest extends CacheTestCase
|
||||
{
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new FilesystemCache('', $defaultLifetime);
|
||||
}
|
||||
|
||||
protected function isPruned(CacheInterface $cache, $name)
|
||||
{
|
||||
$getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile');
|
||||
$getFileMethod->setAccessible(true);
|
||||
|
||||
return !file_exists($getFileMethod->invoke($cache, $name));
|
||||
}
|
||||
}
|
||||
172
core/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php
vendored
Normal file
172
core/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
use Symfony\Component\Cache\Simple\MemcachedCache;
|
||||
|
||||
class MemcachedCacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testSetTtl' => 'Testing expiration slows down the test suite',
|
||||
'testSetMultipleTtl' => 'Testing expiration slows down the test suite',
|
||||
'testDefaultLifeTime' => 'Testing expiration slows down the test suite',
|
||||
];
|
||||
|
||||
protected static $client;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!MemcachedCache::isSupported()) {
|
||||
self::markTestSkipped('Extension memcached >=2.2.0 required.');
|
||||
}
|
||||
self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'));
|
||||
self::$client->get('foo');
|
||||
$code = self::$client->getResultCode();
|
||||
|
||||
if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) {
|
||||
self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
$client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]) : self::$client;
|
||||
|
||||
return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||
}
|
||||
|
||||
public function testCreatePersistentConnectionShouldNotDupServerList()
|
||||
{
|
||||
$instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']);
|
||||
$this->assertCount(1, $instance->getServerList());
|
||||
|
||||
$instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']);
|
||||
$this->assertCount(1, $instance->getServerList());
|
||||
}
|
||||
|
||||
public function testOptions()
|
||||
{
|
||||
$client = MemcachedCache::createConnection([], [
|
||||
'libketama_compatible' => false,
|
||||
'distribution' => 'modula',
|
||||
'compression' => true,
|
||||
'serializer' => 'php',
|
||||
'hash' => 'md5',
|
||||
]);
|
||||
|
||||
$this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER));
|
||||
$this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH));
|
||||
$this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION));
|
||||
$this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE));
|
||||
$this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideBadOptions
|
||||
*/
|
||||
public function testBadOptions($name, $value)
|
||||
{
|
||||
$this->expectException('ErrorException');
|
||||
$this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::');
|
||||
MemcachedCache::createConnection([], [$name => $value]);
|
||||
}
|
||||
|
||||
public function provideBadOptions()
|
||||
{
|
||||
return [
|
||||
['foo', 'bar'],
|
||||
['hash', 'zyx'],
|
||||
['serializer', 'zyx'],
|
||||
['distribution', 'zyx'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testDefaultOptions()
|
||||
{
|
||||
$this->assertTrue(MemcachedCache::isSupported());
|
||||
|
||||
$client = MemcachedCache::createConnection([]);
|
||||
|
||||
$this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION));
|
||||
$this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL));
|
||||
$this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE));
|
||||
}
|
||||
|
||||
public function testOptionSerializer()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\CacheException');
|
||||
$this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
|
||||
if (!\Memcached::HAVE_JSON) {
|
||||
$this->markTestSkipped('Memcached::HAVE_JSON required');
|
||||
}
|
||||
|
||||
new MemcachedCache(MemcachedCache::createConnection([], ['serializer' => 'json']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideServersSetting
|
||||
*/
|
||||
public function testServersSetting($dsn, $host, $port)
|
||||
{
|
||||
$client1 = MemcachedCache::createConnection($dsn);
|
||||
$client2 = MemcachedCache::createConnection([$dsn]);
|
||||
$client3 = MemcachedCache::createConnection([[$host, $port]]);
|
||||
$expect = [
|
||||
'host' => $host,
|
||||
'port' => $port,
|
||||
];
|
||||
|
||||
$f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; };
|
||||
$this->assertSame([$expect], array_map($f, $client1->getServerList()));
|
||||
$this->assertSame([$expect], array_map($f, $client2->getServerList()));
|
||||
$this->assertSame([$expect], array_map($f, $client3->getServerList()));
|
||||
}
|
||||
|
||||
public function provideServersSetting()
|
||||
{
|
||||
yield [
|
||||
'memcached://127.0.0.1/50',
|
||||
'127.0.0.1',
|
||||
11211,
|
||||
];
|
||||
yield [
|
||||
'memcached://localhost:11222?weight=25',
|
||||
'localhost',
|
||||
11222,
|
||||
];
|
||||
if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) {
|
||||
yield [
|
||||
'memcached://user:password@127.0.0.1?weight=50',
|
||||
'127.0.0.1',
|
||||
11211,
|
||||
];
|
||||
}
|
||||
yield [
|
||||
'memcached:///var/run/memcached.sock?weight=25',
|
||||
'/var/run/memcached.sock',
|
||||
0,
|
||||
];
|
||||
yield [
|
||||
'memcached:///var/local/run/memcached.socket?weight=25',
|
||||
'/var/local/run/memcached.socket',
|
||||
0,
|
||||
];
|
||||
if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) {
|
||||
yield [
|
||||
'memcached://user:password@/var/local/run/memcached.socket?weight=25',
|
||||
'/var/local/run/memcached.socket',
|
||||
0,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
25
core/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php
vendored
Normal file
25
core/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
use Symfony\Component\Cache\Simple\MemcachedCache;
|
||||
|
||||
class MemcachedCacheTextModeTest extends MemcachedCacheTest
|
||||
{
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]);
|
||||
|
||||
return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||
}
|
||||
}
|
||||
96
core/vendor/symfony/cache/Tests/Simple/NullCacheTest.php
vendored
Normal file
96
core/vendor/symfony/cache/Tests/Simple/NullCacheTest.php
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Cache\Simple\NullCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class NullCacheTest extends TestCase
|
||||
{
|
||||
public function createCachePool()
|
||||
{
|
||||
return new NullCache();
|
||||
}
|
||||
|
||||
public function testGetItem()
|
||||
{
|
||||
$cache = $this->createCachePool();
|
||||
|
||||
$this->assertNull($cache->get('key'));
|
||||
}
|
||||
|
||||
public function testHas()
|
||||
{
|
||||
$this->assertFalse($this->createCachePool()->has('key'));
|
||||
}
|
||||
|
||||
public function testGetMultiple()
|
||||
{
|
||||
$cache = $this->createCachePool();
|
||||
|
||||
$keys = ['foo', 'bar', 'baz', 'biz'];
|
||||
|
||||
$default = new \stdClass();
|
||||
$items = $cache->getMultiple($keys, $default);
|
||||
$count = 0;
|
||||
|
||||
foreach ($items as $key => $item) {
|
||||
$this->assertContains($key, $keys, 'Cache key can not change.');
|
||||
$this->assertSame($default, $item);
|
||||
|
||||
// Remove $key for $keys
|
||||
foreach ($keys as $k => $v) {
|
||||
if ($v === $key) {
|
||||
unset($keys[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
++$count;
|
||||
}
|
||||
|
||||
$this->assertSame(4, $count);
|
||||
}
|
||||
|
||||
public function testClear()
|
||||
{
|
||||
$this->assertTrue($this->createCachePool()->clear());
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$this->assertTrue($this->createCachePool()->delete('key'));
|
||||
}
|
||||
|
||||
public function testDeleteMultiple()
|
||||
{
|
||||
$this->assertTrue($this->createCachePool()->deleteMultiple(['key', 'foo', 'bar']));
|
||||
}
|
||||
|
||||
public function testSet()
|
||||
{
|
||||
$cache = $this->createCachePool();
|
||||
|
||||
$this->assertFalse($cache->set('key', 'val'));
|
||||
$this->assertNull($cache->get('key'));
|
||||
}
|
||||
|
||||
public function testSetMultiple()
|
||||
{
|
||||
$cache = $this->createCachePool();
|
||||
|
||||
$this->assertFalse($cache->setMultiple(['key' => 'val']));
|
||||
$this->assertNull($cache->get('key'));
|
||||
}
|
||||
}
|
||||
47
core/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php
vendored
Normal file
47
core/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\PdoCache;
|
||||
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PdoCacheTest extends CacheTestCase
|
||||
{
|
||||
use PdoPruneableTrait;
|
||||
|
||||
protected static $dbFile;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!\extension_loaded('pdo_sqlite')) {
|
||||
self::markTestSkipped('Extension pdo_sqlite required.');
|
||||
}
|
||||
|
||||
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
|
||||
|
||||
$pool = new PdoCache('sqlite:'.self::$dbFile);
|
||||
$pool->createTable();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
@unlink(self::$dbFile);
|
||||
}
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new PdoCache('sqlite:'.self::$dbFile, 'ns', $defaultLifetime);
|
||||
}
|
||||
}
|
||||
48
core/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php
vendored
Normal file
48
core/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Symfony\Component\Cache\Simple\PdoCache;
|
||||
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PdoDbalCacheTest extends CacheTestCase
|
||||
{
|
||||
use PdoPruneableTrait;
|
||||
|
||||
protected static $dbFile;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!\extension_loaded('pdo_sqlite')) {
|
||||
self::markTestSkipped('Extension pdo_sqlite required.');
|
||||
}
|
||||
|
||||
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
|
||||
|
||||
$pool = new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]));
|
||||
$pool->createTable();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
@unlink(self::$dbFile);
|
||||
}
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime);
|
||||
}
|
||||
}
|
||||
143
core/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php
vendored
Normal file
143
core/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\NullCache;
|
||||
use Symfony\Component\Cache\Simple\PhpArrayCache;
|
||||
use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PhpArrayCacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testBasicUsageWithLongKey' => 'PhpArrayCache does no writes',
|
||||
|
||||
'testDelete' => 'PhpArrayCache does no writes',
|
||||
'testDeleteMultiple' => 'PhpArrayCache does no writes',
|
||||
'testDeleteMultipleGenerator' => 'PhpArrayCache does no writes',
|
||||
|
||||
'testSetTtl' => 'PhpArrayCache does no expiration',
|
||||
'testSetMultipleTtl' => 'PhpArrayCache does no expiration',
|
||||
'testSetExpiredTtl' => 'PhpArrayCache does no expiration',
|
||||
'testSetMultipleExpiredTtl' => 'PhpArrayCache does no expiration',
|
||||
|
||||
'testGetInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testSetInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testDeleteInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testDeleteMultipleInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testSetInvalidTtl' => 'PhpArrayCache does no validation',
|
||||
'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation',
|
||||
'testHasInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testSetValidData' => 'PhpArrayCache does no validation',
|
||||
|
||||
'testDefaultLifeTime' => 'PhpArrayCache does not allow configuring a default lifetime.',
|
||||
'testPrune' => 'PhpArrayCache just proxies',
|
||||
];
|
||||
|
||||
protected static $file;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php';
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
|
||||
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
}
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
return new PhpArrayCacheWrapper(self::$file, new NullCache());
|
||||
}
|
||||
|
||||
public function testStore()
|
||||
{
|
||||
$arrayWithRefs = [];
|
||||
$arrayWithRefs[0] = 123;
|
||||
$arrayWithRefs[1] = &$arrayWithRefs[0];
|
||||
|
||||
$object = (object) [
|
||||
'foo' => 'bar',
|
||||
'foo2' => 'bar2',
|
||||
];
|
||||
|
||||
$expected = [
|
||||
'null' => null,
|
||||
'serializedString' => serialize($object),
|
||||
'arrayWithRefs' => $arrayWithRefs,
|
||||
'object' => $object,
|
||||
'arrayWithObject' => ['bar' => $object],
|
||||
];
|
||||
|
||||
$cache = new PhpArrayCache(self::$file, new NullCache());
|
||||
$cache->warmUp($expected);
|
||||
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertSame(serialize($value), serialize($cache->get($key)), 'Warm up should create a PHP file that OPCache can load in memory');
|
||||
}
|
||||
}
|
||||
|
||||
public function testStoredFile()
|
||||
{
|
||||
$expected = [
|
||||
'integer' => 42,
|
||||
'float' => 42.42,
|
||||
'boolean' => true,
|
||||
'array_simple' => ['foo', 'bar'],
|
||||
'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'],
|
||||
];
|
||||
|
||||
$cache = new PhpArrayCache(self::$file, new NullCache());
|
||||
$cache->warmUp($expected);
|
||||
|
||||
$values = eval(substr(file_get_contents(self::$file), 6));
|
||||
|
||||
$this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory');
|
||||
}
|
||||
}
|
||||
|
||||
class PhpArrayCacheWrapper extends PhpArrayCache
|
||||
{
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
\call_user_func(\Closure::bind(function () use ($key, $value) {
|
||||
$this->values[$key] = $value;
|
||||
$this->warmUp($this->values);
|
||||
$this->values = eval(substr(file_get_contents($this->file), 6));
|
||||
}, $this, PhpArrayCache::class));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
if (!\is_array($values) && !$values instanceof \Traversable) {
|
||||
return parent::setMultiple($values, $ttl);
|
||||
}
|
||||
\call_user_func(\Closure::bind(function () use ($values) {
|
||||
foreach ($values as $key => $value) {
|
||||
$this->values[$key] = $value;
|
||||
}
|
||||
$this->warmUp($this->values);
|
||||
$this->values = eval(substr(file_get_contents($this->file), 6));
|
||||
}, $this, PhpArrayCache::class));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
55
core/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php
vendored
Normal file
55
core/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\FilesystemCache;
|
||||
use Symfony\Component\Cache\Simple\PhpArrayCache;
|
||||
use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PhpArrayCacheWithFallbackTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testGetInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testDeleteInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testDeleteMultipleInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
//'testSetValidData' => 'PhpArrayCache does no validation',
|
||||
'testSetInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testSetInvalidTtl' => 'PhpArrayCache does no validation',
|
||||
'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation',
|
||||
'testHasInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testPrune' => 'PhpArrayCache just proxies',
|
||||
];
|
||||
|
||||
protected static $file;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php';
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if (file_exists(sys_get_temp_dir().'/symfony-cache')) {
|
||||
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
|
||||
}
|
||||
}
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new PhpArrayCache(self::$file, new FilesystemCache('php-array-fallback', $defaultLifetime));
|
||||
}
|
||||
}
|
||||
42
core/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php
vendored
Normal file
42
core/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Simple\PhpFilesCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class PhpFilesCacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testDefaultLifeTime' => 'PhpFilesCache does not allow configuring a default lifetime.',
|
||||
];
|
||||
|
||||
public function createSimpleCache()
|
||||
{
|
||||
if (!PhpFilesCache::isSupported()) {
|
||||
$this->markTestSkipped('OPcache extension is not enabled.');
|
||||
}
|
||||
|
||||
return new PhpFilesCache('sf-cache');
|
||||
}
|
||||
|
||||
protected function isPruned(CacheInterface $cache, $name)
|
||||
{
|
||||
$getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile');
|
||||
$getFileMethod->setAccessible(true);
|
||||
|
||||
return !file_exists($getFileMethod->invoke($cache, $name));
|
||||
}
|
||||
}
|
||||
30
core/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php
vendored
Normal file
30
core/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Simple\Psr6Cache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class Psr6CacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testPrune' => 'Psr6Cache just proxies',
|
||||
];
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new Psr6Cache(new FilesystemAdapter('', $defaultLifetime));
|
||||
}
|
||||
}
|
||||
24
core/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php
vendored
Normal file
24
core/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
class RedisArrayCacheTest extends AbstractRedisCacheTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setupBeforeClass();
|
||||
if (!class_exists('RedisArray')) {
|
||||
self::markTestSkipped('The RedisArray class is required.');
|
||||
}
|
||||
self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]);
|
||||
}
|
||||
}
|
||||
82
core/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php
vendored
Normal file
82
core/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\RedisCache;
|
||||
|
||||
class RedisCacheTest extends AbstractRedisCacheTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setupBeforeClass();
|
||||
self::$redis = RedisCache::createConnection('redis://'.getenv('REDIS_HOST'));
|
||||
}
|
||||
|
||||
public function testCreateConnection()
|
||||
{
|
||||
$redisHost = getenv('REDIS_HOST');
|
||||
|
||||
$redis = RedisCache::createConnection('redis://'.$redisHost);
|
||||
$this->assertInstanceOf(\Redis::class, $redis);
|
||||
$this->assertTrue($redis->isConnected());
|
||||
$this->assertSame(0, $redis->getDbNum());
|
||||
|
||||
$redis = RedisCache::createConnection('redis://'.$redisHost.'/2');
|
||||
$this->assertSame(2, $redis->getDbNum());
|
||||
|
||||
$redis = RedisCache::createConnection('redis://'.$redisHost, ['timeout' => 3]);
|
||||
$this->assertEquals(3, $redis->getTimeout());
|
||||
|
||||
$redis = RedisCache::createConnection('redis://'.$redisHost.'?timeout=4');
|
||||
$this->assertEquals(4, $redis->getTimeout());
|
||||
|
||||
$redis = RedisCache::createConnection('redis://'.$redisHost, ['read_timeout' => 5]);
|
||||
$this->assertEquals(5, $redis->getReadTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFailedCreateConnection
|
||||
*/
|
||||
public function testFailedCreateConnection($dsn)
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Redis connection failed');
|
||||
RedisCache::createConnection($dsn);
|
||||
}
|
||||
|
||||
public function provideFailedCreateConnection()
|
||||
{
|
||||
return [
|
||||
['redis://localhost:1234'],
|
||||
['redis://foo@localhost'],
|
||||
['redis://localhost/123'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidCreateConnection
|
||||
*/
|
||||
public function testInvalidCreateConnection($dsn)
|
||||
{
|
||||
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Invalid Redis DSN');
|
||||
RedisCache::createConnection($dsn);
|
||||
}
|
||||
|
||||
public function provideInvalidCreateConnection()
|
||||
{
|
||||
return [
|
||||
['foo://localhost'],
|
||||
['redis://'],
|
||||
];
|
||||
}
|
||||
}
|
||||
27
core/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php
vendored
Normal file
27
core/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
class RedisClusterCacheTest extends AbstractRedisCacheTest
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!class_exists('RedisCluster')) {
|
||||
self::markTestSkipped('The RedisCluster class is required.');
|
||||
}
|
||||
if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) {
|
||||
self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
|
||||
}
|
||||
|
||||
self::$redis = new \RedisCluster(null, explode(' ', $hosts));
|
||||
}
|
||||
}
|
||||
171
core/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php
vendored
Normal file
171
core/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Simple;
|
||||
|
||||
use Symfony\Component\Cache\Simple\FilesystemCache;
|
||||
use Symfony\Component\Cache\Simple\TraceableCache;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
*/
|
||||
class TraceableCacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = [
|
||||
'testPrune' => 'TraceableCache just proxies',
|
||||
];
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new TraceableCache(new FilesystemCache('', $defaultLifetime));
|
||||
}
|
||||
|
||||
public function testGetMissTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$pool->get('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('get', $call->name);
|
||||
$this->assertSame(['k' => false], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(1, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testGetHitTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$pool->set('k', 'foo');
|
||||
$pool->get('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(2, $calls);
|
||||
|
||||
$call = $calls[1];
|
||||
$this->assertSame(1, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
}
|
||||
|
||||
public function testGetMultipleMissTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$pool->set('k1', 123);
|
||||
$values = $pool->getMultiple(['k0', 'k1']);
|
||||
foreach ($values as $value) {
|
||||
}
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(2, $calls);
|
||||
|
||||
$call = $calls[1];
|
||||
$this->assertSame('getMultiple', $call->name);
|
||||
$this->assertSame(['k1' => true, 'k0' => false], $call->result);
|
||||
$this->assertSame(1, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testHasMissTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$pool->has('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('has', $call->name);
|
||||
$this->assertSame(['k' => false], $call->result);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testHasHitTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$pool->set('k', 'foo');
|
||||
$pool->has('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(2, $calls);
|
||||
|
||||
$call = $calls[1];
|
||||
$this->assertSame('has', $call->name);
|
||||
$this->assertSame(['k' => true], $call->result);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testDeleteTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$pool->delete('k');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('delete', $call->name);
|
||||
$this->assertSame(['k' => true], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testDeleteMultipleTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$arg = ['k0', 'k1'];
|
||||
$pool->deleteMultiple($arg);
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('deleteMultiple', $call->name);
|
||||
$this->assertSame(['keys' => $arg, 'result' => true], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testTraceSetTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$pool->set('k', 'foo');
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('set', $call->name);
|
||||
$this->assertSame(['k' => true], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
|
||||
public function testSetMultipleTrace()
|
||||
{
|
||||
$pool = $this->createSimpleCache();
|
||||
$pool->setMultiple(['k' => 'foo']);
|
||||
$calls = $pool->getCalls();
|
||||
$this->assertCount(1, $calls);
|
||||
|
||||
$call = $calls[0];
|
||||
$this->assertSame('setMultiple', $call->name);
|
||||
$this->assertSame(['keys' => ['k'], 'result' => true], $call->result);
|
||||
$this->assertSame(0, $call->hits);
|
||||
$this->assertSame(0, $call->misses);
|
||||
$this->assertNotEmpty($call->start);
|
||||
$this->assertNotEmpty($call->end);
|
||||
}
|
||||
}
|
||||
34
core/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php
vendored
Normal file
34
core/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Traits;
|
||||
|
||||
trait PdoPruneableTrait
|
||||
{
|
||||
protected function isPruned($cache, $name)
|
||||
{
|
||||
$o = new \ReflectionObject($cache);
|
||||
|
||||
if (!$o->hasMethod('getConnection')) {
|
||||
self::fail('Cache does not have "getConnection()" method.');
|
||||
}
|
||||
|
||||
$getPdoConn = $o->getMethod('getConnection');
|
||||
$getPdoConn->setAccessible(true);
|
||||
|
||||
/** @var \Doctrine\DBAL\Statement $select */
|
||||
$select = $getPdoConn->invoke($cache)->prepare('SELECT 1 FROM cache_items WHERE item_id LIKE :id');
|
||||
$select->bindValue(':id', sprintf('%%%s', $name));
|
||||
$select->execute();
|
||||
|
||||
return 0 === \count($select->fetchAll(\PDO::FETCH_COLUMN));
|
||||
}
|
||||
}
|
||||
268
core/vendor/symfony/cache/Traits/AbstractTrait.php
vendored
Normal file
268
core/vendor/symfony/cache/Traits/AbstractTrait.php
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Traits;
|
||||
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait AbstractTrait
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
private $namespace;
|
||||
private $namespaceVersion = '';
|
||||
private $versioningIsEnabled = false;
|
||||
private $deferred = [];
|
||||
|
||||
/**
|
||||
* @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', ['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;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->doClear($this->namespace) || $cleared;
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to clear the cache', ['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) {
|
||||
}
|
||||
CacheItem::log($this->logger, 'Failed to delete key "{key}"', ['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 = '';
|
||||
|
||||
return $wasEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
$this->namespaceVersion = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the native unserialize() function but throws an exception if anything goes wrong.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected static function unserialize($value)
|
||||
{
|
||||
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)
|
||||
{
|
||||
CacheItem::validateKey($key);
|
||||
|
||||
if ($this->versioningIsEnabled && '' === $this->namespaceVersion) {
|
||||
$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 (null === $this->maxIdLength) {
|
||||
return $this->namespace.$this->namespaceVersion.$key;
|
||||
}
|
||||
if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) {
|
||||
$id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 22));
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function handleUnserializeCallback($class)
|
||||
{
|
||||
throw new \DomainException('Class not found: '.$class);
|
||||
}
|
||||
}
|
||||
117
core/vendor/symfony/cache/Traits/ApcuTrait.php
vendored
Normal file
117
core/vendor/symfony/cache/Traits/ApcuTrait.php
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Traits;
|
||||
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\CacheException;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
try {
|
||||
foreach (apcu_fetch($ids, $ok) ?: [] as $k => $v) {
|
||||
if (null !== $v || $ok) {
|
||||
yield $k => $v;
|
||||
}
|
||||
}
|
||||
} catch (\Error $e) {
|
||||
throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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 (\Error $e) {
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
if (1 === \count($values)) {
|
||||
// Workaround https://github.com/krakjoe/apcu/issues/170
|
||||
apcu_delete(key($values));
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
108
core/vendor/symfony/cache/Traits/ArrayTrait.php
vendored
Normal file
108
core/vendor/symfony/cache/Traits/ArrayTrait.php
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Traits;
|
||||
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @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()
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasItem($key)
|
||||
{
|
||||
CacheItem::validateKey($key);
|
||||
|
||||
return isset($this->expiries[$key]) && ($this->expiries[$key] > time() || !$this->deleteItem($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->values = $this->expiries = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteItem($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) {
|
||||
try {
|
||||
if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) {
|
||||
$this->values[$key] = $value = null;
|
||||
} elseif (!$this->storeSerialized) {
|
||||
$value = $this->values[$key];
|
||||
} elseif ('b:0;' === $value = $this->values[$key]) {
|
||||
$value = false;
|
||||
} elseif (false === $value = unserialize($value)) {
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
$this->values[$key] = $value = null;
|
||||
$isHit = false;
|
||||
}
|
||||
unset($keys[$i]);
|
||||
|
||||
yield $key => $f($key, $value, $isHit);
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
yield $key => $f($key, null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user