Skip to content

Commit 492623f

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 492623f

File tree

2 files changed

+75
-5
lines changed

2 files changed

+75
-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: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,40 @@ 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+
44+
return;
45+
}
46+
47+
$this->assertConfigurationIsValid([
48+
'meilisearch' => [
49+
'indices' => [
50+
[
51+
'name' => 'items',
52+
'class' => 'App\Entity\Post',
53+
'settings' => $value,
54+
],
55+
],
56+
],
57+
]);
58+
}
59+
2660
/**
2761
* @return iterable<array{inputConfig: array<mixed>, expectedConfig: array<mixed>}>
2862
*/
@@ -294,6 +328,34 @@ public static function dataTestConfigurationTree(): iterable
294328
];
295329
}
296330

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

0 commit comments

Comments
 (0)