Laravel version update
Laravel version update
This commit is contained in:
@@ -55,12 +55,12 @@ class ApcStore extends TaggableStore implements Store
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
{
|
||||
$this->apc->put($this->prefix.$key, $value, $minutes * 60);
|
||||
$this->apc->put($this->prefix.$key, $value, (int) ($minutes * 60));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,11 +113,11 @@ class ApcStore extends TaggableStore implements Store
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->apc->flush();
|
||||
return $this->apc->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,10 +83,10 @@ class ApcWrapper
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->apcu ? apcu_clear_cache() : apc_clear_cache('user');
|
||||
return $this->apcu ? apcu_clear_cache() : apc_clear_cache('user');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class ArrayStore extends TaggableStore implements Store
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
@@ -50,7 +50,8 @@ class ArrayStore extends TaggableStore implements Store
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
{
|
||||
$this->storage[$key] = ((int) $this->storage[$key]) + $value;
|
||||
$this->storage[$key] = ! isset($this->storage[$key])
|
||||
? $value : ((int) $this->storage[$key]) + $value;
|
||||
|
||||
return $this->storage[$key];
|
||||
}
|
||||
@@ -95,11 +96,13 @@ class ArrayStore extends TaggableStore implements Store
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->storage = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Arr;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Contracts\Cache\Factory as FactoryContract;
|
||||
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Contracts\Cache\Repository
|
||||
*/
|
||||
class CacheManager implements FactoryContract
|
||||
{
|
||||
/**
|
||||
@@ -46,7 +49,7 @@ class CacheManager implements FactoryContract
|
||||
* Get a cache store instance by name.
|
||||
*
|
||||
* @param string|null $name
|
||||
* @return mixed
|
||||
* @return \Illuminate\Contracts\Cache\Repository
|
||||
*/
|
||||
public function store($name = null)
|
||||
{
|
||||
@@ -74,7 +77,7 @@ class CacheManager implements FactoryContract
|
||||
*/
|
||||
protected function get($name)
|
||||
{
|
||||
return isset($this->stores[$name]) ? $this->stores[$name] : $this->resolve($name);
|
||||
return $this->stores[$name] ?? $this->resolve($name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +164,12 @@ class CacheManager implements FactoryContract
|
||||
{
|
||||
$prefix = $this->getPrefix($config);
|
||||
|
||||
$memcached = $this->app['memcached.connector']->connect($config['servers']);
|
||||
$memcached = $this->app['memcached.connector']->connect(
|
||||
$config['servers'],
|
||||
$config['persistent_id'] ?? null,
|
||||
$config['options'] ?? [],
|
||||
array_filter($config['sasl'] ?? [])
|
||||
);
|
||||
|
||||
return $this->repository(new MemcachedStore($memcached, $prefix));
|
||||
}
|
||||
@@ -186,7 +194,7 @@ class CacheManager implements FactoryContract
|
||||
{
|
||||
$redis = $this->app['redis'];
|
||||
|
||||
$connection = Arr::get($config, 'connection', 'default');
|
||||
$connection = $config['connection'] ?? 'default';
|
||||
|
||||
return $this->repository(new RedisStore($redis, $this->getPrefix($config), $connection));
|
||||
}
|
||||
@@ -199,11 +207,11 @@ class CacheManager implements FactoryContract
|
||||
*/
|
||||
protected function createDatabaseDriver(array $config)
|
||||
{
|
||||
$connection = $this->app['db']->connection(Arr::get($config, 'connection'));
|
||||
$connection = $this->app['db']->connection($config['connection'] ?? null);
|
||||
|
||||
return $this->repository(
|
||||
new DatabaseStore(
|
||||
$connection, $this->app['encrypter'], $config['table'], $this->getPrefix($config)
|
||||
$connection, $config['table'], $this->getPrefix($config)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -218,9 +226,9 @@ class CacheManager implements FactoryContract
|
||||
{
|
||||
$repository = new Repository($store);
|
||||
|
||||
if ($this->app->bound('Illuminate\Contracts\Events\Dispatcher')) {
|
||||
if ($this->app->bound(DispatcherContract::class)) {
|
||||
$repository->setEventDispatcher(
|
||||
$this->app['Illuminate\Contracts\Events\Dispatcher']
|
||||
$this->app[DispatcherContract::class]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -235,7 +243,7 @@ class CacheManager implements FactoryContract
|
||||
*/
|
||||
protected function getPrefix(array $config)
|
||||
{
|
||||
return Arr::get($config, 'prefix') ?: $this->app['config']['cache.prefix'];
|
||||
return $config['prefix'] ?? $this->app['config']['cache.prefix'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,7 +287,7 @@ class CacheManager implements FactoryContract
|
||||
*/
|
||||
public function extend($driver, Closure $callback)
|
||||
{
|
||||
$this->customCreators[$driver] = $callback;
|
||||
$this->customCreators[$driver] = $callback->bindTo($this, $this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -293,6 +301,6 @@ class CacheManager implements FactoryContract
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
return call_user_func_array([$this->store(), $method], $parameters);
|
||||
return $this->store()->$method(...$parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Cache\Console\ClearCommand;
|
||||
|
||||
class CacheServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -32,22 +31,6 @@ class CacheServiceProvider extends ServiceProvider
|
||||
$this->app->singleton('memcached.connector', function () {
|
||||
return new MemcachedConnector;
|
||||
});
|
||||
|
||||
$this->registerCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the cache related console commands.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerCommands()
|
||||
{
|
||||
$this->app->singleton('command.cache.clear', function ($app) {
|
||||
return new ClearCommand($app['cache']);
|
||||
});
|
||||
|
||||
$this->commands('command.cache.clear');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +41,7 @@ class CacheServiceProvider extends ServiceProvider
|
||||
public function provides()
|
||||
{
|
||||
return [
|
||||
'cache', 'cache.store', 'memcached.connector', 'command.cache.clear',
|
||||
'cache', 'cache.store', 'memcached.connector',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class CacheTableCommand extends Command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function fire()
|
||||
public function handle()
|
||||
{
|
||||
$fullPath = $this->createBaseMigration();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Illuminate\Cache\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Cache\CacheManager;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
@@ -30,17 +31,26 @@ class ClearCommand extends Command
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* Create a new cache clear command instance.
|
||||
*
|
||||
* @param \Illuminate\Cache\CacheManager $cache
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(CacheManager $cache)
|
||||
public function __construct(CacheManager $cache, Filesystem $files)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->cache = $cache;
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,21 +60,55 @@ class ClearCommand extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$tags = array_filter(explode(',', $this->option('tags')));
|
||||
$this->laravel['events']->fire(
|
||||
'cache:clearing', [$this->argument('store'), $this->tags()]
|
||||
);
|
||||
|
||||
$cache = $this->cache->store($store = $this->argument('store'));
|
||||
$this->cache()->flush();
|
||||
|
||||
$this->laravel['events']->fire('cache:clearing', [$store, $tags]);
|
||||
$this->flushFacades();
|
||||
|
||||
if (! empty($tags)) {
|
||||
$cache->tags($tags)->flush();
|
||||
} else {
|
||||
$cache->flush();
|
||||
}
|
||||
$this->laravel['events']->fire(
|
||||
'cache:cleared', [$this->argument('store'), $this->tags()]
|
||||
);
|
||||
|
||||
$this->info('Cache cleared successfully.');
|
||||
}
|
||||
|
||||
$this->laravel['events']->fire('cache:cleared', [$store, $tags]);
|
||||
/**
|
||||
* Flush the real-time facades stored in the cache directory.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function flushFacades()
|
||||
{
|
||||
foreach ($this->files->files(storage_path('framework/cache')) as $file) {
|
||||
if (preg_match('/facade-.*\.php$/', $file)) {
|
||||
$this->files->delete($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache instance for the command.
|
||||
*
|
||||
* @return \Illuminate\Cache\Repository
|
||||
*/
|
||||
protected function cache()
|
||||
{
|
||||
$cache = $this->cache->store($this->argument('store'));
|
||||
|
||||
return empty($this->tags()) ? $cache : $cache->tags($this->tags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tags passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function tags()
|
||||
{
|
||||
return array_filter(explode(',', $this->option('tags')));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
57
vendor/laravel/framework/src/Illuminate/Cache/Console/ForgetCommand.php
vendored
Normal file
57
vendor/laravel/framework/src/Illuminate/Cache/Console/ForgetCommand.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Cache\CacheManager;
|
||||
|
||||
class ForgetCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'cache:forget {key : The key to remove} {store? : The store to remove the key from}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Remove an item from the cache';
|
||||
|
||||
/**
|
||||
* The cache manager instance.
|
||||
*
|
||||
* @var \Illuminate\Cache\CacheManager
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Create a new cache clear command instance.
|
||||
*
|
||||
* @param \Illuminate\Cache\CacheManager $cache
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(CacheManager $cache)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->cache->store($this->argument('store'))->forget(
|
||||
$this->argument('key')
|
||||
);
|
||||
|
||||
$this->info('The ['.$this->argument('key').'] key has been removed from the cache.');
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
@@ -14,7 +15,7 @@ class CreateCacheTable extends Migration
|
||||
{
|
||||
Schema::create('cache', function (Blueprint $table) {
|
||||
$table->string('key')->unique();
|
||||
$table->text('value');
|
||||
$table->mediumText('value');
|
||||
$table->integer('expiration');
|
||||
});
|
||||
}
|
||||
@@ -26,6 +27,6 @@ class CreateCacheTable extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('cache');
|
||||
Schema::dropIfExists('cache');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ namespace Illuminate\Cache;
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
|
||||
|
||||
class DatabaseStore implements Store
|
||||
{
|
||||
use RetrievesMultipleKeys;
|
||||
use InteractsWithTime, RetrievesMultipleKeys;
|
||||
|
||||
/**
|
||||
* The database connection instance.
|
||||
@@ -19,13 +19,6 @@ class DatabaseStore implements Store
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* The encrypter instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Encryption\Encrypter
|
||||
*/
|
||||
protected $encrypter;
|
||||
|
||||
/**
|
||||
* The name of the cache table.
|
||||
*
|
||||
@@ -44,16 +37,14 @@ class DatabaseStore implements Store
|
||||
* Create a new database store.
|
||||
*
|
||||
* @param \Illuminate\Database\ConnectionInterface $connection
|
||||
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
||||
* @param string $table
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ConnectionInterface $connection, EncrypterContract $encrypter, $table, $prefix = '')
|
||||
public function __construct(ConnectionInterface $connection, $table, $prefix = '')
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->prefix = $prefix;
|
||||
$this->encrypter = $encrypter;
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
@@ -72,19 +63,22 @@ class DatabaseStore implements Store
|
||||
// If we have a cache record we will check the expiration time against current
|
||||
// time on the system and see if the record has expired. If it has, we will
|
||||
// remove the records from the database table so it isn't returned again.
|
||||
if (! is_null($cache)) {
|
||||
if (is_array($cache)) {
|
||||
$cache = (object) $cache;
|
||||
}
|
||||
|
||||
if (time() >= $cache->expiration) {
|
||||
$this->forget($key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->encrypter->decrypt($cache->value);
|
||||
if (is_null($cache)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cache = is_array($cache) ? (object) $cache : $cache;
|
||||
|
||||
// If this cache expiration date is past the current time, we will remove this
|
||||
// item from the cache. Then we will return a null value since the cache is
|
||||
// expired. We will use "Carbon" to make this comparison with the column.
|
||||
if ($this->currentTime() >= $cache->expiration) {
|
||||
$this->forget($key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return unserialize($cache->value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,24 +86,21 @@ class DatabaseStore implements Store
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
{
|
||||
$key = $this->prefix.$key;
|
||||
|
||||
// All of the cached values in the database are encrypted in case this is used
|
||||
// as a session data store by the consumer. We'll also calculate the expire
|
||||
// time and place that on the table so we will check it on our retrieval.
|
||||
$value = $this->encrypter->encrypt($value);
|
||||
$value = serialize($value);
|
||||
|
||||
$expiration = $this->getTime() + ($minutes * 60);
|
||||
$expiration = $this->getTime() + (int) ($minutes * 60);
|
||||
|
||||
try {
|
||||
$this->table()->insert(compact('key', 'value', 'expiration'));
|
||||
} catch (Exception $e) {
|
||||
$this->table()->where('key', '=', $key)->update(compact('value', 'expiration'));
|
||||
$this->table()->where('key', $key)->update(compact('value', 'expiration'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,25 +145,34 @@ class DatabaseStore implements Store
|
||||
return $this->connection->transaction(function () use ($key, $value, $callback) {
|
||||
$prefixed = $this->prefix.$key;
|
||||
|
||||
$cache = $this->table()->where('key', $prefixed)->lockForUpdate()->first();
|
||||
$cache = $this->table()->where('key', $prefixed)
|
||||
->lockForUpdate()->first();
|
||||
|
||||
// If there is no value in the cache, we will return false here. Otherwise the
|
||||
// value will be decrypted and we will proceed with this function to either
|
||||
// increment or decrement this value based on the given action callbacks.
|
||||
if (is_null($cache)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($cache)) {
|
||||
$cache = (object) $cache;
|
||||
}
|
||||
$cache = is_array($cache) ? (object) $cache : $cache;
|
||||
|
||||
$current = $this->encrypter->decrypt($cache->value);
|
||||
$current = 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
|
||||
// so we do not have to recreate all this logic in each of the functions.
|
||||
$new = $callback((int) $current, $value);
|
||||
|
||||
if (! is_numeric($current)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Here we will update the values in the table. We will also encrypt the value
|
||||
// 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' => $this->encrypter->encrypt($new),
|
||||
'value' => serialize($new),
|
||||
]);
|
||||
|
||||
return $new;
|
||||
@@ -186,7 +186,7 @@ class DatabaseStore implements Store
|
||||
*/
|
||||
protected function getTime()
|
||||
{
|
||||
return time();
|
||||
return $this->currentTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,11 +217,11 @@ class DatabaseStore implements Store
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->table()->delete();
|
||||
return (bool) $this->table()->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,16 +244,6 @@ class DatabaseStore implements Store
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encrypter instance.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Encryption\Encrypter
|
||||
*/
|
||||
public function getEncrypter()
|
||||
{
|
||||
return $this->encrypter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache key prefix.
|
||||
*
|
||||
|
||||
46
vendor/laravel/framework/src/Illuminate/Cache/Events/CacheEvent.php
vendored
Normal file
46
vendor/laravel/framework/src/Illuminate/Cache/Events/CacheEvent.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache\Events;
|
||||
|
||||
abstract class CacheEvent
|
||||
{
|
||||
/**
|
||||
* The key of the event.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $key;
|
||||
|
||||
/**
|
||||
* The tags that were assigned to the key.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tags;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $tags
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($key, array $tags = [])
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->tags = $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tags for the cache event.
|
||||
*
|
||||
* @param array $tags
|
||||
* @return $this
|
||||
*/
|
||||
public function setTags($tags)
|
||||
{
|
||||
$this->tags = $tags;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,8 @@
|
||||
|
||||
namespace Illuminate\Cache\Events;
|
||||
|
||||
class CacheHit
|
||||
class CacheHit extends CacheEvent
|
||||
{
|
||||
/**
|
||||
* The key that was hit.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $key;
|
||||
|
||||
/**
|
||||
* The value that was retrieved.
|
||||
*
|
||||
@@ -18,13 +11,6 @@ class CacheHit
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* The tags that were assigned to the key.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tags;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
@@ -35,8 +21,8 @@ class CacheHit
|
||||
*/
|
||||
public function __construct($key, $value, array $tags = [])
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->tags = $tags;
|
||||
parent::__construct($key, $tags);
|
||||
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,32 +2,7 @@
|
||||
|
||||
namespace Illuminate\Cache\Events;
|
||||
|
||||
class CacheMissed
|
||||
class CacheMissed extends CacheEvent
|
||||
{
|
||||
/**
|
||||
* The key that was missed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $key;
|
||||
|
||||
/**
|
||||
* The tags that were assigned to the key.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tags;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $tags
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($key, array $tags = [])
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->tags = $tags;
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
@@ -2,32 +2,7 @@
|
||||
|
||||
namespace Illuminate\Cache\Events;
|
||||
|
||||
class KeyForgotten
|
||||
class KeyForgotten extends CacheEvent
|
||||
{
|
||||
/**
|
||||
* The key that was forgotten.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $key;
|
||||
|
||||
/**
|
||||
* The tags that were assigned to the key.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tags;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $tags
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($key, $tags = [])
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->tags = $tags;
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
@@ -2,15 +2,8 @@
|
||||
|
||||
namespace Illuminate\Cache\Events;
|
||||
|
||||
class KeyWritten
|
||||
class KeyWritten extends CacheEvent
|
||||
{
|
||||
/**
|
||||
* The key that was written.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $key;
|
||||
|
||||
/**
|
||||
* The value that was written.
|
||||
*
|
||||
@@ -25,13 +18,6 @@ class KeyWritten
|
||||
*/
|
||||
public $minutes;
|
||||
|
||||
/**
|
||||
* The tags that were assigned to the key.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tags;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
@@ -43,8 +29,8 @@ class KeyWritten
|
||||
*/
|
||||
public function __construct($key, $value, $minutes, $tags = [])
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->tags = $tags;
|
||||
parent::__construct($key, $tags);
|
||||
|
||||
$this->value = $value;
|
||||
$this->minutes = $minutes;
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
|
||||
class FileStore implements Store
|
||||
{
|
||||
use RetrievesMultipleKeys;
|
||||
use InteractsWithTime, RetrievesMultipleKeys;
|
||||
|
||||
/**
|
||||
* The Illuminate Filesystem instance.
|
||||
@@ -46,47 +46,7 @@ class FileStore implements Store
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
return Arr::get($this->getPayload($key), 'data');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an item and expiry time from the cache by key.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
protected function getPayload($key)
|
||||
{
|
||||
$path = $this->path($key);
|
||||
|
||||
// If the file doesn't exists, we obviously can't return the cache so we will
|
||||
// just return null. Otherwise, we'll get the contents of the file and get
|
||||
// the expiration UNIX timestamps from the start of the file's contents.
|
||||
try {
|
||||
$expire = substr(
|
||||
$contents = $this->files->get($path, true), 0, 10
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
return ['data' => null, 'time' => null];
|
||||
}
|
||||
|
||||
// If the current time is greater than expiration timestamps we will delete
|
||||
// the file and return null. This helps clean up the old files and keeps
|
||||
// this directory much cleaner for us as old files aren't hanging out.
|
||||
if (time() >= $expire) {
|
||||
$this->forget($key);
|
||||
|
||||
return ['data' => null, 'time' => null];
|
||||
}
|
||||
|
||||
$data = unserialize(substr($contents, 10));
|
||||
|
||||
// Next, we'll extract the number of minutes 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 the cache. We'll round this out.
|
||||
$time = ceil(($expire - time()) / 60);
|
||||
|
||||
return compact('data', 'time');
|
||||
return $this->getPayload($key)['data'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,16 +54,16 @@ class FileStore implements Store
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
{
|
||||
$value = $this->expiration($minutes).serialize($value);
|
||||
$this->ensureCacheDirectoryExists($path = $this->path($key));
|
||||
|
||||
$this->createCacheDirectory($path = $this->path($key));
|
||||
|
||||
$this->files->put($path, $value, true);
|
||||
$this->files->put(
|
||||
$path, $this->expiration($minutes).serialize($value), true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,7 +72,7 @@ class FileStore implements Store
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
protected function createCacheDirectory($path)
|
||||
protected function ensureCacheDirectoryExists($path)
|
||||
{
|
||||
if (! $this->files->exists(dirname($path))) {
|
||||
$this->files->makeDirectory(dirname($path), 0777, true, true);
|
||||
@@ -130,11 +90,9 @@ class FileStore implements Store
|
||||
{
|
||||
$raw = $this->getPayload($key);
|
||||
|
||||
$int = ((int) $raw['data']) + $value;
|
||||
|
||||
$this->put($key, $int, (int) $raw['time']);
|
||||
|
||||
return $int;
|
||||
return tap(((int) $raw['data']) + $value, function ($newValue) use ($key, $raw) {
|
||||
$this->put($key, $newValue, $raw['time']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,9 +127,7 @@ class FileStore implements Store
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
$file = $this->path($key);
|
||||
|
||||
if ($this->files->exists($file)) {
|
||||
if ($this->files->exists($file = $this->path($key))) {
|
||||
return $this->files->delete($file);
|
||||
}
|
||||
|
||||
@@ -181,15 +137,71 @@ class FileStore implements Store
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
if ($this->files->isDirectory($this->directory)) {
|
||||
foreach ($this->files->directories($this->directory) as $directory) {
|
||||
$this->files->deleteDirectory($directory);
|
||||
if (! $this->files->isDirectory($this->directory)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->files->directories($this->directory) as $directory) {
|
||||
if (! $this->files->deleteDirectory($directory)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an item and expiry time from the cache by key.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
protected function getPayload($key)
|
||||
{
|
||||
$path = $this->path($key);
|
||||
|
||||
// If the file doesn't exist, we obviously cannot return the cache so we will
|
||||
// just return null. Otherwise, we'll get the contents of the file and get
|
||||
// the expiration UNIX timestamps from the start of the file's contents.
|
||||
try {
|
||||
$expire = substr(
|
||||
$contents = $this->files->get($path, true), 0, 10
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
return $this->emptyPayload();
|
||||
}
|
||||
|
||||
// If the current time is greater than expiration timestamps we will delete
|
||||
// the file and return null. This helps clean up the old files and keeps
|
||||
// this directory much cleaner for us as old files aren't hanging out.
|
||||
if ($this->currentTime() >= $expire) {
|
||||
$this->forget($key);
|
||||
|
||||
return $this->emptyPayload();
|
||||
}
|
||||
|
||||
$data = unserialize(substr($contents, 10));
|
||||
|
||||
// Next, we'll extract the number of minutes 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;
|
||||
|
||||
return compact('data', 'time');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a default empty payload for the cache.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function emptyPayload()
|
||||
{
|
||||
return ['data' => null, 'time' => null];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,18 +220,14 @@ class FileStore implements Store
|
||||
/**
|
||||
* Get the expiration time based on the given minutes.
|
||||
*
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return int
|
||||
*/
|
||||
protected function expiration($minutes)
|
||||
{
|
||||
$time = time() + ($minutes * 60);
|
||||
$time = $this->availableAt((int) ($minutes * 60));
|
||||
|
||||
if ($minutes === 0 || $time > 9999999999) {
|
||||
return 9999999999;
|
||||
}
|
||||
|
||||
return (int) $time;
|
||||
return $minutes === 0 || $time > 9999999999 ? 9999999999 : (int) $time;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
93
vendor/laravel/framework/src/Illuminate/Cache/Lock.php
vendored
Normal file
93
vendor/laravel/framework/src/Illuminate/Cache/Lock.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Contracts\Cache\LockTimeoutException;
|
||||
|
||||
abstract class Lock
|
||||
{
|
||||
use InteractsWithTime;
|
||||
|
||||
/**
|
||||
* The name of the lock.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* The number of seconds the lock should be maintained.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $seconds;
|
||||
|
||||
/**
|
||||
* Create a new lock instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name, $seconds)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->seconds = $seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function acquire();
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @return bool
|
||||
*/
|
||||
public function get($callback = null)
|
||||
{
|
||||
$result = $this->acquire();
|
||||
|
||||
if ($result && is_callable($callback)) {
|
||||
return tap($callback(), function () {
|
||||
$this->release();
|
||||
});
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock for the given number of seconds.
|
||||
*
|
||||
* @param int $seconds
|
||||
* @param callable|null $callback
|
||||
* @return bool
|
||||
* @throws \Illuminate\Contracts\Cache\LockTimeoutException
|
||||
*/
|
||||
public function block($seconds, $callback = null)
|
||||
{
|
||||
$starting = $this->currentTime();
|
||||
|
||||
while (! $this->acquire()) {
|
||||
usleep(250 * 1000);
|
||||
|
||||
if ($this->currentTime() - $seconds >= $starting) {
|
||||
throw new LockTimeoutException;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_callable($callback)) {
|
||||
return tap($callback(), function () {
|
||||
$this->release();
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Memcached;
|
||||
use RuntimeException;
|
||||
|
||||
class MemcachedConnector
|
||||
{
|
||||
@@ -11,31 +10,26 @@ class MemcachedConnector
|
||||
* Create a new Memcached connection.
|
||||
*
|
||||
* @param array $servers
|
||||
* @param string|null $connectionId
|
||||
* @param array $options
|
||||
* @param array $credentials
|
||||
* @return \Memcached
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function connect(array $servers)
|
||||
public function connect(array $servers, $connectionId = null, array $options = [], array $credentials = [])
|
||||
{
|
||||
$memcached = $this->getMemcached();
|
||||
$memcached = $this->getMemcached(
|
||||
$connectionId, $credentials, $options
|
||||
);
|
||||
|
||||
// For each server in the array, we'll just extract the configuration and add
|
||||
// the server to the Memcached connection. Once we have added all of these
|
||||
// servers we'll verify the connection is successful and return it back.
|
||||
foreach ($servers as $server) {
|
||||
$memcached->addServer(
|
||||
$server['host'], $server['port'], $server['weight']
|
||||
);
|
||||
}
|
||||
|
||||
$memcachedStatus = $memcached->getVersion();
|
||||
|
||||
if (! is_array($memcachedStatus)) {
|
||||
throw new RuntimeException('No Memcached servers added.');
|
||||
}
|
||||
|
||||
if (in_array('255.255.255', $memcachedStatus) && count(array_unique($memcachedStatus)) === 1) {
|
||||
throw new RuntimeException('Could not establish Memcached connection.');
|
||||
if (! $memcached->getServerList()) {
|
||||
// For each server in the array, we'll just extract the configuration and add
|
||||
// the server to the Memcached connection. Once we have added all of these
|
||||
// servers we'll verify the connection is successful and return it back.
|
||||
foreach ($servers as $server) {
|
||||
$memcached->addServer(
|
||||
$server['host'], $server['port'], $server['weight']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $memcached;
|
||||
@@ -44,10 +38,50 @@ class MemcachedConnector
|
||||
/**
|
||||
* Get a new Memcached instance.
|
||||
*
|
||||
* @param string|null $connectionId
|
||||
* @param array $credentials
|
||||
* @param array $options
|
||||
* @return \Memcached
|
||||
*/
|
||||
protected function getMemcached()
|
||||
protected function getMemcached($connectionId, array $credentials, array $options)
|
||||
{
|
||||
return new Memcached;
|
||||
$memcached = $this->createMemcachedInstance($connectionId);
|
||||
|
||||
if (count($credentials) == 2) {
|
||||
$this->setCredentials($memcached, $credentials);
|
||||
}
|
||||
|
||||
if (count($options)) {
|
||||
$memcached->setOptions($options);
|
||||
}
|
||||
|
||||
return $memcached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Memcached instance.
|
||||
*
|
||||
* @param string|null $connectionId
|
||||
* @return \Memcached
|
||||
*/
|
||||
protected function createMemcachedInstance($connectionId)
|
||||
{
|
||||
return empty($connectionId) ? new Memcached : new Memcached($connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SASL credentials on the Memcached connection.
|
||||
*
|
||||
* @param \Memcached $memcached
|
||||
* @param array $credentials
|
||||
* @return void
|
||||
*/
|
||||
protected function setCredentials($memcached, $credentials)
|
||||
{
|
||||
list($username, $password) = $credentials;
|
||||
|
||||
$memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
|
||||
|
||||
$memcached->setSaslAuthData($username, $password);
|
||||
}
|
||||
}
|
||||
|
||||
52
vendor/laravel/framework/src/Illuminate/Cache/MemcachedLock.php
vendored
Normal file
52
vendor/laravel/framework/src/Illuminate/Cache/MemcachedLock.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Cache\Lock as LockContract;
|
||||
|
||||
class MemcachedLock extends Lock implements LockContract
|
||||
{
|
||||
/**
|
||||
* The Memcached instance.
|
||||
*
|
||||
* @var \Memcached
|
||||
*/
|
||||
protected $memcached;
|
||||
|
||||
/**
|
||||
* Create a new lock instance.
|
||||
*
|
||||
* @param \Memcached $memcached
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($memcached, $name, $seconds)
|
||||
{
|
||||
parent::__construct($name, $seconds);
|
||||
|
||||
$this->memcached = $memcached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function acquire()
|
||||
{
|
||||
return $this->memcached->add(
|
||||
$this->name, 1, $this->seconds
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function release()
|
||||
{
|
||||
$this->memcached->delete($this->name);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,15 @@
|
||||
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 Store
|
||||
class MemcachedStore extends TaggableStore implements LockProvider, Store
|
||||
{
|
||||
use InteractsWithTime;
|
||||
|
||||
/**
|
||||
* The Memcached instance.
|
||||
*
|
||||
@@ -21,6 +26,13 @@ class MemcachedStore extends TaggableStore implements Store
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* Indicates whether we are using Memcached version >= 3.0.0.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $onVersionThree;
|
||||
|
||||
/**
|
||||
* Create a new Memcached store.
|
||||
*
|
||||
@@ -32,12 +44,15 @@ class MemcachedStore extends TaggableStore implements Store
|
||||
{
|
||||
$this->setPrefix($prefix);
|
||||
$this->memcached = $memcached;
|
||||
|
||||
$this->onVersionThree = (new ReflectionMethod('Memcached', 'getMulti'))
|
||||
->getNumberOfParameters() == 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an item from the cache by key.
|
||||
*
|
||||
* @param string|array $key
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key)
|
||||
@@ -63,7 +78,13 @@ class MemcachedStore extends TaggableStore implements Store
|
||||
return $this->prefix.$key;
|
||||
}, $keys);
|
||||
|
||||
$values = $this->memcached->getMulti($prefixedKeys, null, Memcached::GET_PRESERVE_ORDER);
|
||||
if ($this->onVersionThree) {
|
||||
$values = $this->memcached->getMulti($prefixedKeys, Memcached::GET_PRESERVE_ORDER);
|
||||
} else {
|
||||
$null = null;
|
||||
|
||||
$values = $this->memcached->getMulti($prefixedKeys, $null, Memcached::GET_PRESERVE_ORDER);
|
||||
}
|
||||
|
||||
if ($this->memcached->getResultCode() != 0) {
|
||||
return array_fill_keys($keys, null);
|
||||
@@ -77,19 +98,19 @@ class MemcachedStore extends TaggableStore implements Store
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
{
|
||||
$this->memcached->set($this->prefix.$key, $value, $minutes * 60);
|
||||
$this->memcached->set($this->prefix.$key, $value, $this->toTimestamp($minutes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of minutes.
|
||||
*
|
||||
* @param array $values
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function putMany(array $values, $minutes)
|
||||
@@ -100,7 +121,7 @@ class MemcachedStore extends TaggableStore implements Store
|
||||
$prefixedValues[$this->prefix.$key] = $value;
|
||||
}
|
||||
|
||||
$this->memcached->setMulti($prefixedValues, $minutes * 60);
|
||||
$this->memcached->setMulti($prefixedValues, $this->toTimestamp($minutes));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,12 +129,12 @@ class MemcachedStore extends TaggableStore implements Store
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value, $minutes)
|
||||
{
|
||||
return $this->memcached->add($this->prefix.$key, $value, $minutes * 60);
|
||||
return $this->memcached->add($this->prefix.$key, $value, $this->toTimestamp($minutes));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,6 +173,18 @@ class MemcachedStore extends TaggableStore implements Store
|
||||
$this->put($key, $value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lock instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function lock($name, $seconds = 0)
|
||||
{
|
||||
return new MemcachedLock($this->memcached, $this->prefix.$name, $seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the cache.
|
||||
*
|
||||
@@ -166,11 +199,22 @@ class MemcachedStore extends TaggableStore implements Store
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->memcached->flush();
|
||||
return $this->memcached->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UNIX timestamp for the given number of minutes.
|
||||
*
|
||||
* @param int $minutes
|
||||
* @return int
|
||||
*/
|
||||
protected function toTimestamp($minutes)
|
||||
{
|
||||
return $minutes > 0 ? $this->availableAt($minutes * 60) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,7 +31,7 @@ class NullStore extends TaggableStore implements Store
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
@@ -89,11 +89,11 @@ class NullStore extends TaggableStore implements Store
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||
|
||||
class RateLimiter
|
||||
{
|
||||
use InteractsWithTime;
|
||||
|
||||
/**
|
||||
* The cache store implementation.
|
||||
*
|
||||
@@ -29,21 +32,17 @@ class RateLimiter
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $maxAttempts
|
||||
* @param int $decayMinutes
|
||||
* @param float|int $decayMinutes
|
||||
* @return bool
|
||||
*/
|
||||
public function tooManyAttempts($key, $maxAttempts, $decayMinutes = 1)
|
||||
{
|
||||
if ($this->cache->has($key.':lockout')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->attempts($key) > $maxAttempts) {
|
||||
$this->cache->add($key.':lockout', time() + ($decayMinutes * 60), $decayMinutes);
|
||||
if ($this->attempts($key) >= $maxAttempts) {
|
||||
if ($this->cache->has($key.':timer')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->resetAttempts($key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -53,14 +52,24 @@ class RateLimiter
|
||||
* Increment the counter for a given key for a given decay time.
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $decayMinutes
|
||||
* @param float|int $decayMinutes
|
||||
* @return int
|
||||
*/
|
||||
public function hit($key, $decayMinutes = 1)
|
||||
{
|
||||
$this->cache->add($key, 1, $decayMinutes);
|
||||
$this->cache->add(
|
||||
$key.':timer', $this->availableAt($decayMinutes * 60), $decayMinutes
|
||||
);
|
||||
|
||||
return (int) $this->cache->increment($key);
|
||||
$added = $this->cache->add($key, 0, $decayMinutes);
|
||||
|
||||
$hits = (int) $this->cache->increment($key);
|
||||
|
||||
if (! $added && $hits == 1) {
|
||||
$this->cache->put($key, 1, $decayMinutes);
|
||||
}
|
||||
|
||||
return $hits;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,11 +105,11 @@ class RateLimiter
|
||||
{
|
||||
$attempts = $this->attempts($key);
|
||||
|
||||
return $attempts === 0 ? $maxAttempts : $maxAttempts - $attempts + 1;
|
||||
return $maxAttempts - $attempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the hits and lockout for the given key.
|
||||
* Clear the hits and lockout timer for the given key.
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
@@ -109,7 +118,7 @@ class RateLimiter
|
||||
{
|
||||
$this->resetAttempts($key);
|
||||
|
||||
$this->cache->forget($key.':lockout');
|
||||
$this->cache->forget($key.':timer');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,6 +129,6 @@ class RateLimiter
|
||||
*/
|
||||
public function availableIn($key)
|
||||
{
|
||||
return $this->cache->get($key.':lockout') - time();
|
||||
return $this->cache->get($key.':timer') - $this->currentTime();
|
||||
}
|
||||
}
|
||||
|
||||
56
vendor/laravel/framework/src/Illuminate/Cache/RedisLock.php
vendored
Normal file
56
vendor/laravel/framework/src/Illuminate/Cache/RedisLock.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Cache\Lock as LockContract;
|
||||
|
||||
class RedisLock extends Lock implements LockContract
|
||||
{
|
||||
/**
|
||||
* The Redis factory implementation.
|
||||
*
|
||||
* @var \Illuminate\Redis\Connections\Connection
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* Create a new lock instance.
|
||||
*
|
||||
* @param \Illuminate\Redis\Connections\Connection $redis
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($redis, $name, $seconds)
|
||||
{
|
||||
parent::__construct($name, $seconds);
|
||||
|
||||
$this->redis = $redis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to acquire the lock.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function acquire()
|
||||
{
|
||||
$result = $this->redis->setnx($this->name, 1);
|
||||
|
||||
if ($result === 1 && $this->seconds > 0) {
|
||||
$this->redis->expire($this->name, $this->seconds);
|
||||
}
|
||||
|
||||
return $result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function release()
|
||||
{
|
||||
$this->redis->del($this->name);
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,14 @@
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Redis\Database as Redis;
|
||||
use Illuminate\Contracts\Redis\Factory as Redis;
|
||||
|
||||
class RedisStore extends TaggableStore implements Store
|
||||
{
|
||||
/**
|
||||
* The Redis database connection.
|
||||
* The Redis factory implementation.
|
||||
*
|
||||
* @var \Illuminate\Redis\Database
|
||||
* @var \Illuminate\Contracts\Redis\Factory
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
@@ -31,7 +31,7 @@ class RedisStore extends TaggableStore implements Store
|
||||
/**
|
||||
* Create a new Redis store.
|
||||
*
|
||||
* @param \Illuminate\Redis\Database $redis
|
||||
* @param \Illuminate\Contracts\Redis\Factory $redis
|
||||
* @param string $prefix
|
||||
* @param string $connection
|
||||
* @return void
|
||||
@@ -40,7 +40,7 @@ class RedisStore extends TaggableStore implements Store
|
||||
{
|
||||
$this->redis = $redis;
|
||||
$this->setPrefix($prefix);
|
||||
$this->connection = $connection;
|
||||
$this->setConnection($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,9 +51,9 @@ class RedisStore extends TaggableStore implements Store
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if (! is_null($value = $this->connection()->get($this->prefix.$key))) {
|
||||
return is_numeric($value) ? $value : unserialize($value);
|
||||
}
|
||||
$value = $this->connection()->get($this->prefix.$key);
|
||||
|
||||
return ! is_null($value) ? $this->unserialize($value) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,19 +66,17 @@ class RedisStore extends TaggableStore implements Store
|
||||
*/
|
||||
public function many(array $keys)
|
||||
{
|
||||
$return = [];
|
||||
$results = [];
|
||||
|
||||
$prefixedKeys = array_map(function ($key) {
|
||||
$values = $this->connection()->mget(array_map(function ($key) {
|
||||
return $this->prefix.$key;
|
||||
}, $keys);
|
||||
|
||||
$values = $this->connection()->mget($prefixedKeys);
|
||||
}, $keys));
|
||||
|
||||
foreach ($values as $index => $value) {
|
||||
$return[$keys[$index]] = is_numeric($value) ? $value : unserialize($value);
|
||||
$results[$keys[$index]] = ! is_null($value) ? $this->unserialize($value) : null;
|
||||
}
|
||||
|
||||
return $return;
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,21 +84,21 @@ class RedisStore extends TaggableStore implements Store
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes)
|
||||
{
|
||||
$value = is_numeric($value) ? $value : serialize($value);
|
||||
|
||||
$this->connection()->setex($this->prefix.$key, (int) max(1, $minutes * 60), $value);
|
||||
$this->connection()->setex(
|
||||
$this->prefix.$key, (int) max(1, $minutes * 60), $this->serialize($value)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of minutes.
|
||||
*
|
||||
* @param array $values
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function putMany(array $values, $minutes)
|
||||
@@ -114,6 +112,23 @@ class RedisStore extends TaggableStore implements Store
|
||||
$this->connection()->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache if the key doesn't exist.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param float|int $minutes
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value, $minutes)
|
||||
{
|
||||
$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)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
@@ -147,9 +162,19 @@ class RedisStore extends TaggableStore implements Store
|
||||
*/
|
||||
public function forever($key, $value)
|
||||
{
|
||||
$value = is_numeric($value) ? $value : serialize($value);
|
||||
$this->connection()->set($this->prefix.$key, $this->serialize($value));
|
||||
}
|
||||
|
||||
$this->connection()->set($this->prefix.$key, $value);
|
||||
/**
|
||||
* Get a lock instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $seconds
|
||||
* @return \Illuminate\Contracts\Cache\Lock
|
||||
*/
|
||||
public function lock($name, $seconds = 0)
|
||||
{
|
||||
return new RedisLock($this->connection(), $this->prefix.$name, $seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,11 +191,13 @@ class RedisStore extends TaggableStore implements Store
|
||||
/**
|
||||
* Remove all items from the cache.
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
$this->connection()->flushdb();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +208,9 @@ class RedisStore extends TaggableStore implements Store
|
||||
*/
|
||||
public function tags($names)
|
||||
{
|
||||
return new RedisTaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
|
||||
return new RedisTaggedCache(
|
||||
$this, new TagSet($this, is_array($names) ? $names : func_get_args())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,7 +237,7 @@ class RedisStore extends TaggableStore implements Store
|
||||
/**
|
||||
* Get the Redis database instance.
|
||||
*
|
||||
* @return \Illuminate\Redis\Database
|
||||
* @return \Illuminate\Contracts\Redis\Factory
|
||||
*/
|
||||
public function getRedis()
|
||||
{
|
||||
@@ -235,4 +264,26 @@ class RedisStore extends TaggableStore implements Store
|
||||
{
|
||||
$this->prefix = ! empty($prefix) ? $prefix.':' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function serialize($value)
|
||||
{
|
||||
return is_numeric($value) ? $value : serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialize the value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function unserialize($value)
|
||||
{
|
||||
return is_numeric($value) ? $value : unserialize($value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class RedisTaggedCache extends TaggedCache
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTime|int $minutes
|
||||
* @param \DateTime|float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes = null)
|
||||
@@ -93,7 +93,7 @@ class RedisTaggedCache extends TaggedCache
|
||||
*/
|
||||
protected function pushKeys($namespace, $key, $reference)
|
||||
{
|
||||
$fullKey = $this->getPrefix().sha1($namespace).':'.$key;
|
||||
$fullKey = $this->store->getPrefix().sha1($namespace).':'.$key;
|
||||
|
||||
foreach (explode('|', $namespace) as $segment) {
|
||||
$this->store->connection()->sadd($this->referenceKey($segment, $reference), $fullKey);
|
||||
@@ -146,7 +146,9 @@ class RedisTaggedCache extends TaggedCache
|
||||
$values = array_unique($this->store->connection()->smembers($referenceKey));
|
||||
|
||||
if (count($values) > 0) {
|
||||
call_user_func_array([$this->store->connection(), 'del'], $values);
|
||||
foreach (array_chunk($values, 1000) as $valuesChunk) {
|
||||
call_user_func_array([$this->store->connection(), 'del'], $valuesChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +161,6 @@ class RedisTaggedCache extends TaggedCache
|
||||
*/
|
||||
protected function referenceKey($segment, $suffix)
|
||||
{
|
||||
return $this->getPrefix().$segment.':'.$suffix;
|
||||
return $this->store->getPrefix().$segment.':'.$suffix;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,26 @@
|
||||
namespace Illuminate\Cache;
|
||||
|
||||
use Closure;
|
||||
use DateTime;
|
||||
use ArrayAccess;
|
||||
use Carbon\Carbon;
|
||||
use DateTimeInterface;
|
||||
use BadMethodCallException;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Cache\Events\CacheHit;
|
||||
use Illuminate\Contracts\Cache\Store;
|
||||
use Illuminate\Cache\Events\KeyWritten;
|
||||
use Illuminate\Cache\Events\CacheMissed;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Cache\Events\KeyForgotten;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Contracts\Cache\Repository as CacheContract;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Contracts\Cache\Store
|
||||
*/
|
||||
class Repository implements CacheContract, ArrayAccess
|
||||
{
|
||||
use InteractsWithTime;
|
||||
use Macroable {
|
||||
__call as macroCall;
|
||||
}
|
||||
@@ -35,7 +44,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
/**
|
||||
* The default number of minutes to store items.
|
||||
*
|
||||
* @var int
|
||||
* @var float|int
|
||||
*/
|
||||
protected $default = 60;
|
||||
|
||||
@@ -50,58 +59,6 @@ class Repository implements CacheContract, ArrayAccess
|
||||
$this->store = $store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event dispatcher instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
* @return void
|
||||
*/
|
||||
public function setEventDispatcher(Dispatcher $events)
|
||||
{
|
||||
$this->events = $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event for this cache instance.
|
||||
*
|
||||
* @param string $event
|
||||
* @param array $payload
|
||||
* @return void
|
||||
*/
|
||||
protected function fireCacheEvent($event, $payload)
|
||||
{
|
||||
if (! isset($this->events)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($event) {
|
||||
case 'hit':
|
||||
if (count($payload) == 2) {
|
||||
$payload[] = [];
|
||||
}
|
||||
|
||||
return $this->events->fire(new Events\CacheHit($payload[0], $payload[1], $payload[2]));
|
||||
case 'missed':
|
||||
if (count($payload) == 1) {
|
||||
$payload[] = [];
|
||||
}
|
||||
|
||||
return $this->events->fire(new Events\CacheMissed($payload[0], $payload[1]));
|
||||
case 'delete':
|
||||
if (count($payload) == 1) {
|
||||
$payload[] = [];
|
||||
}
|
||||
|
||||
return $this->events->fire(new Events\KeyForgotten($payload[0], $payload[1]));
|
||||
case 'write':
|
||||
if (count($payload) == 3) {
|
||||
$payload[] = [];
|
||||
}
|
||||
|
||||
return $this->events->fire(new Events\KeyWritten($payload[0], $payload[1], $payload[2], $payload[3]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an item exists in the cache.
|
||||
*
|
||||
@@ -128,12 +85,15 @@ class Repository implements CacheContract, ArrayAccess
|
||||
|
||||
$value = $this->store->get($this->itemKey($key));
|
||||
|
||||
// If we could not find the cache value, we will fire the missed event and get
|
||||
// the default value for this cache value. This default could be a callback
|
||||
// so we will execute the value function which will resolve it if needed.
|
||||
if (is_null($value)) {
|
||||
$this->fireCacheEvent('missed', [$key]);
|
||||
$this->event(new CacheMissed($key));
|
||||
|
||||
$value = value($default);
|
||||
} else {
|
||||
$this->fireCacheEvent('hit', [$key, $value]);
|
||||
$this->event(new CacheHit($key, $value));
|
||||
}
|
||||
|
||||
return $value;
|
||||
@@ -149,25 +109,58 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function many(array $keys)
|
||||
{
|
||||
$normalizedKeys = [];
|
||||
$values = $this->store->many(collect($keys)->map(function ($value, $key) {
|
||||
return is_string($key) ? $key : $value;
|
||||
})->values()->all());
|
||||
|
||||
foreach ($keys as $key => $value) {
|
||||
$normalizedKeys[] = is_string($key) ? $key : $value;
|
||||
return collect($values)->map(function ($value, $key) use ($keys) {
|
||||
return $this->handleManyResult($keys, $key, $value);
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
if (is_null($default)) {
|
||||
return $this->many($keys);
|
||||
}
|
||||
|
||||
$values = $this->store->many($normalizedKeys);
|
||||
|
||||
foreach ($values as $key => &$value) {
|
||||
if (is_null($value)) {
|
||||
$this->fireCacheEvent('missed', [$key]);
|
||||
|
||||
$value = isset($keys[$key]) ? value($keys[$key]) : null;
|
||||
} else {
|
||||
$this->fireCacheEvent('hit', [$key, $value]);
|
||||
foreach ($keys as $key) {
|
||||
if (! isset($default[$key])) {
|
||||
$default[$key] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
return $this->many($default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a result for the "many" method.
|
||||
*
|
||||
* @param array $keys
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function handleManyResult($keys, $key, $value)
|
||||
{
|
||||
// If we could not find the cache value, we will fire the missed event and get
|
||||
// the default value for this cache value. This default could be a callback
|
||||
// so we will execute the value function which will resolve it if needed.
|
||||
if (is_null($value)) {
|
||||
$this->event(new CacheMissed($key));
|
||||
|
||||
return isset($keys[$key]) ? value($keys[$key]) : null;
|
||||
}
|
||||
|
||||
// If we found a valid value we will fire the "hit" event and return the value
|
||||
// back from this function. The "hit" event gives developers an opportunity
|
||||
// to listen for every possible cache "hit" throughout this applications.
|
||||
$this->event(new CacheHit($key, $value));
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,11 +172,9 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function pull($key, $default = null)
|
||||
{
|
||||
$value = $this->get($key, $default);
|
||||
|
||||
$this->forget($key);
|
||||
|
||||
return $value;
|
||||
return tap($this->get($key, $default), function ($value) use ($key) {
|
||||
$this->forget($key);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,64 +182,82 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTime|int $minutes
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function put($key, $value, $minutes = null)
|
||||
{
|
||||
if (is_array($key) && filter_var($value, FILTER_VALIDATE_INT) !== false) {
|
||||
if (is_array($key)) {
|
||||
return $this->putMany($key, $value);
|
||||
}
|
||||
|
||||
$minutes = $this->getMinutes($minutes);
|
||||
|
||||
if (! is_null($minutes)) {
|
||||
if (! is_null($minutes = $this->getMinutes($minutes))) {
|
||||
$this->store->put($this->itemKey($key), $value, $minutes);
|
||||
|
||||
$this->fireCacheEvent('write', [$key, $value, $minutes]);
|
||||
$this->event(new KeyWritten($key, $value, $minutes));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$this->put($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store multiple items in the cache for a given number of minutes.
|
||||
*
|
||||
* @param array $values
|
||||
* @param int $minutes
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function putMany(array $values, $minutes)
|
||||
{
|
||||
$minutes = $this->getMinutes($minutes);
|
||||
|
||||
if (! is_null($minutes)) {
|
||||
if (! is_null($minutes = $this->getMinutes($minutes))) {
|
||||
$this->store->putMany($values, $minutes);
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$this->fireCacheEvent('write', [$key, $value, $minutes]);
|
||||
$this->event(new KeyWritten($key, $value, $minutes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$this->putMany($values, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache if the key does not exist.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param \DateTime|int $minutes
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $minutes
|
||||
* @return bool
|
||||
*/
|
||||
public function add($key, $value, $minutes)
|
||||
{
|
||||
$minutes = $this->getMinutes($minutes);
|
||||
|
||||
if (is_null($minutes)) {
|
||||
if (is_null($minutes = $this->getMinutes($minutes))) {
|
||||
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);
|
||||
return $this->store->add(
|
||||
$this->itemKey($key), $value, $minutes
|
||||
);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -258,6 +267,30 @@ class Repository implements CacheContract, ArrayAccess
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function increment($key, $value = 1)
|
||||
{
|
||||
return $this->store->increment($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the value of an item in the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return int|bool
|
||||
*/
|
||||
public function decrement($key, $value = 1)
|
||||
{
|
||||
return $this->store->decrement($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an item in the cache indefinitely.
|
||||
*
|
||||
@@ -269,23 +302,25 @@ class Repository implements CacheContract, ArrayAccess
|
||||
{
|
||||
$this->store->forever($this->itemKey($key), $value);
|
||||
|
||||
$this->fireCacheEvent('write', [$key, $value, 0]);
|
||||
$this->event(new KeyWritten($key, $value, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the cache, or store the default value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param \DateTime|int $minutes
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $minutes
|
||||
* @param \Closure $callback
|
||||
* @return mixed
|
||||
*/
|
||||
public function remember($key, $minutes, Closure $callback)
|
||||
{
|
||||
// If the item exists in the cache we will just return this immediately
|
||||
// otherwise we will execute the given Closure and cache the result
|
||||
// of that execution for the given number of minutes in storage.
|
||||
if (! is_null($value = $this->get($key))) {
|
||||
$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 (! is_null($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
@@ -315,10 +350,12 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function rememberForever($key, Closure $callback)
|
||||
{
|
||||
// If the item exists in the cache we will just return this immediately
|
||||
// otherwise we will execute the given Closure and cache the result
|
||||
// of that execution for the given number of minutes. It's easy.
|
||||
if (! is_null($value = $this->get($key))) {
|
||||
$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 (! is_null($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
@@ -330,16 +367,42 @@ class Repository implements CacheContract, ArrayAccess
|
||||
/**
|
||||
* Remove an item from the cache.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function forget($key)
|
||||
{
|
||||
$success = $this->store->forget($this->itemKey($key));
|
||||
return tap($this->store->forget($this->itemKey($key)), function () use ($key) {
|
||||
$this->event(new KeyForgotten($key));
|
||||
});
|
||||
}
|
||||
|
||||
$this->fireCacheEvent('delete', [$key]);
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
return $this->forget($key);
|
||||
}
|
||||
|
||||
return $success;
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
$this->forget($key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return $this->store->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,19 +415,17 @@ class Repository implements CacheContract, ArrayAccess
|
||||
*/
|
||||
public function tags($names)
|
||||
{
|
||||
if (method_exists($this->store, 'tags')) {
|
||||
$taggedCache = $this->store->tags($names);
|
||||
|
||||
if (! is_null($this->events)) {
|
||||
$taggedCache->setEventDispatcher($this->events);
|
||||
}
|
||||
|
||||
$taggedCache->setDefaultCacheTime($this->default);
|
||||
|
||||
return $taggedCache;
|
||||
if (! method_exists($this->store, 'tags')) {
|
||||
throw new BadMethodCallException('This cache store does not support tagging.');
|
||||
}
|
||||
|
||||
throw new BadMethodCallException('This cache store does not support tagging.');
|
||||
$cache = $this->store->tags($names);
|
||||
|
||||
if (! is_null($this->events)) {
|
||||
$cache->setEventDispatcher($this->events);
|
||||
}
|
||||
|
||||
return $cache->setDefaultCacheTime($this->default);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,7 +442,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
/**
|
||||
* Get the default cache time.
|
||||
*
|
||||
* @return int
|
||||
* @return float|int
|
||||
*/
|
||||
public function getDefaultCacheTime()
|
||||
{
|
||||
@@ -391,12 +452,14 @@ class Repository implements CacheContract, ArrayAccess
|
||||
/**
|
||||
* Set the default cache time in minutes.
|
||||
*
|
||||
* @param int $minutes
|
||||
* @return void
|
||||
* @param float|int $minutes
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultCacheTime($minutes)
|
||||
{
|
||||
$this->default = $minutes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -409,6 +472,30 @@ class Repository implements CacheContract, ArrayAccess
|
||||
return $this->store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event for this cache instance.
|
||||
*
|
||||
* @param string $event
|
||||
* @return void
|
||||
*/
|
||||
protected function event($event)
|
||||
{
|
||||
if (isset($this->events)) {
|
||||
$this->events->dispatch($event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event dispatcher instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
* @return void
|
||||
*/
|
||||
public function setEventDispatcher(Dispatcher $events)
|
||||
{
|
||||
$this->events = $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a cached value exists.
|
||||
*
|
||||
@@ -457,18 +544,18 @@ class Repository implements CacheContract, ArrayAccess
|
||||
/**
|
||||
* Calculate the number of minutes with the given duration.
|
||||
*
|
||||
* @param \DateTime|int $duration
|
||||
* @return int|null
|
||||
* @param \DateTimeInterface|\DateInterval|float|int $duration
|
||||
* @return float|int|null
|
||||
*/
|
||||
protected function getMinutes($duration)
|
||||
{
|
||||
if ($duration instanceof DateTime) {
|
||||
$fromNow = Carbon::now()->diffInMinutes(Carbon::instance($duration), false);
|
||||
$duration = $this->parseDateInterval($duration);
|
||||
|
||||
return $fromNow > 0 ? $fromNow : null;
|
||||
if ($duration instanceof DateTimeInterface) {
|
||||
$duration = Carbon::now()->diffInSeconds(Carbon::createFromTimestamp($duration->getTimestamp()), false) / 60;
|
||||
}
|
||||
|
||||
return is_string($duration) ? (int) $duration : $duration;
|
||||
return (int) ($duration * 60) > 0 ? $duration : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -484,7 +571,7 @@ class Repository implements CacheContract, ArrayAccess
|
||||
return $this->macroCall($method, $parameters);
|
||||
}
|
||||
|
||||
return call_user_func_array([$this->store, $method], $parameters);
|
||||
return $this->store->$method(...$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,7 @@ trait RetrievesMultipleKeys
|
||||
* Store multiple items in the cache for a given number of minutes.
|
||||
*
|
||||
* @param array $values
|
||||
* @param int $minutes
|
||||
* @param float|int $minutes
|
||||
* @return void
|
||||
*/
|
||||
public function putMany(array $values, $minutes)
|
||||
|
||||
@@ -44,24 +44,16 @@ class TagSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unique tag identifier for a given tag.
|
||||
* Reset the tag and return the new tag identifier.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function tagId($name)
|
||||
public function resetTag($name)
|
||||
{
|
||||
return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name);
|
||||
}
|
||||
$this->store->forever($this->tagKey($name), $id = str_replace('.', '', uniqid('', true)));
|
||||
|
||||
/**
|
||||
* Get an array of tag identifiers for all of the tags in the set.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function tagIds()
|
||||
{
|
||||
return array_map([$this, 'tagId'], $this->names);
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,16 +67,24 @@ class TagSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the tag and return the new tag identifier.
|
||||
* Get an array of tag identifiers for all of the tags in the set.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function tagIds()
|
||||
{
|
||||
return array_map([$this, 'tagId'], $this->names);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unique tag identifier for a given tag.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function resetTag($name)
|
||||
public function tagId($name)
|
||||
{
|
||||
$this->store->forever($this->tagKey($name), $id = str_replace('.', '', uniqid('', true)));
|
||||
|
||||
return $id;
|
||||
return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,16 +29,6 @@ class TaggedCache extends Repository
|
||||
$this->tags = $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function fireCacheEvent($event, $payload)
|
||||
{
|
||||
$payload[] = $this->tags->getNames();
|
||||
|
||||
parent::fireCacheEvent($event, $payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the value of an item in the cache.
|
||||
*
|
||||
@@ -91,4 +81,15 @@ class TaggedCache extends Repository
|
||||
{
|
||||
return sha1($this->tags->getNamespace()).':'.$key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event for this cache instance.
|
||||
*
|
||||
* @param string $event
|
||||
* @return void
|
||||
*/
|
||||
protected function event($event)
|
||||
{
|
||||
parent::event($event->setTags($this->tags->getNames()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "illuminate/cache",
|
||||
"description": "The Illuminate Cache package.",
|
||||
"license": "MIT",
|
||||
"homepage": "http://laravel.com",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
@@ -14,10 +14,9 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"illuminate/contracts": "5.2.*",
|
||||
"illuminate/support": "5.2.*",
|
||||
"nesbot/carbon": "~1.20"
|
||||
"php": ">=7.0",
|
||||
"illuminate/contracts": "5.5.*",
|
||||
"illuminate/support": "5.5.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -26,13 +25,16 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.2-dev"
|
||||
"dev-master": "5.5-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/database": "Required to use the database cache driver (5.2.*).",
|
||||
"illuminate/filesystem": "Required to use the file cache driver (5.2.*).",
|
||||
"illuminate/redis": "Required to use the redis cache driver (5.2.*)."
|
||||
"illuminate/database": "Required to use the database cache driver (5.5.*).",
|
||||
"illuminate/filesystem": "Required to use the file cache driver (5.5.*).",
|
||||
"illuminate/redis": "Required to use the redis cache driver (5.5.*)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user