feat: allow resetting settings to default (#3935)

Co-authored-by: Sami Mazouz <sychocouldy@gmail.com>
This commit is contained in:
Tristian Kelly 2024-10-21 10:17:24 -04:00 committed by GitHub
parent ee60a7f8ca
commit 084ae6fceb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 83 additions and 1 deletions

View File

@ -13,6 +13,7 @@ use Flarum\Http\RequestUtil;
use Flarum\Settings\Event; use Flarum\Settings\Event;
use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Support\Arr;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
@ -20,6 +21,8 @@ use Psr\Http\Server\RequestHandlerInterface;
class SetSettingsController implements RequestHandlerInterface class SetSettingsController implements RequestHandlerInterface
{ {
public static array $resetWhen = [];
public function __construct( public function __construct(
protected SettingsRepositoryInterface $settings, protected SettingsRepositoryInterface $settings,
protected Dispatcher $dispatcher protected Dispatcher $dispatcher
@ -37,7 +40,11 @@ class SetSettingsController implements RequestHandlerInterface
foreach ($settings as $k => $v) { foreach ($settings as $k => $v) {
$this->dispatcher->dispatch(new Event\Serializing($k, $v)); $this->dispatcher->dispatch(new Event\Serializing($k, $v));
$this->settings->set($k, $v); if (! is_null($resetWhen = Arr::get(static::$resetWhen, $k)) && $resetWhen($v)) {
$this->settings->delete($k);
} else {
$this->settings->set($k, $v);
}
} }
$this->dispatcher->dispatch(new Event\Saved($settings)); $this->dispatcher->dispatch(new Event\Saved($settings));

View File

@ -10,12 +10,14 @@
namespace Flarum\Extend; namespace Flarum\Extend;
use Flarum\Admin\WhenSavingSettings; use Flarum\Admin\WhenSavingSettings;
use Flarum\Api\Controller\SetSettingsController;
use Flarum\Api\Resource\ForumResource; use Flarum\Api\Resource\ForumResource;
use Flarum\Api\Schema\Attribute; use Flarum\Api\Schema\Attribute;
use Flarum\Extension\Extension; 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\Arr;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
class Settings implements ExtenderInterface class Settings implements ExtenderInterface
@ -24,6 +26,7 @@ class Settings implements ExtenderInterface
private array $defaults = []; private array $defaults = [];
private array $lessConfigs = []; private array $lessConfigs = [];
private array $resetJsCacheFor = []; private array $resetJsCacheFor = [];
private array $resetWhen = [];
/** /**
* Serialize a setting value to the ForumSerializer attributes. * Serialize a setting value to the ForumSerializer attributes.
@ -62,6 +65,20 @@ class Settings implements ExtenderInterface
return $this; return $this;
} }
/**
* Delete a custom setting value when the callback returns true.
* This allows the setting to be reset to its default value.
*
* @param string $key: The key of the setting.
* @param (callable(mixed $value): bool) $callback: The callback to determine if the setting should be reset.
*/
public function resetWhen(string $key, callable|string $callback): self
{
$this->resetWhen[$key] = $callback;
return $this;
}
/** /**
* Register a setting as a LESS configuration variable. * Register a setting as a LESS configuration variable.
* *
@ -113,6 +130,16 @@ class Settings implements ExtenderInterface
}); });
} }
if (! empty($this->resetWhen)) {
foreach ($this->resetWhen as $key => $callback) {
Arr::set(
SetSettingsController::$resetWhen,
$key,
ContainerUtil::wrapCallback($callback, $container)
);
}
}
if (! empty($this->settings)) { if (! empty($this->settings)) {
(new ApiResource(ForumResource::class)) (new ApiResource(ForumResource::class))
->fields(function () use ($container) { ->fields(function () use ($container) {

View File

@ -187,6 +187,54 @@ class SettingsTest extends TestCase
$this->assertEquals(null, $value); $this->assertEquals(null, $value);
} }
#[Test]
public function resetting_setting_returns_default_value()
{
$this->extend(
(new Extend\Settings())
->default('custom-prefix.filter_this_setting', 'extenderDefault')
->resetWhen('custom-prefix.filter_this_setting', function (mixed $value): bool {
return $value === '';
})
);
$this->send(
$this->request('POST', '/api/settings', [
'authenticatedAs' => 1,
'json' => [
'custom-prefix.filter_this_setting' => ''
]
])
);
$value = $this->app()
->getContainer()
->make('flarum.settings')
->get('custom-prefix.filter_this_setting');
$this->assertEquals('extenderDefault', $value);
}
#[Test]
public function not_resetting_setting_returns_value()
{
$this->send(
$this->request('POST', '/api/settings', [
'authenticatedAs' => 1,
'json' => [
'custom-prefix.filter_this_setting' => ''
]
])
);
$value = $this->app()
->getContainer()
->make('flarum.settings')
->get('custom-prefix.filter_this_setting');
$this->assertEquals('', $value);
}
#[Test] #[Test]
public function custom_less_var_does_not_work_by_default() public function custom_less_var_does_not_work_by_default()
{ {