Skip to content

Commit 2748f2b

Browse files
authored
Merge pull request #116 from codeigniter4/test-support
feat: Allow current settings to be completely cleared out.
2 parents 0f0d9d2 + 797e2b6 commit 2748f2b

File tree

8 files changed

+107
-1
lines changed

8 files changed

+107
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ phpunit
66
composer.lock
77
.DS_Store
88
.idea/
9+
.vscode/

docs/basic-usage.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ it effectively resets itself back to the default value in config file, if any.
3737
service('settings')->forget('App.siteName');
3838
```
3939

40+
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.
41+
42+
```php
43+
service('settings')->flush();
44+
```
45+
4046
### Contextual Settings
4147

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

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

5460
```php
5561
$context = 'user:' . user_id();
@@ -93,3 +99,13 @@ setting()->forget('App.siteName');
9399
!!! Note
94100

95101
Due to the shorthand nature of the helper function it cannot access contextual settings.
102+
103+
### Commands
104+
105+
From the `spark` command line tool you can clear all settings from the database with the `settings:clear` command.
106+
107+
```bash
108+
php spark settings:clear
109+
```
110+
111+
You will be prompted to confirm the action before it is performed.

src/Commands/ClearSettings.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace CodeIgniter\Settings\Commands;
4+
5+
use CodeIgniter\CLI\BaseCommand;
6+
use CodeIgniter\CLI\CLI;
7+
8+
class ClearSettings extends BaseCommand
9+
{
10+
protected $group = 'Housekeeping';
11+
protected $name = 'settings:clear';
12+
protected $description = 'Clears all settings from the database.';
13+
14+
public function run(array $params)
15+
{
16+
if (CLI::prompt('This will delete all settings from the database. Are you sure you want to continue?', ['y', 'n'], 'required') !== 'y') {
17+
return;
18+
}
19+
20+
service('setting')->flush();
21+
22+
CLI::write('Settings cleared from the database.', 'green');
23+
}
24+
}

src/Handlers/ArrayHandler.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ public function forget(string $class, string $property, ?string $context = null)
4747
$this->forgetStored($class, $property, $context);
4848
}
4949

50+
public function flush()
51+
{
52+
$this->general = [];
53+
$this->contexts = [];
54+
}
55+
5056
/**
5157
* Checks whether this value is in storage.
5258
*/

src/Handlers/BaseHandler.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ public function forget(string $class, string $property, ?string $context = null)
5050
throw new RuntimeException('Forget method not implemented for current Settings handler.');
5151
}
5252

53+
/**
54+
* All handlers MUST support flushing all values.
55+
*
56+
* @return void
57+
*
58+
* @throws RuntimeException
59+
*/
60+
public function flush()
61+
{
62+
throw new RuntimeException('Flush method not implemented for current Settings handler.');
63+
}
64+
5365
/**
5466
* Takes care of converting some item types so they can be safely
5567
* stored and re-hydrated into the config files.

src/Handlers/DatabaseHandler.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,19 @@ public function forget(string $class, string $property, ?string $context = null)
140140
$this->forgetStored($class, $property, $context);
141141
}
142142

143+
/**
144+
* Deletes all records from persistent storage, if found,
145+
* and from the local cache.
146+
*
147+
* @return void
148+
*/
149+
public function flush()
150+
{
151+
$this->builder->truncate();
152+
153+
parent::flush();
154+
}
155+
143156
/**
144157
* Fetches values from the database in bulk to minimize calls.
145158
* General (null) is always fetched once, contexts are fetched

src/Settings.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ public function forget(string $key, ?string $context = null)
101101
}
102102
}
103103

104+
/**
105+
* Removes all settings from the persistent storage,
106+
* Useful during testing. Use with caution.
107+
*
108+
* @return void
109+
*/
110+
public function flush()
111+
{
112+
foreach ($this->getWriteHandlers() as $handler) {
113+
$handler->flush();
114+
}
115+
}
116+
104117
/**
105118
* Returns the handler that is set to store values.
106119
*

tests/DatabaseHandlerTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,27 @@ public function testForgetWithNoStoredRecord()
221221
]);
222222
}
223223

224+
public function testFlush()
225+
{
226+
// Default value in the config file
227+
$this->assertSame('Settings Test', $this->settings->get('Test.siteName'));
228+
229+
$this->settings->set('Test.siteName', 'Foo');
230+
231+
// Should be the last value set
232+
$this->assertSame('Foo', $this->settings->get('Test.siteName'));
233+
234+
$this->settings->flush();
235+
236+
$this->dontSeeInDatabase($this->table, [
237+
'class' => 'Tests\Support\Config\Test',
238+
'key' => 'siteName',
239+
]);
240+
241+
// Should be back to the default value
242+
$this->assertSame('Settings Test', $this->settings->get('Test.siteName'));
243+
}
244+
224245
public function testSetWithContext()
225246
{
226247
$this->settings->set('Test.siteName', 'Banana', 'environment:test');

0 commit comments

Comments
 (0)