Skip to content
Open
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
37 changes: 37 additions & 0 deletions docs/basic-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,32 @@ when retrieved.
service('settings')->set('App.siteName', 'My Great Site');
```

You can save multiple values with `setMany()`. This behaves like calling `set()` for each key/value pair,
but allows supported handlers to persist the changes more efficiently.

```php
service('settings')->setMany([
'App.siteName' => 'My Great Site',
'App.siteEmail' => '[email protected]',
]);
```

You can delete a value from the persistent storage with the `forget()` method. Since it is removed from the storage,
it effectively resets itself back to the default value in config file, if any.

```php
service('settings')->forget('App.siteName');
```

You can delete multiple values with `forgetMany()`.

```php
service('settings')->forgetMany([
'App.siteName',
'App.siteEmail',
]);
```

If you ever need to completely remove all settings from their persistent storage, you can use the `flush()` method. This immediately removes all settings from the database and the in-memory cache.

```php
Expand All @@ -62,6 +81,16 @@ $context = 'user:' . user_id();
service('settings')->set('App.theme', 'dark', $context);
```

The same context can be applied to a batch of values:

```php
$context = 'user:' . user_id();
service('settings')->setMany([
'App.theme' => 'dark',
'App.locale' => 'en',
], $context);
```

Now when your filter is determining which theme to apply it can check for the current user as the context:

```php
Expand Down Expand Up @@ -91,9 +120,17 @@ setting('App.siteName', 'My Great Site');
// Using the service through the helper
$name = setting()->get('App.siteName');
setting()->set('App.siteName', 'My Great Site');
setting()->setMany([
'App.siteName' => 'My Great Site',
'App.siteEmail' => '[email protected]',
]);

// Forgetting a value
setting()->forget('App.siteName');
setting()->forgetMany([
'App.siteName',
'App.siteEmail',
]);
```

!!! Note
Expand Down
25 changes: 25 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ Handlers like `database` and `file` support deferred writes. When `deferWrites`
are batched and persisted efficiently at the end of the request during the `post_system` event. This minimizes the number of
database queries or file I/O operations, improving performance for write-heavy operations.

!!! note
This is separate from the explicit `setMany()` and `forgetMany()` APIs. Batch APIs allow callers to group multiple settings
in one method call, while deferred writes decide whether writes are persisted immediately or at the end of the request.
The two features are independent and can be combined.

### Multiple handlers

Example:
Expand Down Expand Up @@ -94,6 +99,16 @@ $settings->set('Example.prop3', 'value3');

The deferred approach is especially beneficial when updating existing records or performing many operations in a single request.

For explicit batches, use `setMany()` or `forgetMany()`:

```php
$settings->setMany([
'Example.prop1' => 'value1',
'Example.prop2' => 'value2',
'Example.prop3' => 'value3',
]);
```

---

## FileHandler
Expand Down Expand Up @@ -136,6 +151,16 @@ $settings->set('Example.prop3', 'value3');

The deferred approach is especially beneficial when updating multiple properties in the same class.

For explicit batches, use `setMany()` or `forgetMany()`:

```php
$settings->setMany([
'Example.prop1' => 'value1',
'Example.prop2' => 'value2',
'Example.prop3' => 'value3',
]);
```

---

## ArrayHandler
Expand Down
3 changes: 2 additions & 1 deletion docs/limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ The following are known limitations of the library:
1. **Immediate writes (`deferWrites => false`)**: Each setting is written to storage immediately when you call `set()` or `forget()`.
The first operation hydrates all settings for that context (1 SELECT query), then each subsequent write performs a separate
INSERT or UPDATE. While `DatabaseHandler` and `FileHandler` use an in-memory cache to maintain fast reads, individual write
operations may result in multiple database queries or file writes per request.
operations may result in multiple database queries or file writes per request. When multiple changes are known ahead of time,
use `setMany()` or `forgetMany()` to group them explicitly and allow supported handlers to persist them more efficiently.

2. **Deferred writes (`deferWrites => true`)**: All settings are batched and written to storage at the end of the request
(during the `post_system` event). This minimizes the number of database queries and file writes, improving performance.
Expand Down
30 changes: 30 additions & 0 deletions src/Handlers/BaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ public function set(string $class, string $property, $value = null, ?string $con
throw new RuntimeException('Set method not implemented for current Settings handler.');
}

/**
* If the Handler supports saving values, it MAY override this method
* to provide optimized batch functionality.
*
* @param list<array{class: string, property: string, value: mixed}> $settings
*
* @throws RuntimeException
*/
public function setMany(array $settings, ?string $context = null): void
{
foreach ($settings as $setting) {
$this->set($setting['class'], $setting['property'], $setting['value'], $context);
}
}

/**
* If the Handler supports forgetting values, it
* MUST override this method to provide that functionality.
Expand All @@ -48,6 +63,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 forgetting values, it MAY override this method
* to provide optimized batch functionality.
*
* @param list<array{class: string, property: string}> $settings
*
* @throws RuntimeException
*/
public function forgetMany(array $settings, ?string $context = null): void
{
foreach ($settings as $setting) {
$this->forget($setting['class'], $setting['property'], $context);
}
}

/**
* All handlers MUST support flushing all values.
*
Expand Down
Loading
Loading