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

Appearance settings

[OptionsResolver] Add new OptionConfigurator class to define options with fluent interface #33848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions 5 src/Symfony/Component/OptionsResolver/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

5.1.0
-----

* added fluent configuration of options using `OptionResolver::define()`

5.0.0
-----

Expand Down
127 changes: 127 additions & 0 deletions 127 src/Symfony/Component/OptionsResolver/OptionConfigurator.php
Original file line number Diff line number Diff line change
@@ -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
yceruto marked this conversation as resolved.
Show resolved Hide resolved
*
* @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
yceruto marked this conversation as resolved.
Show resolved Hide resolved
{
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;
}
}
yceruto marked this conversation as resolved.
Show resolved Hide resolved
14 changes: 13 additions & 1 deletion 14 src/Symfony/Component/OptionsResolver/OptionsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,18 @@ public function addAllowedTypes(string $option, $allowedTypes)
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);
yceruto marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Removes the option with the given name.
*
Expand Down Expand Up @@ -830,7 +842,7 @@ public function resolve(array $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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

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;
Expand Down Expand Up @@ -2378,4 +2379,35 @@ public function testAccessToParentOptionFromNestedNormalizerAndLazyOption()
];
$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'));
}
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.