Skip to content

Commit

Permalink
Merge pull request #116 from codeigniter4/test-support
Browse files Browse the repository at this point in the history
feat: Allow current settings to be completely cleared out.
  • Loading branch information
lonnieezell authored Jan 6, 2024
2 parents 0f0d9d2 + 797e2b6 commit 2748f2b
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 1 deletion.
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/
18 changes: 17 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 Expand Up @@ -93,3 +99,13 @@ setting()->forget('App.siteName');
!!! Note

Due to the shorthand nature of the helper function it cannot access contextual settings.

### Commands

From the `spark` command line tool you can clear all settings from the database with the `settings:clear` command.

```bash
php spark settings:clear
```

You will be prompted to confirm the action before it is performed.
24 changes: 24 additions & 0 deletions src/Commands/ClearSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace CodeIgniter\Settings\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') {
return;
}

service('setting')->flush();

CLI::write('Settings cleared from the database.', 'green');
}
}
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
13 changes: 13 additions & 0 deletions src/Handlers/DatabaseHandler.php
Original file line number Diff line number Diff line change
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 2748f2b

Please sign in to comment.