From b9c09d603a9f30548f017f3c9d44704c6b592fc7 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Tue, 26 Oct 2021 22:56:24 +0100 Subject: [PATCH 01/18] Create default settings extender --- src/Extend/Settings.php | 29 ++++++++++++++- src/Settings/DefaultSettingsManager.php | 27 ++++++++++++++ .../MemoryCacheSettingsRepository.php | 13 +++++-- src/Settings/SettingsServiceProvider.php | 7 +++- tests/integration/extenders/SettingsTest.php | 37 +++++++++++++++++++ .../MemoryCacheSettingsRepositoryTest.php | 7 +++- 6 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 src/Settings/DefaultSettingsManager.php diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index e100e94b0a..d791f193f7 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -13,12 +13,14 @@ use Flarum\Api\Serializer\ForumSerializer; use Flarum\Extension\Extension; use Flarum\Foundation\ContainerUtil; +use Flarum\Settings\DefaultSettingsManager; use Flarum\Settings\SettingsRepositoryInterface; use Illuminate\Contracts\Container\Container; class Settings implements ExtenderInterface { private $settings = []; + private $defaults = []; /** * Serialize a setting value to the ForumSerializer attributes. @@ -38,13 +40,36 @@ class Settings implements ExtenderInterface */ public function serializeToForum(string $attributeName, string $key, $callback = null, $default = null): self { - $this->settings[$key] = compact('attributeName', 'callback', 'default'); + $this->settings[$key] = compact('attributeName', 'callback'); + + if ($default) { + $this->default($key, $default); + } + + return $this; + } + + /** + * Set a default value for a setting. + * Recommended instead of inserting the default value with a migration. + */ + public function default(string $key, $value): self + { + $this->defaults[$key] = $value; return $this; } public function extend(Container $container, Extension $extension = null) { + if (! empty($this->defaults)) { + $container->extend(DefaultSettingsManager::class, function (DefaultSettingsManager $manager) { + foreach ($this->defaults as $key => $default) { + $manager->set($key, $default); + } + }); + } + if (! empty($this->settings)) { AbstractSerializer::addAttributeMutator( ForumSerializer::class, @@ -53,7 +78,7 @@ function () use ($container) { $attributes = []; foreach ($this->settings as $key => $setting) { - $value = $settings->get($key, $setting['default']); + $value = $settings->get($key); if (isset($setting['callback'])) { $callback = ContainerUtil::wrapCallback($setting['callback'], $container); diff --git a/src/Settings/DefaultSettingsManager.php b/src/Settings/DefaultSettingsManager.php new file mode 100644 index 0000000000..255d27c4e7 --- /dev/null +++ b/src/Settings/DefaultSettingsManager.php @@ -0,0 +1,27 @@ +defaults, $key, $default); + } + + public function set($key, $value) + { + $this->defaults[$key] = $value; + } +} diff --git a/src/Settings/MemoryCacheSettingsRepository.php b/src/Settings/MemoryCacheSettingsRepository.php index 1328e282e3..304886b5cf 100644 --- a/src/Settings/MemoryCacheSettingsRepository.php +++ b/src/Settings/MemoryCacheSettingsRepository.php @@ -19,9 +19,12 @@ class MemoryCacheSettingsRepository implements SettingsRepositoryInterface protected $cache = []; - public function __construct(SettingsRepositoryInterface $inner) + protected $defaultSettingsManager; + + public function __construct(SettingsRepositoryInterface $inner, DefaultSettingsManager $defaultSettingsManager) { $this->inner = $inner; + $this->defaultSettingsManager = $defaultSettingsManager; } public function all(): array @@ -36,13 +39,15 @@ public function all(): array public function get($key, $default = null) { + $value = $this->defaultSettingsManager->get($key, $default); + if (array_key_exists($key, $this->cache)) { - return $this->cache[$key]; + $value = $this->cache[$key]; } elseif (! $this->isCached) { - return Arr::get($this->all(), $key, $default); + $value = Arr::get($this->all(), $key, $value); } - return $default; + return $value; } public function set($key, $value) diff --git a/src/Settings/SettingsServiceProvider.php b/src/Settings/SettingsServiceProvider.php index 4bfb8f466a..11cebe284a 100644 --- a/src/Settings/SettingsServiceProvider.php +++ b/src/Settings/SettingsServiceProvider.php @@ -20,11 +20,16 @@ class SettingsServiceProvider extends AbstractServiceProvider */ public function register() { + $this->container->singleton(DefaultSettingsManager::class); + + $this->container->alias(DefaultSettingsManager::class, 'flarum.default_settings'); + $this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) { return new MemoryCacheSettingsRepository( new DatabaseSettingsRepository( $container->make(ConnectionInterface::class) - ) + ), + $this->container->make(DefaultSettingsManager::class) ); }); diff --git a/tests/integration/extenders/SettingsTest.php b/tests/integration/extenders/SettingsTest.php index 437707f9f4..7be88c1a0b 100644 --- a/tests/integration/extenders/SettingsTest.php +++ b/tests/integration/extenders/SettingsTest.php @@ -163,6 +163,43 @@ public function custom_setting_default_passed_to_callback() $this->assertArrayHasKey('customPrefix.noCustomSetting', $payload['data']['attributes']); $this->assertEquals('customDefaultModified2', $payload['data']['attributes']['customPrefix.noCustomSetting']); } + + /** + * @test + */ + public function custom_setting_default_prioritizes_extender() + { + $this->extend( + (new Extend\Settings()) + ->serializeToForum('customPrefix.unavailableCustomSetting3', 'custom-prefix.unavailable_custom_setting3') + ->default('custom-prefix.unavailable_custom_setting3', 'extenderDefault') + ); + + $value = $this->app() + ->getContainer() + ->make('flarum.settings') + ->get('custom-prefix.unavailable_custom_setting3', 'defaultParameterValue'); + + $this->assertEquals('extenderDefault', $value); + } + + /** + * @test + */ + public function custom_setting_default_falls_back_to_parameter() + { + $this->extend( + (new Extend\Settings()) + ->serializeToForum('customPrefix.unavailableCustomSetting4', 'custom-prefix.unavailable_custom_setting4') + ); + + $value = $this->app() + ->getContainer() + ->make('flarum.settings') + ->get('custom-prefix.unavailable_custom_setting4', 'defaultParameterValue'); + + $this->assertEquals('defaultParameterValue', $value); + } } class CustomInvokableClass diff --git a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php index 72d855b403..2d6725e515 100644 --- a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php +++ b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php @@ -9,6 +9,7 @@ namespace Flarum\Tests\unit\Settings; +use Flarum\Settings\DefaultSettingsManager; use Flarum\Settings\MemoryCacheSettingsRepository; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Testing\unit\TestCase; @@ -17,6 +18,7 @@ class MemoryCacheSettingsRepositoryTest extends TestCase { private $baseRepository; + private $defaultSettingsManager; private $repository; /** @@ -25,7 +27,8 @@ class MemoryCacheSettingsRepositoryTest extends TestCase protected function setUp(): void { $this->baseRepository = m::mock(SettingsRepositoryInterface::class); - $this->repository = new MemoryCacheSettingsRepository($this->baseRepository); + $this->defaultSettingsManager = m::mock(DefaultSettingsManager::class); + $this->repository = new MemoryCacheSettingsRepository($this->baseRepository, $this->defaultSettingsManager); } public function test_it_should_return_all_settings_when_not_cached() @@ -39,6 +42,7 @@ public function test_it_should_return_all_settings_when_not_cached() public function test_it_should_retrieve_a_specific_value() { $this->baseRepository->shouldReceive('all')->once()->andReturn(['key1' => 'value1', 'key2' => 'value2']); + $this->defaultSettingsManager->shouldReceive('get')->twice(); $this->assertEquals('value2', $this->repository->get('key2')); $this->assertEquals('value2', $this->repository->get('key2')); // Assert twice to ensure we hit the cache @@ -47,6 +51,7 @@ public function test_it_should_retrieve_a_specific_value() public function test_it_should_set_a_key_value_pair() { $this->baseRepository->shouldReceive('set')->once(); + $this->defaultSettingsManager->shouldReceive('get')->once(); $this->repository->set('key', 'value'); From d30cb39b8a7940ac5da69a860c4b458de2e0e49f Mon Sep 17 00:00:00 2001 From: SychO9 Date: Tue, 26 Oct 2021 23:05:55 +0100 Subject: [PATCH 02/18] Deprecate migration `addSettings` helper --- src/Database/Migration.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Database/Migration.php b/src/Database/Migration.php index 410e05671e..1fb0bcb2f8 100644 --- a/src/Database/Migration.php +++ b/src/Database/Migration.php @@ -9,6 +9,7 @@ namespace Flarum\Database; +use Flarum\Extend\Settings; use Flarum\Settings\DatabaseSettingsRepository; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Builder; @@ -120,6 +121,9 @@ public static function renameColumns($tableName, array $columnNames) /** * Add default values for config values. + * + * @deprecated Use the Settings extender's `default` method instead to register settings. + * @see Settings::default() */ public static function addSettings(array $defaults) { From 6aea45f8867cefac2d27bdb11f887e18b76f22e4 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Wed, 27 Oct 2021 10:55:36 +0100 Subject: [PATCH 03/18] Switch to an array of defaults --- src/Extend/Settings.php | 8 ++++-- src/Settings/DefaultSettingsManager.php | 27 ------------------- .../MemoryCacheSettingsRepository.php | 16 +++++------ src/Settings/SettingsServiceProvider.php | 8 +++--- .../MemoryCacheSettingsRepositoryTest.php | 7 +---- 5 files changed, 18 insertions(+), 48 deletions(-) delete mode 100644 src/Settings/DefaultSettingsManager.php diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index d791f193f7..ec88ceac36 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -63,10 +63,14 @@ public function default(string $key, $value): self public function extend(Container $container, Extension $extension = null) { if (! empty($this->defaults)) { - $container->extend(DefaultSettingsManager::class, function (DefaultSettingsManager $manager) { + $container->extend('flarum.settings.default', function (array $settings) { foreach ($this->defaults as $key => $default) { - $manager->set($key, $default); + if (! isset($settings[$key])) { + $settings[$key] = $default; + } } + + return $settings; }); } diff --git a/src/Settings/DefaultSettingsManager.php b/src/Settings/DefaultSettingsManager.php deleted file mode 100644 index 255d27c4e7..0000000000 --- a/src/Settings/DefaultSettingsManager.php +++ /dev/null @@ -1,27 +0,0 @@ -defaults, $key, $default); - } - - public function set($key, $value) - { - $this->defaults[$key] = $value; - } -} diff --git a/src/Settings/MemoryCacheSettingsRepository.php b/src/Settings/MemoryCacheSettingsRepository.php index 304886b5cf..9ec343c61f 100644 --- a/src/Settings/MemoryCacheSettingsRepository.php +++ b/src/Settings/MemoryCacheSettingsRepository.php @@ -19,18 +19,18 @@ class MemoryCacheSettingsRepository implements SettingsRepositoryInterface protected $cache = []; - protected $defaultSettingsManager; + protected $defaultSettings = []; - public function __construct(SettingsRepositoryInterface $inner, DefaultSettingsManager $defaultSettingsManager) + public function __construct(SettingsRepositoryInterface $inner, array $defaultSettings) { $this->inner = $inner; - $this->defaultSettingsManager = $defaultSettingsManager; + $this->defaultSettings = $defaultSettings; } public function all(): array { if (! $this->isCached) { - $this->cache = $this->inner->all(); + $this->cache = array_merge($this->defaultSettings, $this->inner->all()); $this->isCached = true; } @@ -39,15 +39,13 @@ public function all(): array public function get($key, $default = null) { - $value = $this->defaultSettingsManager->get($key, $default); - if (array_key_exists($key, $this->cache)) { - $value = $this->cache[$key]; + return $this->cache[$key]; } elseif (! $this->isCached) { - $value = Arr::get($this->all(), $key, $value); + return Arr::get($this->all(), $key, $default); } - return $value; + return $default; } public function set($key, $value) diff --git a/src/Settings/SettingsServiceProvider.php b/src/Settings/SettingsServiceProvider.php index 11cebe284a..c4f90c70d5 100644 --- a/src/Settings/SettingsServiceProvider.php +++ b/src/Settings/SettingsServiceProvider.php @@ -20,16 +20,16 @@ class SettingsServiceProvider extends AbstractServiceProvider */ public function register() { - $this->container->singleton(DefaultSettingsManager::class); - - $this->container->alias(DefaultSettingsManager::class, 'flarum.default_settings'); + $this->container->singleton('flarum.settings.default', function () { + return []; + }); $this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) { return new MemoryCacheSettingsRepository( new DatabaseSettingsRepository( $container->make(ConnectionInterface::class) ), - $this->container->make(DefaultSettingsManager::class) + $this->container->make('flarum.settings.default') ); }); diff --git a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php index 2d6725e515..40771206c7 100644 --- a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php +++ b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php @@ -9,7 +9,6 @@ namespace Flarum\Tests\unit\Settings; -use Flarum\Settings\DefaultSettingsManager; use Flarum\Settings\MemoryCacheSettingsRepository; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Testing\unit\TestCase; @@ -18,7 +17,6 @@ class MemoryCacheSettingsRepositoryTest extends TestCase { private $baseRepository; - private $defaultSettingsManager; private $repository; /** @@ -27,8 +25,7 @@ class MemoryCacheSettingsRepositoryTest extends TestCase protected function setUp(): void { $this->baseRepository = m::mock(SettingsRepositoryInterface::class); - $this->defaultSettingsManager = m::mock(DefaultSettingsManager::class); - $this->repository = new MemoryCacheSettingsRepository($this->baseRepository, $this->defaultSettingsManager); + $this->repository = new MemoryCacheSettingsRepository($this->baseRepository, []); } public function test_it_should_return_all_settings_when_not_cached() @@ -42,7 +39,6 @@ public function test_it_should_return_all_settings_when_not_cached() public function test_it_should_retrieve_a_specific_value() { $this->baseRepository->shouldReceive('all')->once()->andReturn(['key1' => 'value1', 'key2' => 'value2']); - $this->defaultSettingsManager->shouldReceive('get')->twice(); $this->assertEquals('value2', $this->repository->get('key2')); $this->assertEquals('value2', $this->repository->get('key2')); // Assert twice to ensure we hit the cache @@ -51,7 +47,6 @@ public function test_it_should_retrieve_a_specific_value() public function test_it_should_set_a_key_value_pair() { $this->baseRepository->shouldReceive('set')->once(); - $this->defaultSettingsManager->shouldReceive('get')->once(); $this->repository->set('key', 'value'); From 9732b70195667af25dcfdd851b481f73eb299192 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Wed, 27 Oct 2021 13:09:30 +0100 Subject: [PATCH 04/18] Deprecate `serializeToForum` default parameter --- src/Extend/Settings.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index ec88ceac36..b5d31c6232 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -35,16 +35,13 @@ class Settings implements ExtenderInterface * The callable should return: * - mixed $value: The modified value. * - * @param mixed $default: Optional default serialized value. Will be run through the optional callback. + * @todo remove $default in 2.0 + * @param mixed $default: Deprecated optional default serialized value. Will be run through the optional callback. * @return self */ public function serializeToForum(string $attributeName, string $key, $callback = null, $default = null): self { - $this->settings[$key] = compact('attributeName', 'callback'); - - if ($default) { - $this->default($key, $default); - } + $this->settings[$key] = compact('attributeName', 'callback', 'default'); return $this; } @@ -82,7 +79,7 @@ function () use ($container) { $attributes = []; foreach ($this->settings as $key => $setting) { - $value = $settings->get($key); + $value = $settings->get($key, $setting['default']); if (isset($setting['callback'])) { $callback = ContainerUtil::wrapCallback($setting['callback'], $container); From 2ee1e69ac532a62b2e6d74041204232df27baafd Mon Sep 17 00:00:00 2001 From: SychO9 Date: Wed, 27 Oct 2021 13:36:55 +0100 Subject: [PATCH 05/18] Fix early settings resolution issues --- src/Extend/Settings.php | 6 ++---- src/Settings/MemoryCacheSettingsRepository.php | 15 +++++++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index b5d31c6232..6bc11e181a 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -60,11 +60,9 @@ public function default(string $key, $value): self public function extend(Container $container, Extension $extension = null) { if (! empty($this->defaults)) { - $container->extend('flarum.settings.default', function (array $settings) { + $container->extend('flarum.settings.default', function (array $settings): array { foreach ($this->defaults as $key => $default) { - if (! isset($settings[$key])) { - $settings[$key] = $default; - } + $settings[$key] = $settings[$key] ?? $default; } return $settings; diff --git a/src/Settings/MemoryCacheSettingsRepository.php b/src/Settings/MemoryCacheSettingsRepository.php index 9ec343c61f..8a05d0a31b 100644 --- a/src/Settings/MemoryCacheSettingsRepository.php +++ b/src/Settings/MemoryCacheSettingsRepository.php @@ -30,17 +30,19 @@ public function __construct(SettingsRepositoryInterface $inner, array $defaultSe public function all(): array { if (! $this->isCached) { - $this->cache = array_merge($this->defaultSettings, $this->inner->all()); + $this->cache = $this->inner->all(); $this->isCached = true; } - return $this->cache; + return $this->getCache(); } public function get($key, $default = null) { - if (array_key_exists($key, $this->cache)) { - return $this->cache[$key]; + $cache = $this->getCache(); + + if (array_key_exists($key, $cache)) { + return $cache[$key]; } elseif (! $this->isCached) { return Arr::get($this->all(), $key, $default); } @@ -61,4 +63,9 @@ public function delete($key) $this->inner->delete($key); } + + protected function getCache(): array + { + return array_merge($this->defaultSettings, $this->cache); + } } From e43a23a15c7f3dd0eea523f5f09b4774bb38a506 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Wed, 27 Oct 2021 13:39:54 +0100 Subject: [PATCH 06/18] Revert "Switch to an array of defaults" This reverts commit 6aea45f8 --- src/Extend/Settings.php | 6 ++--- src/Settings/DefaultSettingsManager.php | 27 +++++++++++++++++++ .../MemoryCacheSettingsRepository.php | 8 +++--- src/Settings/SettingsServiceProvider.php | 8 +++--- .../MemoryCacheSettingsRepositoryTest.php | 7 ++++- 5 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 src/Settings/DefaultSettingsManager.php diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index 6bc11e181a..39af470604 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -60,12 +60,10 @@ public function default(string $key, $value): self public function extend(Container $container, Extension $extension = null) { if (! empty($this->defaults)) { - $container->extend('flarum.settings.default', function (array $settings): array { + $container->extend(DefaultSettingsManager::class, function (DefaultSettingsManager $manager) { foreach ($this->defaults as $key => $default) { - $settings[$key] = $settings[$key] ?? $default; + $manager->set($key, $default); } - - return $settings; }); } diff --git a/src/Settings/DefaultSettingsManager.php b/src/Settings/DefaultSettingsManager.php new file mode 100644 index 0000000000..255d27c4e7 --- /dev/null +++ b/src/Settings/DefaultSettingsManager.php @@ -0,0 +1,27 @@ +defaults, $key, $default); + } + + public function set($key, $value) + { + $this->defaults[$key] = $value; + } +} diff --git a/src/Settings/MemoryCacheSettingsRepository.php b/src/Settings/MemoryCacheSettingsRepository.php index 8a05d0a31b..f961304be8 100644 --- a/src/Settings/MemoryCacheSettingsRepository.php +++ b/src/Settings/MemoryCacheSettingsRepository.php @@ -19,12 +19,12 @@ class MemoryCacheSettingsRepository implements SettingsRepositoryInterface protected $cache = []; - protected $defaultSettings = []; + protected $defaultSettingsManager; - public function __construct(SettingsRepositoryInterface $inner, array $defaultSettings) + public function __construct(SettingsRepositoryInterface $inner, DefaultSettingsManager $defaultSettingsManager) { $this->inner = $inner; - $this->defaultSettings = $defaultSettings; + $this->defaultSettingsManager = $defaultSettingsManager; } public function all(): array @@ -66,6 +66,6 @@ public function delete($key) protected function getCache(): array { - return array_merge($this->defaultSettings, $this->cache); + return array_merge($this->defaultSettingsManager->all(), $this->cache); } } diff --git a/src/Settings/SettingsServiceProvider.php b/src/Settings/SettingsServiceProvider.php index c4f90c70d5..11cebe284a 100644 --- a/src/Settings/SettingsServiceProvider.php +++ b/src/Settings/SettingsServiceProvider.php @@ -20,16 +20,16 @@ class SettingsServiceProvider extends AbstractServiceProvider */ public function register() { - $this->container->singleton('flarum.settings.default', function () { - return []; - }); + $this->container->singleton(DefaultSettingsManager::class); + + $this->container->alias(DefaultSettingsManager::class, 'flarum.default_settings'); $this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) { return new MemoryCacheSettingsRepository( new DatabaseSettingsRepository( $container->make(ConnectionInterface::class) ), - $this->container->make('flarum.settings.default') + $this->container->make(DefaultSettingsManager::class) ); }); diff --git a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php index 40771206c7..2d6725e515 100644 --- a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php +++ b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php @@ -9,6 +9,7 @@ namespace Flarum\Tests\unit\Settings; +use Flarum\Settings\DefaultSettingsManager; use Flarum\Settings\MemoryCacheSettingsRepository; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Testing\unit\TestCase; @@ -17,6 +18,7 @@ class MemoryCacheSettingsRepositoryTest extends TestCase { private $baseRepository; + private $defaultSettingsManager; private $repository; /** @@ -25,7 +27,8 @@ class MemoryCacheSettingsRepositoryTest extends TestCase protected function setUp(): void { $this->baseRepository = m::mock(SettingsRepositoryInterface::class); - $this->repository = new MemoryCacheSettingsRepository($this->baseRepository, []); + $this->defaultSettingsManager = m::mock(DefaultSettingsManager::class); + $this->repository = new MemoryCacheSettingsRepository($this->baseRepository, $this->defaultSettingsManager); } public function test_it_should_return_all_settings_when_not_cached() @@ -39,6 +42,7 @@ public function test_it_should_return_all_settings_when_not_cached() public function test_it_should_retrieve_a_specific_value() { $this->baseRepository->shouldReceive('all')->once()->andReturn(['key1' => 'value1', 'key2' => 'value2']); + $this->defaultSettingsManager->shouldReceive('get')->twice(); $this->assertEquals('value2', $this->repository->get('key2')); $this->assertEquals('value2', $this->repository->get('key2')); // Assert twice to ensure we hit the cache @@ -47,6 +51,7 @@ public function test_it_should_retrieve_a_specific_value() public function test_it_should_set_a_key_value_pair() { $this->baseRepository->shouldReceive('set')->once(); + $this->defaultSettingsManager->shouldReceive('get')->once(); $this->repository->set('key', 'value'); From 6b320e6999b11c357767f3b3dc1f1ccb4da1a546 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Wed, 27 Oct 2021 13:41:07 +0100 Subject: [PATCH 07/18] Make immutable --- src/Extend/Settings.php | 2 +- src/Settings/DefaultSettingsManager.php | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index 39af470604..9b20f7c6dc 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -62,7 +62,7 @@ public function extend(Container $container, Extension $extension = null) if (! empty($this->defaults)) { $container->extend(DefaultSettingsManager::class, function (DefaultSettingsManager $manager) { foreach ($this->defaults as $key => $default) { - $manager->set($key, $default); + $manager->add($key, $default); } }); } diff --git a/src/Settings/DefaultSettingsManager.php b/src/Settings/DefaultSettingsManager.php index 255d27c4e7..58501dcda5 100644 --- a/src/Settings/DefaultSettingsManager.php +++ b/src/Settings/DefaultSettingsManager.php @@ -20,8 +20,13 @@ public function get($key, $default = null) return Arr::get($this->defaults, $key, $default); } - public function set($key, $value) + public function add($key, $value) { - $this->defaults[$key] = $value; + $this->defaults[$key] = $this->defaults[$key] ?? $value; + } + + public function all(): array + { + return $this->defaults; } } From 7ecddad4a87a6ce4c085678c6499f88619094abc Mon Sep 17 00:00:00 2001 From: SychO9 Date: Wed, 27 Oct 2021 13:41:50 +0100 Subject: [PATCH 08/18] Rename container binding --- src/Settings/SettingsServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Settings/SettingsServiceProvider.php b/src/Settings/SettingsServiceProvider.php index 11cebe284a..ccddbf2dbe 100644 --- a/src/Settings/SettingsServiceProvider.php +++ b/src/Settings/SettingsServiceProvider.php @@ -22,7 +22,7 @@ public function register() { $this->container->singleton(DefaultSettingsManager::class); - $this->container->alias(DefaultSettingsManager::class, 'flarum.default_settings'); + $this->container->alias(DefaultSettingsManager::class, 'flarum.settings.default'); $this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) { return new MemoryCacheSettingsRepository( From f119eb7c3806d56020e820e60232ce87266d536d Mon Sep 17 00:00:00 2001 From: SychO9 Date: Wed, 27 Oct 2021 14:04:57 +0100 Subject: [PATCH 09/18] Make it a repository --- src/Extend/Settings.php | 6 +++--- ...ingsManager.php => DefaultSettingsRepository.php} | 9 +++++++-- src/Settings/MemoryCacheSettingsRepository.php | 2 +- src/Settings/SettingsServiceProvider.php | 6 +++--- .../Settings/MemoryCacheSettingsRepositoryTest.php | 12 ++++++++---- 5 files changed, 22 insertions(+), 13 deletions(-) rename src/Settings/{DefaultSettingsManager.php => DefaultSettingsRepository.php} (69%) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index 9b20f7c6dc..b69e70ece6 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -13,7 +13,7 @@ use Flarum\Api\Serializer\ForumSerializer; use Flarum\Extension\Extension; use Flarum\Foundation\ContainerUtil; -use Flarum\Settings\DefaultSettingsManager; +use Flarum\Settings\DefaultSettingsRepository; use Flarum\Settings\SettingsRepositoryInterface; use Illuminate\Contracts\Container\Container; @@ -60,9 +60,9 @@ public function default(string $key, $value): self public function extend(Container $container, Extension $extension = null) { if (! empty($this->defaults)) { - $container->extend(DefaultSettingsManager::class, function (DefaultSettingsManager $manager) { + $container->extend(DefaultSettingsRepository::class, function (DefaultSettingsRepository $defaultSettings) { foreach ($this->defaults as $key => $default) { - $manager->add($key, $default); + $defaultSettings->set($key, $default); } }); } diff --git a/src/Settings/DefaultSettingsManager.php b/src/Settings/DefaultSettingsRepository.php similarity index 69% rename from src/Settings/DefaultSettingsManager.php rename to src/Settings/DefaultSettingsRepository.php index 58501dcda5..dda6131bad 100644 --- a/src/Settings/DefaultSettingsManager.php +++ b/src/Settings/DefaultSettingsRepository.php @@ -11,7 +11,7 @@ use Illuminate\Support\Arr; -class DefaultSettingsManager +class DefaultSettingsRepository implements SettingsRepositoryInterface { protected $defaults = []; @@ -20,11 +20,16 @@ public function get($key, $default = null) return Arr::get($this->defaults, $key, $default); } - public function add($key, $value) + public function set($key, $value) { $this->defaults[$key] = $this->defaults[$key] ?? $value; } + public function delete($keyLike) + { + throw new \RuntimeException('Cannot delete immutable default setting.'); + } + public function all(): array { return $this->defaults; diff --git a/src/Settings/MemoryCacheSettingsRepository.php b/src/Settings/MemoryCacheSettingsRepository.php index f961304be8..35fd5289b0 100644 --- a/src/Settings/MemoryCacheSettingsRepository.php +++ b/src/Settings/MemoryCacheSettingsRepository.php @@ -21,7 +21,7 @@ class MemoryCacheSettingsRepository implements SettingsRepositoryInterface protected $defaultSettingsManager; - public function __construct(SettingsRepositoryInterface $inner, DefaultSettingsManager $defaultSettingsManager) + public function __construct(SettingsRepositoryInterface $inner, DefaultSettingsRepository $defaultSettingsManager) { $this->inner = $inner; $this->defaultSettingsManager = $defaultSettingsManager; diff --git a/src/Settings/SettingsServiceProvider.php b/src/Settings/SettingsServiceProvider.php index ccddbf2dbe..09f4e7d23f 100644 --- a/src/Settings/SettingsServiceProvider.php +++ b/src/Settings/SettingsServiceProvider.php @@ -20,16 +20,16 @@ class SettingsServiceProvider extends AbstractServiceProvider */ public function register() { - $this->container->singleton(DefaultSettingsManager::class); + $this->container->singleton(DefaultSettingsRepository::class); - $this->container->alias(DefaultSettingsManager::class, 'flarum.settings.default'); + $this->container->alias(DefaultSettingsRepository::class, 'flarum.settings.default'); $this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) { return new MemoryCacheSettingsRepository( new DatabaseSettingsRepository( $container->make(ConnectionInterface::class) ), - $this->container->make(DefaultSettingsManager::class) + $this->container->make(DefaultSettingsRepository::class) ); }); diff --git a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php index 2d6725e515..e23219ea71 100644 --- a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php +++ b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php @@ -9,7 +9,7 @@ namespace Flarum\Tests\unit\Settings; -use Flarum\Settings\DefaultSettingsManager; +use Flarum\Settings\DefaultSettingsRepository; use Flarum\Settings\MemoryCacheSettingsRepository; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Testing\unit\TestCase; @@ -27,13 +27,14 @@ class MemoryCacheSettingsRepositoryTest extends TestCase protected function setUp(): void { $this->baseRepository = m::mock(SettingsRepositoryInterface::class); - $this->defaultSettingsManager = m::mock(DefaultSettingsManager::class); + $this->defaultSettingsManager = m::mock(DefaultSettingsRepository::class); $this->repository = new MemoryCacheSettingsRepository($this->baseRepository, $this->defaultSettingsManager); } public function test_it_should_return_all_settings_when_not_cached() { $this->baseRepository->shouldReceive('all')->once()->andReturn(['key' => 'value']); + $this->defaultSettingsManager->shouldReceive('all')->twice(); $this->assertEquals(['key' => 'value'], $this->repository->all()); $this->assertEquals(['key' => 'value'], $this->repository->all()); // Assert twice to ensure we hit the cache @@ -42,7 +43,8 @@ public function test_it_should_return_all_settings_when_not_cached() public function test_it_should_retrieve_a_specific_value() { $this->baseRepository->shouldReceive('all')->once()->andReturn(['key1' => 'value1', 'key2' => 'value2']); - $this->defaultSettingsManager->shouldReceive('get')->twice(); + $this->defaultSettingsManager->shouldReceive('all')->times(3); + $this->defaultSettingsManager->shouldReceive('get')->never(); $this->assertEquals('value2', $this->repository->get('key2')); $this->assertEquals('value2', $this->repository->get('key2')); // Assert twice to ensure we hit the cache @@ -51,7 +53,9 @@ public function test_it_should_retrieve_a_specific_value() public function test_it_should_set_a_key_value_pair() { $this->baseRepository->shouldReceive('set')->once(); - $this->defaultSettingsManager->shouldReceive('get')->once(); + $this->defaultSettingsManager->shouldReceive('all')->once(); + $this->defaultSettingsManager->shouldReceive('get')->never(); + $this->defaultSettingsManager->shouldReceive('set')->never(); $this->repository->set('key', 'value'); From a7305a054659d8157f7cd1f60aa34c467e7f0643 Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Wed, 27 Oct 2021 14:05:42 +0100 Subject: [PATCH 10/18] Update src/Extend/Settings.php Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> --- src/Extend/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index b69e70ece6..7b66b585b1 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -48,7 +48,7 @@ public function serializeToForum(string $attributeName, string $key, $callback = /** * Set a default value for a setting. - * Recommended instead of inserting the default value with a migration. + * Replaces inserting the default value with a migration. */ public function default(string $key, $value): self { From af746f4990ed118476c159ca187ad7195c8c7858 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Thu, 28 Oct 2021 09:53:10 +0100 Subject: [PATCH 11/18] Throw exception when trying to modify default setting --- src/Settings/DefaultSettingsRepository.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Settings/DefaultSettingsRepository.php b/src/Settings/DefaultSettingsRepository.php index dda6131bad..e762f6c5f3 100644 --- a/src/Settings/DefaultSettingsRepository.php +++ b/src/Settings/DefaultSettingsRepository.php @@ -10,6 +10,7 @@ namespace Flarum\Settings; use Illuminate\Support\Arr; +use RuntimeException; class DefaultSettingsRepository implements SettingsRepositoryInterface { @@ -22,12 +23,16 @@ public function get($key, $default = null) public function set($key, $value) { - $this->defaults[$key] = $this->defaults[$key] ?? $value; + if (isset($this->defaults[$key])) { + throw new RuntimeException("Cannot modify immutable default setting $key."); + } + + $this->defaults[$key] = $value; } public function delete($keyLike) { - throw new \RuntimeException('Cannot delete immutable default setting.'); + throw new RuntimeException("Cannot delete immutable default setting $keyLike."); } public function all(): array From 68111264388d82840ff5594895e48276d7a7480f Mon Sep 17 00:00:00 2001 From: SychO9 Date: Thu, 28 Oct 2021 09:58:14 +0100 Subject: [PATCH 12/18] Deprecate `SettingsRepositoryInterface@get` default value --- src/Settings/SettingsRepositoryInterface.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Settings/SettingsRepositoryInterface.php b/src/Settings/SettingsRepositoryInterface.php index 8bb3d7ab2b..b96a95cdeb 100644 --- a/src/Settings/SettingsRepositoryInterface.php +++ b/src/Settings/SettingsRepositoryInterface.php @@ -13,6 +13,13 @@ interface SettingsRepositoryInterface { public function all(): array; + /** + * @todo remove $default in 2.0 + * + * @param $key + * @param mixed $default: Deprecated + * @return mixed + */ public function get($key, $default = null); public function set($key, $value); From 31f8fd6021604b1ce3008ca214b2d38b6c48c8f3 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Thu, 28 Oct 2021 11:53:24 +0100 Subject: [PATCH 13/18] Wrap DefaultSettingsRepository around the rest. --- src/Extend/Settings.php | 2 +- src/Settings/DefaultSettingsRepository.php | 23 ++++++++++++++----- .../MemoryCacheSettingsRepository.php | 18 ++++----------- src/Settings/SettingsServiceProvider.php | 14 +++++++---- .../MemoryCacheSettingsRepositoryTest.php | 11 +-------- 5 files changed, 32 insertions(+), 36 deletions(-) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index 7b66b585b1..205fec7c44 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -62,7 +62,7 @@ public function extend(Container $container, Extension $extension = null) if (! empty($this->defaults)) { $container->extend(DefaultSettingsRepository::class, function (DefaultSettingsRepository $defaultSettings) { foreach ($this->defaults as $key => $default) { - $defaultSettings->set($key, $default); + $defaultSettings->default($key, $default); } }); } diff --git a/src/Settings/DefaultSettingsRepository.php b/src/Settings/DefaultSettingsRepository.php index e762f6c5f3..8aa778009d 100644 --- a/src/Settings/DefaultSettingsRepository.php +++ b/src/Settings/DefaultSettingsRepository.php @@ -9,19 +9,20 @@ namespace Flarum\Settings; -use Illuminate\Support\Arr; use RuntimeException; class DefaultSettingsRepository implements SettingsRepositoryInterface { protected $defaults = []; - public function get($key, $default = null) + private $inner; + + public function setInner(SettingsRepositoryInterface $inner): void { - return Arr::get($this->defaults, $key, $default); + $this->inner = $inner; } - public function set($key, $value) + public function default(string $key, $value): void { if (isset($this->defaults[$key])) { throw new RuntimeException("Cannot modify immutable default setting $key."); @@ -30,13 +31,23 @@ public function set($key, $value) $this->defaults[$key] = $value; } + public function get($key, $default = null) + { + return $this->inner->get($key, $this->defaults[$key] ?? $default); + } + + public function set($key, $value) + { + $this->inner->set($key, $value); + } + public function delete($keyLike) { - throw new RuntimeException("Cannot delete immutable default setting $keyLike."); + $this->inner->delete($keyLike); } public function all(): array { - return $this->defaults; + return array_merge($this->defaults, $this->inner->all()); } } diff --git a/src/Settings/MemoryCacheSettingsRepository.php b/src/Settings/MemoryCacheSettingsRepository.php index 35fd5289b0..1328e282e3 100644 --- a/src/Settings/MemoryCacheSettingsRepository.php +++ b/src/Settings/MemoryCacheSettingsRepository.php @@ -19,12 +19,9 @@ class MemoryCacheSettingsRepository implements SettingsRepositoryInterface protected $cache = []; - protected $defaultSettingsManager; - - public function __construct(SettingsRepositoryInterface $inner, DefaultSettingsRepository $defaultSettingsManager) + public function __construct(SettingsRepositoryInterface $inner) { $this->inner = $inner; - $this->defaultSettingsManager = $defaultSettingsManager; } public function all(): array @@ -34,15 +31,13 @@ public function all(): array $this->isCached = true; } - return $this->getCache(); + return $this->cache; } public function get($key, $default = null) { - $cache = $this->getCache(); - - if (array_key_exists($key, $cache)) { - return $cache[$key]; + if (array_key_exists($key, $this->cache)) { + return $this->cache[$key]; } elseif (! $this->isCached) { return Arr::get($this->all(), $key, $default); } @@ -63,9 +58,4 @@ public function delete($key) $this->inner->delete($key); } - - protected function getCache(): array - { - return array_merge($this->defaultSettingsManager->all(), $this->cache); - } } diff --git a/src/Settings/SettingsServiceProvider.php b/src/Settings/SettingsServiceProvider.php index 09f4e7d23f..9dd8a992a9 100644 --- a/src/Settings/SettingsServiceProvider.php +++ b/src/Settings/SettingsServiceProvider.php @@ -25,12 +25,16 @@ public function register() $this->container->alias(DefaultSettingsRepository::class, 'flarum.settings.default'); $this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) { - return new MemoryCacheSettingsRepository( - new DatabaseSettingsRepository( - $container->make(ConnectionInterface::class) - ), - $this->container->make(DefaultSettingsRepository::class) + $defaults = $container->make(DefaultSettingsRepository::class); + $defaults->setInner( + new MemoryCacheSettingsRepository( + new DatabaseSettingsRepository( + $container->make(ConnectionInterface::class) + ) + ) ); + + return $defaults; }); $this->container->alias(SettingsRepositoryInterface::class, 'flarum.settings'); diff --git a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php index e23219ea71..72d855b403 100644 --- a/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php +++ b/tests/unit/Settings/MemoryCacheSettingsRepositoryTest.php @@ -9,7 +9,6 @@ namespace Flarum\Tests\unit\Settings; -use Flarum\Settings\DefaultSettingsRepository; use Flarum\Settings\MemoryCacheSettingsRepository; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Testing\unit\TestCase; @@ -18,7 +17,6 @@ class MemoryCacheSettingsRepositoryTest extends TestCase { private $baseRepository; - private $defaultSettingsManager; private $repository; /** @@ -27,14 +25,12 @@ class MemoryCacheSettingsRepositoryTest extends TestCase protected function setUp(): void { $this->baseRepository = m::mock(SettingsRepositoryInterface::class); - $this->defaultSettingsManager = m::mock(DefaultSettingsRepository::class); - $this->repository = new MemoryCacheSettingsRepository($this->baseRepository, $this->defaultSettingsManager); + $this->repository = new MemoryCacheSettingsRepository($this->baseRepository); } public function test_it_should_return_all_settings_when_not_cached() { $this->baseRepository->shouldReceive('all')->once()->andReturn(['key' => 'value']); - $this->defaultSettingsManager->shouldReceive('all')->twice(); $this->assertEquals(['key' => 'value'], $this->repository->all()); $this->assertEquals(['key' => 'value'], $this->repository->all()); // Assert twice to ensure we hit the cache @@ -43,8 +39,6 @@ public function test_it_should_return_all_settings_when_not_cached() public function test_it_should_retrieve_a_specific_value() { $this->baseRepository->shouldReceive('all')->once()->andReturn(['key1' => 'value1', 'key2' => 'value2']); - $this->defaultSettingsManager->shouldReceive('all')->times(3); - $this->defaultSettingsManager->shouldReceive('get')->never(); $this->assertEquals('value2', $this->repository->get('key2')); $this->assertEquals('value2', $this->repository->get('key2')); // Assert twice to ensure we hit the cache @@ -53,9 +47,6 @@ public function test_it_should_retrieve_a_specific_value() public function test_it_should_set_a_key_value_pair() { $this->baseRepository->shouldReceive('set')->once(); - $this->defaultSettingsManager->shouldReceive('all')->once(); - $this->defaultSettingsManager->shouldReceive('get')->never(); - $this->defaultSettingsManager->shouldReceive('set')->never(); $this->repository->set('key', 'value'); From 60bcaad4d76914c0c3ceb8711279f33a9314b9a2 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Thu, 28 Oct 2021 12:01:41 +0100 Subject: [PATCH 14/18] Improve extender phpdoc --- src/Extend/Settings.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index 205fec7c44..da77c63a96 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -49,6 +49,10 @@ public function serializeToForum(string $attributeName, string $key, $callback = /** * Set a default value for a setting. * Replaces inserting the default value with a migration. + * + * @param string $key: The setting key, must be unique. Namespace it with the extension ID (example: 'my-extension-id.setting_key'). + * @param mixed $value: The setting value. + * @return self */ public function default(string $key, $value): self { From c7e03fb8a7608bf446f5f0a5f7e17c9288ef7176 Mon Sep 17 00:00:00 2001 From: SychO9 Date: Sun, 31 Oct 2021 20:24:07 +0100 Subject: [PATCH 15/18] test: Null setting values should not be treated as unset and should be returned --- tests/integration/extenders/SettingsTest.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/integration/extenders/SettingsTest.php b/tests/integration/extenders/SettingsTest.php index 7be88c1a0b..454fd370f6 100644 --- a/tests/integration/extenders/SettingsTest.php +++ b/tests/integration/extenders/SettingsTest.php @@ -200,6 +200,26 @@ public function custom_setting_default_falls_back_to_parameter() $this->assertEquals('defaultParameterValue', $value); } + + /** + * @test + */ + public function null_custom_setting_returns_null() + { + $this->setting('custom-prefix.custom_null_setting', null); + + $this->extend( + (new Extend\Settings()) + ->default('custom-prefix.custom_null_setting', 'extenderDefault') + ); + + $value = $this->app() + ->getContainer() + ->make('flarum.settings') + ->get('custom-prefix.custom_null_setting'); + + $this->assertEquals(null, $value); + } } class CustomInvokableClass From 8f859f31f0851ab0ab2b340747c7b66f9372a43f Mon Sep 17 00:00:00 2001 From: SychO9 Date: Sun, 31 Oct 2021 20:24:18 +0100 Subject: [PATCH 16/18] chore: Add comment --- src/Settings/DefaultSettingsRepository.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Settings/DefaultSettingsRepository.php b/src/Settings/DefaultSettingsRepository.php index 8aa778009d..b69b7577f7 100644 --- a/src/Settings/DefaultSettingsRepository.php +++ b/src/Settings/DefaultSettingsRepository.php @@ -33,6 +33,8 @@ public function default(string $key, $value): void public function get($key, $default = null) { + // Global default overrules local default because local default is deprecated, + // and will be removed in 2.0 return $this->inner->get($key, $this->defaults[$key] ?? $default); } From 5fc9e0d596229d5dc856b09f34a905882770eb5d Mon Sep 17 00:00:00 2001 From: SychO9 Date: Sun, 31 Oct 2021 20:41:09 +0100 Subject: [PATCH 17/18] chore: store defaults in a collection --- src/Extend/Settings.php | 11 ++++++++--- src/Settings/DefaultSettingsRepository.php | 20 ++++++-------------- src/Settings/SettingsServiceProvider.php | 15 +++++++-------- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index da77c63a96..41790d6276 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -16,6 +16,7 @@ use Flarum\Settings\DefaultSettingsRepository; use Flarum\Settings\SettingsRepositoryInterface; use Illuminate\Contracts\Container\Container; +use Illuminate\Support\Collection; class Settings implements ExtenderInterface { @@ -64,9 +65,13 @@ public function default(string $key, $value): self public function extend(Container $container, Extension $extension = null) { if (! empty($this->defaults)) { - $container->extend(DefaultSettingsRepository::class, function (DefaultSettingsRepository $defaultSettings) { - foreach ($this->defaults as $key => $default) { - $defaultSettings->default($key, $default); + $container->extend('flarum.settings.default', function (Collection $defaults) { + foreach ($this->defaults as $key => $value) { + if ($defaults->has($key)) { + throw new \RuntimeException("Cannot modify immutable default setting $key."); + } + + $defaults->put($key, $value); } }); } diff --git a/src/Settings/DefaultSettingsRepository.php b/src/Settings/DefaultSettingsRepository.php index b69b7577f7..ad5300cf01 100644 --- a/src/Settings/DefaultSettingsRepository.php +++ b/src/Settings/DefaultSettingsRepository.php @@ -9,33 +9,25 @@ namespace Flarum\Settings; -use RuntimeException; +use Illuminate\Support\Collection; class DefaultSettingsRepository implements SettingsRepositoryInterface { - protected $defaults = []; + protected $defaults; private $inner; - public function setInner(SettingsRepositoryInterface $inner): void + public function __construct(SettingsRepositoryInterface $inner, Collection $defaults) { $this->inner = $inner; - } - - public function default(string $key, $value): void - { - if (isset($this->defaults[$key])) { - throw new RuntimeException("Cannot modify immutable default setting $key."); - } - - $this->defaults[$key] = $value; + $this->defaults = $defaults; } public function get($key, $default = null) { // Global default overrules local default because local default is deprecated, // and will be removed in 2.0 - return $this->inner->get($key, $this->defaults[$key] ?? $default); + return $this->inner->get($key, $this->defaults->get($key, $default)); } public function set($key, $value) @@ -50,6 +42,6 @@ public function delete($keyLike) public function all(): array { - return array_merge($this->defaults, $this->inner->all()); + return array_merge($this->defaults->toArray(), $this->inner->all()); } } diff --git a/src/Settings/SettingsServiceProvider.php b/src/Settings/SettingsServiceProvider.php index 9dd8a992a9..bb2090b037 100644 --- a/src/Settings/SettingsServiceProvider.php +++ b/src/Settings/SettingsServiceProvider.php @@ -12,6 +12,7 @@ use Flarum\Foundation\AbstractServiceProvider; use Illuminate\Contracts\Container\Container; use Illuminate\Database\ConnectionInterface; +use Illuminate\Support\Collection; class SettingsServiceProvider extends AbstractServiceProvider { @@ -20,21 +21,19 @@ class SettingsServiceProvider extends AbstractServiceProvider */ public function register() { - $this->container->singleton(DefaultSettingsRepository::class); - - $this->container->alias(DefaultSettingsRepository::class, 'flarum.settings.default'); + $this->container->singleton('flarum.settings.default', function () { + return new Collection(); + }); $this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) { - $defaults = $container->make(DefaultSettingsRepository::class); - $defaults->setInner( + return new DefaultSettingsRepository( new MemoryCacheSettingsRepository( new DatabaseSettingsRepository( $container->make(ConnectionInterface::class) ) - ) + ), + $container->make('flarum.settings.default') ); - - return $defaults; }); $this->container->alias(SettingsRepositoryInterface::class, 'flarum.settings'); From f1c5c9c11f7dee067d41901d9ac02a0f431cac8b Mon Sep 17 00:00:00 2001 From: luceos Date: Sun, 31 Oct 2021 19:42:26 +0000 Subject: [PATCH 18/18] Apply fixes from StyleCI [ci skip] [skip ci] --- src/Extend/Settings.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Extend/Settings.php b/src/Extend/Settings.php index 41790d6276..24e1689a1a 100644 --- a/src/Extend/Settings.php +++ b/src/Extend/Settings.php @@ -13,7 +13,6 @@ use Flarum\Api\Serializer\ForumSerializer; use Flarum\Extension\Extension; use Flarum\Foundation\ContainerUtil; -use Flarum\Settings\DefaultSettingsRepository; use Flarum\Settings\SettingsRepositoryInterface; use Illuminate\Contracts\Container\Container; use Illuminate\Support\Collection;