Skip to content
Closed
6 changes: 6 additions & 0 deletions docs/basic-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ If you ever need to completely remove all settings from their persistent storage
service('settings')->flush();
```

Also, you can use the `take()` method to retrieve a setting and then remove it from the persistent storage in one go. This is useful when you want to retrieve a value and ensure it is no longer available for future use.

```php
$siteName = service('settings')->take('App.siteName');
```

### Contextual Settings

In addition to the default behavior describe above, `Settings` can be used to define "contextual settings".
Expand Down
9 changes: 9 additions & 0 deletions src/Handlers/ArrayHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ public function forget(string $class, string $property, ?string $context = null)
$this->forgetStored($class, $property, $context);
}

public function take(string $class, string $property, ?string $context = null): mixed
{
$value = $this->get($class, $property, $context);

$this->forget($class, $property, $context);

return $value;
}

public function flush()
{
$this->general = [];
Expand Down
15 changes: 15 additions & 0 deletions src/Handlers/BaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ public function forget(string $class, string $property, ?string $context = null)
throw new RuntimeException('Forget method not implemented for current Settings handler.');
}

/**
* If the Handler supports pulling values, it
* MUST override this method to provide that functionality.
* Not all Handlers will support writing values.
* Must throw RuntimeException for any failures.
*
* @return mixed
*
* @throws RuntimeException
*/
public function take(string $class, string $property, ?string $context = null)
{
throw new RuntimeException('Pull method not implemented for current Settings handler.');
}

/**
* All handlers MUST support flushing all values.
*
Expand Down
15 changes: 15 additions & 0 deletions src/Handlers/DatabaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,21 @@ public function forget(string $class, string $property, ?string $context = null)
$this->forgetStored($class, $property, $context);
}

/**
* Retrieves a value from persistent storage
* and deletes it from the local cache.
*
* @return mixed|null
*/
public function take(string $class, string $property, ?string $context = null): mixed
{
$value = $this->get($class, $property, $context);

$this->forget($class, $property, $context);

return $value;
}

/**
* Deletes all records from persistent storage, if found,
* and from the local cache.
Expand Down
14 changes: 14 additions & 0 deletions src/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ public function forget(string $key, ?string $context = null)
}
}

/**
* Retrieves a value from the persistent storage and removes it.
*
* @return mixed
*/
public function take(string $key, ?string $context = null)
{
[$class, $property] = $this->prepareClassAndProperty($key);

foreach ($this->getWriteHandlers() as $handler) {
return $handler->take($class, $property, $context);
}
}

/**
* Removes all settings from the persistent storage,
* Useful during testing. Use with caution.
Expand Down
20 changes: 20 additions & 0 deletions tests/DatabaseHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,26 @@ public function testForgetSuccess()
]);
}

public function testPullSuccess()
{
$this->hasInDatabase($this->table, [
'class' => 'Tests\Support\Config\Example',
'key' => 'siteName',
'value' => 'foo',
'created_at' => Time::now()->toDateTimeString(),
'updated_at' => Time::now()->toDateTimeString(),
]);

$value = $this->settings->take('Example.siteName');

$this->dontSeeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Example',
'key' => 'siteName',
]);

$this->assertSame('foo', $value);
}

public function testForgetWithNoStoredRecord()
{
$this->settings->forget('Example.siteName');
Expand Down
20 changes: 20 additions & 0 deletions tests/SettingsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,24 @@ public function testForgetWithContext()

$this->assertSame('Bar', $this->settings->get('Example.siteName', 'category:disease'));
}

public function testPullWithContext()
{
$this->settings->set('Example.siteName', 'Amnesia', 'category:disease');

$value = $this->settings->take('Example.siteName', 'category:disease');

$this->assertSame('Amnesia', $value);
$this->assertSame('Settings Test', $this->settings->get('Example.siteName', 'category:disease'));
}

public function testPullWithoutContext()
{
$this->settings->set('Example.siteName', 'NoContext');

$value = $this->settings->take('Example.siteName');

$this->assertSame('NoContext', $value);
$this->assertSame('Settings Test', $this->settings->get('Example.siteName'));
}
}