Permalink
Browse files

[Form] Fixed ResolvedFormType to really be replaceable

  • Loading branch information...
webmozart committed Jul 29, 2012
1 parent 1f83baa commit 73f3ce31123de6f0760618ee0331d56cbfbd382f
View
@@ -152,12 +152,12 @@ CHANGELOG
* deprecated the options "data_timezone" and "user_timezone" in DateType, DateTimeType and TimeType
and renamed them to "model_timezone" and "view_timezone"
* fixed: TransformationFailedExceptions thrown in the model transformer are now caught by the form
- * added FormRegistry and ResolvedFormTypeInterface
+ * added FormRegistryInterface, ResolvedFormTypeInterface and ResolvedFormTypeFactoryInterface
* deprecated FormFactory methods
* `addType`
* `hasType`
* `getType`
- * [BC BREAK] FormFactory now expects a FormRegistryInterface as constructor argument
+ * [BC BREAK] FormFactory now expects a FormRegistryInterface and a ResolvedFormTypeFactoryInterface as constructor argument
* [BC BREAK] The method `createBuilder` in FormTypeInterface is not supported anymore for performance reasons
* [BC BREAK] Removed `setTypes` from FormBuilder
* deprecated AbstractType methods
View
@@ -23,9 +23,15 @@ class FormFactory implements FormFactoryInterface
*/
private $registry;
- public function __construct(FormRegistryInterface $registry)
+ /**
+ * @var ResolvedFormTypeFactoryInterface
+ */
+ private $resolvedTypeFactory;
+
+ public function __construct(FormRegistryInterface $registry, ResolvedFormTypeFactoryInterface $resolvedTypeFactory)
{
$this->registry = $registry;
+ $this->resolvedTypeFactory = $resolvedTypeFactory;
}
/**
@@ -73,14 +79,20 @@ public function createNamedBuilder($name, $type, $data = null, array $options =
$options['data'] = $data;
}
- if ($type instanceof ResolvedFormTypeInterface) {
- $this->registry->addType($type);
- } elseif ($type instanceof FormTypeInterface) {
- $type = $this->registry->resolveType($type);
- $this->registry->addType($type);
+ if ($type instanceof FormTypeInterface) {
+ // An unresolved type instance was passed. Type extensions
+ // are not supported for these. If you want to use type
+ // extensions, you should create form extensions or register
+ // your type in the Dependency Injection configuration instead.
+ $parentType = $type->getParent();
+ $type = $this->resolvedTypeFactory->createResolvedType(
+ $type,
+ array(),
+ $parentType ? $this->registry->getType($parentType) : null
+ );
} elseif (is_string($type)) {
$type = $this->registry->getType($type);
- } else {
+ } elseif (!$type instanceof ResolvedFormTypeInterface) {
throw new UnexpectedTypeException($type, 'string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface');
}
@@ -152,12 +164,18 @@ public function hasType($name)
* @param FormTypeInterface $type The type
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
- * {@link FormRegistryInterface::resolveType()} and
- * {@link FormRegistryInterface::addType()} instead.
+ * form extensions or type registration in the Dependency
+ * Injection Container instead.
*/
public function addType(FormTypeInterface $type)
{
- $this->registry->addType($this->registry->resolveType($type));
+ $parentType = $type->getParent();
+
+ $this->registry->addType($this->resolvedTypeFactory->createResolvedType(
+ $type,
+ array(),
+ $parentType ? $this->registry->getType($parentType) : null
+ ));
}
/**
View
@@ -37,14 +37,20 @@ class FormRegistry implements FormRegistryInterface
*/
private $guesser;
+ /**
+ * @var ResolvedFormTypeFactoryInterface
+ */
+ private $resolvedTypeFactory;
+
/**
* Constructor.
*
- * @param array $extensions An array of FormExtensionInterface
+ * @param array $extensions An array of FormExtensionInterface
+ * @param ResolvedFormTypeFactoryInterface $resolvedTypeFactory The factory for resolved form types.
*
* @throws UnexpectedTypeException if any extension does not implement FormExtensionInterface
*/
- public function __construct(array $extensions)
+ public function __construct(array $extensions, ResolvedFormTypeFactoryInterface $resolvedTypeFactory)
{
foreach ($extensions as $extension) {
if (!$extension instanceof FormExtensionInterface) {
@@ -53,26 +59,7 @@ public function __construct(array $extensions)
}
$this->extensions = $extensions;
- }
-
- /**
- * {@inheritdoc}
- */
- public function resolveType(FormTypeInterface $type)
- {
- $typeExtensions = array();
-
- foreach ($this->extensions as $extension) {
- /* @var FormExtensionInterface $extension */
- $typeExtensions = array_merge(
- $typeExtensions,
- $extension->getTypeExtensions($type->getName())
- );
- }
-
- $parent = $type->getParent() ? $this->getType($type->getParent()) : null;
-
- return new ResolvedFormType($type, $typeExtensions, $parent);
+ $this->resolvedTypeFactory = $resolvedTypeFactory;
}
/**
@@ -93,6 +80,7 @@ public function getType($name)
}
if (!isset($this->types[$name])) {
+ /** @var FormTypeInterface $type */
$type = null;
foreach ($this->extensions as $extension) {
@@ -107,7 +95,22 @@ public function getType($name)
throw new FormException(sprintf('Could not load type "%s"', $name));
}
- $this->addType($this->resolveType($type));
+ $parentType = $type->getParent();
+ $typeExtensions = array();
+
+ foreach ($this->extensions as $extension) {
+ /* @var FormExtensionInterface $extension */
+ $typeExtensions = array_merge(
+ $typeExtensions,
+ $extension->getTypeExtensions($name)
+ );
+ }
+
+ $this->addType($this->resolvedTypeFactory->createResolvedType(
+ $type,
+ $typeExtensions,
+ $parentType ? $this->getType($parentType) : null
+ ));
}
return $this->types[$name];
View
@@ -22,6 +22,10 @@
* Adds a form type.
*
* @param ResolvedFormTypeInterface $type The type
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+ * form extensions or type registration in the Dependency
+ * Injection Container instead.
*/
public function addType(ResolvedFormTypeInterface $type);
@@ -48,18 +52,6 @@ public function getType($name);
*/
public function hasType($name);
- /**
- * Resolves a form type.
- *
- * @param FormTypeInterface $type
- *
- * @return ResolvedFormTypeInterface
- *
- * @throws Exception\UnexpectedTypeException if the types parent {@link FormTypeInterface::getParent()} is not a string
- * @throws Exception\FormException if the types parent can not be retrieved from any extension
- */
- public function resolveType(FormTypeInterface $type);
-
/**
* Returns the guesser responsible for guessing types.
*
View
@@ -35,7 +35,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
private $typeExtensions;
/**
- * @var ResolvedFormType
+ * @var ResolvedFormTypeInterface
*/
private $parent;
@@ -44,7 +44,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
*/
private $optionsResolver;
- public function __construct(FormTypeInterface $innerType, array $typeExtensions = array(), ResolvedFormType $parent = null)
+ public function __construct(FormTypeInterface $innerType, array $typeExtensions = array(), ResolvedFormTypeInterface $parent = null)
{
if (!preg_match('/^[a-z0-9_]*$/i', $innerType->getName())) {
throw new FormException(sprintf(
@@ -148,7 +148,16 @@ public function createView(FormInterface $form, FormView $parent = null)
return $view;
}
- private function buildForm(FormBuilderInterface $builder, array $options)
+ /**
+ * Configures a form builder for the type hierarchy.
+ *
+ * This method is protected in order to allow implementing classes
+ * to change or call it in re-implementations of {@link createBuilder()}.
+ *
+ * @param FormBuilderInterface $builder The builder to configure.
+ * @param array $options The options used for the configuration.
+ */
+ public function buildForm(FormBuilderInterface $builder, array $options)
{
if (null !== $this->parent) {
$this->parent->buildForm($builder, $options);
@@ -162,7 +171,19 @@ private function buildForm(FormBuilderInterface $builder, array $options)
}
}
- private function buildView(FormView $view, FormInterface $form, array $options)
+ /**
+ * Configures a form view for the type hierarchy.
+ *
+ * This method is protected in order to allow implementing classes
+ * to change or call it in re-implementations of {@link createView()}.
+ *
+ * It is called before the children of the view are built.
+ *
+ * @param FormView $view The form view to configure.
+ * @param FormInterface $form The form corresponding to the view.
+ * @param array $options The options used for the configuration.
+ */
+ public function buildView(FormView $view, FormInterface $form, array $options)
{
if (null !== $this->parent) {
$this->parent->buildView($view, $form, $options);
@@ -176,7 +197,19 @@ private function buildView(FormView $view, FormInterface $form, array $options)
}
}
- private function finishView(FormView $view, FormInterface $form, array $options)
+ /**
+ * Finishes a form view for the type hierarchy.
+ *
+ * This method is protected in order to allow implementing classes
+ * to change or call it in re-implementations of {@link createView()}.
+ *
+ * It is called after the children of the view have been built.
+ *
+ * @param FormView $view The form view to configure.
+ * @param FormInterface $form The form corresponding to the view.
+ * @param array $options The options used for the configuration.
+ */
+ public function finishView(FormView $view, FormInterface $form, array $options)
{
if (null !== $this->parent) {
$this->parent->finishView($view, $form, $options);
@@ -190,7 +223,15 @@ private function finishView(FormView $view, FormInterface $form, array $options)
}
}
- private function getOptionsResolver()
+ /**
+ * Returns the configured options resolver used for this type.
+ *
+ * This method is protected in order to allow implementing classes
+ * to change or call it in re-implementations of {@link createBuilder()}.
+ *
+ * @return \Symfony\Component\OptionsResolver\OptionsResolverInterface The options resolver.
+ */
+ public function getOptionsResolver()
{
if (null === $this->optionsResolver) {
if (null !== $this->parent) {
@@ -0,0 +1,26 @@
+<?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;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ResolvedFormTypeFactory implements ResolvedFormTypeFactoryInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function createResolvedType(FormTypeInterface $type, array $typeExtensions, ResolvedFormTypeInterface $parent = null)
+ {
+ return new ResolvedFormType($type, $typeExtensions, $parent);
+ }
+}
@@ -0,0 +1,38 @@
+<?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;
+
+/**
+ * Creates ResolvedFormTypeInterface instances.
+ *
+ * This interface allows you to use your custom ResolvedFormTypeInterface
+ * implementation, within which you can customize the concrete FormBuilderInterface
+ * implementations or FormView subclasses that are used by the framework.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ResolvedFormTypeFactoryInterface
+{
+ /**
+ * Resolves a form type.
+ *
+ * @param FormTypeInterface $type
+ * @param array $typeExtensions
+ * @param ResolvedFormTypeInterface $parent
+ *
+ * @return ResolvedFormTypeInterface
+ *
+ * @throws Exception\UnexpectedTypeException if the types parent {@link FormTypeInterface::getParent()} is not a string
+ * @throws Exception\FormException if the types parent can not be retrieved from any extension
+ */
+ public function createResolvedType(FormTypeInterface $type, array $typeExtensions, ResolvedFormTypeInterface $parent = null);
+}
@@ -67,4 +67,41 @@ public function createBuilder(FormFactoryInterface $factory, $name, array $optio
* @return FormView The created form view.
*/
public function createView(FormInterface $form, FormView $parent = null);
+
+ /**
+ * Configures a form builder for the type hierarchy.
+ *
+ * @param FormBuilderInterface $builder The builder to configure.
+ * @param array $options The options used for the configuration.
+ */
+ public function buildForm(FormBuilderInterface $builder, array $options);
+
+ /**
+ * Configures a form view for the type hierarchy.
+ *
+ * It is called before the children of the view are built.
+ *
+ * @param FormView $view The form view to configure.
+ * @param FormInterface $form The form corresponding to the view.
+ * @param array $options The options used for the configuration.
+ */
+ public function buildView(FormView $view, FormInterface $form, array $options);
+
+ /**
+ * Finishes a form view for the type hierarchy.
+ *
+ * It is called after the children of the view have been built.
+ *
+ * @param FormView $view The form view to configure.
+ * @param FormInterface $form The form corresponding to the view.
+ * @param array $options The options used for the configuration.
+ */
+ public function finishView(FormView $view, FormInterface $form, array $options);
+
+ /**
+ * Returns the configured options resolver used for this type.
+ *
+ * @return \Symfony\Component\OptionsResolver\OptionsResolverInterface The options resolver.
+ */
+ public function getOptionsResolver();
}
Oops, something went wrong.

0 comments on commit 73f3ce3

Please sign in to comment.