Skip to content

Commit e35b4d5

Browse files
committed
fix(configuration): Use VariableNode on "settings"
"arrayNode" does not support arbitrary configuration keys. Therefore, I switch to variableNode with dynamic check. Fixed #369
1 parent a02a467 commit e35b4d5

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

src/DependencyInjection/Configuration.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Meilisearch\Bundle\Searchable;
88
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
99
use Symfony\Component\Config\Definition\ConfigurationInterface;
10+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1011

1112
final class Configuration implements ConfigurationInterface
1213
{
@@ -62,11 +63,20 @@ public function getConfigTreeBuilder(): TreeBuilder
6263
->info('Property accessor path (like method or property name) used to decide if an entry should be indexed.')
6364
->defaultNull()
6465
->end()
65-
->arrayNode('settings')
66+
->variableNode('settings')
67+
->defaultValue([])
6668
->info('Configure indices settings, see: https://www.meilisearch.com/docs/reference/api/settings')
6769
->beforeNormalization()
6870
->always()
69-
->then(static function (array $value) {
71+
->then(static function (mixed $value) {
72+
if (is_null($value)) {
73+
return [];
74+
}
75+
76+
if (!\is_array($value)) {
77+
throw new InvalidConfigurationException('Settings must be an array.');
78+
}
79+
7080
$stringSettings = ['distinctAttribute', 'proximityPrecision', 'searchCutoffMs'];
7181

7282
foreach ($stringSettings as $setting) {
@@ -77,9 +87,7 @@ public function getConfigTreeBuilder(): TreeBuilder
7787

7888
return $value;
7989
})
80-
->end()
81-
->arrayPrototype()
82-
->variablePrototype()->end()
90+
->end()
8391
->end()
8492
->end()
8593
->end()

tests/Unit/ConfigurationTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,39 @@ public function testValidConfig(array $inputConfig, array $expectedConfig): void
2323
$this->assertProcessedConfigurationEquals($inputConfig, $expectedConfig);
2424
}
2525

26+
/**
27+
* @dataProvider dataTestSettingsDynamicChecker
28+
*/
29+
public function testInvalidSettingsType(mixed $value, bool $passed): void
30+
{
31+
if (!$passed) {
32+
$this->assertConfigurationIsInvalid([
33+
'meilisearch' => [
34+
'indices' => [
35+
[
36+
'name' => 'items',
37+
'class' => 'App\Entity\Post',
38+
'settings' => $value
39+
],
40+
],
41+
]
42+
], 'Settings must be an array.');
43+
return;
44+
}
45+
46+
$this->assertConfigurationIsValid([
47+
'meilisearch' => [
48+
'indices' => [
49+
[
50+
'name' => 'items',
51+
'class' => 'App\Entity\Post',
52+
'settings' => $value
53+
],
54+
],
55+
]
56+
]);
57+
}
58+
2659
/**
2760
* @return iterable<array{inputConfig: array<mixed>, expectedConfig: array<mixed>}>
2861
*/
@@ -294,6 +327,34 @@ public static function dataTestConfigurationTree(): iterable
294327
];
295328
}
296329

330+
public static function dataTestSettingsDynamicChecker(): iterable
331+
{
332+
yield "string is not acceptable" => [
333+
"settings" => "hello",
334+
"passed" => false,
335+
];
336+
337+
yield "int is not acceptable" => [
338+
"settings" => 1,
339+
"passed" => false,
340+
];
341+
342+
yield "bool is not acceptable" => [
343+
"settings" => true,
344+
"passed" => false,
345+
];
346+
347+
yield "array is acceptable" => [
348+
"settings" => [],
349+
"passed" => true,
350+
];
351+
352+
yield "null is acceptable" => [
353+
"settings" => null,
354+
"passed" => true,
355+
];
356+
}
357+
297358
protected function getConfiguration(): Configuration
298359
{
299360
return new Configuration();

0 commit comments

Comments
 (0)