Allow admins to remove entries from some config arrays (#1155)

This is done by setting the respective value to null
This commit is contained in:
Tim Neumann 2023-09-24 21:42:44 +02:00 committed by GitHub
parent 3b241529b7
commit c2dd25fc7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 6 deletions

View File

@ -40,7 +40,7 @@ The Engelsystem may be installed manually or by using the provided [docker setup
* Recommended: Directory Listing should be disabled.
* There must be a MySQL database set up with a user who has full rights to that database.
* If necessary, create a `config/config.php` to override values from `config/config.default.php`.
* To edit values from the `footer_items`, `themes`, `locales`, `tshirt_sizes` or `headers` lists, directly modify the `config/config.default.php` file or rename it to `config/config.php`.
* To disable/remove values from the `themes`, `tshirt_sizes`, `headers`, `header_items`, `footer_items`, or `locales` lists, set the value of the entry to `null`.
* To import the database, the `bin/migrate` script has to be run. If you can't execute scripts, you can use the `initial-install.sql` file from the release zip.
* In the browser, login with credentials `admin` : `asdfasdf` and change the password.

View File

@ -30,11 +30,13 @@ return [
// Header links
// Available link placeholders: %lang%
// To disable a header_item in the config.php, you can set its value to null
'header_items' => [
//'Foo' => 'https://foo.bar/batz-%lang%.html',
],
// Footer links
// To disable a footer item in the config.php, you can set its value to null
'footer_items' => [
// URL to the angel faq and job description
'FAQ' => env('FAQ_URL', '/faq'),
@ -131,6 +133,8 @@ return [
// Default theme, 1=style1.css
'theme' => env('THEME', 1),
// Supported themes
// To disable a theme in the config.php, you can set its value to null
'themes' => [
16 => [
'name' => 'Engelsystem cccamp23 (2023)',
@ -331,6 +335,7 @@ return [
&& env('IFSG_ENABLED', false),
// Available locales in /resources/lang/
// To disable a locale in the config.php, you can set its value to null
'locales' => [
'de_DE' => 'Deutsch',
'en_US' => 'English',
@ -339,7 +344,8 @@ return [
// The default locale to use
'default_locale' => env('DEFAULT_LOCALE', 'en_US'),
// Available T-Shirt sizes, set value to null if not available
// Available T-Shirt sizes
// To disable a t-shirt size in the config.php, you can set its value to null
'tshirt_sizes' => [
'S' => 'Small Straight-Cut',
'S-G' => 'Small Fitted-Cut',
@ -388,6 +394,8 @@ return [
// Add additional headers
'add_headers' => (bool) env('ADD_HEADERS', true),
// Predefined headers
// To disable a header in the config.php, you can set its value to null
'headers' => [
'X-Content-Type-Options' => 'nosniff',
'X-Frame-Options' => 'sameorigin',

View File

@ -14,6 +14,10 @@ class ConfigServiceProvider extends ServiceProvider
{
protected array $configFiles = ['app.php', 'config.default.php', 'config.php'];
# remember to update ConfigServiceProviderTest, config.default.php, and README.md
protected array $configVarsToPruneNulls
= ['themes', 'tshirt_sizes', 'headers', 'header_items', 'footer_items', 'locales'];
public function __construct(Application $app, protected ?EventConfig $eventConfig = null)
{
parent::__construct($app);
@ -42,6 +46,12 @@ class ConfigServiceProvider extends ServiceProvider
if (empty($config->get(null))) {
throw new Exception('Configuration not found');
}
foreach ($this->configVarsToPruneNulls as $key) {
$config->set($key, array_filter($config->get($key), function ($v) {
return !is_null($v);
}));
}
}
public function boot(): void

View File

@ -19,6 +19,9 @@ class ConfigServiceProviderTest extends ServiceProviderTest
{
use ArraySubsetAsserts;
private array $configVarsWhereNullIsPruned =
['themes', 'tshirt_sizes', 'headers', 'header_items', 'footer_items', 'locales'];
/**
* @covers \Engelsystem\Config\ConfigServiceProvider::getConfigPath
* @covers \Engelsystem\Config\ConfigServiceProvider::register
@ -29,11 +32,40 @@ class ConfigServiceProviderTest extends ServiceProviderTest
/** @var Config|MockObject $config */
list($app, $config) = $this->getConfiguredApp(__DIR__ . '/../../../config');
$this->setExpects($config, 'set', null, null, $this->exactly(3));
$config->expects($this->exactly(4))
$config
->expects($this->exactly(4 + sizeof($this->configVarsWhereNullIsPruned)))
->method('get')
->with(null)
->willReturnOnConsecutiveCalls([], [], [], ['lor' => 'em']);
->with($this->callback(function (mixed $arg) {
return is_null($arg) || in_array($arg, $this->configVarsWhereNullIsPruned);
}))
->will($this->returnCallback(function (mixed $arg) {
if (in_array($arg, $this->configVarsWhereNullIsPruned)) {
return [$arg . '_foo' => $arg . '_bar', $arg . '_willBePruned' => null];
} elseif (is_null($arg)) {
return ['some' => 'value'];
} else {
throw new Exception('Unexpected arg: ' . $arg);
}
}));
$config
->expects($this->exactly(3 + sizeof($this->configVarsWhereNullIsPruned)))
->method('set')
//With does not support a callback funtion with multiple args ...
//Therefore, we misuse will
->will($this->returnCallback(function (mixed $key, mixed $value = null) {
if (is_array($key)) {
return null;
}
if (in_array($key, $this->configVarsWhereNullIsPruned)) {
if ($value == [$key . '_foo' => $key . '_bar']) {
return null;
}
throw new Exception('Value for key ' . print_r($key, true) .
'is not as expected: ' . print_r($value, true));
}
throw new Exception('Unexpected key: ' . print_r($key, true));
}));
$configFile = __DIR__ . '/../../../config/config.php';
$configExists = file_exists($configFile);