mirror of
https://github.com/flarum/framework.git
synced 2025-01-27 12:52:00 +08:00
feat: Default Settings Extender (#3127)
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
This commit is contained in:
parent
fa82773cc8
commit
ba493a90c1
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
namespace Flarum\Database;
|
namespace Flarum\Database;
|
||||||
|
|
||||||
|
use Flarum\Extend\Settings;
|
||||||
use Flarum\Settings\DatabaseSettingsRepository;
|
use Flarum\Settings\DatabaseSettingsRepository;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Database\Schema\Builder;
|
use Illuminate\Database\Schema\Builder;
|
||||||
|
@ -120,6 +121,9 @@ abstract class Migration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add default values for config values.
|
* 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)
|
public static function addSettings(array $defaults)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,10 +15,12 @@ use Flarum\Extension\Extension;
|
||||||
use Flarum\Foundation\ContainerUtil;
|
use Flarum\Foundation\ContainerUtil;
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class Settings implements ExtenderInterface
|
class Settings implements ExtenderInterface
|
||||||
{
|
{
|
||||||
private $settings = [];
|
private $settings = [];
|
||||||
|
private $defaults = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize a setting value to the ForumSerializer attributes.
|
* Serialize a setting value to the ForumSerializer attributes.
|
||||||
|
@ -33,7 +35,8 @@ class Settings implements ExtenderInterface
|
||||||
* The callable should return:
|
* The callable should return:
|
||||||
* - mixed $value: The modified value.
|
* - 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
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function serializeToForum(string $attributeName, string $key, $callback = null, $default = null): self
|
public function serializeToForum(string $attributeName, string $key, $callback = null, $default = null): self
|
||||||
|
@ -43,8 +46,35 @@ class Settings implements ExtenderInterface
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
$this->defaults[$key] = $value;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function extend(Container $container, Extension $extension = null)
|
public function extend(Container $container, Extension $extension = null)
|
||||||
{
|
{
|
||||||
|
if (! empty($this->defaults)) {
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (! empty($this->settings)) {
|
if (! empty($this->settings)) {
|
||||||
AbstractSerializer::addAttributeMutator(
|
AbstractSerializer::addAttributeMutator(
|
||||||
ForumSerializer::class,
|
ForumSerializer::class,
|
||||||
|
|
47
framework/core/src/Settings/DefaultSettingsRepository.php
Normal file
47
framework/core/src/Settings/DefaultSettingsRepository.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* For detailed copyright and license information, please view the
|
||||||
|
* LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Settings;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class DefaultSettingsRepository implements SettingsRepositoryInterface
|
||||||
|
{
|
||||||
|
protected $defaults;
|
||||||
|
|
||||||
|
private $inner;
|
||||||
|
|
||||||
|
public function __construct(SettingsRepositoryInterface $inner, Collection $defaults)
|
||||||
|
{
|
||||||
|
$this->inner = $inner;
|
||||||
|
$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->get($key, $default));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($key, $value)
|
||||||
|
{
|
||||||
|
$this->inner->set($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($keyLike)
|
||||||
|
{
|
||||||
|
$this->inner->delete($keyLike);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function all(): array
|
||||||
|
{
|
||||||
|
return array_merge($this->defaults->toArray(), $this->inner->all());
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,13 @@ interface SettingsRepositoryInterface
|
||||||
{
|
{
|
||||||
public function all(): array;
|
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 get($key, $default = null);
|
||||||
|
|
||||||
public function set($key, $value);
|
public function set($key, $value);
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Flarum\Settings;
|
||||||
use Flarum\Foundation\AbstractServiceProvider;
|
use Flarum\Foundation\AbstractServiceProvider;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class SettingsServiceProvider extends AbstractServiceProvider
|
class SettingsServiceProvider extends AbstractServiceProvider
|
||||||
{
|
{
|
||||||
|
@ -20,11 +21,18 @@ class SettingsServiceProvider extends AbstractServiceProvider
|
||||||
*/
|
*/
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
|
$this->container->singleton('flarum.settings.default', function () {
|
||||||
|
return new Collection();
|
||||||
|
});
|
||||||
|
|
||||||
$this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) {
|
$this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) {
|
||||||
return new MemoryCacheSettingsRepository(
|
return new DefaultSettingsRepository(
|
||||||
new DatabaseSettingsRepository(
|
new MemoryCacheSettingsRepository(
|
||||||
$container->make(ConnectionInterface::class)
|
new DatabaseSettingsRepository(
|
||||||
)
|
$container->make(ConnectionInterface::class)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
$container->make('flarum.settings.default')
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,63 @@ class SettingsTest extends TestCase
|
||||||
$this->assertArrayHasKey('customPrefix.noCustomSetting', $payload['data']['attributes']);
|
$this->assertArrayHasKey('customPrefix.noCustomSetting', $payload['data']['attributes']);
|
||||||
$this->assertEquals('customDefaultModified2', $payload['data']['attributes']['customPrefix.noCustomSetting']);
|
$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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
class CustomInvokableClass
|
||||||
|
|
Loading…
Reference in New Issue
Block a user