Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d280f5b

Browse files
committed
Add a new method addNormalizer and normalization hierarchy
1 parent 3895acd commit d280f5b

File tree

5 files changed

+160
-5
lines changed

5 files changed

+160
-5
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+
4.3.0
5+
-----
6+
7+
* added `addNormalizer` method
8+
49
4.2.0
510
-----
611

src/Symfony/Component/OptionsResolver/Debug/OptionsResolverIntrospector.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ public function getAllowedValues(string $option): array
8484
* @throws NoConfigurationException on no configured normalizer
8585
*/
8686
public function getNormalizer(string $option): \Closure
87+
{
88+
return current($this->getNormalizers($option));
89+
}
90+
91+
/**
92+
* @throws NoConfigurationException on no configured normalizer
93+
*/
94+
public function getNormalizers(string $option): array
8795
{
8896
return ($this->get)('normalizers', $option, sprintf('No normalizer was set for the "%s" option.', $option));
8997
}

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class OptionsResolver implements Options
5757
/**
5858
* A list of normalizer closures.
5959
*
60-
* @var \Closure[]
60+
* @var \Closure[][]
6161
*/
6262
private $normalizers = [];
6363

@@ -484,7 +484,56 @@ public function setNormalizer($option, \Closure $normalizer)
484484
throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined))));
485485
}
486486

487-
$this->normalizers[$option] = $normalizer;
487+
$this->normalizers[$option] = [$normalizer];
488+
489+
// Make sure the option is processed
490+
unset($this->resolved[$option]);
491+
492+
return $this;
493+
}
494+
495+
/**
496+
* Adds a normalizer for an option.
497+
*
498+
* The normalizer should be a closure with the following signature:
499+
*
500+
* function (Options $options, $value) {
501+
* // ...
502+
* }
503+
*
504+
* The closure is invoked when {@link resolve()} is called. The closure
505+
* has access to the resolved values of other options through the passed
506+
* {@link Options} instance.
507+
*
508+
* The second parameter passed to the closure is the value of
509+
* the option.
510+
*
511+
* The resolved option value is set to the return value of the closure.
512+
*
513+
* @param string $option The option name
514+
* @param \Closure $normalizer The normalizer
515+
* @param bool $forcePrepend If set to true, prepend instead of appending
516+
*
517+
* @return $this
518+
*
519+
* @throws UndefinedOptionsException If the option is undefined
520+
* @throws AccessException If called from a lazy option or normalizer
521+
*/
522+
public function addNormalizer(string $option, \Closure $normalizer, bool $forcePrepend = false): self
523+
{
524+
if ($this->locked) {
525+
throw new AccessException('Normalizers cannot be set from a lazy option or normalizer.');
526+
}
527+
528+
if (!isset($this->defined[$option])) {
529+
throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined))));
530+
}
531+
532+
if ($forcePrepend) {
533+
array_unshift($this->normalizers[$option], $normalizer);
534+
} else {
535+
$this->normalizers[$option][] = $normalizer;
536+
}
488537

489538
// Make sure the option is processed
490539
unset($this->resolved[$option]);
@@ -966,15 +1015,15 @@ public function offsetGet($option/*, bool $triggerDeprecation = true*/)
9661015
throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', implode('", "', array_keys($this->calling))));
9671016
}
9681017

969-
$normalizer = $this->normalizers[$option];
970-
9711018
// The following section must be protected from cyclic
9721019
// calls. Set $calling for the current $option to detect a cyclic
9731020
// dependency
9741021
// BEGIN
9751022
$this->calling[$option] = true;
9761023
try {
977-
$value = $normalizer($this, $value);
1024+
foreach ($this->normalizers[$option] as $normalizer) {
1025+
$value = $normalizer($this, $value);
1026+
}
9781027
} finally {
9791028
unset($this->calling[$option]);
9801029
}

src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,42 @@ public function testGetNormalizerThrowsOnNotDefinedOption()
201201
$this->assertSame('bar', $debug->getNormalizer('foo'));
202202
}
203203

204+
public function testGetNormalizers()
205+
{
206+
$resolver = new OptionsResolver();
207+
$resolver->setDefined('foo');
208+
$resolver->addNormalizer('foo', $normalizer1 = function () {});
209+
$resolver->addNormalizer('foo', $normalizer2 = function () {});
210+
211+
$debug = new OptionsResolverIntrospector($resolver);
212+
$this->assertSame([$normalizer1, $normalizer2], $debug->getNormalizers('foo'));
213+
}
214+
215+
/**
216+
* @expectedException \Symfony\Component\OptionsResolver\Exception\NoConfigurationException
217+
* @expectedExceptionMessage No normalizer was set for the "foo" option.
218+
*/
219+
public function testGetNormalizersThrowsOnNoConfiguredValue()
220+
{
221+
$resolver = new OptionsResolver();
222+
$resolver->setDefined('foo');
223+
224+
$debug = new OptionsResolverIntrospector($resolver);
225+
$debug->getNormalizers('foo');
226+
}
227+
228+
/**
229+
* @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
230+
* @expectedExceptionMessage The option "foo" does not exist.
231+
*/
232+
public function testGetNormalizersThrowsOnNotDefinedOption()
233+
{
234+
$resolver = new OptionsResolver();
235+
236+
$debug = new OptionsResolverIntrospector($resolver);
237+
$debug->getNormalizers('foo');
238+
}
239+
204240
public function testGetDeprecationMessage()
205241
{
206242
$resolver = new OptionsResolver();

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,63 @@ public function testNormalizerNotCalledForUnsetOptions()
15541554
$this->assertEmpty($this->resolver->resolve());
15551555
}
15561556

1557+
public function testAddNormalizerReturnsThis()
1558+
{
1559+
$this->resolver->setDefault('foo', 'bar');
1560+
1561+
$this->assertSame($this->resolver, $this->resolver->addNormalizer('foo', function () {}));
1562+
}
1563+
1564+
public function testAddNormalizerClosure()
1565+
{
1566+
// defined by superclass
1567+
$this->resolver->setDefault('foo', 'bar');
1568+
$this->resolver->setNormalizer('foo', function (Options $options, $value) {
1569+
return '1st-normalized '.$value;
1570+
});
1571+
// defined by subclass
1572+
$this->resolver->addNormalizer('foo', function (Options $options, $value) {
1573+
return '2nd-normalized '.$value;
1574+
});
1575+
1576+
$this->assertEquals(['foo' => '2nd-normalized 1st-normalized bar'], $this->resolver->resolve());
1577+
}
1578+
1579+
public function testForcePrependAddNormalizerClosure()
1580+
{
1581+
// defined by superclass
1582+
$this->resolver->setDefault('foo', 'bar');
1583+
$this->resolver->setNormalizer('foo', function (Options $options, $value) {
1584+
return '2nd-normalized '.$value;
1585+
});
1586+
// defined by subclass
1587+
$this->resolver->addNormalizer('foo', function (Options $options, $value) {
1588+
return '1st-normalized '.$value;
1589+
}, true);
1590+
1591+
$this->assertEquals(['foo' => '2nd-normalized 1st-normalized bar'], $this->resolver->resolve());
1592+
}
1593+
1594+
/**
1595+
* @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
1596+
*/
1597+
public function testAddNormalizerFailsIfUnknownOption()
1598+
{
1599+
$this->resolver->addNormalizer('foo', function () {});
1600+
}
1601+
1602+
/**
1603+
* @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException
1604+
*/
1605+
public function testFailIfAddNormalizerFromLazyOption()
1606+
{
1607+
$this->resolver->setDefault('foo', function (Options $options) {
1608+
$options->addNormalizer('foo', function () {});
1609+
});
1610+
1611+
$this->resolver->resolve();
1612+
}
1613+
15571614
public function testSetDefaultsReturnsThis()
15581615
{
15591616
$this->assertSame($this->resolver, $this->resolver->setDefaults(['foo', 'bar']));

0 commit comments

Comments
 (0)