mirror of
https://github.com/flarum/framework.git
synced 2025-01-26 14:51:00 +08:00
feat: Allow registering settings as Less
config vars through Settings Extender (#3011)
Co-authored-by: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com>
This commit is contained in:
parent
62b92ba02e
commit
e8ffdead39
|
@ -21,6 +21,7 @@ class Settings implements ExtenderInterface
|
|||
{
|
||||
private $settings = [];
|
||||
private $defaults = [];
|
||||
private $lessConfigs = [];
|
||||
|
||||
/**
|
||||
* Serialize a setting value to the ForumSerializer attributes.
|
||||
|
@ -61,6 +62,28 @@ class Settings implements ExtenderInterface
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a setting as a LESS configuration variable.
|
||||
*
|
||||
* @param string $configName: The name of the configuration variable, in hyphen case.
|
||||
* @param string $key: The key of the setting.
|
||||
* @param string|callable|null $callback: Optional callback to modify the value.
|
||||
*
|
||||
* The callback can be a closure or an invokable class, and should accept:
|
||||
* - mixed $value: The value of the setting.
|
||||
*
|
||||
* The callable should return:
|
||||
* - mixed $value: The modified value.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function registerLessConfigVar(string $configName, string $key, $callback = null): self
|
||||
{
|
||||
$this->lessConfigs[$configName] = compact('key', 'callback');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function extend(Container $container, Extension $extension = null)
|
||||
{
|
||||
if (! empty($this->defaults)) {
|
||||
|
@ -97,5 +120,19 @@ class Settings implements ExtenderInterface
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (! empty($this->lessConfigs)) {
|
||||
$container->extend('flarum.less.config', function (array $existingConfig, Container $container) {
|
||||
$config = $this->lessConfigs;
|
||||
|
||||
foreach ($config as $var => $data) {
|
||||
if (isset($data['callback'])) {
|
||||
$config[$var]['callback'] = ContainerUtil::wrapCallback($data['callback'], $container);
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($existingConfig, $config);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,7 +163,8 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||
$validator = new ValidateCustomLess(
|
||||
$container->make('flarum.assets.forum'),
|
||||
$container->make('flarum.locales'),
|
||||
$container
|
||||
$container,
|
||||
$container->make('flarum.less.config')
|
||||
);
|
||||
$validator->whenSettingsSaved($event);
|
||||
}
|
||||
|
@ -175,7 +176,8 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||
$validator = new ValidateCustomLess(
|
||||
$container->make('flarum.assets.forum'),
|
||||
$container->make('flarum.locales'),
|
||||
$container
|
||||
$container,
|
||||
$container->make('flarum.less.config')
|
||||
);
|
||||
$validator->whenSettingsSaving($event);
|
||||
}
|
||||
|
|
|
@ -43,20 +43,21 @@ class ValidateCustomLess
|
|||
protected $container;
|
||||
|
||||
/**
|
||||
* @param Assets $assets
|
||||
* @param LocaleManager $locales
|
||||
* @param Container $container
|
||||
* @var array
|
||||
*/
|
||||
public function __construct(Assets $assets, LocaleManager $locales, Container $container)
|
||||
protected $customLessSettings;
|
||||
|
||||
public function __construct(Assets $assets, LocaleManager $locales, Container $container, array $customLessSettings = [])
|
||||
{
|
||||
$this->assets = $assets;
|
||||
$this->locales = $locales;
|
||||
$this->container = $container;
|
||||
$this->customLessSettings = $customLessSettings;
|
||||
}
|
||||
|
||||
public function whenSettingsSaving(Saving $event)
|
||||
{
|
||||
if (! isset($event->settings['custom_less'])) {
|
||||
if (! isset($event->settings['custom_less']) && ! $this->hasDirtyCustomLessSettings($event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,7 @@ class ValidateCustomLess
|
|||
|
||||
public function whenSettingsSaved(Saved $event)
|
||||
{
|
||||
if (! isset($event->settings['custom_less'])) {
|
||||
if (! isset($event->settings['custom_less']) && ! $this->hasDirtyCustomLessSettings($event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -105,4 +106,24 @@ class ValidateCustomLess
|
|||
$this->assets->makeLocaleCss($locale)->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Saved|Saving $event
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasDirtyCustomLessSettings($event): bool
|
||||
{
|
||||
if (empty($this->customLessSettings)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dirtySettings = array_intersect(
|
||||
array_keys($event->settings),
|
||||
array_map(function ($setting) {
|
||||
return $setting['key'];
|
||||
}, $this->customLessSettings)
|
||||
);
|
||||
|
||||
return ! empty($dirtySettings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,29 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
|||
];
|
||||
}
|
||||
);
|
||||
|
||||
$this->container->singleton('flarum.less.config', function (Container $container) {
|
||||
return [
|
||||
'config-primary-color' => [
|
||||
'key' => 'theme_primary_color',
|
||||
],
|
||||
'config-secondary-color' => [
|
||||
'key' => 'theme_secondary_color',
|
||||
],
|
||||
'config-dark-mode' => [
|
||||
'key' => 'theme_dark_mode',
|
||||
'callback' => function ($value) {
|
||||
return $value ? 'true' : 'false';
|
||||
},
|
||||
],
|
||||
'config-colored-header' => [
|
||||
'key' => 'theme_colored_header',
|
||||
'callback' => function ($value) {
|
||||
return $value ? 'true' : 'false';
|
||||
},
|
||||
],
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,17 +155,18 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
|||
private function addLessVariables(SourceCollector $sources)
|
||||
{
|
||||
$sources->addString(function () {
|
||||
$vars = $this->container->make('flarum.less.config');
|
||||
$settings = $this->container->make(SettingsRepositoryInterface::class);
|
||||
|
||||
$vars = [
|
||||
'config-primary-color' => $settings->get('theme_primary_color', '#000'),
|
||||
'config-secondary-color' => $settings->get('theme_secondary_color', '#000'),
|
||||
'config-dark-mode' => $settings->get('theme_dark_mode') ? 'true' : 'false',
|
||||
'config-colored-header' => $settings->get('theme_colored_header') ? 'true' : 'false'
|
||||
];
|
||||
return array_reduce(array_keys($vars), function ($string, $name) use ($vars, $settings) {
|
||||
$var = $vars[$name];
|
||||
$value = $settings->get($var['key'], $var['default'] ?? null);
|
||||
|
||||
return array_reduce(array_keys($vars), function ($string, $name) use ($vars) {
|
||||
return $string."@$name: {$vars[$name]};";
|
||||
if (isset($var['callback'])) {
|
||||
$value = $var['callback']($value);
|
||||
}
|
||||
|
||||
return $string."@$name: {$value};";
|
||||
}, '');
|
||||
});
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ class RecompileFrontendAssets
|
|||
|
||||
public function whenSettingsSaved(Saved $event)
|
||||
{
|
||||
// @deprecated 'theme_' check, to be removed in 2.0
|
||||
if (preg_grep('/^theme_/i', array_keys($event->settings))) {
|
||||
$this->flushCss();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,10 @@ class SettingsServiceProvider extends AbstractServiceProvider
|
|||
public function register()
|
||||
{
|
||||
$this->container->singleton('flarum.settings.default', function () {
|
||||
return new Collection();
|
||||
return new Collection([
|
||||
'theme_primary_color' => '#4D698E',
|
||||
'theme_secondary_color' => '#4D698E',
|
||||
]);
|
||||
});
|
||||
|
||||
$this->container->singleton(SettingsRepositoryInterface::class, function (Container $container) {
|
||||
|
|
3
framework/core/tests/fixtures/less/config.less
vendored
Normal file
3
framework/core/tests/fixtures/less/config.less
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
body {
|
||||
--custom-config-setting: @custom-config-setting;
|
||||
}
|
|
@ -220,6 +220,61 @@ class SettingsTest extends TestCase
|
|||
|
||||
$this->assertEquals(null, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_less_var_does_not_work_by_default()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Frontend('forum'))
|
||||
->css(__DIR__.'/../../fixtures/less/config.less'),
|
||||
);
|
||||
|
||||
$response = $this->send($this->request('GET', '/'));
|
||||
|
||||
$this->assertEquals(500, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function custom_less_var_works_if_registered()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Frontend('forum'))
|
||||
->css(__DIR__.'/../../fixtures/less/config.less'),
|
||||
(new Extend\Settings())
|
||||
->registerLessConfigVar('custom-config-setting', 'custom-prefix.custom_setting')
|
||||
);
|
||||
|
||||
$response = $this->send($this->request('GET', '/'));
|
||||
|
||||
$cssFilePath = $this->app()->getContainer()->make('filesystem')->disk('flarum-assets')->path('forum.css');
|
||||
$this->assertStringContainsString('--custom-config-setting:customValue', file_get_contents($cssFilePath));
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function cant_save_setting_if_invalid_less_var()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Settings())
|
||||
->registerLessConfigVar('custom-config-setting2', 'custom-prefix.custom_setting2')
|
||||
);
|
||||
|
||||
$response = $this->send($this->request('POST', '/api/settings', [
|
||||
'authenticatedAs' => 1,
|
||||
'json' => [
|
||||
'custom-prefix.custom_setting2' => '@muralf'
|
||||
],
|
||||
]));
|
||||
|
||||
$this->assertEquals(422, $response->getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
class CustomInvokableClass
|
||||
|
|
Loading…
Reference in New Issue
Block a user