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
|
||||
=========
|
||||
|
||||
5.1.0
|
||||
-----
|
||||
|
||||
* added fluent configuration of options using `OptionResolver::define()`
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@ -830,7 +842,7 @@ class OptionsResolver implements Options
|
||||
* Returns the resolved value of an option.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\OptionsResolver\Tests;
|
||||
|
||||
use PHPUnit\Framework\Assert;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\OptionsResolver\Debug\OptionsResolverIntrospector;
|
||||
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
@ -2378,4 +2379,35 @@ class OptionsResolverTest extends TestCase
|
||||
];
|
||||
$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