Skip to content

Commit

Permalink
Merge pull request #16 from codeigniter4/context
Browse files Browse the repository at this point in the history
Contexts
  • Loading branch information
MGatner authored Nov 15, 2021
2 parents c7d6c8f + 3bc96e8 commit 6a26ae8
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 75 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,39 @@ it effectively resets itself back to the default value in config file, if any.
service('setting')->forget('App.siteName')
```

### Contextual Settings

In addition to the default behavior describe above, `Settings` can can be used to define "contextual settings".
A context may be anything you want, but common examples are a runtime environment or an authenticated user.
In order to use a context you pass it as an additional parameter to the `get()`/`set()`/`forget()` methods; if
a context setting is requested and does not exist then the general value will be used.

Contexts may be any unique string you choose, but a recommended format for supplying some consistency is to
give them a category and identifier, like `environment:production` or `group:42`.

An example... Say your App config includes the name of a theme to use to enhance your display. By default
your config file specifies `App.theme = 'default'`. When a user changes their theme, you do not want this to
change the theme for all visitors to the site, so you need to provide the user as the *context* for the change:

```php
$context = 'user:' . user_id();
service('setting')->set('App.theme', 'dark', $context);
```

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

```php
$context = 'user:' . user_id();
$theme = service('setting')->get('App.theme', $context);

// or using the helper
setting()->get('App.theme', $context);
```

Contexts are a cascading check, so if a context does not match a value it will fall back on general,
i.e. `service('setting')->get('App.theme')`. Return value priority is as follows:
"Setting with a context > Setting without context > Config value > null".

### Using the Helper

The helper provides a shortcut to the using the service. It must first be loaded using the `helper()` method
Expand All @@ -100,6 +133,8 @@ setting()->set('App.siteName', 'My Great Site');
setting()->forget('App.siteName');
```

> Note: Due to the shorthand nature of the helper function it cannot access contextual settings.
## Known Limitations

The following are known limitations of the library:
Expand Down
6 changes: 6 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Upgrade Guide

## Version 1 to 2
***

* Due to the addition of contexts the `BaseHandler` abstract class was changed. Update any handlers that extend this class to include the new and changed methods.
25 changes: 25 additions & 0 deletions src/Database/Migrations/2021-11-14-143905_AddContextColumn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Sparks\Settings\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddContextColumn extends Migration
{
public function up()
{
$this->forge->addColumn(config('Settings')->database['table'], [
'context' => [
'type' => 'varchar',
'constraint' => 255,
'null' => true,
'after' => 'type',
],
]);
}

public function down()
{
$this->forge->dropColumn(config('Settings')->database['table'], 'context');
}
}
29 changes: 26 additions & 3 deletions src/Handlers/BaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@

namespace Sparks\Settings\Handlers;

use RuntimeException;

abstract class BaseHandler
{
/**
* Checks whether this handler has a value set.
*/
abstract public function has(string $class, string $property, ?string $context = null): bool;

/**
* Returns a single value from the handler, if stored.
*
* @return mixed
*/
abstract public function get(string $class, string $property);
abstract public function get(string $class, string $property, ?string $context = null);

/**
* If the Handler supports saving values, it
Expand All @@ -18,11 +25,27 @@ abstract public function get(string $class, string $property);
*
* @param mixed $value
*
* @throws RuntimeException
*
* @return mixed
*/
public function set(string $class, string $property, $value = null, ?string $context = null)
{
throw new RuntimeException('Set method not implemented for current Settings handler.');
}

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

/**
Expand Down
Loading

0 comments on commit 6a26ae8

Please sign in to comment.