vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php line 78

Open in your IDE?
  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\Form\Exception\ExceptionInterface;
  12. use Symfony\Component\Form\Exception\InvalidArgumentException;
  13. use Symfony\Component\Form\Exception\LogicException;
  14. use Symfony\Component\Form\Exception\UnexpectedTypeException;
  15. /**
  16.  * The central registry of the Form component.
  17.  *
  18.  * @author Bernhard Schussek <bschussek@gmail.com>
  19.  */
  20. class FormRegistry implements FormRegistryInterface
  21. {
  22.     /**
  23.      * Extensions.
  24.      *
  25.      * @var FormExtensionInterface[]
  26.      */
  27.     private $extensions = [];
  28.     /**
  29.      * @var ResolvedFormTypeInterface[]
  30.      */
  31.     private $types = [];
  32.     /**
  33.      * @var FormTypeGuesserInterface|false|null
  34.      */
  35.     private $guesser false;
  36.     /**
  37.      * @var ResolvedFormTypeFactoryInterface
  38.      */
  39.     private $resolvedTypeFactory;
  40.     private $checkedTypes = [];
  41.     /**
  42.      * @param FormExtensionInterface[]         $extensions          An array of FormExtensionInterface
  43.      * @param ResolvedFormTypeFactoryInterface $resolvedTypeFactory The factory for resolved form types
  44.      *
  45.      * @throws UnexpectedTypeException if any extension does not implement FormExtensionInterface
  46.      */
  47.     public function __construct(array $extensionsResolvedFormTypeFactoryInterface $resolvedTypeFactory)
  48.     {
  49.         foreach ($extensions as $extension) {
  50.             if (!$extension instanceof FormExtensionInterface) {
  51.                 throw new UnexpectedTypeException($extension'Symfony\Component\Form\FormExtensionInterface');
  52.             }
  53.         }
  54.         $this->extensions $extensions;
  55.         $this->resolvedTypeFactory $resolvedTypeFactory;
  56.     }
  57.     /**
  58.      * {@inheritdoc}
  59.      */
  60.     public function getType($name)
  61.     {
  62.         if (!isset($this->types[$name])) {
  63.             $type null;
  64.             foreach ($this->extensions as $extension) {
  65.                 if ($extension->hasType($name)) {
  66.                     $type $extension->getType($name);
  67.                     break;
  68.                 }
  69.             }
  70.             if (!$type) {
  71.                 // Support fully-qualified class names
  72.                 if (!class_exists($name)) {
  73.                     throw new InvalidArgumentException(sprintf('Could not load type "%s": class does not exist.'$name));
  74.                 }
  75.                 if (!is_subclass_of($name'Symfony\Component\Form\FormTypeInterface')) {
  76.                     throw new InvalidArgumentException(sprintf('Could not load type "%s": class does not implement "Symfony\Component\Form\FormTypeInterface".'$name));
  77.                 }
  78.                 $type = new $name();
  79.             }
  80.             $this->types[$name] = $this->resolveType($type);
  81.         }
  82.         return $this->types[$name];
  83.     }
  84.     /**
  85.      * Wraps a type into a ResolvedFormTypeInterface implementation and connects
  86.      * it with its parent type.
  87.      *
  88.      * @param FormTypeInterface $type The type to resolve
  89.      *
  90.      * @return ResolvedFormTypeInterface The resolved type
  91.      */
  92.     private function resolveType(FormTypeInterface $type)
  93.     {
  94.         $typeExtensions = [];
  95.         $parentType $type->getParent();
  96.         $fqcn = \get_class($type);
  97.         if (isset($this->checkedTypes[$fqcn])) {
  98.             $types implode(' > 'array_merge(array_keys($this->checkedTypes), [$fqcn]));
  99.             throw new LogicException(sprintf('Circular reference detected for form type "%s" (%s).'$fqcn$types));
  100.         }
  101.         $this->checkedTypes[$fqcn] = true;
  102.         try {
  103.             foreach ($this->extensions as $extension) {
  104.                 $typeExtensions array_merge(
  105.                     $typeExtensions,
  106.                     $extension->getTypeExtensions($fqcn)
  107.                 );
  108.             }
  109.             return $this->resolvedTypeFactory->createResolvedType(
  110.                 $type,
  111.                 $typeExtensions,
  112.                 $parentType $this->getType($parentType) : null
  113.             );
  114.         } finally {
  115.             unset($this->checkedTypes[$fqcn]);
  116.         }
  117.     }
  118.     /**
  119.      * {@inheritdoc}
  120.      */
  121.     public function hasType($name)
  122.     {
  123.         if (isset($this->types[$name])) {
  124.             return true;
  125.         }
  126.         try {
  127.             $this->getType($name);
  128.         } catch (ExceptionInterface $e) {
  129.             return false;
  130.         }
  131.         return true;
  132.     }
  133.     /**
  134.      * {@inheritdoc}
  135.      */
  136.     public function getTypeGuesser()
  137.     {
  138.         if (false === $this->guesser) {
  139.             $guessers = [];
  140.             foreach ($this->extensions as $extension) {
  141.                 $guesser $extension->getTypeGuesser();
  142.                 if ($guesser) {
  143.                     $guessers[] = $guesser;
  144.                 }
  145.             }
  146.             $this->guesser = !empty($guessers) ? new FormTypeGuesserChain($guessers) : null;
  147.         }
  148.         return $this->guesser;
  149.     }
  150.     /**
  151.      * {@inheritdoc}
  152.      */
  153.     public function getExtensions()
  154.     {
  155.         return $this->extensions;
  156.     }
  157. }