Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Illuminate/Cache/ApcStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,24 @@ public function forever($key, $value)
return $this->put($key, $value, 0);
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds)
{
$value = $this->apc->get($key = $this->getPrefix().$key);

if (is_null($value)) {
return false;
}

return $this->apc->put($key, $value, $seconds);
}

/**
* Remove an item from the cache.
*
Expand Down
23 changes: 23 additions & 0 deletions src/Illuminate/Cache/ArrayStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Cache;

use Illuminate\Contracts\Cache\LockProvider;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\InteractsWithTime;

Expand Down Expand Up @@ -130,6 +131,28 @@ public function forever($key, $value)
return $this->put($key, $value, 0);
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds)
{
$item = Arr::get($this->storage, $key = $this->getPrefix().$key, null);

if (is_null($item)) {
return false;
}

$item['expiresAt'] = $this->calculateExpiration($seconds);

$this->storage = array_merge($this->storage, [$key => $item]);

return true;
}

/**
* Remove an item from the cache.
*
Expand Down
15 changes: 15 additions & 0 deletions src/Illuminate/Cache/DatabaseStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,21 @@ public function restoreLock($name, $owner)
return $this->lock($name, 0, $owner);
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds)
{
return (bool) $this->table()
->where('key', '=', $this->getPrefix().$key)
->where('expiration', '>', $now = $this->getTime())
->update(['expiration' => $now + $seconds]);
}

/**
* Remove an item from the cache.
*
Expand Down
37 changes: 37 additions & 0 deletions src/Illuminate/Cache/DynamoDbStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,43 @@ public function restoreLock($name, $owner)
return $this->lock($name, 0, $owner);
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*
* @throws DynamoDbException
*/
public function touch($key, $seconds)
{
try {
$this->dynamo->updateItem([
'TableName' => $this->table,
'Key' => [$this->keyAttribute => ['S' => $this->getPrefix().$key]],
'UpdateExpression' => 'SET #expiry = :expiry',
'ConditionExpression' => 'attribute_exists(#key) AND #expiry > :now',
'ExpressionAttributeNames' => [
'#key' => $this->keyAttribute,
'#expiry' => $this->expirationAttribute,
],
'ExpressionAttributeValues' => [
':expiry' => ['N' => (string) $this->toTimestamp($seconds)],
':now' => ['N' => (string) $this->currentTime()],
],
]);
} catch (DynamoDbException $e) {
if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) {
return false;
}

throw $e;
}

return true;
}

/**
* Remove an item from the cache.
*
Expand Down
18 changes: 18 additions & 0 deletions src/Illuminate/Cache/FileStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,24 @@ public function restoreLock($name, $owner)
return $this->lock($name, 0, $owner);
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds)
{
$payload = $this->getPayload($this->getPrefix().$key);

if (is_null($payload['data'])) {
return false;
}

return $this->put($key, $payload['data'], $seconds);
}

/**
* Remove an item from the cache.
*
Expand Down
12 changes: 12 additions & 0 deletions src/Illuminate/Cache/MemcachedStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,18 @@ public function restoreLock($name, $owner)
return $this->lock($name, 0, $owner);
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds)
{
return $this->memcached->touch($this->getPrefix().$key, $this->calculateExpiration($seconds));
}

/**
* Remove an item from the cache.
*
Expand Down
14 changes: 14 additions & 0 deletions src/Illuminate/Cache/MemoizedStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,20 @@ public function restoreLock($name, $owner)
return $this->repository->resoreLock(...func_get_args());
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds)
{
unset($this->cache[$this->prefix($key)]);

return $this->repository->touch($key, $seconds);
}

/**
* Remove an item from the cache.
*
Expand Down
12 changes: 12 additions & 0 deletions src/Illuminate/Cache/NullStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ public function restoreLock($name, $owner)
return $this->lock($name, 0, $owner);
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds)
{
return false;
}

/**
* Remove an item from the cache.
*
Expand Down
12 changes: 12 additions & 0 deletions src/Illuminate/Cache/RedisStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,18 @@ public function restoreLock($name, $owner)
return $this->lock($name, 0, $owner);
}

/**
* Adjust the expiration time of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds)
{
return (bool) $this->connection()->expire($this->getPrefix().$key, (int) max(1, $seconds));
}

/**
* Remove an item from the cache.
*
Expand Down
20 changes: 20 additions & 0 deletions src/Illuminate/Cache/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,26 @@ public function flexible($key, $ttl, $callback, $lock = null)
return $value;
}

/**
* Set the expiration of a cached item; null TTL will retain the item forever.
*
* @param string $key
* @param \DateTimeInterface|\DateInterval|int|null $ttl
* @return bool
*/
public function touch($key, $ttl = null)
{
$value = $this->get($key);

if (is_null($value)) {
return false;
}

return is_null($ttl)
? $this->forever($key, $value)
: $this->store->touch($this->itemKey($key), $this->getSeconds($ttl));
}

