8000 [OptionsResolver] Support simple option validation · Issue #11705 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[OptionsResolver] Support simple option validation #11705

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

Closed
webmozart opened this issue Aug 19, 2014 · 4 comments
Closed

[OptionsResolver] Support simple option validation #11705

webmozart opened this issue Aug 19, 2014 · 4 comments

Comments

@webmozart
Copy link
Contributor

For many projects or even Symfony components, the full functionality of the OptionsResolver is overkill. Nevertheless, the component contains code that is very useful, but not easily accessible.

I suggest to make the validate* methods in the OptionsResolver class accessible through a simple low-level API such as:

use Symfony\Component\OptionsResolver\Options;

// throws MissingOptionsException if the option(s) is (are) missing
Options::require($options, 'toTz');

// throws InvalidOptionsException if any of the options have an invalid type
Options::validateTypes($options, array(
    'fromTz' => 'string',
    'toTz' => 'string',
    'dateFormat' => 'string',
    'timeFormat' => 'string',
    'calendar' => array('null', 'integer'),
));

// throws InvalidOptionsException if any of the options contain an invalid value
Options::validateValues($options, array(
    'calendar' => array(
        \IntlDateFormatter::GREGORIAN,
        \IntlDateFormatter::TRADITIONAL,
    ),
));

// throws InvalidOptionsException if any of the given options is not known
$options = Options::resolve($options, array(
    'fromTz' => null,
    'toTz' => null,
    'dateFormat' => \IntlDateFormatter::MEDIUM,
    'timeFormat' => \IntlDateFormatter::SHORT,
    'calendar' => \IntlDateFormatter::GREGORIAN,
));

Opinions?

@ste93cry
Copy link
Contributor

I really like this feature, I read about something similar in this blog post where Octivi used the OptionsResolver component to validate the querystring parameters. But wouldn't this feature be a clone of what the validator already does?

@webmozart
Copy link
Contributor Author

@ste93cry No. The options resolver is really just for validating simple options arrays against a few basic checks (allowed and required options, default values, optionally types and allowed values). It's meant to be light-weight and used wherever you pass options to a method.

The validator, on the other hand, is much more powerful (hence also requires more time/memory) - too powerful for this simple use case.

@shoomyth
Copy link

Nice idea. But imo Options class is a container for values and not a Helper. So maybe it's reasonable to create new class for this functionality?

@webmozart
Copy link
Contributor Author

See the description of #11716 for an answer to your question.

fabpot added a commit that referenced this issue Sep 23, 2014
…for basic option resolving (webmozart)

This PR was merged into the 2.6-dev branch.

Discussion
----------

[OptionsResolver] Added a light-weight, low-level API for basic option resolving

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #11705
| License       | MIT
| Doc PR        | symfony/symfony-docs#4159

See [the updated documentation](https://github.com/webmozart/symfony-docs/blob/issue11705/components/options_resolver.rst) for details on the usage of the simple API.

The most important motivation for this change is DX and speed. The basic features of the component should be easily usable in a wide variety of use cases without impacting performance.

For DX reasons, I added the static methods to the `Options` class, which makes the code concise and easy to read and understand:

```php
use Symfony\Component\OptionsResolver\Options;

$options = Options::validateRequired($options, 'format');

$options = Options::validateTypes($options, array(
    'format' => array('string', 'int'),
    'calendar' => 'int',
));

$options = Options::validateValues($options, array(
    'calendar' => array(
        \IntlDateFormatter::GREGORIAN,
        \IntlDateFormatter::TRADITIONAL,
    ),
));

$options = Options::resolve($options, array(
    'format' => null,
    'calendar' => \IntlDateFormatter::GREGORIAN,
));
```

If you need to distribute the option configuration, this PR also extracts the configuration part of the `OptionsResolver` class into a new class `OptionsConfig`, which can be passed around. When the configuration is complete, pass the config object to `Options::resolve()` as second argument:

```php
$config = new OptionsConfig();

$config->setDefaults(array(
    'format' => \IntlDateFormatter::MEDIUM,
    'calendar' => \IntlDateFormatter::GREGORIAN,
));

$options = Options::resolve($options, $config);
```

Consequently - since `OptionsResolver` extends `OptionsConfig` - the two following statements now become identical:

```php
$options = $resolver->resolve($options);
$options = Options::resolve($options, $resolver);
```

Commits
-------

9066025 [OptionsResolver] Added a light-weight, low-level API for basic option resolving
@fabpot fabpot closed this as completed Sep 23, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants
0