123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587 |
- <?php
-
- namespace Illuminate\Cache;
-
- use Closure;
- use ArrayAccess;
- 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;
- }
-
- /**
- * 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 minutes to store items.
- *
- * @var float|int
- */
- protected $default = 60;
-
- /**
- * 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 string $key
- * @return bool
- */
- public function has($key)
- {
- return ! is_null($this->get($key));
- }
-
- /**
- * Retrieve an item from the cache by key.
- *
- * @param string $key
- * @param mixed $default
- * @return mixed
- */
- public function get($key, $default = null)
- {
- 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}
- */
- public function getMultiple($keys, $default = null)
- {
- if (is_null($default)) {
- return $this->many($keys);
- }
-
- foreach ($keys as $key) {
- if (! isset($default[$key])) {
- $default[$key] = null;
- }
- }
-
- 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;
- }
-
- /**
- * Retrieve an item from the cache and delete it.
- *
- * @param string $key
- * @param mixed $default
- * @return mixed
- */
- public function pull($key, $default = null)
- {
- return tap($this->get($key, $default), function ($value) use ($key) {
- $this->forget($key);
- });
- }
-
- /**
- * Store an item in the cache.
- *
- * @param string $key
- * @param mixed $value
- * @param \DateTimeInterface|\DateInterval|float|int|null $minutes
- * @return void
- */
- public function put($key, $value, $minutes = 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));
- }
- }
-
- /**
- * {@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 \DateTimeInterface|\DateInterval|float|int $minutes
- * @return void
- */
- public function putMany(array $values, $minutes)
- {
- if (! is_null($minutes = $this->getMinutes($minutes))) {
- $this->store->putMany($values, $minutes);
-
- foreach ($values as $key => $value) {
- $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 \DateTimeInterface|\DateInterval|float|int $minutes
- * @return bool
- */
- public function add($key, $value, $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
- );
- }
-
- // 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 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 void
- */
- public function forever($key, $value)
- {
- $this->store->forever($this->itemKey($key), $value);
-
- $this->event(new KeyWritten($key, $value, 0));
- }
-
- /**
- * Get an item from the cache, or store the default value.
- *
- * @param string $key
- * @param \DateTimeInterface|\DateInterval|float|int $minutes
- * @param \Closure $callback
- * @return mixed
- */
- public function remember($key, $minutes, 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.
- if (! is_null($value)) {
- return $value;
- }
-
- $this->put($key, $value = $callback(), $minutes);
-
- return $value;
- }
-
- /**
- * Get an item from the cache, or store the default value forever.
- *
- * @param string $key
- * @param \Closure $callback
- * @return mixed
- */
- public function sear($key, Closure $callback)
- {
- return $this->rememberForever($key, $callback);
- }
-
- /**
- * Get an item from the cache, or store the default value forever.
- *
- * @param string $key
- * @param \Closure $callback
- * @return mixed
- */
- 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 for a
- // given number of minutes so it's 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 () use ($key) {
- $this->event(new KeyForgotten($key));
- });
- }
-
- /**
- * {@inheritdoc}
- */
- public function delete($key)
- {
- return $this->forget($key);
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteMultiple($keys)
- {
- foreach ($keys as $key) {
- $this->forget($key);
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function clear()
- {
- 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 (! method_exists($this->store, 'tags')) {
- 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);
- }
-
- /**
- * Format the key for a cache item.
- *
- * @param string $key
- * @return string
- */
- protected function itemKey($key)
- {
- return $key;
- }
-
- /**
- * Get the default cache time.
- *
- * @return float|int
- */
- public function getDefaultCacheTime()
- {
- return $this->default;
- }
-
- /**
- * Set the default cache time in minutes.
- *
- * @param float|int $minutes
- * @return $this
- */
- public function setDefaultCacheTime($minutes)
- {
- $this->default = $minutes;
-
- return $this;
- }
-
- /**
- * Get the cache store implementation.
- *
- * @return \Illuminate\Contracts\Cache\Store
- */
- public function getStore()
- {
- 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.
- *
- * @param string $key
- * @return bool
- */
- public function offsetExists($key)
- {
- return $this->has($key);
- }
-
- /**
- * Retrieve an item from the cache by key.
- *
- * @param string $key
- * @return mixed
- */
- public function offsetGet($key)
- {
- 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)
- {
- $this->put($key, $value, $this->default);
- }
-
- /**
- * Remove an item from the cache.
- *
- * @param string $key
- * @return void
- */
- public function offsetUnset($key)
- {
- $this->forget($key);
- }
-
- /**
- * Calculate the number of minutes with the given duration.
- *
- * @param \DateTimeInterface|\DateInterval|float|int $duration
- * @return float|int|null
- */
- protected function getMinutes($duration)
- {
- $duration = $this->parseDateInterval($duration);
-
- if ($duration instanceof DateTimeInterface) {
- $duration = Carbon::now()->diffInSeconds(Carbon::createFromTimestamp($duration->getTimestamp()), false) / 60;
- }
-
- return (int) ($duration * 60) > 0 ? $duration : null;
- }
-
- /**
- * 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;
- }
- }
|