4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Form
;
14 use Symfony\Component\Form\Exception\ExceptionInterface
;
15 use Symfony\Component\Form\Exception\UnexpectedTypeException
;
16 use Symfony\Component\Form\Exception\InvalidArgumentException
;
19 * The central registry of the Form component.
21 * @author Bernhard Schussek <bschussek@gmail.com>
23 class FormRegistry
implements FormRegistryInterface
28 * @var FormExtensionInterface[] An array of FormExtensionInterface
30 private $extensions = array();
35 private $types = array();
38 * @var FormTypeGuesserInterface|false|null
40 private $guesser = false;
43 * @var ResolvedFormTypeFactoryInterface
45 private $resolvedTypeFactory;
50 * @param FormExtensionInterface[] $extensions An array of FormExtensionInterface
51 * @param ResolvedFormTypeFactoryInterface $resolvedTypeFactory The factory for resolved form types.
53 * @throws UnexpectedTypeException if any extension does not implement FormExtensionInterface
55 public function __construct(array $extensions, ResolvedFormTypeFactoryInterface
$resolvedTypeFactory)
57 foreach ($extensions as $extension) {
58 if (!$extension instanceof FormExtensionInterface
) {
59 throw new UnexpectedTypeException($extension, 'Symfony\Component\Form\FormExtensionInterface');
63 $this->extensions
= $extensions;
64 $this->resolvedTypeFactory
= $resolvedTypeFactory;
70 public function getType($name)
72 if (!is_string($name)) {
73 throw new UnexpectedTypeException($name, 'string');
76 if (!isset($this->types
[$name])) {
77 /** @var FormTypeInterface $type */
80 foreach ($this->extensions
as $extension) {
81 /* @var FormExtensionInterface $extension */
82 if ($extension->hasType($name)) {
83 $type = $extension->getType($name);
89 throw new InvalidArgumentException(sprintf('Could not load type "%s"', $name));
92 $this->resolveAndAddType($type);
95 return $this->types
[$name];
99 * Wraps a type into a ResolvedFormTypeInterface implementation and connects
100 * it with its parent type.
102 * @param FormTypeInterface $type The type to resolve.
104 * @return ResolvedFormTypeInterface The resolved type.
106 private function resolveAndAddType(FormTypeInterface
$type)
108 $parentType = $type->getParent();
110 if ($parentType instanceof FormTypeInterface
) {
111 $this->resolveAndAddType($parentType);
112 $parentType = $parentType->getName();
115 $typeExtensions = array();
117 foreach ($this->extensions
as $extension) {
118 /* @var FormExtensionInterface $extension */
119 $typeExtensions = array_merge(
121 $extension->getTypeExtensions($type->getName())
125 $this->types
[$type->getName()] = $this->resolvedTypeFactory
->createResolvedType(
128 $parentType ? $this->getType($parentType) : null
135 public function hasType($name)
137 if (isset($this->types
[$name])) {
142 $this->getType($name);
143 } catch (ExceptionInterface
$e) {
153 public function getTypeGuesser()
155 if (false === $this->guesser
) {
158 foreach ($this->extensions
as $extension) {
159 /* @var FormExtensionInterface $extension */
160 $guesser = $extension->getTypeGuesser();
163 $guessers[] = $guesser;
167 $this->guesser
= !empty($guessers) ? new FormTypeGuesserChain($guessers) : null;
170 return $this->guesser
;
176 public function getExtensions()
178 return $this->extensions
;