[Cache] Inline some hot function calls
This commit is contained in:
parent
e98454664a
commit
52b4bfc042
@ -237,7 +237,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
|
|||||||
if (true === $e || array() === $e) {
|
if (true === $e || array() === $e) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (is_array($e) || 1 === count($values)) {
|
if (\is_array($e) || 1 === \count($values)) {
|
||||||
foreach (is_array($e) ? $e : array_keys($values) as $id) {
|
foreach (is_array($e) ? $e : array_keys($values) as $id) {
|
||||||
$ok = false;
|
$ok = false;
|
||||||
$v = $values[$id];
|
$v = $values[$id];
|
||||||
|
@ -30,13 +30,13 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn
|
|||||||
{
|
{
|
||||||
private $adapters = array();
|
private $adapters = array();
|
||||||
private $adapterCount;
|
private $adapterCount;
|
||||||
private $saveUp;
|
private $syncItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items
|
* @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items
|
||||||
* @param int $maxLifetime The max lifetime of items propagated from lower adapters to upper ones
|
* @param int $defaultLifetime The default lifetime of items propagated from lower adapters to upper ones
|
||||||
*/
|
*/
|
||||||
public function __construct(array $adapters, $maxLifetime = 0)
|
public function __construct(array $adapters, $defaultLifetime = 0)
|
||||||
{
|
{
|
||||||
if (!$adapters) {
|
if (!$adapters) {
|
||||||
throw new InvalidArgumentException('At least one adapter must be specified.');
|
throw new InvalidArgumentException('At least one adapter must be specified.');
|
||||||
@ -55,16 +55,20 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn
|
|||||||
}
|
}
|
||||||
$this->adapterCount = count($this->adapters);
|
$this->adapterCount = count($this->adapters);
|
||||||
|
|
||||||
$this->saveUp = \Closure::bind(
|
$this->syncItem = \Closure::bind(
|
||||||
function ($adapter, $item) use ($maxLifetime) {
|
function ($sourceItem, $item) use ($defaultLifetime) {
|
||||||
$origDefaultLifetime = $item->defaultLifetime;
|
$item->value = $sourceItem->value;
|
||||||
|
$item->expiry = $sourceItem->expiry;
|
||||||
|
$item->isHit = $sourceItem->isHit;
|
||||||
|
|
||||||
if (0 < $maxLifetime && ($origDefaultLifetime <= 0 || $maxLifetime < $origDefaultLifetime)) {
|
if (0 < $sourceItem->defaultLifetime && $sourceItem->defaultLifetime < $defaultLifetime) {
|
||||||
$item->defaultLifetime = $maxLifetime;
|
$defaultLifetime = $sourceItem->defaultLifetime;
|
||||||
|
}
|
||||||
|
if (0 < $defaultLifetime && ($item->defaultLifetime <= 0 || $defaultLifetime < $item->defaultLifetime)) {
|
||||||
|
$item->defaultLifetime = $defaultLifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
$adapter->save($item);
|
return $item;
|
||||||
$item->defaultLifetime = $origDefaultLifetime;
|
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
CacheItem::class
|
CacheItem::class
|
||||||
@ -76,18 +80,21 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn
|
|||||||
*/
|
*/
|
||||||
public function getItem($key)
|
public function getItem($key)
|
||||||
{
|
{
|
||||||
$saveUp = $this->saveUp;
|
$syncItem = $this->syncItem;
|
||||||
|
$misses = array();
|
||||||
|
|
||||||
foreach ($this->adapters as $i => $adapter) {
|
foreach ($this->adapters as $i => $adapter) {
|
||||||
$item = $adapter->getItem($key);
|
$item = $adapter->getItem($key);
|
||||||
|
|
||||||
if ($item->isHit()) {
|
if ($item->isHit()) {
|
||||||
while (0 <= --$i) {
|
while (0 <= --$i) {
|
||||||
$saveUp($this->adapters[$i], $item);
|
$this->adapters[$i]->save($syncItem($item, $misses[$i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$misses[$i] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
@ -104,6 +111,7 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn
|
|||||||
private function generateItems($items, $adapterIndex)
|
private function generateItems($items, $adapterIndex)
|
||||||
{
|
{
|
||||||
$missing = array();
|
$missing = array();
|
||||||
|
$misses = array();
|
||||||
$nextAdapterIndex = $adapterIndex + 1;
|
$nextAdapterIndex = $adapterIndex + 1;
|
||||||
$nextAdapter = isset($this->adapters[$nextAdapterIndex]) ? $this->adapters[$nextAdapterIndex] : null;
|
$nextAdapter = isset($this->adapters[$nextAdapterIndex]) ? $this->adapters[$nextAdapterIndex] : null;
|
||||||
|
|
||||||
@ -112,17 +120,18 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn
|
|||||||
yield $k => $item;
|
yield $k => $item;
|
||||||
} else {
|
} else {
|
||||||
$missing[] = $k;
|
$missing[] = $k;
|
||||||
|
$misses[$k] = $item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($missing) {
|
if ($missing) {
|
||||||
$saveUp = $this->saveUp;
|
$syncItem = $this->syncItem;
|
||||||
$adapter = $this->adapters[$adapterIndex];
|
$adapter = $this->adapters[$adapterIndex];
|
||||||
$items = $this->generateItems($nextAdapter->getItems($missing), $nextAdapterIndex);
|
$items = $this->generateItems($nextAdapter->getItems($missing), $nextAdapterIndex);
|
||||||
|
|
||||||
foreach ($items as $k => $item) {
|
foreach ($items as $k => $item) {
|
||||||
if ($item->isHit()) {
|
if ($item->isHit()) {
|
||||||
$saveUp($adapter, $item);
|
$adapter->save($syncItem($item, $misses[$k]));
|
||||||
}
|
}
|
||||||
|
|
||||||
yield $k => $item;
|
yield $k => $item;
|
||||||
|
@ -84,7 +84,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl
|
|||||||
*/
|
*/
|
||||||
public function getItem($key)
|
public function getItem($key)
|
||||||
{
|
{
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
if (null === $this->values) {
|
if (null === $this->values) {
|
||||||
@ -99,7 +99,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl
|
|||||||
|
|
||||||
if ('N;' === $value) {
|
if ('N;' === $value) {
|
||||||
$value = null;
|
$value = null;
|
||||||
} elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||||
try {
|
try {
|
||||||
$e = null;
|
$e = null;
|
||||||
$value = unserialize($value);
|
$value = unserialize($value);
|
||||||
@ -123,7 +123,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl
|
|||||||
public function getItems(array $keys = array())
|
public function getItems(array $keys = array())
|
||||||
{
|
{
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl
|
|||||||
*/
|
*/
|
||||||
public function hasItem($key)
|
public function hasItem($key)
|
||||||
{
|
{
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
if (null === $this->values) {
|
if (null === $this->values) {
|
||||||
@ -154,7 +154,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl
|
|||||||
*/
|
*/
|
||||||
public function deleteItem($key)
|
public function deleteItem($key)
|
||||||
{
|
{
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
if (null === $this->values) {
|
if (null === $this->values) {
|
||||||
@ -173,7 +173,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl
|
|||||||
$fallbackKeys = array();
|
$fallbackKeys = array();
|
||||||
|
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl
|
|||||||
|
|
||||||
if ('N;' === $value) {
|
if ('N;' === $value) {
|
||||||
yield $key => $f($key, null, true);
|
yield $key => $f($key, null, true);
|
||||||
} elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||||
try {
|
try {
|
||||||
yield $key => $f($key, unserialize($value), true);
|
yield $key => $f($key, unserialize($value), true);
|
||||||
} catch (\Error $e) {
|
} catch (\Error $e) {
|
||||||
|
@ -107,7 +107,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R
|
|||||||
public function invalidateTags(array $tags)
|
public function invalidateTags(array $tags)
|
||||||
{
|
{
|
||||||
foreach ($tags as $k => $tag) {
|
foreach ($tags as $k => $tag) {
|
||||||
if ('' !== $tag && is_string($tag)) {
|
if ('' !== $tag && \is_string($tag)) {
|
||||||
$tags[$k] = $tag.static::TAGS_PREFIX;
|
$tags[$k] = $tag.static::TAGS_PREFIX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,7 +161,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R
|
|||||||
$tagKeys = array();
|
$tagKeys = array();
|
||||||
|
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
if ('' !== $key && is_string($key)) {
|
if ('' !== $key && \is_string($key)) {
|
||||||
$key = static::TAGS_PREFIX.$key;
|
$key = static::TAGS_PREFIX.$key;
|
||||||
$tagKeys[$key] = $key;
|
$tagKeys[$key] = $key;
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R
|
|||||||
public function deleteItems(array $keys)
|
public function deleteItems(array $keys)
|
||||||
{
|
{
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
if ('' !== $key && is_string($key)) {
|
if ('' !== $key && \is_string($key)) {
|
||||||
$keys[] = static::TAGS_PREFIX.$key;
|
$keys[] = static::TAGS_PREFIX.$key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ final class CacheItem implements CacheItemInterface
|
|||||||
$this->expiry = $this->defaultLifetime > 0 ? time() + $this->defaultLifetime : null;
|
$this->expiry = $this->defaultLifetime > 0 ? time() + $this->defaultLifetime : null;
|
||||||
} elseif ($time instanceof \DateInterval) {
|
} elseif ($time instanceof \DateInterval) {
|
||||||
$this->expiry = (int) \DateTime::createFromFormat('U', time())->add($time)->format('U');
|
$this->expiry = (int) \DateTime::createFromFormat('U', time())->add($time)->format('U');
|
||||||
} elseif (is_int($time)) {
|
} elseif (\is_int($time)) {
|
||||||
$this->expiry = $time + time();
|
$this->expiry = $time + time();
|
||||||
} else {
|
} 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)));
|
throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', is_object($time) ? get_class($time) : gettype($time)));
|
||||||
@ -109,17 +109,17 @@ final class CacheItem implements CacheItemInterface
|
|||||||
*/
|
*/
|
||||||
public function tag($tags)
|
public function tag($tags)
|
||||||
{
|
{
|
||||||
if (!is_array($tags)) {
|
if (!\is_array($tags)) {
|
||||||
$tags = array($tags);
|
$tags = array($tags);
|
||||||
}
|
}
|
||||||
foreach ($tags as $tag) {
|
foreach ($tags as $tag) {
|
||||||
if (!is_string($tag)) {
|
if (!\is_string($tag)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given', is_object($tag) ? get_class($tag) : gettype($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])) {
|
if (isset($this->tags[$tag])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!isset($tag[0])) {
|
if ('' === $tag) {
|
||||||
throw new InvalidArgumentException('Cache tag length must be greater than zero');
|
throw new InvalidArgumentException('Cache tag length must be greater than zero');
|
||||||
}
|
}
|
||||||
if (false !== strpbrk($tag, '{}()/\@:')) {
|
if (false !== strpbrk($tag, '{}()/\@:')) {
|
||||||
@ -152,10 +152,10 @@ final class CacheItem implements CacheItemInterface
|
|||||||
*/
|
*/
|
||||||
public static function validateKey($key)
|
public static function validateKey($key)
|
||||||
{
|
{
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
if (!isset($key[0])) {
|
if ('' === $key) {
|
||||||
throw new InvalidArgumentException('Cache key length must be greater than zero');
|
throw new InvalidArgumentException('Cache key length must be greater than zero');
|
||||||
}
|
}
|
||||||
if (false !== strpbrk($key, '{}()/\@:')) {
|
if (false !== strpbrk($key, '{}()/\@:')) {
|
||||||
|
@ -79,7 +79,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
|
|||||||
{
|
{
|
||||||
if ($keys instanceof \Traversable) {
|
if ($keys instanceof \Traversable) {
|
||||||
$keys = iterator_to_array($keys, false);
|
$keys = iterator_to_array($keys, false);
|
||||||
} elseif (!is_array($keys)) {
|
} 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)));
|
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys)));
|
||||||
}
|
}
|
||||||
$ids = array();
|
$ids = array();
|
||||||
@ -103,13 +103,13 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
|
|||||||
*/
|
*/
|
||||||
public function setMultiple($values, $ttl = null)
|
public function setMultiple($values, $ttl = null)
|
||||||
{
|
{
|
||||||
if (!is_array($values) && !$values instanceof \Traversable) {
|
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)));
|
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values)));
|
||||||
}
|
}
|
||||||
$valuesById = array();
|
$valuesById = array();
|
||||||
|
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
if (is_int($key)) {
|
if (\is_int($key)) {
|
||||||
$key = (string) $key;
|
$key = (string) $key;
|
||||||
}
|
}
|
||||||
$valuesById[$this->getId($key)] = $value;
|
$valuesById[$this->getId($key)] = $value;
|
||||||
@ -126,7 +126,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
$keys = array();
|
$keys = array();
|
||||||
foreach (is_array($e) ? $e : array_keys($valuesById) as $id) {
|
foreach (\is_array($e) ? $e : array_keys($valuesById) as $id) {
|
||||||
$keys[] = substr($id, strlen($this->namespace));
|
$keys[] = substr($id, strlen($this->namespace));
|
||||||
}
|
}
|
||||||
CacheItem::log($this->logger, 'Failed to save values', array('keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null));
|
CacheItem::log($this->logger, 'Failed to save values', array('keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null));
|
||||||
@ -141,7 +141,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
|
|||||||
{
|
{
|
||||||
if ($keys instanceof \Traversable) {
|
if ($keys instanceof \Traversable) {
|
||||||
$keys = iterator_to_array($keys, false);
|
$keys = iterator_to_array($keys, false);
|
||||||
} elseif (!is_array($keys)) {
|
} 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)));
|
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
|
|||||||
if ($ttl instanceof \DateInterval) {
|
if ($ttl instanceof \DateInterval) {
|
||||||
$ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U');
|
$ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U');
|
||||||
}
|
}
|
||||||
if (is_int($ttl)) {
|
if (\is_int($ttl)) {
|
||||||
return 0 < $ttl ? $ttl : false;
|
return 0 < $ttl ? $ttl : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte
|
|||||||
{
|
{
|
||||||
if ($keys instanceof \Traversable) {
|
if ($keys instanceof \Traversable) {
|
||||||
$keys = iterator_to_array($keys, false);
|
$keys = iterator_to_array($keys, false);
|
||||||
} elseif (!is_array($keys)) {
|
} 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)));
|
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) {
|
foreach ($keys as $key) {
|
||||||
@ -72,7 +72,7 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte
|
|||||||
*/
|
*/
|
||||||
public function deleteMultiple($keys)
|
public function deleteMultiple($keys)
|
||||||
{
|
{
|
||||||
if (!is_array($keys) && !$keys instanceof \Traversable) {
|
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)));
|
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) {
|
foreach ($keys as $key) {
|
||||||
@ -97,13 +97,13 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte
|
|||||||
*/
|
*/
|
||||||
public function setMultiple($values, $ttl = null)
|
public function setMultiple($values, $ttl = null)
|
||||||
{
|
{
|
||||||
if (!is_array($values) && !$values instanceof \Traversable) {
|
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)));
|
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values)));
|
||||||
}
|
}
|
||||||
$valuesArray = array();
|
$valuesArray = array();
|
||||||
|
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
is_int($key) || CacheItem::validateKey($key);
|
\is_int($key) || CacheItem::validateKey($key);
|
||||||
$valuesArray[$key] = $value;
|
$valuesArray[$key] = $value;
|
||||||
}
|
}
|
||||||
if (false === $ttl = $this->normalizeTtl($ttl)) {
|
if (false === $ttl = $this->normalizeTtl($ttl)) {
|
||||||
@ -139,7 +139,7 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte
|
|||||||
if ($ttl instanceof \DateInterval) {
|
if ($ttl instanceof \DateInterval) {
|
||||||
$ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U');
|
$ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U');
|
||||||
}
|
}
|
||||||
if (is_int($ttl)) {
|
if (\is_int($ttl)) {
|
||||||
return 0 < $ttl ? $ttl : false;
|
return 0 < $ttl ? $ttl : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf
|
|||||||
*/
|
*/
|
||||||
public function get($key, $default = null)
|
public function get($key, $default = null)
|
||||||
{
|
{
|
||||||
$miss = null !== $default && is_object($default) ? $default : $this->miss;
|
$miss = null !== $default && \is_object($default) ? $default : $this->miss;
|
||||||
|
|
||||||
foreach ($this->caches as $i => $cache) {
|
foreach ($this->caches as $i => $cache) {
|
||||||
$value = $cache->get($key, $miss);
|
$value = $cache->get($key, $miss);
|
||||||
@ -80,7 +80,7 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf
|
|||||||
*/
|
*/
|
||||||
public function getMultiple($keys, $default = null)
|
public function getMultiple($keys, $default = null)
|
||||||
{
|
{
|
||||||
$miss = null !== $default && is_object($default) ? $default : $this->miss;
|
$miss = null !== $default && \is_object($default) ? $default : $this->miss;
|
||||||
|
|
||||||
return $this->generateItems($this->caches[0]->getMultiple($keys, $miss), 0, $miss, $default);
|
return $this->generateItems($this->caches[0]->getMultiple($keys, $miss), 0, $miss, $default);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
*/
|
*/
|
||||||
public function get($key, $default = null)
|
public function get($key, $default = null)
|
||||||
{
|
{
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
if (null === $this->values) {
|
if (null === $this->values) {
|
||||||
@ -77,7 +77,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
|
|
||||||
if ('N;' === $value) {
|
if ('N;' === $value) {
|
||||||
$value = null;
|
$value = null;
|
||||||
} elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||||
try {
|
try {
|
||||||
$e = null;
|
$e = null;
|
||||||
$value = unserialize($value);
|
$value = unserialize($value);
|
||||||
@ -99,11 +99,11 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
{
|
{
|
||||||
if ($keys instanceof \Traversable) {
|
if ($keys instanceof \Traversable) {
|
||||||
$keys = iterator_to_array($keys, false);
|
$keys = iterator_to_array($keys, false);
|
||||||
} elseif (!is_array($keys)) {
|
} 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)));
|
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) {
|
foreach ($keys as $key) {
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
*/
|
*/
|
||||||
public function has($key)
|
public function has($key)
|
||||||
{
|
{
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
if (null === $this->values) {
|
if (null === $this->values) {
|
||||||
@ -134,7 +134,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
*/
|
*/
|
||||||
public function delete($key)
|
public function delete($key)
|
||||||
{
|
{
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
if (null === $this->values) {
|
if (null === $this->values) {
|
||||||
@ -149,7 +149,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
*/
|
*/
|
||||||
public function deleteMultiple($keys)
|
public function deleteMultiple($keys)
|
||||||
{
|
{
|
||||||
if (!is_array($keys) && !$keys instanceof \Traversable) {
|
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)));
|
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
$fallbackKeys = array();
|
$fallbackKeys = array();
|
||||||
|
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
*/
|
*/
|
||||||
public function set($key, $value, $ttl = null)
|
public function set($key, $value, $ttl = null)
|
||||||
{
|
{
|
||||||
if (!is_string($key)) {
|
if (!\is_string($key)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
if (null === $this->values) {
|
if (null === $this->values) {
|
||||||
@ -198,7 +198,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
*/
|
*/
|
||||||
public function setMultiple($values, $ttl = null)
|
public function setMultiple($values, $ttl = null)
|
||||||
{
|
{
|
||||||
if (!is_array($values) && !$values instanceof \Traversable) {
|
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)));
|
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
$fallbackValues = array();
|
$fallbackValues = array();
|
||||||
|
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
if (!is_string($key) && !is_int($key)) {
|
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)));
|
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
|
|||||||
|
|
||||||
if ('N;' === $value) {
|
if ('N;' === $value) {
|
||||||
yield $key => null;
|
yield $key => null;
|
||||||
} elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||||
try {
|
try {
|
||||||
yield $key => unserialize($value);
|
yield $key => unserialize($value);
|
||||||
} catch (\Error $e) {
|
} catch (\Error $e) {
|
||||||
|
@ -38,7 +38,7 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa
|
|||||||
if ($pool instanceof AbstractAdapter) {
|
if ($pool instanceof AbstractAdapter) {
|
||||||
$this->createCacheItem = \Closure::bind(
|
$this->createCacheItem = \Closure::bind(
|
||||||
function ($key, $value, $allowInt = false) {
|
function ($key, $value, $allowInt = false) {
|
||||||
if ($allowInt && is_int($key)) {
|
if ($allowInt && \is_int($key)) {
|
||||||
$key = (string) $key;
|
$key = (string) $key;
|
||||||
} else {
|
} else {
|
||||||
CacheItem::validateKey($key);
|
CacheItem::validateKey($key);
|
||||||
@ -121,7 +121,7 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa
|
|||||||
{
|
{
|
||||||
if ($keys instanceof \Traversable) {
|
if ($keys instanceof \Traversable) {
|
||||||
$keys = iterator_to_array($keys, false);
|
$keys = iterator_to_array($keys, false);
|
||||||
} elseif (!is_array($keys)) {
|
} 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)));
|
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa
|
|||||||
*/
|
*/
|
||||||
public function setMultiple($values, $ttl = null)
|
public function setMultiple($values, $ttl = null)
|
||||||
{
|
{
|
||||||
$valuesIsArray = is_array($values);
|
$valuesIsArray = \is_array($values);
|
||||||
if (!$valuesIsArray && !$values instanceof \Traversable) {
|
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)));
|
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values)));
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa
|
|||||||
$items = $this->pool->getItems($items);
|
$items = $this->pool->getItems($items);
|
||||||
} else {
|
} else {
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
if (is_int($key)) {
|
if (\is_int($key)) {
|
||||||
$key = (string) $key;
|
$key = (string) $key;
|
||||||
}
|
}
|
||||||
$items[$key] = $this->pool->getItem($key)->set($value);
|
$items[$key] = $this->pool->getItem($key)->set($value);
|
||||||
@ -199,7 +199,7 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa
|
|||||||
{
|
{
|
||||||
if ($keys instanceof \Traversable) {
|
if ($keys instanceof \Traversable) {
|
||||||
$keys = iterator_to_array($keys, false);
|
$keys = iterator_to_array($keys, false);
|
||||||
} elseif (!is_array($keys)) {
|
} 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)));
|
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn
|
|||||||
*/
|
*/
|
||||||
public function get($key, $default = null)
|
public function get($key, $default = null)
|
||||||
{
|
{
|
||||||
$miss = null !== $default && is_object($default) ? $default : $this->miss;
|
$miss = null !== $default && \is_object($default) ? $default : $this->miss;
|
||||||
$event = $this->start(__FUNCTION__);
|
$event = $this->start(__FUNCTION__);
|
||||||
try {
|
try {
|
||||||
$value = $this->pool->get($key, $miss);
|
$value = $this->pool->get($key, $miss);
|
||||||
@ -109,7 +109,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
$values = $values();
|
$values = $values();
|
||||||
} elseif (is_array($values)) {
|
} elseif (\is_array($values)) {
|
||||||
$event->result['keys'] = array_keys($values);
|
$event->result['keys'] = array_keys($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn
|
|||||||
*/
|
*/
|
||||||
public function getMultiple($keys, $default = null)
|
public function getMultiple($keys, $default = null)
|
||||||
{
|
{
|
||||||
$miss = null !== $default && is_object($default) ? $default : $this->miss;
|
$miss = null !== $default && \is_object($default) ? $default : $this->miss;
|
||||||
$event = $this->start(__FUNCTION__);
|
$event = $this->start(__FUNCTION__);
|
||||||
try {
|
try {
|
||||||
$result = $this->pool->getMultiple($keys, $miss);
|
$result = $this->pool->getMultiple($keys, $miss);
|
||||||
|
@ -241,7 +241,7 @@ trait AbstractTrait
|
|||||||
if (null === $this->maxIdLength) {
|
if (null === $this->maxIdLength) {
|
||||||
return $this->namespace.$this->namespaceVersion.$key;
|
return $this->namespace.$this->namespaceVersion.$key;
|
||||||
}
|
}
|
||||||
if (strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) {
|
if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) {
|
||||||
$id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -22);
|
$id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -22);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,15 +66,15 @@ return array(
|
|||||||
EOF;
|
EOF;
|
||||||
|
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
CacheItem::validateKey(is_int($key) ? (string) $key : $key);
|
CacheItem::validateKey(\is_int($key) ? (string) $key : $key);
|
||||||
|
|
||||||
if (null === $value || is_object($value)) {
|
if (null === $value || \is_object($value)) {
|
||||||
try {
|
try {
|
||||||
$value = serialize($value);
|
$value = serialize($value);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, get_class($value)), 0, $e);
|
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, get_class($value)), 0, $e);
|
||||||
}
|
}
|
||||||
} elseif (is_array($value)) {
|
} elseif (\is_array($value)) {
|
||||||
try {
|
try {
|
||||||
$serialized = serialize($value);
|
$serialized = serialize($value);
|
||||||
$unserialized = unserialize($serialized);
|
$unserialized = unserialize($serialized);
|
||||||
@ -85,12 +85,12 @@ EOF;
|
|||||||
if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) {
|
if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) {
|
||||||
$value = $serialized;
|
$value = $serialized;
|
||||||
}
|
}
|
||||||
} elseif (is_string($value)) {
|
} elseif (\is_string($value)) {
|
||||||
// Serialize strings if they could be confused with serialized objects or arrays
|
// Serialize strings if they could be confused with serialized objects or arrays
|
||||||
if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) {
|
if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) {
|
||||||
$value = serialize($value);
|
$value = serialize($value);
|
||||||
}
|
}
|
||||||
} elseif (!is_scalar($value)) {
|
} elseif (!\is_scalar($value)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value)));
|
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ trait PhpFilesTrait
|
|||||||
foreach ($values as $id => $value) {
|
foreach ($values as $id => $value) {
|
||||||
if ('N;' === $value) {
|
if ('N;' === $value) {
|
||||||
$values[$id] = null;
|
$values[$id] = null;
|
||||||
} elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
} elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) {
|
||||||
$values[$id] = parent::unserialize($value);
|
$values[$id] = parent::unserialize($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,21 +122,21 @@ trait PhpFilesTrait
|
|||||||
$allowCompile = 'cli' !== PHP_SAPI || ini_get('opcache.enable_cli');
|
$allowCompile = 'cli' !== PHP_SAPI || ini_get('opcache.enable_cli');
|
||||||
|
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
if (null === $value || is_object($value)) {
|
if (null === $value || \is_object($value)) {
|
||||||
$value = serialize($value);
|
$value = serialize($value);
|
||||||
} elseif (is_array($value)) {
|
} elseif (\is_array($value)) {
|
||||||
$serialized = serialize($value);
|
$serialized = serialize($value);
|
||||||
$unserialized = parent::unserialize($serialized);
|
$unserialized = parent::unserialize($serialized);
|
||||||
// Store arrays serialized if they contain any objects or references
|
// Store arrays serialized if they contain any objects or references
|
||||||
if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) {
|
if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) {
|
||||||
$value = $serialized;
|
$value = $serialized;
|
||||||
}
|
}
|
||||||
} elseif (is_string($value)) {
|
} elseif (\is_string($value)) {
|
||||||
// Serialize strings if they could be confused with serialized objects or arrays
|
// Serialize strings if they could be confused with serialized objects or arrays
|
||||||
if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) {
|
if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) {
|
||||||
$value = serialize($value);
|
$value = serialize($value);
|
||||||
}
|
}
|
||||||
} elseif (!is_scalar($value)) {
|
} elseif (!\is_scalar($value)) {
|
||||||
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value)));
|
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ trait RedisTrait
|
|||||||
$cursor = null;
|
$cursor = null;
|
||||||
do {
|
do {
|
||||||
$keys = $host instanceof \Predis\Client ? $host->scan($cursor, 'MATCH', $namespace.'*', 'COUNT', 1000) : $host->scan($cursor, $namespace.'*', 1000);
|
$keys = $host instanceof \Predis\Client ? $host->scan($cursor, 'MATCH', $namespace.'*', 'COUNT', 1000) : $host->scan($cursor, $namespace.'*', 1000);
|
||||||
if (isset($keys[1]) && is_array($keys[1])) {
|
if (isset($keys[1]) && \is_array($keys[1])) {
|
||||||
$cursor = $keys[0];
|
$cursor = $keys[0];
|
||||||
$keys = $keys[1];
|
$keys = $keys[1];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user