vendor/symfony/form/ResolvedFormType.php line 106

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Form;
  11. use Symfony\Component\EventDispatcher\EventDispatcher;
  12. use Symfony\Component\Form\Exception\UnexpectedTypeException;
  13. use Symfony\Component\OptionsResolver\Exception\ExceptionInterface;
  14. use Symfony\Component\OptionsResolver\OptionsResolver;
  15. /**
  16.  * A wrapper for a form type and its extensions.
  17.  *
  18.  * @author Bernhard Schussek <bschussek@gmail.com>
  19.  */
  20. class ResolvedFormType implements ResolvedFormTypeInterface
  21. {
  22.     private FormTypeInterface $innerType;
  23.     /**
  24.      * @var FormTypeExtensionInterface[]
  25.      */
  26.     private array $typeExtensions;
  27.     private ?ResolvedFormTypeInterface $parent;
  28.     private OptionsResolver $optionsResolver;
  29.     /**
  30.      * @param FormTypeExtensionInterface[] $typeExtensions
  31.      */
  32.     public function __construct(FormTypeInterface $innerType, array $typeExtensions = [], ResolvedFormTypeInterface $parent null)
  33.     {
  34.         foreach ($typeExtensions as $extension) {
  35.             if (!$extension instanceof FormTypeExtensionInterface) {
  36.                 throw new UnexpectedTypeException($extensionFormTypeExtensionInterface::class);
  37.             }
  38.         }
  39.         $this->innerType $innerType;
  40.         $this->typeExtensions $typeExtensions;
  41.         $this->parent $parent;
  42.     }
  43.     public function getBlockPrefix(): string
  44.     {
  45.         return $this->innerType->getBlockPrefix();
  46.     }
  47.     public function getParent(): ?ResolvedFormTypeInterface
  48.     {
  49.         return $this->parent;
  50.     }
  51.     public function getInnerType(): FormTypeInterface
  52.     {
  53.         return $this->innerType;
  54.     }
  55.     public function getTypeExtensions(): array
  56.     {
  57.         return $this->typeExtensions;
  58.     }
  59.     public function createBuilder(FormFactoryInterface $factorystring $name, array $options = []): FormBuilderInterface
  60.     {
  61.         try {
  62.             $options $this->getOptionsResolver()->resolve($options);
  63.         } catch (ExceptionInterface $e) {
  64.             throw new $e(sprintf('An error has occurred resolving the options of the form "%s": 'get_debug_type($this->getInnerType())).$e->getMessage(), $e->getCode(), $e);
  65.         }
  66.         // Should be decoupled from the specific option at some point
  67.         $dataClass $options['data_class'] ?? null;
  68.         $builder $this->newBuilder($name$dataClass$factory$options);
  69.         $builder->setType($this);
  70.         return $builder;
  71.     }
  72.     public function createView(FormInterface $formFormView $parent null): FormView
  73.     {
  74.         return $this->newView($parent);
  75.     }
  76.     public function buildForm(FormBuilderInterface $builder, array $options)
  77.     {
  78.         $this->parent?->buildForm($builder$options);
  79.         $this->innerType->buildForm($builder$options);
  80.         foreach ($this->typeExtensions as $extension) {
  81.             $extension->buildForm($builder$options);
  82.         }
  83.     }
  84.     public function buildView(FormView $viewFormInterface $form, array $options)
  85.     {
  86.         $this->parent?->buildView($view$form$options);
  87.         $this->innerType->buildView($view$form$options);
  88.         foreach ($this->typeExtensions as $extension) {
  89.             $extension->buildView($view$form$options);
  90.         }
  91.     }
  92.     public function finishView(FormView $viewFormInterface $form, array $options)
  93.     {
  94.         $this->parent?->finishView($view$form$options);
  95.         $this->innerType->finishView($view$form$options);
  96.         foreach ($this->typeExtensions as $extension) {
  97.             /* @var FormTypeExtensionInterface $extension */
  98.             $extension->finishView($view$form$options);
  99.         }
  100.     }
  101.     public function getOptionsResolver(): OptionsResolver
  102.     {
  103.         if (!isset($this->optionsResolver)) {
  104.             if (null !== $this->parent) {
  105.                 $this->optionsResolver = clone $this->parent->getOptionsResolver();
  106.             } else {
  107.                 $this->optionsResolver = new OptionsResolver();
  108.             }
  109.             $this->innerType->configureOptions($this->optionsResolver);
  110.             foreach ($this->typeExtensions as $extension) {
  111.                 $extension->configureOptions($this->optionsResolver);
  112.             }
  113.         }
  114.         return $this->optionsResolver;
  115.     }
  116.     /**
  117.      * Creates a new builder instance.
  118.      *
  119.      * Override this method if you want to customize the builder class.
  120.      */
  121.     protected function newBuilder(string $name, ?string $dataClassFormFactoryInterface $factory, array $options): FormBuilderInterface
  122.     {
  123.         if ($this->innerType instanceof ButtonTypeInterface) {
  124.             return new ButtonBuilder($name$options);
  125.         }
  126.         if ($this->innerType instanceof SubmitButtonTypeInterface) {
  127.             return new SubmitButtonBuilder($name$options);
  128.         }
  129.         return new FormBuilder($name$dataClass, new EventDispatcher(), $factory$options);
  130.     }
  131.     /**
  132.      * Creates a new view instance.
  133.      *
  134.      * Override this method if you want to customize the view class.
  135.      */
  136.     protected function newView(FormView $parent null): FormView
  137.     {
  138.         return new FormView($parent);
  139.     }
  140. }