From 91a0719e651faf83f37fe8bf271f92aecc4549b5 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Wed, 3 Jan 2024 23:34:25 -0600 Subject: [PATCH 1/7] feat: Allow current settings to be completely cleared out. --- .gitignore | 1 + docs/basic-usage.md | 8 +++++++- src/Commands/ClearSettings.php | 21 +++++++++++++++++++++ src/Handlers/ArrayHandler.php | 6 ++++++ src/Handlers/BaseHandler.php | 12 ++++++++++++ src/Handlers/DatabaseHandler.php | 15 ++++++++++++++- src/Settings.php | 13 +++++++++++++ tests/DatabaseHandlerTest.php | 21 +++++++++++++++++++++ 8 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/Commands/ClearSettings.php 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..bbae68f 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(); diff --git a/src/Commands/ClearSettings.php b/src/Commands/ClearSettings.php new file mode 100644 index 0000000..0f6c5fe --- /dev/null +++ b/src/Commands/ClearSettings.php @@ -0,0 +1,21 @@ +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..73b8f25 100644 --- a/src/Handlers/DatabaseHandler.php +++ b/src/Handlers/DatabaseHandler.php @@ -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([ @@ -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'); From d95d93c893d2f7691ec0a93027e9effd3172276f Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Thu, 4 Jan 2024 22:56:03 -0600 Subject: [PATCH 2/7] Finishing up the ClearSettings command. --- src/Commands/ClearSettings.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Commands/ClearSettings.php b/src/Commands/ClearSettings.php index 0f6c5fe..b5c1c55 100644 --- a/src/Commands/ClearSettings.php +++ b/src/Commands/ClearSettings.php @@ -1,6 +1,6 @@ flush(); + + CLI::write('Settings cleared from the database.', 'green'); } } From 4d70d722ea6558ea6d400903a83b8f2d9be4a74d Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Thu, 4 Jan 2024 22:58:26 -0600 Subject: [PATCH 3/7] Documenting the command --- docs/basic-usage.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/basic-usage.md b/docs/basic-usage.md index bbae68f..0030fa2 100644 --- a/docs/basic-usage.md +++ b/docs/basic-usage.md @@ -99,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. From 90b605bc2125ad30bb31459f32807043680a398f Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Thu, 4 Jan 2024 23:01:28 -0600 Subject: [PATCH 4/7] Making stan happy --- src/Handlers/DatabaseHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Handlers/DatabaseHandler.php b/src/Handlers/DatabaseHandler.php index 73b8f25..4fb488d 100644 --- a/src/Handlers/DatabaseHandler.php +++ b/src/Handlers/DatabaseHandler.php @@ -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([ From b26c6de4d5a7e9215c0a54114cff3373508629bc Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Thu, 4 Jan 2024 23:01:56 -0600 Subject: [PATCH 5/7] Making stan happy --- src/Handlers/DatabaseHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Handlers/DatabaseHandler.php b/src/Handlers/DatabaseHandler.php index 4fb488d..73b8f25 100644 --- a/src/Handlers/DatabaseHandler.php +++ b/src/Handlers/DatabaseHandler.php @@ -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([ From 9d91da7fa44e87336cb43d5360db315dd4f558b2 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Thu, 4 Jan 2024 23:03:31 -0600 Subject: [PATCH 6/7] Update DatabaseHandler.php --- src/Handlers/DatabaseHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Handlers/DatabaseHandler.php b/src/Handlers/DatabaseHandler.php index 73b8f25..4fb488d 100644 --- a/src/Handlers/DatabaseHandler.php +++ b/src/Handlers/DatabaseHandler.php @@ -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([ From 797e2b69296c6eab5666aeea17b93b6eae0390c4 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Fri, 5 Jan 2024 08:34:37 -0600 Subject: [PATCH 7/7] Update src/Commands/ClearSettings.php Co-authored-by: Michal Sniatala --- src/Commands/ClearSettings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/ClearSettings.php b/src/Commands/ClearSettings.php index b5c1c55..b31d547 100644 --- a/src/Commands/ClearSettings.php +++ b/src/Commands/ClearSettings.php @@ -13,7 +13,7 @@ class ClearSettings extends BaseCommand 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') { + if (CLI::prompt('This will delete all settings from the database. Are you sure you want to continue?', ['y', 'n'], 'required') !== 'y') { return; }