Skip to content

Commit

Permalink
feat: Allow current settings to be completely cleared out.
Browse files Browse the repository at this point in the history
  • Loading branch information
lonnieezell committed Jan 4, 2024
1 parent 0f0d9d2 commit 91a0719
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ phpunit
composer.lock
.DS_Store
.idea/
.vscode/
8 changes: 7 additions & 1 deletion docs/basic-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ it effectively resets itself back to the default value in config file, if any.
service('settings')->forget('App.siteName');
```

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
service('settings')->flush();
```

### Contextual Settings

In addition to the default behavior describe above, `Settings` can be used to define "contextual settings".
Expand All @@ -49,7 +55,7 @@ give them a category and identifier, like `environment:production`, `group:super

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:
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();
Expand Down
21 changes: 21 additions & 0 deletions src/Commands/ClearSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;

class ClearSettings extends BaseCommand
{
protected $group = 'Housekeeping';
protected $name = 'settings:clear';
protected $description = 'Clears all settings from the database.';

public function run(array $params)
{
if (! CLI::prompt('This will delete all settings from the database. Are you sure you want to continue?', ['y', 'n'], 'required') === 'y') {

Check failure on line 16 in src/Commands/ClearSettings.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 7.4 Static Analysis

Strict comparison using === between bool and 'y' will always evaluate to false.

Check failure on line 16 in src/Commands/ClearSettings.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.0 Static Analysis

Strict comparison using === between bool and 'y' will always evaluate to false.

Check failure on line 16 in src/Commands/ClearSettings.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.1 Static Analysis

Strict comparison using === between bool and 'y' will always evaluate to false.

Check failure on line 16 in src/Commands/ClearSettings.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.2 Static Analysis

Strict comparison using === between bool and 'y' will always evaluate to false.
return;
}

}
}
6 changes: 6 additions & 0 deletions src/Handlers/ArrayHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ public function forget(string $class, string $property, ?string $context = null)
$this->forgetStored($class, $property, $context);
}

public function flush()
{
$this->general = [];
$this->contexts = [];
}

/**
* Checks whether this value is in storage.
*/
Expand Down
12 changes: 12 additions & 0 deletions src/Handlers/BaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ public function forget(string $class, string $property, ?string $context = null)
throw new RuntimeException('Forget method not implemented for current Settings handler.');
}

/**
* All handlers MUST support flushing all values.
*
* @return void
*
* @throws RuntimeException
*/
public function flush()
{
throw new RuntimeException('Flush method not implemented for current Settings handler.');
}

/**
* Takes care of converting some item types so they can be safely
* stored and re-hydrated into the config files.
Expand Down
15 changes: 14 additions & 1 deletion src/Handlers/DatabaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public function set(string $class, string $property, $value = null, ?string $con
'context' => $context,
'updated_at' => $time,
]);
// ...otherwise insert it
// ...otherwise insert it
} else {
$result = $this->builder
->insert([
Expand Down Expand Up @@ -140,6 +140,19 @@ public function forget(string $class, string $property, ?string $context = null)
$this->forgetStored($class, $property, $context);
}

/**
* Deletes all records from persistent storage, if found,
* and from the local cache.
*
* @return void
*/
public function flush()
{
$this->builder->truncate();

parent::flush();
}

/**
* Fetches values from the database in bulk to minimize calls.
* General (null) is always fetched once, contexts are fetched
Expand Down
13 changes: 13 additions & 0 deletions src/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ public function forget(string $key, ?string $context = null)
}
}

/**
* Removes all settings from the persistent storage,
* Useful during testing. Use with caution.
*
* @return void
*/
public function flush()
{
foreach ($this->getWriteHandlers() as $handler) {
$handler->flush();
}
}

/**
* Returns the handler that is set to store values.
*
Expand Down
21 changes: 21 additions & 0 deletions tests/DatabaseHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,27 @@ public function testForgetWithNoStoredRecord()
]);
}

public function testFlush()
{
// Default value in the config file
$this->assertSame('Settings Test', $this->settings->get('Test.siteName'));

$this->settings->set('Test.siteName', 'Foo');

// Should be the last value set
$this->assertSame('Foo', $this->settings->get('Test.siteName'));

$this->settings->flush();

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

// Should be back to the default value
$this->assertSame('Settings Test', $this->settings->get('Test.siteName'));
}

public function testSetWithContext()
{
$this->settings->set('Test.siteName', 'Banana', 'environment:test');
Expand Down

0 comments on commit 91a0719

Please sign in to comment.