updated-packages

This commit is contained in:
RafficMohammed
2023-01-08 00:13:22 +05:30
parent 3ff7df7487
commit da241bacb6
12659 changed files with 563377 additions and 510538 deletions

View File

@@ -2,9 +2,7 @@
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
class ApcStore extends TaggableStore implements Store
class ApcStore extends TaggableStore
{
use RetrievesMultipleKeys;
@@ -51,16 +49,16 @@ class ApcStore extends TaggableStore implements Store
}
/**
* Store an item in the cache for a given number of minutes.
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function put($key, $value, $minutes)
public function put($key, $value, $seconds)
{
$this->apc->put($this->prefix.$key, $value, (int) ($minutes * 60));
return $this->apc->put($this->prefix.$key, $value, $seconds);
}
/**
@@ -92,11 +90,11 @@ class ApcStore extends TaggableStore implements Store
*
* @param string $key
* @param mixed $value
* @return void
* @return bool
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
return $this->put($key, $value, 0);
}
/**

View File

@@ -2,11 +2,11 @@
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Support\InteractsWithTime;
class ArrayStore extends TaggableStore implements Store
class ArrayStore extends TaggableStore
{
use RetrievesMultipleKeys;
use InteractsWithTime, RetrievesMultipleKeys;
/**
* The array of stored values.
@@ -23,20 +23,39 @@ class ArrayStore extends TaggableStore implements Store
*/
public function get($key)
{
return $this->storage[$key] ?? null;
if (! isset($this->storage[$key])) {
return;
}
$item = $this->storage[$key];
$expiresAt = $item['expiresAt'] ?? 0;
if ($expiresAt !== 0 && $this->currentTime() > $expiresAt) {
$this->forget($key);
return;
}
return $item['value'];
}
/**
* Store an item in the cache for a given number of minutes.
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function put($key, $value, $minutes)
public function put($key, $value, $seconds)
{
$this->storage[$key] = $value;
$this->storage[$key] = [
'value' => $value,
'expiresAt' => $this->calculateExpiration($seconds),
];
return true;
}
/**
@@ -48,10 +67,15 @@ class ArrayStore extends TaggableStore implements Store
*/
public function increment($key, $value = 1)
{
$this->storage[$key] = ! isset($this->storage[$key])
? $value : ((int) $this->storage[$key]) + $value;
if (! isset($this->storage[$key])) {
$this->forever($key, $value);
return $this->storage[$key];
return $this->storage[$key]['value'];
}
$this->storage[$key]['value'] = ((int) $this->storage[$key]['value']) + $value;
return $this->storage[$key]['value'];
}
/**
@@ -71,11 +95,11 @@ class ArrayStore extends TaggableStore implements Store
*
* @param string $key
* @param mixed $value
* @return void
* @return bool
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
return $this->put($key, $value, 0);
}
/**
@@ -86,9 +110,13 @@ class ArrayStore extends TaggableStore implements Store
*/
public function forget($key)
{
unset($this->storage[$key]);
if (array_key_exists($key, $this->storage)) {
unset($this->storage[$key]);
return true;
return true;
}
return false;
}
/**
@@ -112,4 +140,26 @@ class ArrayStore extends TaggableStore implements Store
{
return '';
}
/**
* Get the expiration time of the key.
*
* @param int $seconds
* @return int
*/
protected function calculateExpiration($seconds)
{
return $this->toTimestamp($seconds);
}
/**
* Get the UNIX timestamp for the given number of seconds.
*
* @param int $seconds
* @return int
*/
protected function toTimestamp($seconds)
{
return $seconds > 0 ? $this->availableAt($seconds) : 0;
}
}

View File

