Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9daae60

Browse files
committed
Add prototype definition support for nested options
1 parent0a66727 commit9daae60

File tree

3 files changed

+138
-1
lines changed

3 files changed

+138
-1
lines changed

‎src/Symfony/Component/OptionsResolver/CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.3.0
5+
-----
6+
7+
* added prototype definition for nested options
8+
49
5.1.0
510
-----
611

‎src/Symfony/Component/OptionsResolver/OptionsResolver.php‎

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ class OptionsResolver implements Options
130130

131131
private$parentsOptions = [];
132132

133+
/**
134+
* Whether the whole options definition is marked as array prototype.
135+
*/
136+
private$prototype =false;
137+
138+
/**
139+
* The prototype array's index that is being reading.
140+
*/
141+
private$prototypeIndex;
142+
133143
/**
134144
* Sets the default value of a given option.
135145
*
@@ -789,6 +799,29 @@ public function getInfo(string $option): ?string
789799
return$this->info[$option] ??null;
790800
}
791801

802+
/**
803+
* Marks the whole options definition as array prototype.
804+
*
805+
* @return $this
806+
*
807+
* @throws AccessException If called from a lazy option or normalizer
808+
*/
809+
publicfunctionsetPrototype(bool$prototype):self
810+
{
811+
if ($this->locked) {
812+
thrownewAccessException('The prototype property cannot be set from a lazy option or normalizer.');
813+
}
814+
815+
$this->prototype =$prototype;
816+
817+
return$this;
818+
}
819+
820+
publicfunctionisPrototype():bool
821+
{
822+
return$this->prototype;
823+
}
824+
792825
/**
793826
* Removes the option with the given name.
794827
*
@@ -975,8 +1008,23 @@ public function offsetGet($option, bool $triggerDeprecation = true)
9751008
foreach ($this->nested[$option]as$closure) {
9761009
$closure($resolver,$this);
9771010
}
978-
$value =$resolver->resolve($value);
1011+
1012+
if ($resolver->prototype) {
1013+
$values = [];
1014+
foreach ($valueas$index =>$prototypeValue) {
1015+
if (!\is_array($prototypeValue)) {
1016+
thrownewInvalidOptionsException(sprintf('The value of the option "%s" is expected to be of type array of array, but is of type array of "%s".',$this->formatOptions([$option]),get_debug_type($prototypeValue)));
1017+
}
1018+
1019+
$resolver->prototypeIndex =$index;
1020+
$values[$index] =$resolver->resolve($prototypeValue);
1021+
}
1022+
$value =$values;
1023+
}else {
1024+
$value =$resolver->resolve($value);
1025+
}
9791026
}finally {
1027+
$resolver->prototypeIndex =null;
9801028
unset($this->calling[$option]);
9811029
}
9821030
}
@@ -1286,6 +1334,10 @@ private function formatOptions(array $options): string
12861334
$prefix .=sprintf('[%s]',implode('][',$this->parentsOptions));
12871335
}
12881336

1337+
if ($this->prototype &&null !==$this->prototypeIndex) {
1338+
$prefix .=sprintf('[%s]',$this->prototypeIndex);
1339+
}
1340+
12891341
$options =array_map(staticfunction (string$option)use ($prefix):string {
12901342
returnsprintf('%s[%s]',$prefix,$option);
12911343
},$options);

‎src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php‎

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
useSymfony\Component\OptionsResolver\Debug\OptionsResolverIntrospector;
1818
useSymfony\Component\OptionsResolver\Exception\AccessException;
1919
useSymfony\Component\OptionsResolver\Exception\InvalidOptionsException;
20+
useSymfony\Component\OptionsResolver\Exception\MissingOptionsException;
2021
useSymfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
2122
useSymfony\Component\OptionsResolver\Options;
2223
useSymfony\Component\OptionsResolver\OptionsResolver;
@@ -2500,4 +2501,83 @@ public function testSetDeprecatedWithoutPackageAndVersion()
25002501
->setDeprecated('foo')
25012502
;
25022503
}
2504+
2505+
publicfunctiontestInvalidValueForPrototypeDefinition()
2506+
{
2507+
$this->expectException(InvalidOptionsException::class);
2508+
$this->expectExceptionMessage('The value of the option "connections" is expected to be of type array of array, but is of type array of "string".');
2509+
2510+
$this->resolver
2511+
->setDefault('connections',staticfunction (OptionsResolver$resolver) {
2512+
$resolver
2513+
->setPrototype(true)
2514+
->setDefined(['table','user','password'])
2515+
;
2516+
})
2517+
;
2518+
2519+
$this->resolver->resolve(['connections' => ['foo']]);
2520+
}
2521+
2522+
publicfunctiontestMissingOptionForPrototypeDefinition()
2523+
{
2524+
$this->expectException(MissingOptionsException::class);
2525+
$this->expectExceptionMessage('The required option "connections[1][table]" is missing.');
2526+
2527+
$this->resolver
2528+
->setDefault('connections',staticfunction (OptionsResolver$resolver) {
2529+
$resolver
2530+
->setPrototype(true)
2531+
->setRequired('table')
2532+
;
2533+
})
2534+
;
2535+
2536+
$this->resolver->resolve(['connections' => [
2537+
['table' =>'default'],
2538+
[],// <- missing required option "table"
2539+
]]);
2540+
}
2541+
2542+
publicfunctiontestPrototypeDefinition()
2543+
{
2544+
$this->resolver
2545+
->setDefault('connections',staticfunction (OptionsResolver$resolver) {
2546+
$resolver
2547+
->setPrototype(true)
2548+
->setRequired('table')
2549+
->setDefaults(['user' =>'root','password' =>null])
2550+
;
2551+
})
2552+
;
2553+
2554+
$actualOptions =$this->resolver->resolve([
2555+
'connections' => [
2556+
'default' => [
2557+
'table' =>'default',
2558+
],
2559+
'custom' => [
2560+
'user' =>'foo',
2561+
'password' =>'pa$$',
2562+
'table' =>'symfony',
2563+
],
2564+
],
2565+
]);
2566+
$expectedOptions = [
2567+
'connections' => [
2568+
'default' => [
2569+
'user' =>'root',
2570+
'password' =>null,
2571+
'table' =>'default',
2572+
],
2573+
'custom' => [
2574+
'user' =>'foo',
2575+
'password' =>'pa$$',
2576+
'table' =>'symfony',
2577+
],
2578+
],
2579+
];
2580+
2581+
$this->assertSame($expectedOptions,$actualOptions);
2582+
}
25032583
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp