feature #33848 [OptionsResolver] Add new OptionConfigurator class to define options with fluent interface (lmillucci, yceruto)
This PR was merged into the 5.1-dev branch.
Discussion
----------
[OptionsResolver] Add new OptionConfigurator class to define options with fluent interface
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | Fix #33735
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/12426
- [x] submit changes to the documentation
This PR adds OptionConfigurator to the OptionsResolver
Commits
-------
1ff56407e1
[OptionsResolver] Add new OptionConfigurator class to define options with fluent interface
This commit is contained in:
commit
4e659cae87
@ -1,6 +1,11 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
5.1.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* added fluent configuration of options using `OptionResolver::define()`
|
||||||
|
|
||||||
5.0.0
|
5.0.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
127
src/Symfony/Component/OptionsResolver/OptionConfigurator.php
Normal file
127
src/Symfony/Component/OptionsResolver/OptionConfigurator.php
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\OptionsResolver;
|
||||||
|
|
||||||
|
use Symfony\Component\OptionsResolver\Exception\AccessException;
|
||||||
|
|
||||||
|
final class OptionConfigurator
|
||||||
|
{
|
||||||
|
private $name;
|
||||||
|
private $resolver;
|
||||||
|
|
||||||
|
public function __construct(string $name, OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
$this->resolver = $resolver;
|
||||||
|
$this->resolver->setDefined($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds allowed types for this option.
|
||||||
|
*
|
||||||
|
* @param string ...$types One or more accepted types
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws AccessException If called from a lazy option or normalizer
|
||||||
|
*/
|
||||||
|
public function allowedTypes(string ...$types): self
|
||||||
|
{
|
||||||
|
$this->resolver->setAllowedTypes($this->name, $types);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets allowed values for this option.
|
||||||
|
*
|
||||||
|
* @param mixed ...$values One or more acceptable values/closures
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws AccessException If called from a lazy option or normalizer
|
||||||
|
*/
|
||||||
|
public function allowedValues(...$values): self
|
||||||
|
{
|
||||||
|
$this->resolver->setAllowedValues($this->name, $values);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default value for this option.
|
||||||
|
*
|
||||||
|
* @param mixed $value The default value of the option
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws AccessException If called from a lazy option or normalizer
|
||||||
|
*/
|
||||||
|
public function default($value): self
|
||||||
|
{
|
||||||
|
$this->resolver->setDefault($this->name, $value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an option configurator with the given name.
|
||||||
|
*/
|
||||||
|
public function define(string $option): self
|
||||||
|
{
|
||||||
|
return $this->resolver->define($option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks this option as deprecated.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*
|
||||||
|
* @param string|\Closure $deprecationMessage
|
||||||
|
*/
|
||||||
|
public function deprecated($deprecationMessage = 'The option "%name%" is deprecated.'): self
|
||||||
|
{
|
||||||
|
$this->resolver->setDeprecated($this->name, $deprecationMessage);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the normalizer for this option.
|
||||||
|
*
|
||||||
|
* @param \Closure $normalizer The normalizer
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws AccessException If called from a lazy option or normalizer
|
||||||
|
*/
|
||||||
|
public function normalize(\Closure $normalizer): self
|
||||||
|
{
|
||||||
|
$this->resolver->setNormalizer($this->name, $normalizer);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks this option as required.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws AccessException If called from a lazy option or normalizer
|
||||||
|
*/
|
||||||
|
public function required(): self
|
||||||
|
{
|
||||||
|
$this->resolver->setRequired($this->name);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -703,6 +703,18 @@ class OptionsResolver implements Options
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an option configurator with the given name.
|
||||||
|
*/
|
||||||
|
public function define(string $option): OptionConfigurator
|
||||||
|
{
|
||||||
|
if (isset($this->defined[$option])) {
|
||||||
|
throw new OptionDefinitionException(sprintf('The options "%s" is already defined.', $option));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OptionConfigurator($option, $this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the option with the given name.
|
* Removes the option with the given name.
|
||||||
*
|
*
|
||||||
@ -830,7 +842,7 @@ class OptionsResolver implements Options
|
|||||||
* Returns the resolved value of an option.
|
* Returns the resolved value of an option.
|
||||||
*
|
*
|
||||||
* @param string $option The option name
|
* @param string $option The option name
|
||||||
* @param bool $triggerDeprecation Whether to trigger the deprecation or not
|
* @param bool $triggerDeprecation Whether to trigger the deprecation or not (true by default)
|
||||||
*
|
*
|
||||||
* @return mixed The option value
|
* @return mixed The option value
|
||||||
*
|
*
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\OptionsResolver\Tests;
|
|||||||
|
|
||||||
use PHPUnit\Framework\Assert;
|
use PHPUnit\Framework\Assert;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\OptionsResolver\Debug\OptionsResolverIntrospector;
|
||||||
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
|
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
|
||||||
use Symfony\Component\OptionsResolver\Options;
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
@ -2378,4 +2379,35 @@ class OptionsResolverTest extends TestCase
|
|||||||
];
|
];
|
||||||
$this->assertSame($expectedOptions, $actualOptions);
|
$this->assertSame($expectedOptions, $actualOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFailsIfOptionIsAlreadyDefined()
|
||||||
|
{
|
||||||
|
$this->expectException('Symfony\Component\OptionsResolver\Exception\OptionDefinitionException');
|
||||||
|
$this->expectExceptionMessage('The options "foo" is already defined.');
|
||||||
|
$this->resolver->define('foo');
|
||||||
|
$this->resolver->define('foo');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testResolveOptionsDefinedByOptionConfigurator()
|
||||||
|
{
|
||||||
|
$this->resolver->define('foo')
|
||||||
|
->required()
|
||||||
|
->deprecated()
|
||||||
|
->default('bar')
|
||||||
|
->allowedTypes('string', 'bool')
|
||||||
|
->allowedValues('bar', 'zab')
|
||||||
|
->normalize(static function (Options $options, $value) {
|
||||||
|
return $value;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
$introspector = new OptionsResolverIntrospector($this->resolver);
|
||||||
|
|
||||||
|
$this->assertTrue(true, $this->resolver->isDefined('foo'));
|
||||||
|
$this->assertTrue(true, $this->resolver->isDeprecated('foo'));
|
||||||
|
$this->assertTrue(true, $this->resolver->hasDefault('foo'));
|
||||||
|
$this->assertSame('bar', $introspector->getDefault('foo'));
|
||||||
|
$this->assertSame(['string', 'bool'], $introspector->getAllowedTypes('foo'));
|
||||||
|
$this->assertSame(['bar', 'zab'], $introspector->getAllowedValues('foo'));
|
||||||
|
$this->assertCount(1, $introspector->getNormalizers('foo'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user