diff --git a/.gitignore b/.gitignore index 6f3cfe7..57e6fd3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ phpunit composer.lock .DS_Store .idea/ +.vscode/ diff --git a/docs/basic-usage.md b/docs/basic-usage.md index 6d7a655..0030fa2 100644 --- a/docs/basic-usage.md +++ b/docs/basic-usage.md @@ -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". @@ -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(); @@ -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. diff --git a/src/Commands/ClearSettings.php b/src/Commands/ClearSettings.php new file mode 100644 index 0000000..b31d547 --- /dev/null +++ b/src/Commands/ClearSettings.php @@ -0,0 +1,24 @@ +flush(); + + CLI::write('Settings cleared from the database.', 'green'); + } +} diff --git a/src/Handlers/ArrayHandler.php b/src/Handlers/ArrayHandler.php index b78bfdb..29467ee 100644 --- a/src/Handlers/ArrayHandler.php +++ b/src/Handlers/ArrayHandler.php @@ -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. */ diff --git a/src/Handlers/BaseHandler.php b/src/Handlers/BaseHandler.php index ad3a99d..861588f 100644 --- a/src/Handlers/BaseHandler.php +++ b/src/Handlers/BaseHandler.php @@ -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. diff --git a/src/Handlers/DatabaseHandler.php b/src/Handlers/DatabaseHandler.php index 9f7f0b8..4fb488d 100644 --- a/src/Handlers/DatabaseHandler.php +++ b/src/Handlers/DatabaseHandler.php @@ -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 diff --git a/src/Settings.php b/src/Settings.php index 244ea9f..7df538f 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -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. * diff --git a/tests/DatabaseHandlerTest.php b/tests/DatabaseHandlerTest.php index 2244c2c..691ff15 100644 --- a/tests/DatabaseHandlerTest.php +++ b/tests/DatabaseHandlerTest.php @@ -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');