Viewing file: Repository.php (16.69 KB) -rwxr-xr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
namespace Illuminate\Cache;
use ArrayAccess; use BadMethodCallException; use Closure; use DateTimeInterface; use Illuminate\Cache\Events\CacheHit; use Illuminate\Cache\Events\CacheMissed; use Illuminate\Cache\Events\KeyForgotten; use Illuminate\Cache\Events\KeyWritten; use Illuminate\Contracts\Cache\Repository as CacheContract; use Illuminate\Contracts\Cache\Store; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Support\Carbon; use Illuminate\Support\InteractsWithTime; use Illuminate\Support\Traits\Macroable;
/** * @mixin \Illuminate\Contracts\Cache\Store */ class Repository implements ArrayAccess, CacheContract { use InteractsWithTime, Macroable { __call as macroCall; }
/** * The cache store implementation. * * @var \Illuminate\Contracts\Cache\Store */ protected $store;
/** * The event dispatcher implementation. * * @var \Illuminate\Contracts\Events\Dispatcher */ protected $events;
/** * The default number of seconds to store items. * * @var int|null */ protected $default = 3600;
/** * Create a new cache repository instance. * * @param \Illuminate\Contracts\Cache\Store $store * @return void */ public function __construct(Store $store) { $this->store = $store; }
/** * Determine if an item exists in the cache. * * @param array|string $key * @return bool */ public function has($key): bool { 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. * * @template TCacheValue * * @param array|string $key * @param TCacheValue|(\Closure(): TCacheValue) $default * @return (TCacheValue is null ? mixed : TCacheValue) */ public function get($key, $default = null): mixed { if (is_array($key)) { return $this->many($key); }
$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->event(new CacheMissed($key));
$value = value($default); } else { $this->event(new CacheHit($key, $value)); }
return $value; }
/** * 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) { $values = $this->store->many(collect($keys)->map(function ($value, $key) { return is_string($key) ? $key : $value; })->values()->all());
return collect($values)->map(function ($value, $key) use ($keys) { return $this->handleManyResult($keys, $key, $value); })->all(); }
/** * {@inheritdoc} * * @return iterable */ public function getMultiple($keys, $default = null): iterable { $defaults = [];
foreach ($keys as $key) { $defaults[$key] = $default; }
return $this->many($defaults); }
/** * 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]) && ! array_is_list($keys)) ? 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; }
/** * Retrieve an item from the cache and delete it. * * @template TCacheValue * * @param array|string $key * @param TCacheValue|(\Closure(): TCacheValue) $default * @return (TCacheValue is null ? mixed : TCacheValue) */ public function pull($key, $default = null) { return tap($this->get($key, $default), function () use ($key) { $this->forget($key); }); }
/** * Store an item in the cache. * * @param array|string $key * @param mixed $value * @param \DateTimeInterface|\DateInterval|int|null $ttl * @return bool */ public function put($key, $value, $ttl = null) { if (is_array($key)) { return $this->putMany($key, $value); }
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; }
/** * {@inheritdoc} * * @return bool */ public function set($key, $value, $ttl = null): bool { return $this->put($key, $value, $ttl); }
/** * Store multiple items in the cache for a given number of seconds. * * @param array $values * @param \DateTimeInterface|\DateInterval|int|null $ttl * @return bool */ public function putMany(array $values, $ttl = null) { 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, $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; }
/** * {@inheritdoc} * * @return bool */ public function setMultiple($values, $ttl = null): bool { 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|int|null $ttl * @return bool */ public function add($key, $value, $ttl = null) { $seconds = null;
if ($ttl !== null) { $seconds = $this->getSeconds($ttl);
if ($seconds <= 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, $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))) { return $this->put($key, $value, $seconds); }
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. * * @param string $key * @param mixed $value * @return bool */ public function forever($key, $value) { $result = $this->store->forever($this->itemKey($key), $value);
if ($result) { $this->event(new KeyWritten($key, $value)); }
return $result; }
/** * Get an item from the cache, or execute the given Closure and store the result. * * @template TCacheValue * * @param string $key * @param \Closure|\DateTimeInterface|\DateInterval|int|null $ttl * @param \Closure(): TCacheValue $callback * @return TCacheValue */ 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 seconds so it's available for all subsequent requests. if (! is_null($value)) { return $value; }
$value = $callback();
$this->put($key, $value, value($ttl, $value));
return $value; }
/** * Get an item from the cache, or execute the given Closure and store the result forever. * * @template TCacheValue * * @param string $key * @param \Closure(): TCacheValue $callback * @return TCacheValue */ public function sear($key, Closure $callback) { return $this->rememberForever($key, $callback); }
/** * Get an item from the cache, or execute the given Closure and store the result forever. * * @template TCacheValue * * @param string $key * @param \Closure(): TCacheValue $callback * @return TCacheValue */ public function rememberForever($key, 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 forever so it is available for all subsequent requests. if (! is_null($value)) { return $value; }
$this->forever($key, $value = $callback());
return $value; }
/** * Remove an item from the cache. * * @param string $key * @return bool */ public function forget($key) { return tap($this->store->forget($this->itemKey($key)), function ($result) use ($key) { if ($result) { $this->event(new KeyForgotten($key)); } }); }
/** * {@inheritdoc} * * @return bool */ public function delete($key): bool { return $this->forget($key); }
/** * {@inheritdoc} * * @return bool */ public function deleteMultiple($keys): bool { $result = true;
foreach ($keys as $key) { if (! $this->forget($key)) { $result = false; } }
return $result; }
/** * {@inheritdoc} * * @return bool */ public function clear(): bool { return $this->store->flush(); }
/** * Begin executing a new tags operation if the store supports it. * * @param array|mixed $names * @return \Illuminate\Cache\TaggedCache * * @throws \BadMethodCallException */ public function tags($names) { if (! $this->supportsTags()) { throw new BadMethodCallException('This cache store does not support tagging.'); }
$cache = $this->store->tags(is_array($names) ? $names : func_get_args());
if (! is_null($this->events)) { $cache->setEventDispatcher($this->events); }
return $cache->setDefaultCacheTime($this->default); }
/** * Format the key for a cache item. * * @param string $key * @return string */ protected function itemKey($key) { return $key; }
/** * Calculate the number of seconds for the given TTL. * * @param \DateTimeInterface|\DateInterval|int $ttl * @return int */ protected function getSeconds($ttl) { $duration = $this->parseDateInterval($ttl);
if ($duration instanceof DateTimeInterface) { $duration = Carbon::now()->diffInRealSeconds($duration, false); }
return (int) ($duration > 0 ? $duration : 0); }
/** * Determine if the current store supports tags. * * @return bool */ public function supportsTags() { return method_exists($this->store, 'tags'); }
/** * Get the default cache time. * * @return int|null */ public function getDefaultCacheTime() { return $this->default; }
/** * Set the default cache time in seconds. * * @param int|null $seconds * @return $this */ public function setDefaultCacheTime($seconds) { $this->default = $seconds;
return $this; }
/** * Get the cache store implementation. * * @return \Illuminate\Contracts\Cache\Store */ public function getStore() { return $this->store; }
/** * Set the cache store implementation. * * @param \Illuminate\Contracts\Cache\Store $store * @return static */ public function setStore($store) { $this->store = $store;
return $this; }
/** * Fire an event for this cache instance. * * @param object|string $event * @return void */ protected function event($event) { $this->events?->dispatch($event); }
/** * Get the event dispatcher instance. * * @return \Illuminate\Contracts\Events\Dispatcher */ public function getEventDispatcher() { return $this->events; }
/** * 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. * * @param string $key * @return bool */ public function offsetExists($key): bool { return $this->has($key); }
/** * Retrieve an item from the cache by key. * * @param string $key * @return mixed */ public function offsetGet($key): mixed { return $this->get($key); }
/** * Store an item in the cache for the default time. * * @param string $key * @param mixed $value * @return void */ public function offsetSet($key, $value): void { $this->put($key, $value, $this->default); }
/** * Remove an item from the cache. * * @param string $key * @return void */ public function offsetUnset($key): void { $this->forget($key); }
/** * Handle dynamic calls into macros or pass missing methods to the store. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { if (static::hasMacro($method)) { return $this->macroCall($method, $parameters); }
return $this->store->$method(...$parameters); }
/** * Clone cache repository instance. * * @return void */ public function __clone() { $this->store = clone $this->store; } }
|