feature #23694 [Form] Add debug:form command (yceruto)
This PR was merged into the 3.4 branch.
Discussion
----------
[Form] Add debug:form command
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | https://github.com/symfony/symfony/issues/23688
| License | MIT
| Doc PR | -
![debug-form](https://user-images.githubusercontent.com/2028198/29007125-c3508cd6-7aca-11e7-91e2-c2b509847db5.png)
A short class name (e.g. `DateType`) can be passed as `class` argument too (the command will try to resolve its FQCN if it's in known form type namespaces).
Commits
-------
4f040d78fe
Add debug:form command
This commit is contained in:
commit
dd3276c2e8
@ -220,6 +220,8 @@ class FrameworkExtension extends Extension
|
|||||||
if (!class_exists('Symfony\Component\Validator\Validation')) {
|
if (!class_exists('Symfony\Component\Validator\Validation')) {
|
||||||
throw new LogicException('The Validator component is required to use the Form component.');
|
throw new LogicException('The Validator component is required to use the Form component.');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$container->removeDefinition('Symfony\Component\Form\Command\DebugCommand');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->registerSecurityCsrfConfiguration($config['csrf_protection'], $container, $loader);
|
$this->registerSecurityCsrfConfiguration($config['csrf_protection'], $container, $loader);
|
||||||
|
@ -96,5 +96,11 @@
|
|||||||
<service id="Symfony\Bundle\FrameworkBundle\Command\YamlLintCommand">
|
<service id="Symfony\Bundle\FrameworkBundle\Command\YamlLintCommand">
|
||||||
<tag name="console.command" command="lint:yaml" />
|
<tag name="console.command" command="lint:yaml" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="Symfony\Component\Form\Command\DebugCommand">
|
||||||
|
<argument type="service" id="form.registry" />
|
||||||
|
<argument type="collection" /> <!-- All form types namespaces are stored here by FormPass -->
|
||||||
|
<tag name="console.command" command="debug:form" />
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
"symfony/dom-crawler": "~2.8|~3.0|~4.0",
|
"symfony/dom-crawler": "~2.8|~3.0|~4.0",
|
||||||
"symfony/polyfill-intl-icu": "~1.0",
|
"symfony/polyfill-intl-icu": "~1.0",
|
||||||
"symfony/security": "~2.8|~3.0|~4.0",
|
"symfony/security": "~2.8|~3.0|~4.0",
|
||||||
"symfony/form": "~3.3|~4.0",
|
"symfony/form": "~3.4|~4.0",
|
||||||
"symfony/expression-language": "~2.8|~3.0|~4.0",
|
"symfony/expression-language": "~2.8|~3.0|~4.0",
|
||||||
"symfony/process": "~2.8|~3.0|~4.0",
|
"symfony/process": "~2.8|~3.0|~4.0",
|
||||||
"symfony/security-core": "~3.2|~4.0",
|
"symfony/security-core": "~3.2|~4.0",
|
||||||
|
96
src/Symfony/Component/Form/Command/DebugCommand.php
Normal file
96
src/Symfony/Component/Form/Command/DebugCommand.php
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?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\Form\Command;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
use Symfony\Component\Form\Console\Helper\DescriptorHelper;
|
||||||
|
use Symfony\Component\Form\FormRegistryInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A console command for retrieving information about form types.
|
||||||
|
*
|
||||||
|
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||||
|
*/
|
||||||
|
class DebugCommand extends Command
|
||||||
|
{
|
||||||
|
protected static $defaultName = 'debug:form';
|
||||||
|
|
||||||
|
private $formRegistry;
|
||||||
|
private $namespaces;
|
||||||
|
|
||||||
|
public function __construct(FormRegistryInterface $formRegistry, array $namespaces = array('Symfony\Component\Form\Extension\Core\Type'))
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->formRegistry = $formRegistry;
|
||||||
|
$this->namespaces = $namespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setDefinition(array(
|
||||||
|
new InputArgument('class', InputArgument::REQUIRED, 'The form type class'),
|
||||||
|
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt or json)', 'txt'),
|
||||||
|
))
|
||||||
|
->setDescription('Displays form type information')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
|
if (!class_exists($class = $input->getArgument('class'))) {
|
||||||
|
$class = $this->getFqcnTypeClass($input, $io, $class);
|
||||||
|
}
|
||||||
|
|
||||||
|
$object = $this->formRegistry->getType($class);
|
||||||
|
|
||||||
|
$helper = new DescriptorHelper();
|
||||||
|
$options['format'] = $input->getOption('format');
|
||||||
|
$helper->describe($io, $object, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFqcnTypeClass(InputInterface $input, SymfonyStyle $io, $shortClassName)
|
||||||
|
{
|
||||||
|
$classes = array();
|
||||||
|
foreach ($this->namespaces as $namespace) {
|
||||||
|
if (class_exists($fqcn = $namespace.'\\'.$shortClassName)) {
|
||||||
|
$classes[] = $fqcn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 === $count = count($classes)) {
|
||||||
|
throw new \InvalidArgumentException(sprintf("Could not find type \"%s\" into the following namespaces:\n %s", $shortClassName, implode("\n ", $this->namespaces)));
|
||||||
|
}
|
||||||
|
if (1 === $count) {
|
||||||
|
return $classes[0];
|
||||||
|
}
|
||||||
|
if (!$input->isInteractive()) {
|
||||||
|
throw new \InvalidArgumentException(sprintf("The type \"%s\" is ambiguous.\nDid you mean one of these?\n %s", $shortClassName, implode("\n ", $classes)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $io->choice(sprintf("The type \"%s\" is ambiguous.\n\n Select one of the following form types to display its information:", $shortClassName), $classes, $classes[0]);
|
||||||
|
}
|
||||||
|
}
|
122
src/Symfony/Component/Form/Console/Descriptor/Descriptor.php
Normal file
122
src/Symfony/Component/Form/Console/Descriptor/Descriptor.php
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<?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\Form\Console\Descriptor;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Descriptor\DescriptorInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
use Symfony\Component\Form\ResolvedFormTypeInterface;
|
||||||
|
use Symfony\Component\Form\Util\OptionsResolverWrapper;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
abstract class Descriptor implements DescriptorInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var SymfonyStyle
|
||||||
|
*/
|
||||||
|
protected $output;
|
||||||
|
protected $type;
|
||||||
|
protected $ownOptions = array();
|
||||||
|
protected $overriddenOptions = array();
|
||||||
|
protected $parentOptions = array();
|
||||||
|
protected $extensionOptions = array();
|
||||||
|
protected $requiredOptions = array();
|
||||||
|
protected $parents = array();
|
||||||
|
protected $extensions = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function describe(OutputInterface $output, $object, array $options = array())
|
||||||
|
{
|
||||||
|
$this->output = $output;
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case $object instanceof ResolvedFormTypeInterface:
|
||||||
|
$this->describeResolvedFormType($object, $options);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function describeResolvedFormType(ResolvedFormTypeInterface $resolvedFormType, array $options = array());
|
||||||
|
|
||||||
|
protected function collectOptions(ResolvedFormTypeInterface $type)
|
||||||
|
{
|
||||||
|
$this->parents = array();
|
||||||
|
$this->extensions = array();
|
||||||
|
|
||||||
|
if (null !== $type->getParent()) {
|
||||||
|
$optionsResolver = clone $this->getParentOptionsResolver($type->getParent());
|
||||||
|
} else {
|
||||||
|
$optionsResolver = new OptionsResolver();
|
||||||
|
}
|
||||||
|
|
||||||
|
$type->getInnerType()->configureOptions($ownOptionsResolver = new OptionsResolverWrapper());
|
||||||
|
$this->ownOptions = array_diff($ownOptionsResolver->getDefinedOptions(), $optionsResolver->getDefinedOptions());
|
||||||
|
$overriddenOptions = array_intersect(array_merge($ownOptionsResolver->getDefinedOptions(), $ownOptionsResolver->getUndefinedOptions()), $optionsResolver->getDefinedOptions());
|
||||||
|
|
||||||
|
$this->parentOptions = array();
|
||||||
|
foreach ($this->parents as $class => $parentOptions) {
|
||||||
|
$this->overriddenOptions[$class] = array_intersect($overriddenOptions, $parentOptions);
|
||||||
|
$this->parentOptions[$class] = array_diff($parentOptions, $overriddenOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
$type->getInnerType()->configureOptions($optionsResolver);
|
||||||
|
$this->collectTypeExtensionsOptions($type, $optionsResolver);
|
||||||
|
$this->extensionOptions = array();
|
||||||
|
foreach ($this->extensions as $class => $extensionOptions) {
|
||||||
|
$this->overriddenOptions[$class] = array_intersect($overriddenOptions, $extensionOptions);
|
||||||
|
$this->extensionOptions[$class] = array_diff($extensionOptions, $overriddenOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->overriddenOptions = array_filter($this->overriddenOptions);
|
||||||
|
$this->requiredOptions = $optionsResolver->getRequiredOptions();
|
||||||
|
|
||||||
|
$this->parents = array_keys($this->parents);
|
||||||
|
$this->extensions = array_keys($this->extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getParentOptionsResolver(ResolvedFormTypeInterface $type)
|
||||||
|
{
|
||||||
|
$this->parents[$class = get_class($type->getInnerType())] = array();
|
||||||
|
|
||||||
|
if (null !== $type->getParent()) {
|
||||||
|
$optionsResolver = clone $this->getParentOptionsResolver($type->getParent());
|
||||||
|
} else {
|
||||||
|
$optionsResolver = new OptionsResolver();
|
||||||
|
}
|
||||||
|
|
||||||
|
$inheritedOptions = $optionsResolver->getDefinedOptions();
|
||||||
|
$type->getInnerType()->configureOptions($optionsResolver);
|
||||||
|
$this->parents[$class] = array_diff($optionsResolver->getDefinedOptions(), $inheritedOptions);
|
||||||
|
|
||||||
|
$this->collectTypeExtensionsOptions($type, $optionsResolver);
|
||||||
|
|
||||||
|
return $optionsResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function collectTypeExtensionsOptions(ResolvedFormTypeInterface $type, OptionsResolver $optionsResolver)
|
||||||
|
{
|
||||||
|
foreach ($type->getTypeExtensions() as $extension) {
|
||||||
|
$inheritedOptions = $optionsResolver->getDefinedOptions();
|
||||||
|
$extension->configureOptions($optionsResolver);
|
||||||
|
$this->extensions[get_class($extension)] = array_diff($optionsResolver->getDefinedOptions(), $inheritedOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
<?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\Form\Console\Descriptor;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\ResolvedFormTypeInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class JsonDescriptor extends Descriptor
|
||||||
|
{
|
||||||
|
protected function describeResolvedFormType(ResolvedFormTypeInterface $resolvedFormType, array $options = array())
|
||||||
|
{
|
||||||
|
$this->collectOptions($resolvedFormType);
|
||||||
|
|
||||||
|
$formOptions = array(
|
||||||
|
'own' => $this->ownOptions,
|
||||||
|
'overridden' => $this->overriddenOptions,
|
||||||
|
'parent' => $this->parentOptions,
|
||||||
|
'extension' => $this->extensionOptions,
|
||||||
|
'required' => $this->requiredOptions,
|
||||||
|
);
|
||||||
|
$this->sortOptions($formOptions);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'class' => get_class($resolvedFormType->getInnerType()),
|
||||||
|
'block_prefix' => $resolvedFormType->getInnerType()->getBlockPrefix(),
|
||||||
|
'options' => $formOptions,
|
||||||
|
'parent_types' => $this->parents,
|
||||||
|
'type_extensions' => $this->extensions,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->writeData($data, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function writeData(array $data, array $options)
|
||||||
|
{
|
||||||
|
$flags = isset($options['json_encoding']) ? $options['json_encoding'] : 0;
|
||||||
|
$this->output->write(json_encode($data, $flags | JSON_PRETTY_PRINT)."\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function sortOptions(array &$options)
|
||||||
|
{
|
||||||
|
foreach ($options as &$opts) {
|
||||||
|
$sorted = false;
|
||||||
|
foreach ($opts as &$opt) {
|
||||||
|
if (is_array($opt)) {
|
||||||
|
sort($opt);
|
||||||
|
$sorted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$sorted) {
|
||||||
|
sort($opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
108
src/Symfony/Component/Form/Console/Descriptor/TextDescriptor.php
Normal file
108
src/Symfony/Component/Form/Console/Descriptor/TextDescriptor.php
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?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\Form\Console\Descriptor;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Helper\TableSeparator;
|
||||||
|
use Symfony\Component\Form\ResolvedFormTypeInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class TextDescriptor extends Descriptor
|
||||||
|
{
|
||||||
|
protected function describeResolvedFormType(ResolvedFormTypeInterface $resolvedFormType, array $options = array())
|
||||||
|
{
|
||||||
|
$this->collectOptions($resolvedFormType);
|
||||||
|
|
||||||
|
$formOptions = $this->normalizeAndSortOptionsColumns(array_filter(array(
|
||||||
|
'own' => $this->ownOptions,
|
||||||
|
'overridden' => $this->overriddenOptions,
|
||||||
|
'parent' => $this->parentOptions,
|
||||||
|
'extension' => $this->extensionOptions,
|
||||||
|
)));
|
||||||
|
|
||||||
|
// setting headers and column order
|
||||||
|
$tableHeaders = array_intersect_key(array(
|
||||||
|
'own' => 'Options',
|
||||||
|
'overridden' => 'Overridden options',
|
||||||
|
'parent' => 'Parent options',
|
||||||
|
'extension' => 'Extension options',
|
||||||
|
), $formOptions);
|
||||||
|
|
||||||
|
$tableRows = array();
|
||||||
|
$count = count(max($formOptions));
|
||||||
|
for ($i = 0; $i < $count; ++$i) {
|
||||||
|
$cells = array();
|
||||||
|
foreach (array_keys($tableHeaders) as $group) {
|
||||||
|
if (isset($formOptions[$group][$i])) {
|
||||||
|
$option = $formOptions[$group][$i];
|
||||||
|
|
||||||
|
if (is_string($option) && in_array($option, $this->requiredOptions)) {
|
||||||
|
$option .= ' <info>(required)</info>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$cells[] = $option;
|
||||||
|
} else {
|
||||||
|
$cells[] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tableRows[] = $cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->output->title(sprintf('%s (Block prefix: "%s")', get_class($resolvedFormType->getInnerType()), $resolvedFormType->getInnerType()->getBlockPrefix()));
|
||||||
|
$this->output->table($tableHeaders, $tableRows);
|
||||||
|
|
||||||
|
if ($this->parents) {
|
||||||
|
$this->output->section('Parent types');
|
||||||
|
$this->output->listing($this->parents);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->extensions) {
|
||||||
|
$this->output->section('Type extensions');
|
||||||
|
$this->output->listing($this->extensions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function normalizeAndSortOptionsColumns(array $options)
|
||||||
|
{
|
||||||
|
foreach ($options as $group => &$opts) {
|
||||||
|
$sorted = false;
|
||||||
|
foreach ($opts as $class => $opt) {
|
||||||
|
if (!is_array($opt) || 0 === count($opt)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($opts[$class]);
|
||||||
|
|
||||||
|
if (!$sorted) {
|
||||||
|
$opts = array();
|
||||||
|
} else {
|
||||||
|
$opts[] = null;
|
||||||
|
}
|
||||||
|
$opts[] = sprintf('<info>%s</info>', (new \ReflectionClass($class))->getShortName());
|
||||||
|
$opts[] = new TableSeparator();
|
||||||
|
|
||||||
|
sort($opt);
|
||||||
|
$sorted = true;
|
||||||
|
$opts = array_merge($opts, $opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$sorted) {
|
||||||
|
sort($opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?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\Form\Console\Helper;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Helper\DescriptorHelper as BaseDescriptorHelper;
|
||||||
|
use Symfony\Component\Form\Console\Descriptor\JsonDescriptor;
|
||||||
|
use Symfony\Component\Form\Console\Descriptor\TextDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class DescriptorHelper extends BaseDescriptorHelper
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->register('txt', new TextDescriptor())
|
||||||
|
->register('json', new JsonDescriptor())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|||||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
use Symfony\Component\Form\Command\DebugCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds all services with the tags "form.type", "form.type_extension" and
|
* Adds all services with the tags "form.type", "form.type_extension" and
|
||||||
@ -33,13 +34,15 @@ class FormPass implements CompilerPassInterface
|
|||||||
private $formTypeTag;
|
private $formTypeTag;
|
||||||
private $formTypeExtensionTag;
|
private $formTypeExtensionTag;
|
||||||
private $formTypeGuesserTag;
|
private $formTypeGuesserTag;
|
||||||
|
private $formDebugCommandService;
|
||||||
|
|
||||||
public function __construct($formExtensionService = 'form.extension', $formTypeTag = 'form.type', $formTypeExtensionTag = 'form.type_extension', $formTypeGuesserTag = 'form.type_guesser')
|
public function __construct($formExtensionService = 'form.extension', $formTypeTag = 'form.type', $formTypeExtensionTag = 'form.type_extension', $formTypeGuesserTag = 'form.type_guesser', $formDebugCommandService = DebugCommand::class)
|
||||||
{
|
{
|
||||||
$this->formExtensionService = $formExtensionService;
|
$this->formExtensionService = $formExtensionService;
|
||||||
$this->formTypeTag = $formTypeTag;
|
$this->formTypeTag = $formTypeTag;
|
||||||
$this->formTypeExtensionTag = $formTypeExtensionTag;
|
$this->formTypeExtensionTag = $formTypeExtensionTag;
|
||||||
$this->formTypeGuesserTag = $formTypeGuesserTag;
|
$this->formTypeGuesserTag = $formTypeGuesserTag;
|
||||||
|
$this->formDebugCommandService = $formDebugCommandService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function process(ContainerBuilder $container)
|
public function process(ContainerBuilder $container)
|
||||||
@ -61,12 +64,19 @@ class FormPass implements CompilerPassInterface
|
|||||||
{
|
{
|
||||||
// Get service locator argument
|
// Get service locator argument
|
||||||
$servicesMap = array();
|
$servicesMap = array();
|
||||||
|
$namespaces = array('Symfony\Component\Form\Extension\Core\Type' => true);
|
||||||
|
|
||||||
// Builds an array with fully-qualified type class names as keys and service IDs as values
|
// Builds an array with fully-qualified type class names as keys and service IDs as values
|
||||||
foreach ($container->findTaggedServiceIds($this->formTypeTag, true) as $serviceId => $tag) {
|
foreach ($container->findTaggedServiceIds($this->formTypeTag, true) as $serviceId => $tag) {
|
||||||
// Add form type service to the service locator
|
// Add form type service to the service locator
|
||||||
$serviceDefinition = $container->getDefinition($serviceId);
|
$serviceDefinition = $container->getDefinition($serviceId);
|
||||||
$servicesMap[$serviceDefinition->getClass()] = new Reference($serviceId);
|
$servicesMap[$formType = $serviceDefinition->getClass()] = new Reference($serviceId);
|
||||||
|
$namespaces[substr($formType, 0, strrpos($formType, '\\'))] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($container->hasDefinition($this->formDebugCommandService)) {
|
||||||
|
$commandDefinition = $container->getDefinition($this->formDebugCommandService);
|
||||||
|
$commandDefinition->setArgument(1, array_keys($namespaces));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ServiceLocatorTagPass::register($container, $servicesMap);
|
return ServiceLocatorTagPass::register($container, $servicesMap);
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
<?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\Form\Tests\Command;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Console\Application;
|
||||||
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
|
use Symfony\Component\Form\Command\DebugCommand;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\FormRegistryInterface;
|
||||||
|
use Symfony\Component\Form\ResolvedFormTypeInterface;
|
||||||
|
|
||||||
|
class DebugCommandTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testDebugSingleFormType()
|
||||||
|
{
|
||||||
|
$tester = $this->createCommandTester();
|
||||||
|
$ret = $tester->execute(array('class' => 'FormType'), array('decorated' => false));
|
||||||
|
|
||||||
|
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
|
||||||
|
$this->assertContains('Symfony\Component\Form\Extension\Core\Type\FormType (Block prefix: "form")', $tester->getDisplay());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testDebugInvalidFormType()
|
||||||
|
{
|
||||||
|
$this->createCommandTester()->execute(array('class' => 'test'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return CommandTester
|
||||||
|
*/
|
||||||
|
private function createCommandTester()
|
||||||
|
{
|
||||||
|
$resolvedFormType = $this->getMockBuilder(ResolvedFormTypeInterface::class)->getMock();
|
||||||
|
$resolvedFormType
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getParent')
|
||||||
|
->willReturn(null)
|
||||||
|
;
|
||||||
|
$resolvedFormType
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getInnerType')
|
||||||
|
->willReturn(new FormType())
|
||||||
|
;
|
||||||
|
$resolvedFormType
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getTypeExtensions')
|
||||||
|
->willReturn(array())
|
||||||
|
;
|
||||||
|
|
||||||
|
$formRegistry = $this->getMockBuilder(FormRegistryInterface::class)->getMock();
|
||||||
|
$formRegistry
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getType')
|
||||||
|
->will($this->returnValue($resolvedFormType))
|
||||||
|
;
|
||||||
|
|
||||||
|
$command = new DebugCommand($formRegistry);
|
||||||
|
$application = new Application();
|
||||||
|
$application->add($command);
|
||||||
|
|
||||||
|
return new CommandTester($application->find('debug:form'));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
<?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\Form\Tests\Console\Descriptor;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Console\Input\ArrayInput;
|
||||||
|
use Symfony\Component\Console\Output\BufferedOutput;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\Extension\Csrf\Type\FormTypeCsrfExtension;
|
||||||
|
use Symfony\Component\Form\ResolvedFormType;
|
||||||
|
use Symfony\Component\Form\ResolvedFormTypeInterface;
|
||||||
|
use Symfony\Component\Security\Csrf\CsrfTokenManager;
|
||||||
|
|
||||||
|
abstract class AbstractDescriptorTest extends TestCase
|
||||||
|
{
|
||||||
|
/** @dataProvider getDescribeResolvedFormTypeTestData */
|
||||||
|
public function testDescribeResolvedFormType(ResolvedFormTypeInterface $type, array $options, $fixtureName)
|
||||||
|
{
|
||||||
|
$expectedDescription = $this->getExpectedDescription($fixtureName);
|
||||||
|
$describedObject = $this->getObjectDescription($type, $options);
|
||||||
|
|
||||||
|
if ('json' === $this->getFormat()) {
|
||||||
|
$this->assertEquals(json_encode(json_decode($expectedDescription), JSON_PRETTY_PRINT), json_encode(json_decode($describedObject), JSON_PRETTY_PRINT));
|
||||||
|
} else {
|
||||||
|
$this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $describedObject)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescribeResolvedFormTypeTestData()
|
||||||
|
{
|
||||||
|
$typeExtensions = array(
|
||||||
|
new FormTypeCsrfExtension(new CsrfTokenManager()),
|
||||||
|
);
|
||||||
|
$parent = new ResolvedFormType(new FormType(), $typeExtensions);
|
||||||
|
|
||||||
|
yield array(new ResolvedFormType(new ChoiceType(), array(), $parent), array(), 'resolved_form_type_1');
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function getDescriptor();
|
||||||
|
|
||||||
|
abstract protected function getFormat();
|
||||||
|
|
||||||
|
private function getObjectDescription($object, array $options = array())
|
||||||
|
{
|
||||||
|
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
|
||||||
|
$io = new SymfonyStyle(new ArrayInput(array()), $output);
|
||||||
|
|
||||||
|
$this->getDescriptor()->describe($io, $object, $options);
|
||||||
|
|
||||||
|
return $output->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getExpectedDescription($name)
|
||||||
|
{
|
||||||
|
return file_get_contents($this->getFixtureFilename($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFixtureFilename($name)
|
||||||
|
{
|
||||||
|
return sprintf('%s/../../Fixtures/Descriptor/%s.%s', __DIR__, $name, $this->getFormat());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
<?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\Form\Tests\Console\Descriptor;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\Console\Descriptor\JsonDescriptor;
|
||||||
|
|
||||||
|
class JsonDescriptorTest extends AbstractDescriptorTest
|
||||||
|
{
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
putenv('COLUMNS=121');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
putenv('COLUMNS');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDescriptor()
|
||||||
|
{
|
||||||
|
return new JsonDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFormat()
|
||||||
|
{
|
||||||
|
return 'json';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
<?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\Form\Tests\Console\Descriptor;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\Console\Descriptor\TextDescriptor;
|
||||||
|
|
||||||
|
class TextDescriptorTest extends AbstractDescriptorTest
|
||||||
|
{
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
putenv('COLUMNS=121');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
putenv('COLUMNS');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDescriptor()
|
||||||
|
{
|
||||||
|
return new TextDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFormat()
|
||||||
|
{
|
||||||
|
return 'txt';
|
||||||
|
}
|
||||||
|
}
|
@ -14,12 +14,14 @@ namespace Symfony\Component\Form\Tests\DependencyInjection;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
|
use Symfony\Component\Form\Command\DebugCommand;
|
||||||
use Symfony\Component\Form\DependencyInjection\FormPass;
|
use Symfony\Component\Form\DependencyInjection\FormPass;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
use Symfony\Component\DependencyInjection\ServiceLocator;
|
use Symfony\Component\DependencyInjection\ServiceLocator;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormRegistryInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
@ -35,6 +37,15 @@ class FormPassTest extends TestCase
|
|||||||
$this->assertFalse($container->hasDefinition('form.extension'));
|
$this->assertFalse($container->hasDefinition('form.extension'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDoNothingIfDebugCommandNotLoaded()
|
||||||
|
{
|
||||||
|
$container = $this->createContainerBuilder();
|
||||||
|
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
|
$this->assertFalse($container->hasDefinition(DebugCommand::class));
|
||||||
|
}
|
||||||
|
|
||||||
public function testAddTaggedTypes()
|
public function testAddTaggedTypes()
|
||||||
{
|
{
|
||||||
$container = $this->createContainerBuilder();
|
$container = $this->createContainerBuilder();
|
||||||
@ -56,6 +67,28 @@ class FormPassTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAddTaggedTypesToDebugCommand()
|
||||||
|
{
|
||||||
|
$container = $this->createContainerBuilder();
|
||||||
|
|
||||||
|
$container->setDefinition('form.extension', $this->createExtensionDefinition());
|
||||||
|
$container->setDefinition(DebugCommand::class, $this->createDebugCommandDefinition());
|
||||||
|
$container->register('my.type1', __CLASS__.'_Type1')->addTag('form.type');
|
||||||
|
$container->register('my.type2', __CLASS__.'_Type2')->addTag('form.type');
|
||||||
|
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
|
$cmdDefinition = $container->getDefinition(DebugCommand::class);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'Symfony\Component\Form\Extension\Core\Type',
|
||||||
|
__NAMESPACE__,
|
||||||
|
),
|
||||||
|
$cmdDefinition->getArgument(1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider addTaggedTypeExtensionsDataProvider
|
* @dataProvider addTaggedTypeExtensionsDataProvider
|
||||||
*/
|
*/
|
||||||
@ -225,6 +258,18 @@ class FormPassTest extends TestCase
|
|||||||
return $definition;
|
return $definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createDebugCommandDefinition()
|
||||||
|
{
|
||||||
|
$definition = new Definition('Symfony\Component\Form\Command\DebugCommand');
|
||||||
|
$definition->setArguments(array(
|
||||||
|
$formRegistry = $this->getMockBuilder(FormRegistryInterface::class)->getMock(),
|
||||||
|
array(),
|
||||||
|
array('Symfony\Component\Form\Extension\Core\Type'),
|
||||||
|
));
|
||||||
|
|
||||||
|
return $definition;
|
||||||
|
}
|
||||||
|
|
||||||
private function createContainerBuilder()
|
private function createContainerBuilder()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"class": "Symfony\\Component\\Form\\Extension\\Core\\Type\\ChoiceType",
|
||||||
|
"block_prefix": "choice",
|
||||||
|
"options": {
|
||||||
|
"own": [
|
||||||
|
"choice_attr",
|
||||||
|
"choice_label",
|
||||||
|
"choice_loader",
|
||||||
|
"choice_name",
|
||||||
|
"choice_translation_domain",
|
||||||
|
"choice_value",
|
||||||
|
"choices",
|
||||||
|
"choices_as_values",
|
||||||
|
"expanded",
|
||||||
|
"group_by",
|
||||||
|
"multiple",
|
||||||
|
"placeholder",
|
||||||
|
"preferred_choices"
|
||||||
|
],
|
||||||
|
"overridden": {
|
||||||
|
"Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType": [
|
||||||
|
"compound",
|
||||||
|
"data_class",
|
||||||
|
"empty_data",
|
||||||
|
"error_bubbling"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"parent": {
|
||||||
|
"Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType": [
|
||||||
|
"action",
|
||||||
|
"attr",
|
||||||
|
"auto_initialize",
|
||||||
|
"block_name",
|
||||||
|
"by_reference",
|
||||||
|
"data",
|
||||||
|
"disabled",
|
||||||
|
"inherit_data",
|
||||||
|
"label",
|
||||||
|
"label_attr",
|
||||||
|
"label_format",
|
||||||
|
"mapped",
|
||||||
|
"method",
|
||||||
|
"post_max_size_message",
|
||||||
|
"property_path",
|
||||||
|
"required",
|
||||||
|
"translation_domain",
|
||||||
|
"trim",
|
||||||
|
"upload_max_size_message"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"extension": {
|
||||||
|
"Symfony\\Component\\Form\\Extension\\Csrf\\Type\\FormTypeCsrfExtension": [
|
||||||
|
"csrf_field_name",
|
||||||
|
"csrf_message",
|
||||||
|
"csrf_protection",
|
||||||
|
"csrf_token_id",
|
||||||
|
"csrf_token_manager"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
|
"parent_types": [
|
||||||
|
"Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType"
|
||||||
|
],
|
||||||
|
"type_extensions": [
|
||||||
|
"Symfony\\Component\\Form\\Extension\\Csrf\\Type\\FormTypeCsrfExtension"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
[33mSymfony\Component\Form\Extension\Core\Type\ChoiceType (Block prefix: "choice")[39m
|
||||||
|
[33m==============================================================================[39m
|
||||||
|
|
||||||
|
--------------------------- -------------------- ------------------------- -----------------------
|
||||||
|
[32m Options [39m [32m Overridden options [39m [32m Parent options [39m [32m Extension options [39m
|
||||||
|
--------------------------- -------------------- ------------------------- -----------------------
|
||||||
|
choice_attr [32mFormType[39m [32mFormType[39m [32mFormTypeCsrfExtension[39m
|
||||||
|
choice_label -------------------- ------------------------- -----------------------
|
||||||
|
choice_loader compound action csrf_field_name
|
||||||
|
choice_name data_class attr csrf_message
|
||||||
|
choice_translation_domain empty_data auto_initialize csrf_protection
|
||||||
|
choice_value error_bubbling block_name csrf_token_id
|
||||||
|
choices by_reference csrf_token_manager
|
||||||
|
choices_as_values data
|
||||||
|
expanded disabled
|
||||||
|
group_by inherit_data
|
||||||
|
multiple label
|
||||||
|
placeholder label_attr
|
||||||
|
preferred_choices label_format
|
||||||
|
mapped
|
||||||
|
method
|
||||||
|
post_max_size_message
|
||||||
|
property_path
|
||||||
|
required
|
||||||
|
translation_domain
|
||||||
|
trim
|
||||||
|
upload_max_size_message
|
||||||
|
--------------------------- -------------------- ------------------------- -----------------------
|
||||||
|
|
||||||
|
[33mParent types[39m
|
||||||
|
[33m------------[39m
|
||||||
|
|
||||||
|
* Symfony\Component\Form\Extension\Core\Type\FormType
|
||||||
|
|
||||||
|
[33mType extensions[39m
|
||||||
|
[33m---------------[39m
|
||||||
|
|
||||||
|
* Symfony\Component\Form\Extension\Csrf\Type\FormTypeCsrfExtension
|
||||||
|
|
91
src/Symfony/Component/Form/Util/OptionsResolverWrapper.php
Normal file
91
src/Symfony/Component/Form/Util/OptionsResolverWrapper.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?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\Form\Util;
|
||||||
|
|
||||||
|
use Symfony\Component\OptionsResolver\Exception\AccessException;
|
||||||
|
use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class OptionsResolverWrapper extends OptionsResolver
|
||||||
|
{
|
||||||
|
private $undefined = array();
|
||||||
|
|
||||||
|
public function setNormalizer($option, \Closure $normalizer)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
parent::setNormalizer($option, $normalizer);
|
||||||
|
} catch (UndefinedOptionsException $e) {
|
||||||
|
$this->undefined[$option] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAllowedValues($option, $allowedValues)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
parent::setAllowedValues($option, $allowedValues);
|
||||||
|
} catch (UndefinedOptionsException $e) {
|
||||||
|
$this->undefined[$option] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addAllowedValues($option, $allowedValues)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
parent::addAllowedValues($option, $allowedValues);
|
||||||
|
} catch (UndefinedOptionsException $e) {
|
||||||
|
$this->undefined[$option] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAllowedTypes($option, $allowedTypes)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
parent::setAllowedTypes($option, $allowedTypes);
|
||||||
|
} catch (UndefinedOptionsException $e) {
|
||||||
|
$this->undefined[$option] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addAllowedTypes($option, $allowedTypes)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
parent::addAllowedTypes($option, $allowedTypes);
|
||||||
|
} catch (UndefinedOptionsException $e) {
|
||||||
|
$this->undefined[$option] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resolve(array $options = array())
|
||||||
|
{
|
||||||
|
throw new AccessException('Resolve options is not supported.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUndefinedOptions()
|
||||||
|
{
|
||||||
|
return array_keys($this->undefined);
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
"php": "^5.5.9|>=7.0.8",
|
"php": "^5.5.9|>=7.0.8",
|
||||||
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
|
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
|
||||||
"symfony/intl": "^2.8.18|^3.2.5|~4.0",
|
"symfony/intl": "^2.8.18|^3.2.5|~4.0",
|
||||||
"symfony/options-resolver": "~2.8|~3.0|~4.0",
|
"symfony/options-resolver": "~3.4|~4.0",
|
||||||
"symfony/polyfill-mbstring": "~1.0",
|
"symfony/polyfill-mbstring": "~1.0",
|
||||||
"symfony/property-access": "~2.8|~3.0|~4.0"
|
"symfony/property-access": "~2.8|~3.0|~4.0"
|
||||||
},
|
},
|
||||||
@ -32,7 +32,8 @@
|
|||||||
"symfony/http-kernel": "^3.3.5|~4.0",
|
"symfony/http-kernel": "^3.3.5|~4.0",
|
||||||
"symfony/security-csrf": "~2.8|~3.0|~4.0",
|
"symfony/security-csrf": "~2.8|~3.0|~4.0",
|
||||||
"symfony/translation": "~2.8|~3.0|~4.0",
|
"symfony/translation": "~2.8|~3.0|~4.0",
|
||||||
"symfony/var-dumper": "~3.3|~4.0"
|
"symfony/var-dumper": "~3.3|~4.0",
|
||||||
|
"symfony/console": "~3.4|~4.0"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
|
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
|
||||||
|
Reference in New Issue
Block a user