/**
* Remove an item from the cache.
*
Expand Down
11 changes: 11 additions & 0 deletions src/Illuminate/Contracts/Cache/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Illuminate\Contracts\Cache;

use Closure;
use DateInterval;
use DateTimeInterface;
use Psr\SimpleCache\CacheInterface;

interface Repository extends CacheInterface
Expand Down Expand Up @@ -99,6 +101,15 @@ public function sear($key, Closure $callback);
*/
public function rememberForever($key, Closure $callback);

/**
* Set the expiration of a cached item; null TTL will retain the item forever.
*
* @param string $key
* @param \DateTimeInterface|\DateInterval|int|null $ttl
* @return bool
*/
public function touch($key, $ttl = null);

/**
* Remove an item from the cache.
*
Expand Down
9 changes: 9 additions & 0 deletions src/Illuminate/Contracts/Cache/Store.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ public function decrement($key, $value = 1);
*/
public function forever($key, $value);

/**
* Set the expiration of a cached item.
*
* @param string $key
* @param int $seconds
* @return bool
*/
public function touch($key, $seconds);

/**
* Remove an item from the cache.
*
Expand Down
1 change: 1 addition & 0 deletions src/Illuminate/Support/Facades/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
* @method static mixed flexible(string $key, array $ttl, callable $callback, array|null $lock = null)
* @method static bool forget(string $key)
* @method static bool delete(string $key)
* @method static bool touch(string $key, \DateTimeInterface|\DateInterval|int|null $ttl = null)
* @method static bool deleteMultiple(iterable $keys)
* @method static bool clear()
* @method static \Illuminate\Cache\TaggedCache tags(array|mixed $names)
Expand Down
13 changes: 13 additions & 0 deletions tests/Cache/CacheApcStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,19 @@ public function testForgetMethodProperlyCallsAPC()
$this->assertTrue($result);
}

public function testTouchMethodProperlyCallsAPC(): void
{
$key = 'key';
$ttl = 60;

$apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get', 'put'])->getMock();

$apc->expects($this->once())->method('get')->with($this->equalTo($key))->willReturn('bar');
$apc->expects($this->once())->method('put')->with($this->equalTo($key), $this->equalTo('bar'), $this->equalTo($ttl))->willReturn(true);

$this->assertTrue((new ApcStore($apc))->touch($key, $ttl));
}

public function testFlushesCached()
{
$apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['flush'])->getMock();
Expand Down
17 changes: 17 additions & 0 deletions tests/Cache/CacheArrayStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@ public function testItemsCanExpire()
$this->assertNull($result);
}

public function testTouchExtendsTtl(): void
{
$key = 'key';
$value = 'value';

$store = new ArrayStore;

Carbon::setTestNow($now = Carbon::now());

$store->put($key, $value, 30);
$store->touch($key, 60);

Carbon::setTestNow($now->addSeconds(45));

$this->assertSame($value, $store->get($key));
}

public function testStoreItemForeverProperlyStoresInArray()
{
$mock = $this->getMockBuilder(ArrayStore::class)->onlyMethods(['put'])->getMock();
Expand Down
Loading
Loading