Skip to content

Introducing take Method #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
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'));
}
}