mirror of
https://github.com/flarum/framework.git
synced 2025-01-26 14:51: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;
|
||||
|
||||
use Flarum\Extend\Settings;
|
||||
use Flarum\Settings\DatabaseSettingsRepository;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Schema\Builder;
|
||||
|
@ -120,6 +121,9 @@ abstract class Migration
|
|||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
|
|
|
@ -15,10 +15,12 @@ use Flarum\Extension\Extension;
|
|||
use Flarum\Foundation\ContainerUtil;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Settings implements ExtenderInterface
|
||||
{
|
||||
private $settings = [];
|
||||
private $defaults = [];
|
||||
|
||||
/**
|
||||
* Serialize a setting value to the ForumSerializer attributes.
|
||||
|
@ -33,7 +35,8 @@ 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
|
||||
|
@ -43,8 +46,35 @@ class Settings implements ExtenderInterface
|
|||
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)
|
||||
{
|
||||
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)) {
|
||||
AbstractSerializer::addAttributeMutator(
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace Flarum\Settings;
|
|||
use Flarum\Foundation\AbstractServiceProvider;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class SettingsServiceProvider extends AbstractServiceProvider
|
||||
{
|
||||
|
@ -20,11 +21,18 @@ class SettingsServiceProvider extends AbstractServiceProvider
|
|||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->container->singleton('flarum.settings.default', function () {
|
||||
return new Collection();
|
||||
});
|
||||
|
||||
$this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) {
|
||||
return new MemoryCacheSettingsRepository(
|
||||
new DatabaseSettingsRepository(
|
||||
$container->make(ConnectionInterface::class)
|
||||
)
|
||||
return new DefaultSettingsRepository(
|
||||
new MemoryCacheSettingsRepository(
|
||||
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->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
|
||||
|
|
Loading…
Reference in New Issue
Block a user