@@ -3,7 +3,9 @@
namespace Illuminate\Cache;
use Closure;
use Illuminate\Support\Arr;
use InvalidArgumentException;
use Aws\DynamoDb\DynamoDbClient;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Contracts\Cache\Factory as FactoryContract;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
@@ -16,7 +18,7 @@ class CacheManager implements FactoryContract
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $app;
@@ -37,7 +39,7 @@ class CacheManager implements FactoryContract
/**
* Create a new Cache manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function __construct($app)
@@ -46,7 +48,7 @@ class CacheManager implements FactoryContract
}
/**
* Get a cache store instance by name.
* Get a cache store instance by name, wrapped in a repository.
*
* @param string|null $name
* @return \Illuminate\Contracts\Cache\Repository
@@ -62,7 +64,7 @@ class CacheManager implements FactoryContract
* Get a cache driver instance.
*
* @param string|null $driver
* @return mixed
* @return \Illuminate\Contracts\Cache\Repository
*/
public function driver($driver = null)
{
@@ -124,7 +126,7 @@ class CacheManager implements FactoryContract
* Create an instance of the APC cache driver.
*
* @param array $config
* @return \Illuminate\Cache\ApcStore
* @return \Illuminate\Cache\Repository
*/
protected function createApcDriver(array $config)
{
@@ -136,7 +138,7 @@ class CacheManager implements FactoryContract
/**
* Create an instance of the array cache driver.
*
* @return \Illuminate\Cache\ArrayStore
* @return \Illuminate\Cache\Repository
*/
protected function createArrayDriver()
{
@@ -147,7 +149,7 @@ class CacheManager implements FactoryContract
* Create an instance of the file cache driver.
*
* @param array $config
* @return \Illuminate\Cache\FileStore
* @return \Illuminate\Cache\Repository
*/
protected function createFileDriver(array $config)
{
@@ -158,7 +160,7 @@ class CacheManager implements FactoryContract
* Create an instance of the Memcached cache driver.
*
* @param array $config
* @return \Illuminate\Cache\MemcachedStore
* @return \Illuminate\Cache\Repository
*/
protected function createMemcachedDriver(array $config)
{
@@ -177,7 +179,7 @@ class CacheManager implements FactoryContract
/**
* Create an instance of the Null cache driver.
*
* @return \Illuminate\Cache\NullStore
* @return \Illuminate\Cache\Repository
*/
protected function createNullDriver()
{
@@ -188,7 +190,7 @@ class CacheManager implements FactoryContract
* Create an instance of the Redis cache driver.
*
* @param array $config
* @return \Illuminate\Cache\RedisStore
* @return \Illuminate\Cache\Repository
*/
protected function createRedisDriver(array $config)
{
@@ -203,7 +205,7 @@ class CacheManager implements FactoryContract
* Create an instance of the database cache driver.
*
* @param array $config
* @return \Illuminate\Cache\DatabaseStore
* @return \Illuminate\Cache\Repository
*/
protected function createDatabaseDriver(array $config)
{
@@ -216,6 +218,38 @@ class CacheManager implements FactoryContract
);
}
/**
* Create an instance of the DynamoDB cache driver.
*
* @param array $config
* @return \Illuminate\Cache\Repository
*/
protected function createDynamodbDriver(array $config)
{
$dynamoConfig = [
'region' => $config['region'],
'version' => 'latest',
'endpoint' => $config['endpoint'] ?? null,
];
if ($config['key'] && $config['secret']) {
$dynamoConfig['credentials'] = Arr::only(
$config, ['key', 'secret', 'token']
);
}
return $this->repository(
new DynamoDbStore(
new DynamoDbClient($dynamoConfig),
$config['table'],
$config['attributes']['key'] ?? 'key',
$config['attributes']['value'] ?? 'value',
$config['attributes']['expiration'] ?? 'expires_at',
$this->getPrefix($config)
)
);
}
/**
* Create a new cache repository with the given implementation.
*
@@ -278,10 +312,29 @@ class CacheManager implements FactoryContract
$this->app['config']['cache.default'] = $name;
}
/**
* Unset the given driver instances.
*
* @param array|string|null $name
* @return $this
*/
public function forgetDriver($name = null)
{
$name = $name ?? $this->getDefaultDriver();
foreach ((array) $name as $cacheName) {
if (isset($this->stores[$cacheName])) {
unset($this->stores[$cacheName]);
}
}
return $this;
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param string $driver
* @param \Closure $callback
* @return $this
*/
@@ -296,7 +349,7 @@ class CacheManager implements FactoryContract
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)

View File

@@ -3,16 +3,10 @@
namespace Illuminate\Cache;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Support\DeferrableProvider;
class CacheServiceProvider extends ServiceProvider
class CacheServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*

View File

@@ -60,15 +60,19 @@ class ClearCommand extends Command
*/
public function handle()
{
$this->laravel['events']->fire(
$this->laravel['events']->dispatch(
'cache:clearing', [$this->argument('store'), $this->tags()]
);
$this->cache()->flush();
$successful = $this->cache()->flush();
$this->flushFacades();
$this->laravel['events']->fire(
if (! $successful) {
return $this->error('Failed to clear cache. Make sure you have the appropriate permissions.');
}
$this->laravel['events']->dispatch(
'cache:cleared', [$this->argument('store'), $this->tags()]
);
@@ -123,7 +127,7 @@ class ClearCommand extends Command
protected function getArguments()
{
return [
['store', InputArgument::OPTIONAL, 'The name of the store you would like to clear.'],
['store', InputArgument::OPTIONAL, 'The name of the store you would like to clear'],
];
}
@@ -135,7 +139,7 @@ class ClearCommand extends Command
protected function getOptions()
{
return [
['tags', null, InputOption::VALUE_OPTIONAL, 'The cache tags you would like to clear.', null],
['tags', null, InputOption::VALUE_OPTIONAL, 'The cache tags you would like to clear', null],
];
}
}

View File

@@ -4,8 +4,10 @@ namespace Illuminate\Cache;
use Closure;
use Exception;
use Illuminate\Support\Str;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Support\InteractsWithTime;
use Illuminate\Database\PostgresConnection;
use Illuminate\Database\ConnectionInterface;
class DatabaseStore implements Store
@@ -78,29 +80,31 @@ class DatabaseStore implements Store
return;
}
return unserialize($cache->value);
return $this->unserialize($cache->value);
}
/**
* Store an item in the cache for a given number of minutes.
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function put($key, $value, $minutes)
public function put($key, $value, $seconds)
{
$key = $this->prefix.$key;
$value = serialize($value);
$value = $this->serialize($value);
$expiration = $this->getTime() + (int) ($minutes * 60);
$expiration = $this->getTime() + $seconds;
try {
$this->table()->insert(compact('key', 'value', 'expiration'));
return $this->table()->insert(compact('key', 'value', 'expiration'));
} catch (Exception $e) {
$this->table()->where('key', $key)->update(compact('value', 'expiration'));
$result = $this->table()->where('key', $key)->update(compact('value', 'expiration'));
return $result > 0;
}
}
@@ -157,7 +161,7 @@ class DatabaseStore implements Store
$cache = is_array($cache) ? (object) $cache : $cache;
$current = unserialize($cache->value);
$current = $this->unserialize($cache->value);
// Here we'll call this callback function that was given to the function which
// is used to either increment or decrement the function. We use a callback
@@ -172,7 +176,7 @@ class DatabaseStore implements Store
// since database cache values are encrypted by default with secure storage
// that can't be easily read. We will return the new value after storing.
$this->table()->where('key', $prefixed)->update([
'value' => serialize($new),
'value' => $this->serialize($new),
]);
return $new;
@@ -194,11 +198,11 @@ class DatabaseStore implements Store
*
* @param string $key
* @param mixed $value
* @return void
* @return bool
*/
public function forever($key, $value)
{
$this->put($key, $value, 5256000);
return $this->put($key, $value, 315360000);
}
/**
@@ -221,7 +225,9 @@ class DatabaseStore implements Store
*/
public function flush()
{
return (bool) $this->table()->delete();
$this->table()->delete();
return true;
}
/**
@@ -253,4 +259,36 @@ class DatabaseStore implements Store
{
return $this->prefix;
}
/**
* Serialize the given value.
*
* @param mixed $value
* @return string
*/
protected function serialize($value)
{
$result = serialize($value);
if ($this->connection instanceof PostgresConnection && Str::contains($result, "\0")) {
$result = base64_encode($result);
}
return $result;
}
/**
* Unserialize the given value.
*
* @param string $value
* @return mixed
*/
protected function unserialize($value)
{
if ($this->connection instanceof PostgresConnection && ! Str::contains($value, [':', ';'])) {
$value = base64_decode($value);
}
return unserialize($value);
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Illuminate\Cache;
class DynamoDbLock extends Lock
{
/**
* The DynamoDB client instance.
*
* @var \Illuminate\Cache\DynamoDbStore
*/
protected $dynamo;
/**
* Create a new lock instance.
*
* @param \Illuminate\Cache\DynamoDbStore $dynamo
* @param string $name
* @param int $seconds
* @param string|null $owner
* @return void
*/
public function __construct(DynamoDbStore $dynamo, $name, $seconds, $owner = null)
{
parent::__construct($name, $seconds, $owner);
$this->dynamo = $dynamo;
}
/**
* Attempt to acquire the lock.
*
* @return bool
*/
public function acquire()
{
return $this->dynamo->add(
$this->name, $this->owner, $this->seconds
);
}
/**
* Release the lock.
*
* @return void
*/
public function release()
{
if ($this->isOwnedByCurrentProcess()) {
$this->dynamo->forget($this->name);
}
}
/**
* Release this lock in disregard of ownership.
*
* @return void
*/
public function forceRelease()
{
$this->dynamo->forget($this->name);
}
/**
* Returns the owner value written into the driver for this lock.
*
* @return mixed
*/
protected function getCurrentOwner()
{
return $this->dynamo->get($this->name);
}
}

View File

@@ -0,0 +1,525 @@
<?php
namespace Illuminate\Cache;
use RuntimeException;
use Illuminate\Support\Str;
use Illuminate\Support\Carbon;
use Aws\DynamoDb\DynamoDbClient;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Support\InteractsWithTime;
use Illuminate\Contracts\Cache\LockProvider;
use Aws\DynamoDb\Exception\DynamoDbException;
class DynamoDbStore implements Store, LockProvider
{
use InteractsWithTime;
/**
* The DynamoDB client instance.
*
* @var \Aws\DynamoDb\DynamoDbClient
*/
protected $dynamo;
/**
* The table name.
*
* @var string
*/
protected $table;
/**
* The name of the attribute that should hold the key.
*
* @var string
*/
protected $keyAttribute;
/**
* The name of the attribute that should hold the value.
*
* @var string
*/
protected $valueAttribute;
/**
* The name of the attribute that should hold the expiration timestamp.
*
* @var string
*/
protected $expirationAttribute;
/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;
/**
* Create a new store instance.
*
* @param \Aws\DynamoDb\DynamoDbClient $dynamo
* @param string $table
* @param string $keyAttribute
* @param string $valueAttribute
* @param string $expirationAttribute
* @param string $prefix
* @return void
*/
public function __construct(DynamoDbClient $dynamo,
$table,
$keyAttribute = 'key',
$valueAttribute = 'value',
$expirationAttribute = 'expires_at',
$prefix = '')
{
$this->table = $table;
$this->dynamo = $dynamo;
$this->keyAttribute = $keyAttribute;
$this->valueAttribute = $valueAttribute;
$this->expirationAttribute = $expirationAttribute;
$this->setPrefix($prefix);
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$response = $this->dynamo->getItem([
'TableName' => $this->table,
'ConsistentRead' => false,
'Key' => [
$this->keyAttribute => [
'S' => $this->prefix.$key,
],
],
]);
if (! isset($response['Item'])) {
return;
}
if ($this->isExpired($response['Item'])) {
return;
}
if (isset($response['Item'][$this->valueAttribute])) {
return $this->unserialize(
$response['Item'][$this->valueAttribute]['S'] ??
$response['Item'][$this->valueAttribute]['N'] ??
null
);
}
}
/**
* Retrieve multiple items from the cache by key.
*
* Items not found in the cache will have a null value.
*
* @param array $keys
* @return array
*/
public function many(array $keys)
{
$prefixedKeys = array_map(function ($key) {
return $this->prefix.$key;
}, $keys);
$response = $this->dynamo->batchGetItem([
'RequestItems' => [
$this->table => [
'ConsistentRead' => false,
'Keys' => collect($prefixedKeys)->map(function ($key) {
return [
$this->keyAttribute => [
'S' => $key,
],
];
})->all(),
],
],
]);
$now = Carbon::now();
return array_merge(collect(array_flip($keys))->map(function () {
})->all(), collect($response['Responses'][$this->table])->mapWithKeys(function ($response) use ($now) {
if ($this->isExpired($response, $now)) {
$value = null;
} else {
$value = $this->unserialize(
$response[$this->valueAttribute]['S'] ??
$response[$this->valueAttribute]['N'] ??
null
);
}
return [Str::replaceFirst($this->prefix, '', $response[$this->keyAttribute]['S']) => $value];
})->all());
}
/**
* Determine if the given item is expired.
*
* @param array $item
* @param \DateTimeInterface|null $expiration
* @return bool
*/
protected function isExpired(array $item, $expiration = null)
{
$expiration = $expiration ?: Carbon::now();
return isset($item[$this->expirationAttribute]) &&
$expiration->getTimestamp() >= $item[$this->expirationAttribute]['N'];
}
/**
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param int $seconds
* @return bool
*/
public function put($key, $value, $seconds)
{
$this->dynamo->putItem([
'TableName' => $this->table,
'Item' => [
$this->keyAttribute => [
'S' => $this->prefix.$key,
],
$this->valueAttribute => [
$this->type($value) => $this->serialize($value),
],
$this->expirationAttribute => [
'N' => (string) $this->toTimestamp($seconds),
],
],
]);
return true;
}
/**
* Store multiple items in the cache for a given number of $seconds.
*
* @param array $values
* @param int $seconds
* @return bool
*/
public function putMany(array $values, $seconds)
{
$expiration = $this->toTimestamp($seconds);
$this->dynamo->batchWriteItem([
'RequestItems' => [
$this->table => collect($values)->map(function ($value, $key) use ($expiration) {
return [
'PutRequest' => [
'Item' => [
$this->keyAttribute => [
'S' => $this->prefix.$key,
],
$this->valueAttribute => [
$this->type($value) => $this->serialize($value),
],
$this->expirationAttribute => [
'N' => (string) $expiration,
],
],
],
];
})->values()->all(),
],
]);
return true;
}
/**
* Store an item in the cache if the key doesn't exist.
*
* @param string $key
* @param mixed $value
* @param int $seconds
* @return bool
*/
public function add($key, $value, $seconds)
{
try {
$this->dynamo->putItem([
'TableName' => $this->table,
'Item' => [
$this->keyAttribute => [
'S' => $this->prefix.$key,
],
$this->valueAttribute => [
$this->type($value) => $this->serialize($value),
],
$this->expirationAttribute => [
'N' => (string) $this->toTimestamp($seconds),
],
],
'ConditionExpression' => 'attribute_not_exists(#key) OR #expires_at < :now',
'ExpressionAttributeNames' => [
'#key' => $this->keyAttribute,
'#expires_at' => $this->expirationAttribute,
],
'ExpressionAttributeValues' => [
':now' => [
'N' => (string) Carbon::now()->getTimestamp(),
],
],
]);
return true;
} catch (DynamoDbException $e) {
if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) {
return false;
}
throw $e;
}
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1)
{
try {
$response = $this->dynamo->updateItem([
'TableName' => $this->table,
'Key' => [
$this->keyAttribute => [
'S' => $this->prefix.$key,
],
],
'ConditionExpression' => 'attribute_exists(#key) AND #expires_at > :now',
'UpdateExpression' => 'SET #value = #value + :amount',
'ExpressionAttributeNames' => [
'#key' => $this->keyAttribute,
'#value' => $this->valueAttribute,
'#expires_at' => $this->expirationAttribute,
],
'ExpressionAttributeValues' => [
':now' => [
'N' => (string) Carbon::now()->getTimestamp(),
],
':amount' => [
'N' => (string) $value,
],
],
'ReturnValues' => 'UPDATED_NEW',
]);
return (int) $response['Attributes'][$this->valueAttribute]['N'];
} catch (DynamoDbException $e) {
if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) {
return false;
}
throw $e;
}
}
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1)
{
try {
$response = $this->dynamo->updateItem([
'TableName' => $this->table,
'Key' => [
$this->keyAttribute => [
'S' => $this->prefix.$key,
],
],
'ConditionExpression' => 'attribute_exists(#key) AND #expires_at > :now',
'UpdateExpression' => 'SET #value = #value - :amount',
'ExpressionAttributeNames' => [
'#key' => $this->keyAttribute,
'#value' => $this->valueAttribute,
'#expires_at' => $this->expirationAttribute,
],
'ExpressionAttributeValues' => [
':now' => [
'N' => (string) Carbon::now()->getTimestamp(),
],
':amount' => [
'N' => (string) $value,
],
],
'ReturnValues' => 'UPDATED_NEW',
]);
return (int) $response['Attributes'][$this->valueAttribute]['N'];
} catch (DynamoDbException $e) {
if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) {
return false;
}
throw $e;
}
}
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return bool
*/
public function forever($key, $value)
{
return $this->put($key, $value, now()->addYears(5)->getTimestamp());
}
/**
* Get a lock instance.
*
* @param string $name
* @param int $seconds
* @param string|null $owner
* @return \Illuminate\Contracts\Cache\Lock
*/
public function lock($name, $seconds = 0, $owner = null)
{
return new DynamoDbLock($this, $this->prefix.$name, $seconds, $owner);
}
/**
* Restore a lock instance using the owner identifier.
*
* @param string $name
* @param string $owner
* @return \Illuminate\Contracts\Cache\Lock
*/
public function restoreLock($name, $owner)
{
return $this->lock($name, 0, $owner);
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key)
{
$this->dynamo->deleteItem([
'TableName' => $this->table,
'Key' => [
$this->keyAttribute => [
'S' => $this->prefix.$key,
],
],
]);
return true;
}
/**
* Remove all items from the cache.
*
* @return bool
*/
public function flush()
{
throw new RuntimeException('DynamoDb does not support flushing an entire table. Please create a new table.');
}
/**
* Get the UNIX timestamp for the given number of seconds.
*
* @param int $seconds
* @return int
*/
protected function toTimestamp($seconds)
{
return $seconds > 0
? $this->availableAt($seconds)
: Carbon::now()->getTimestamp();
}
/**
* Serialize the value.
*
* @param mixed $value
* @return mixed
*/
protected function serialize($value)
{
return is_numeric($value) ? (string) $value : serialize($value);
}
/**
* Unserialize the value.
*
* @param mixed $value
* @return mixed
*/
protected function unserialize($value)
{
if (filter_var($value, FILTER_VALIDATE_INT) !== false) {
return (int) $value;
}
if (is_numeric($value)) {
return (float) $value;
}
return unserialize($value);
}
/**
* Get the DynamoDB type for the given value.
*
* @param mixed $value
* @return string
*/
protected function type($value)
{
return is_numeric($value) ? 'N' : 'S';
}
/**
* Get the cache key prefix.
*
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* Set the cache key prefix.
*
* @param string $prefix
* @return void
*/
public function setPrefix($prefix)
{
$this->prefix = ! empty($prefix) ? $prefix.':' : '';
}
}

View File

@@ -12,26 +12,26 @@ class KeyWritten extends CacheEvent
public $value;
/**
* The number of minutes the key should be valid.
* The number of seconds the key should be valid.
*
* @var int
* @var int|null
*/
public $minutes;
public $seconds;
/**
* Create a new event instance.
*
* @param string $key
* @param mixed $value
* @param int $minutes
* @param int|null $seconds
* @param array $tags
* @return void
*/
public function __construct($key, $value, $minutes, $tags = [])
public function __construct($key, $value, $seconds = null, $tags = [])
{
parent::__construct($key, $tags);
$this->value = $value;
$this->minutes = $minutes;
$this->seconds = $seconds;
}
}

View File

@@ -50,20 +50,22 @@ class FileStore implements Store
}
/**
* Store an item in the cache for a given number of minutes.
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function put($key, $value, $minutes)
public function put($key, $value, $seconds)
{
$this->ensureCacheDirectoryExists($path = $this->path($key));
$this->files->put(
$path, $this->expiration($minutes).serialize($value), true
$result = $this->files->put(
$path, $this->expiration($seconds).serialize($value), true
);
return $result !== false && $result > 0;
}
/**
@@ -112,11 +114,11 @@ class FileStore implements Store
*
* @param string $key
* @param mixed $value
* @return void
* @return bool
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
return $this->put($key, $value, 0);
}
/**
@@ -184,12 +186,18 @@ class FileStore implements Store
return $this->emptyPayload();
}
$data = unserialize(substr($contents, 10));
try {
$data = unserialize(substr($contents, 10));
} catch (Exception $e) {
$this->forget($key);
// Next, we'll extract the number of minutes that are remaining for a cache
return $this->emptyPayload();
}
// Next, we'll extract the number of seconds that are remaining for a cache
// so that we can properly retain the time for things like the increment
// operation that may be performed on this cache on a later operation.
$time = ($expire - $this->currentTime()) / 60;
$time = $expire - $this->currentTime();
return compact('data', 'time');
}
@@ -218,16 +226,16 @@ class FileStore implements Store
}
/**
* Get the expiration time based on the given minutes.
* Get the expiration time based on the given seconds.
*
* @param float|int $minutes
* @param int $seconds
* @return int
*/
protected function expiration($minutes)
protected function expiration($seconds)
{
$time = $this->availableAt((int) ($minutes * 60));
$time = $this->availableAt($seconds);
return $minutes === 0 || $time > 9999999999 ? 9999999999 : (int) $time;
return $seconds === 0 || $time > 9999999999 ? 9999999999 : $time;
}
/**

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Taylor Otwell
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.

View File

@@ -2,10 +2,12 @@
namespace Illuminate\Cache;
use Illuminate\Support\Str;
use Illuminate\Support\InteractsWithTime;
use Illuminate\Contracts\Cache\Lock as LockContract;
use Illuminate\Contracts\Cache\LockTimeoutException;
abstract class Lock
abstract class Lock implements LockContract
{
use InteractsWithTime;
@@ -23,16 +25,29 @@ abstract class Lock
*/
protected $seconds;
/**
* The scope identifier of this lock.
*
* @var string
*/
protected $owner;
/**
* Create a new lock instance.
*
* @param string $name
* @param int $seconds
* @param string|null $owner
* @return void
*/
public function __construct($name, $seconds)
public function __construct($name, $seconds, $owner = null)
{
if (is_null($owner)) {
$owner = Str::random();
}
$this->name = $name;
$this->owner = $owner;
$this->seconds = $seconds;
}
@@ -43,20 +58,36 @@ abstract class Lock
*/
abstract public function acquire();
/**
* Release the lock.
*
* @return void
*/
abstract public function release();
/**
* Returns the owner value written into the driver for this lock.
*
* @return string
*/
abstract protected function getCurrentOwner();
/**
* Attempt to acquire the lock.
*
* @param callable|null $callback
* @return bool
* @return mixed
*/
public function get($callback = null)
{
$result = $this->acquire();
if ($result && is_callable($callback)) {
return tap($callback(), function () {
try {
return $callback();
} finally {
$this->release();
});
}
}
return $result;
@@ -68,6 +99,7 @@ abstract class Lock
* @param int $seconds
* @param callable|null $callback
* @return bool
*
* @throws \Illuminate\Contracts\Cache\LockTimeoutException
*/
public function block($seconds, $callback = null)
@@ -83,11 +115,33 @@ abstract class Lock
}
if (is_callable($callback)) {
return tap($callback(), function () {
try {
return $callback();
} finally {
$this->release();
});
}
}
return true;
}
/**
* Returns the current owner of the lock.
*
* @return string
*/
public function owner()
{
return $this->owner;
}
/**
* Determines whether this lock is allowed to release the lock in the driver.
*
* @return bool
*/
protected function isOwnedByCurrentProcess()
{
return $this->getCurrentOwner() === $this->owner;
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Illuminate\Cache;
class LuaScripts
{
/**
* Get the Lua script to atomically release a lock.
*
* KEYS[1] - The name of the lock
* ARGV[1] - The owner key of the lock instance trying to release it
*
* @return string
*/
public static function releaseLock()
{
return <<<'LUA'
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
LUA;
}
}

View File

@@ -78,7 +78,7 @@ class MemcachedConnector
*/
protected function setCredentials($memcached, $credentials)
{
list($username, $password) = $credentials;
[$username, $password] = $credentials;
$memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);

View File

@@ -2,9 +2,7 @@
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Lock as LockContract;
class MemcachedLock extends Lock implements LockContract
class MemcachedLock extends Lock
{
/**
* The Memcached instance.
@@ -19,11 +17,12 @@ class MemcachedLock extends Lock implements LockContract
* @param \Memcached $memcached
* @param string $name
* @param int $seconds
* @param string|null $owner
* @return void
*/
public function __construct($memcached, $name, $seconds)
public function __construct($memcached, $name, $seconds, $owner = null)
{
parent::__construct($name, $seconds);
parent::__construct($name, $seconds, $owner);
$this->memcached = $memcached;
}
@@ -36,7 +35,7 @@ class MemcachedLock extends Lock implements LockContract
public function acquire()
{
return $this->memcached->add(
$this->name, 1, $this->seconds
$this->name, $this->owner, $this->seconds
);
}
@@ -46,7 +45,29 @@ class MemcachedLock extends Lock implements LockContract
* @return void
*/
public function release()
{
if ($this->isOwnedByCurrentProcess()) {
$this->memcached->delete($this->name);
}
}
/**
* Releases this lock in disregard of ownership.
*
* @return void
*/
public function forceRelease()
{
$this->memcached->delete($this->name);
}
/**
* Returns the owner value written into the driver for this lock.
*
* @return mixed
*/
protected function getCurrentOwner()
{
return $this->memcached->get($this->name);
}
}

View File

@@ -4,11 +4,10 @@ namespace Illuminate\Cache;
use Memcached;
use ReflectionMethod;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Support\InteractsWithTime;
use Illuminate\Contracts\Cache\LockProvider;
class MemcachedStore extends TaggableStore implements LockProvider, Store
class MemcachedStore extends TaggableStore implements LockProvider
{
use InteractsWithTime;
@@ -94,26 +93,28 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
}
/**
* Store an item in the cache for a given number of minutes.
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function put($key, $value, $minutes)
public function put($key, $value, $seconds)
{
$this->memcached->set($this->prefix.$key, $value, $this->toTimestamp($minutes));
return $this->memcached->set(
$this->prefix.$key, $value, $this->calculateExpiration($seconds)
);
}
/**
* Store multiple items in the cache for a given number of minutes.
* Store multiple items in the cache for a given number of seconds.
*
* @param array $values
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function putMany(array $values, $minutes)
public function putMany(array $values, $seconds)
{
$prefixedValues = [];
@@ -121,7 +122,9 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
$prefixedValues[$this->prefix.$key] = $value;
}
$this->memcached->setMulti($prefixedValues, $this->toTimestamp($minutes));
return $this->memcached->setMulti(
$prefixedValues, $this->calculateExpiration($seconds)
);
}
/**
@@ -129,12 +132,14 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @param int $seconds
* @return bool
*/
public function add($key, $value, $minutes)
public function add($key, $value, $seconds)
{
return $this->memcached->add($this->prefix.$key, $value, $this->toTimestamp($minutes));
return $this->memcached->add(
$this->prefix.$key, $value, $this->calculateExpiration($seconds)
);
}
/**
@@ -166,23 +171,36 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
*
* @param string $key
* @param mixed $value
* @return void
* @return bool
*/
public function forever($key, $value)
{
$this->put($key, $value, 0);
return $this->put($key, $value, 0);
}
/**
* Get a lock instance.
*
* @param string $name
* @param int $seconds
* @param string $name
* @param int $seconds
* @param string|null $owner
* @return \Illuminate\Contracts\Cache\Lock
*/
public function lock($name, $seconds = 0)
public function lock($name, $seconds = 0, $owner = null)
{
return new MemcachedLock($this->memcached, $this->prefix.$name, $seconds);
return new MemcachedLock($this->memcached, $this->prefix.$name, $seconds, $owner);
}
/**
* Restore a lock instance using the owner identifier.
*
* @param string $name
* @param string $owner
* @return \Illuminate\Contracts\Cache\Lock
*/
public function restoreLock($name, $owner)
{
return $this->lock($name, 0, $owner);
}
/**
@@ -207,14 +225,25 @@ class MemcachedStore extends TaggableStore implements LockProvider, Store
}
/**
* Get the UNIX timestamp for the given number of minutes.
* Get the expiration time of the key.
*
* @param int $minutes
* @param int $seconds
* @return int
*/
protected function toTimestamp($minutes)
protected function calculateExpiration($seconds)
{
return $minutes > 0 ? $this->availableAt($minutes * 60) : 0;
return $this->toTimestamp($seconds);
}
/**
* Get the UNIX timestamp for the given number of seconds.
*
* @param int $seconds
* @return int
*/
protected function toTimestamp($seconds)
{
return $seconds > 0 ? $this->availableAt($seconds) : 0;
}
/**

View File

@@ -2,9 +2,7 @@
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
class NullStore extends TaggableStore implements Store
class NullStore extends TaggableStore
{
use RetrievesMultipleKeys;
@@ -23,20 +21,19 @@ class NullStore extends TaggableStore implements Store
*/
public function get($key)
{
//
}
/**
* Store an item in the cache for a given number of minutes.
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function put($key, $value, $minutes)
public function put($key, $value, $seconds)
{
//
return false;
}
/**
@@ -44,11 +41,11 @@ class NullStore extends TaggableStore implements Store
*
* @param string $key
* @param mixed $value
* @return int
* @return int|bool
*/
public function increment($key, $value = 1)
{
//
return false;
}
/**
@@ -56,11 +53,11 @@ class NullStore extends TaggableStore implements Store
*
* @param string $key
* @param mixed $value
* @return int
* @return int|bool
*/
public function decrement($key, $value = 1)
{
//
return false;
}
/**
@@ -68,22 +65,22 @@ class NullStore extends TaggableStore implements Store
*
* @param string $key
* @param mixed $value
* @return void
* @return bool
*/
public function forever($key, $value)
{
//
return false;
}
/**
* Remove an item from the cache.
*
* @param string $key
* @return void
* @return bool
*/
public function forget($key)
{
//
return true;
}
/**

View File

@@ -51,21 +51,21 @@ class RateLimiter
* Increment the counter for a given key for a given decay time.
*
* @param string $key
* @param float|int $decayMinutes
* @param int $decaySeconds
* @return int
*/
public function hit($key, $decayMinutes = 1)
public function hit($key, $decaySeconds = 60)
{
$this->cache->add(
$key.':timer', $this->availableAt($decayMinutes * 60), $decayMinutes
$key.':timer', $this->availableAt($decaySeconds), $decaySeconds
);
$added = $this->cache->add($key, 0, $decayMinutes);
$added = $this->cache->add($key, 0, $decaySeconds);
$hits = (int) $this->cache->increment($key);
if (! $added && $hits == 1) {
$this->cache->put($key, 1, $decayMinutes);
$this->cache->put($key, 1, $decaySeconds);
}
return $hits;

View File

@@ -2,9 +2,7 @@
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Lock as LockContract;
class RedisLock extends Lock implements LockContract
class RedisLock extends Lock
{
/**
* The Redis factory implementation.
@@ -19,11 +17,12 @@ class RedisLock extends Lock implements LockContract
* @param \Illuminate\Redis\Connections\Connection $redis
* @param string $name
* @param int $seconds
* @param string|null $owner
* @return void
*/
public function __construct($redis, $name, $seconds)
public function __construct($redis, $name, $seconds, $owner = null)
{
parent::__construct($name, $seconds);
parent::__construct($name, $seconds, $owner);
$this->redis = $redis;
}
@@ -35,7 +34,7 @@ class RedisLock extends Lock implements LockContract
*/
public function acquire()
{
$result = $this->redis->setnx($this->name, 1);
$result = $this->redis->setnx($this->name, $this->owner);
if ($result === 1 && $this->seconds > 0) {
$this->redis->expire($this->name, $this->seconds);
@@ -50,7 +49,27 @@ class RedisLock extends Lock implements LockContract
* @return void
*/
public function release()
{
$this->redis->eval(LuaScripts::releaseLock(), 1, $this->name, $this->owner);
}
/**
* Releases this lock in disregard of ownership.
*
* @return void
*/
public function forceRelease()
{
$this->redis->del($this->name);
}
/**
* Returns the owner value written into the driver for this lock.
*
* @return string
*/
protected function getCurrentOwner()
{
return $this->redis->get($this->name);
}
}

View File

@@ -2,10 +2,10 @@
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Contracts\Cache\LockProvider;
use Illuminate\Contracts\Redis\Factory as Redis;
class RedisStore extends TaggableStore implements Store
class RedisStore extends TaggableStore implements LockProvider
{
/**
* The Redis factory implementation.
@@ -80,36 +80,42 @@ class RedisStore extends TaggableStore implements Store
}
/**
* Store an item in the cache for a given number of minutes.
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function put($key, $value, $minutes)
public function put($key, $value, $seconds)
{
$this->connection()->setex(
$this->prefix.$key, (int) max(1, $minutes * 60), $this->serialize($value)
return (bool) $this->connection()->setex(
$this->prefix.$key, (int) max(1, $seconds), $this->serialize($value)
);
}
/**
* Store multiple items in the cache for a given number of minutes.
* Store multiple items in the cache for a given number of seconds.
*
* @param array $values
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function putMany(array $values, $minutes)
public function putMany(array $values, $seconds)
{
$this->connection()->multi();
$manyResult = null;
foreach ($values as $key => $value) {
$this->put($key, $value, $minutes);
$result = $this->put($key, $value, $seconds);
$manyResult = is_null($manyResult) ? $result : $result && $manyResult;
}
$this->connection()->exec();
return $manyResult ?: false;
}
/**
@@ -117,15 +123,15 @@ class RedisStore extends TaggableStore implements Store
*
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @param int $seconds
* @return bool
*/
public function add($key, $value, $minutes)
public function add($key, $value, $seconds)
{
$lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])";
return (bool) $this->connection()->eval(
$lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $minutes * 60)
$lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $seconds)
);
}
@@ -158,23 +164,36 @@ class RedisStore extends TaggableStore implements Store
*
* @param string $key
* @param mixed $value
* @return void
* @return bool
*/
public function forever($key, $value)
{
$this->connection()->set($this->prefix.$key, $this->serialize($value));
return (bool) $this->connection()->set($this->prefix.$key, $this->serialize($value));
}
/**
* Get a lock instance.
*
* @param string $name
* @param int $seconds
* @param string $name
* @param int $seconds
* @param string|null $owner
* @return \Illuminate\Contracts\Cache\Lock
*/
public function lock($name, $seconds = 0)
public function lock($name, $seconds = 0, $owner = null)
{
return new RedisLock($this->connection(), $this->prefix.$name, $seconds);
return new RedisLock($this->connection(), $this->prefix.$name, $seconds, $owner);
}
/**
* Restore a lock instance using the owner identifier.
*
* @param string $name
* @param string $owner
* @return \Illuminate\Contracts\Cache\Lock
*/
public function restoreLock($name, $owner)
{
return $this->lock($name, 0, $owner);
}
/**

View File

@@ -22,21 +22,25 @@ class RedisTaggedCache extends TaggedCache
*
* @param string $key
* @param mixed $value
* @param \DateTime|float|int|null $minutes
* @return void
* @param \DateTimeInterface|\DateInterval|int|null $ttl
* @return bool
*/
public function put($key, $value, $minutes = null)
public function put($key, $value, $ttl = null)
{
if ($ttl === null) {
return $this->forever($key, $value);
}
$this->pushStandardKeys($this->tags->getNamespace(), $key);
parent::put($key, $value, $minutes);
return parent::put($key, $value, $ttl);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
@@ -50,7 +54,7 @@ class RedisTaggedCache extends TaggedCache
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
@@ -64,27 +68,27 @@ class RedisTaggedCache extends TaggedCache
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
* @param mixed $value
* @return bool
*/
public function forever($key, $value)
{
$this->pushForeverKeys($this->tags->getNamespace(), $key);
parent::forever($key, $value);
return parent::forever($key, $value);
}
/**
* Remove all items from the cache.
*
* @return void
* @return bool
*/
public function flush()
{
$this->deleteForeverKeys();
$this->deleteStandardKeys();
parent::flush();
return parent::flush();
}
/**

View File

@@ -42,11 +42,11 @@ class Repository implements CacheContract, ArrayAccess
protected $events;
/**
* The default number of minutes to store items.
* The default number of seconds to store items.
*
* @var float|int
* @var int|null
*/
protected $default = 60;
protected $default = 3600;
/**
* Create a new cache repository instance.
@@ -70,11 +70,22 @@ class Repository implements CacheContract, ArrayAccess
return ! is_null($this->get($key));
}
/**
* Determine if an item doesn't exist in the cache.
*
* @param string $key
* @return bool
*/
public function missing($key)
{
return ! $this->has($key);
}
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @param mixed $default
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
@@ -123,17 +134,13 @@ class Repository implements CacheContract, ArrayAccess
*/
public function getMultiple($keys, $default = null)
{
if (is_null($default)) {
return $this->many($keys);
}
$defaults = [];
foreach ($keys as $key) {
if (! isset($default[$key])) {
$default[$key] = null;
}
$defaults[$key] = $default;
}
return $this->many($default);
return $this->many($defaults);
}
/**
@@ -167,7 +174,7 @@ class Repository implements CacheContract, ArrayAccess
* Retrieve an item from the cache and delete it.
*
* @param string $key
* @param mixed $default
* @param mixed $default
* @return mixed
*/
public function pull($key, $default = null)
@@ -181,21 +188,33 @@ class Repository implements CacheContract, ArrayAccess
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \DateTimeInterface|\DateInterval|float|int|null $minutes
* @return void
* @param mixed $value
* @param \DateTimeInterface|\DateInterval|int|null $ttl
* @return bool
*/
public function put($key, $value, $minutes = null)
public function put($key, $value, $ttl = null)
{
if (is_array($key)) {
return $this->putMany($key, $value);
}
if (! is_null($minutes = $this->getMinutes($minutes))) {
$this->store->put($this->itemKey($key), $value, $minutes);
$this->event(new KeyWritten($key, $value, $minutes));
if ($ttl === null) {
return $this->forever($key, $value);
}
$seconds = $this->getSeconds($ttl);
if ($seconds <= 0) {
return $this->forget($key);
}
$result = $this->store->put($this->itemKey($key), $value, $seconds);
if ($result) {
$this->event(new KeyWritten($key, $value, $seconds));
}
return $result;
}
/**
@@ -203,25 +222,56 @@ class Repository implements CacheContract, ArrayAccess
*/
public function set($key, $value, $ttl = null)
{
$this->put($key, $value, $ttl);
return $this->put($key, $value, $ttl);
}
/**
* Store multiple items in the cache for a given number of minutes.
* Store multiple items in the cache for a given number of seconds.
*
* @param array $values
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @return void
* @param \DateTimeInterface|\DateInterval|int|null $ttl
* @return bool
*/
public function putMany(array $values, $minutes)
public function putMany(array $values, $ttl = null)
{
if (! is_null($minutes = $this->getMinutes($minutes))) {
$this->store->putMany($values, $minutes);
if ($ttl === null) {
return $this->putManyForever($values);
}
$seconds = $this->getSeconds($ttl);
if ($seconds <= 0) {
return $this->deleteMultiple(array_keys($values));
}
$result = $this->store->putMany($values, $seconds);
if ($result) {
foreach ($values as $key => $value) {
$this->event(new KeyWritten($key, $value, $minutes));
$this->event(new KeyWritten($key, $value, $seconds));
}
}
return $result;
}
/**
* Store multiple items in the cache indefinitely.
*
* @param array $values
* @return bool
*/
protected function putManyForever(array $values)
{
$result = true;
foreach ($values as $key => $value) {
if (! $this->forever($key, $value)) {
$result = false;
}
}
return $result;
}
/**
@@ -229,39 +279,41 @@ class Repository implements CacheContract, ArrayAccess
*/
public function setMultiple($values, $ttl = null)
{
$this->putMany($values, $ttl);
return $this->putMany(is_array($values) ? $values : iterator_to_array($values), $ttl);
}
/**
* Store an item in the cache if the key does not exist.
*
* @param string $key
* @param mixed $value
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @param mixed $value
* @param \DateTimeInterface|\DateInterval|int|null $ttl
* @return bool
*/
public function add($key, $value, $minutes)
public function add($key, $value, $ttl = null)
{
if (is_null($minutes = $this->getMinutes($minutes))) {
return false;
}
if ($ttl !== null) {
if ($this->getSeconds($ttl) <= 0) {
return false;
}
// If the store has an "add" method we will call the method on the store so it
// has a chance to override this logic. Some drivers better support the way
// this operation should work with a total "atomic" implementation of it.
if (method_exists($this->store, 'add')) {
return $this->store->add(
$this->itemKey($key), $value, $minutes
);
// If the store has an "add" method we will call the method on the store so it
// has a chance to override this logic. Some drivers better support the way
// this operation should work with a total "atomic" implementation of it.
if (method_exists($this->store, 'add')) {
$seconds = $this->getSeconds($ttl);
return $this->store->add(
$this->itemKey($key), $value, $seconds
);
}
}
// If the value did not exist in the cache, we will put the value in the cache
// so it exists for subsequent requests. Then, we will return true so it is
// easy to know if the value gets added. Otherwise, we will return false.
if (is_null($this->get($key))) {
$this->put($key, $value, $minutes);
return true;
return $this->put($key, $value, $ttl);
}
return false;
@@ -295,44 +347,48 @@ class Repository implements CacheContract, ArrayAccess
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
* @param mixed $value
* @return bool
*/
public function forever($key, $value)
{
$this->store->forever($this->itemKey($key), $value);
$result = $this->store->forever($this->itemKey($key), $value);
$this->event(new KeyWritten($key, $value, 0));
if ($result) {
$this->event(new KeyWritten($key, $value));
}
return $result;
}
/**
* Get an item from the cache, or store the default value.
* Get an item from the cache, or execute the given Closure and store the result.
*
* @param string $key
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @param \DateTimeInterface|\DateInterval|int|null $ttl
* @param \Closure $callback
* @return mixed
*/
public function remember($key, $minutes, Closure $callback)
public function remember($key, $ttl, Closure $callback)
{
$value = $this->get($key);
// If the item exists in the cache we will just return this immediately and if
// not we will execute the given Closure and cache the result of that for a
// given number of minutes so it's available for all subsequent requests.
// given number of seconds so it's available for all subsequent requests.
if (! is_null($value)) {
return $value;
}
$this->put($key, $value = $callback(), $minutes);
$this->put($key, $value = $callback(), $ttl);
return $value;
}
/**
* Get an item from the cache, or store the default value forever.
* Get an item from the cache, or execute the given Closure and store the result forever.
*
* @param string $key
* @param string $key
* @param \Closure $callback
* @return mixed
*/
@@ -342,9 +398,9 @@ class Repository implements CacheContract, ArrayAccess
}
/**
* Get an item from the cache, or store the default value forever.
* Get an item from the cache, or execute the given Closure and store the result forever.
*
* @param string $key
* @param string $key
* @param \Closure $callback
* @return mixed
*/
@@ -352,9 +408,9 @@ class Repository implements CacheContract, ArrayAccess
{
$value = $this->get($key);
// If the item exists in the cache we will just return this immediately and if
// not we will execute the given Closure and cache the result of that for a
// given number of minutes so it's available for all subsequent requests.
// If the item exists in the cache we will just return this immediately
// and if not we will execute the given Closure and cache the result
// of that forever so it is available for all subsequent requests.
if (! is_null($value)) {
return $value;
}
@@ -372,8 +428,10 @@ class Repository implements CacheContract, ArrayAccess
*/
public function forget($key)
{
return tap($this->store->forget($this->itemKey($key)), function () use ($key) {
$this->event(new KeyForgotten($key));
return tap($this->store->forget($this->itemKey($key)), function ($result) use ($key) {
if ($result) {
$this->event(new KeyForgotten($key));
}
});
}
@@ -390,11 +448,15 @@ class Repository implements CacheContract, ArrayAccess
*/
public function deleteMultiple($keys)
{
$result = true;
foreach ($keys as $key) {
$this->forget($key);
if (! $this->forget($key)) {
$result = false;
}
}
return true;
return $result;
}
/**
@@ -442,7 +504,7 @@ class Repository implements CacheContract, ArrayAccess
/**
* Get the default cache time.
*
* @return float|int
* @return int
*/
public function getDefaultCacheTime()
{
@@ -450,14 +512,14 @@ class Repository implements CacheContract, ArrayAccess
}
/**
* Set the default cache time in minutes.
* Set the default cache time in seconds.
*
* @param float|int $minutes
* @param int|null $seconds
* @return $this
*/
public function setDefaultCacheTime($minutes)
public function setDefaultCacheTime($seconds)
{
$this->default = $minutes;
$this->default = $seconds;
return $this;
}
@@ -542,27 +604,27 @@ class Repository implements CacheContract, ArrayAccess
}
/**
* Calculate the number of minutes with the given duration.
* Calculate the number of seconds for the given TTL.
*
* @param \DateTimeInterface|\DateInterval|float|int $duration
* @return float|int|null
* @param \DateTimeInterface|\DateInterval|int $ttl
* @return int
*/
protected function getMinutes($duration)
protected function getSeconds($ttl)
{
$duration = $this->parseDateInterval($duration);
$duration = $this->parseDateInterval($ttl);
if ($duration instanceof DateTimeInterface) {
$duration = Carbon::now()->diffInSeconds(Carbon::createFromTimestamp($duration->getTimestamp()), false) / 60;
$duration = Carbon::now()->diffInRealSeconds($duration, false);
}
return (int) ($duration * 60) > 0 ? $duration : null;
return (int) $duration > 0 ? $duration : 0;
}
/**
* Handle dynamic calls into macros or pass missing methods to the store.
*
* @param string $method
* @param array $parameters
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)

View File

@@ -24,16 +24,22 @@ trait RetrievesMultipleKeys
}
/**
* Store multiple items in the cache for a given number of minutes.
* Store multiple items in the cache for a given number of seconds.
*
* @param array $values
* @param float|int $minutes
* @return void
* @param int $seconds
* @return bool
*/
public function putMany(array $values, $minutes)
public function putMany(array $values, $seconds)
{
$manyResult = null;
foreach ($values as $key => $value) {
$this->put($key, $value, $minutes);
$result = $this->put($key, $value, $seconds);
$manyResult = is_null($manyResult) ? $result : $result && $manyResult;
}
return $manyResult ?: false;
}
}

View File

@@ -2,7 +2,9 @@
namespace Illuminate\Cache;
abstract class TaggableStore
use Illuminate\Contracts\Cache\Store;
abstract class TaggableStore implements Store
{
/**
* Begin executing a new tags operation.

View File

@@ -6,7 +6,9 @@ use Illuminate\Contracts\Cache\Store;
class TaggedCache extends Repository
{
use RetrievesMultipleKeys;
use RetrievesMultipleKeys {
putMany as putManyAlias;
}
/**
* The tag set instance.
@@ -29,11 +31,27 @@ class TaggedCache extends Repository
$this->tags = $tags;
}
/**
* Store multiple items in the cache for a given number of seconds.
*
* @param array $values
* @param int|null $ttl
* @return bool
*/
public function putMany(array $values, $ttl = null)
{
if ($ttl === null) {
return $this->putManyForever($values);
}
return $this->putManyAlias($values, $ttl);
}
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @param mixed $value
* @return void
*/
public function increment($key, $value = 1)
@@ -45,7 +63,7 @@ class TaggedCache extends Repository
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @param mixed $value
* @return void
*/
public function decrement($key, $value = 1)
@@ -56,11 +74,13 @@ class TaggedCache extends Repository
/**
* Remove all items from the cache.
*
* @return void
* @return bool
*/
public function flush()
{
$this->tags->reset();
return true;
}
/**
@@ -92,4 +112,14 @@ class TaggedCache extends Repository
{
parent::event($event->setTags($this->tags->getNames()));
}
/**
* Get the tag set instance.
*
* @return \Illuminate\Cache\TagSet
*/
public function getTags()
{
return $this->tags;
}
}

View File

@@ -15,8 +15,8 @@
],
"require": {
"php": "^7.1.3",
"illuminate/contracts": "5.6.*",
"illuminate/support": "5.6.*"
"illuminate/contracts": "5.8.*",
"illuminate/support": "5.8.*"
},
"autoload": {
"psr-4": {
@@ -25,13 +25,13 @@
},
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
"dev-master": "5.8-dev"
}
},
"suggest": {
"illuminate/database": "Required to use the database cache driver (5.6.*).",
"illuminate/filesystem": "Required to use the file cache driver (5.6.*).",
"illuminate/redis": "Required to use the redis cache driver (5.6.*)."
"illuminate/database": "Required to use the database cache driver (5.8.*).",
"illuminate/filesystem": "Required to use the file cache driver (5.8.*).",
"illuminate/redis": "Required to use the redis cache driver (5.8.*)."
},
"config": {
"sort-packages": true