diff --git a/UPGRADE-2.1.md b/UPGRADE-2.1.md index dad88e9117..39813e9c47 100644 --- a/UPGRADE-2.1.md +++ b/UPGRADE-2.1.md @@ -145,19 +145,330 @@ ### Form +#### BC Breaks in Form Types and Options + + * A third argument `$options` was added to the methods `buildView()` and + `buildViewBottomUp()` in `FormTypeInterface` and `FormTypeExtensionInterface`. + Furthermore, `buildViewBottomUp()` was renamed to `finishView()`. At last, + all methods in these types now receive instances of `FormBuilderInterface` + and `FormViewInterface` where they received instances of `FormBuilder` and + `FormView` before. You need to change the method signatures in your + form types and extensions as shown below. + + Before: + + ``` + use Symfony\Component\Form\FormBuilder; + use Symfony\Component\Form\FormView; + + public function buildForm(FormBuilder $builder, array $options) + public function buildView(FormView $view, FormInterface $form) + public function buildViewBottomUp(FormView $view, FormInterface $form) + ``` + + After: + + ``` + use Symfony\Component\Form\FormBuilderInterface; + use Symfony\Component\Form\FormViewInterface; + + public function buildForm(FormBuilderInterface $builder, array $options) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) + ``` + + * No options are passed to `getParent()` of `FormTypeInterface` anymore. If + you previously dynamically inherited from `FormType` or `FieldType`, you can now + dynamically set the "compound" option instead. + + Before: + + ``` + public function getParent(array $options) + { + return $options['expanded'] ? 'form' : 'field'; + } + ``` + + After: + + ``` + use Symfony\Component\OptionsResolver\OptionsResolverInterface; + use Symfony\Component\OptionsResolver\Options; + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $compound = function (Options $options) { + return $options['expanded']; + }; + + $resolver->setDefaults(array( + 'compound' => $compound, + )); + } + + public function getParent() + { + return 'form'; + } + ``` + + The new method `setDefaultOptions` is described in the section "Deprecations". + + * The "data_class" option now *must* be set if a form maps to an object. If + you leave it empty, the form will expect an array, an instance of \ArrayAccess + or a scalar value and fail with a corresponding exception. + + Likewise, if a form maps to an array or an instance of \ArrayAccess, the option + *must* be left null now. + + Form mapped to an instance of `Person`: + + ``` + use Symfony\Component\OptionsResolver\OptionsResolverInterface; + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Acme\Demo\Person', + )); + } + ``` + + The new method `setDefaultOptions` is described in the section "Deprecations". + + * The mapping of property paths to arrays has changed. + + Previously, a property path "street" mapped to both a field `$street` of + a class (or its accessors `getStreet()` and `setStreet()`) and an index + `['street']` of an array or an object implementing `\ArrayAccess`. + + Now, the property path "street" only maps to a class field (or accessors), + while the property path "[street]" only maps to indices. + + If you defined property paths manually in the "property_path" option, you + should revise them and adjust them if necessary. + + Before: + + ``` + $builder->add('name', 'text', array( + 'property_path' => 'address.street', + )); + ``` + + After (if the address object is an array): + + ``` + $builder->add('name', 'text', array( + 'property_path' => 'address[street]', + )); + ``` + + If address is an object in this case, the code given in "Before" + works without changes. + + * The methods in class `FormView` were renamed to match the naming used in + `Form` and `FormBuilder`. The following list shows the old names on the + left and the new names on the right: + + * `set`: `setVar` + * `has`: `hasVar` + * `get`: `getVar` + * `all`: `getVars` + * `addChild`: `add` + * `getChild`: `get` + * `getChildren`: `all` + * `removeChild`: `remove` + * `hasChild`: `has` + + The new method `addVars` was added to make the definition of multiple + variables at once more convenient. + + The method `hasChildren` was deprecated. You should use `count` instead. + + Before: + + ``` + $view->set('help', 'A text longer than six characters'); + $view->set('error_class', 'max_length_error'); + ``` + + After: + + ``` + $view->addVars(array( + 'help' => 'A text longer than six characters', + 'error_class' => 'max_length_error', + )); + ``` + + * Form and field names must now start with a letter, digit or underscore + and only contain letters, digits, underscores, hyphens and colons. + + * In the collection type's template, the default name of the prototype field + has changed from `$$name$$` to `__name__`. + + For custom names, dollar signs are no longer prepended and appended. You are + advised to prepend and append two underscores wherever you specify a value + for the field's "prototype_name" option. + + Before: + + ``` + $builder->add('tags', 'collection', array('prototype' => 'proto')); + + // results in the name "$$proto$$" in the template + ``` + + After: + + ``` + $builder->add('tags', 'collection', array('prototype' => '__proto__')); + + // results in the name "__proto__" in the template + ``` + + * The "read_only" option now renders as `readonly="readonly"`, use + "disabled" instead for `disabled="disabled"`. + * Child forms are no longer automatically validated. That means that you must explicitly set the `Valid` constraint in your model if you want to validate - associated objects. + objects modified by child forms. If you don't want to set the `Valid` constraint, or if there is no reference from the data of the parent form to the data of the child form, you can - enable BC behavior by setting the `cascade_validation` form option to `true` + enable BC behavior by setting the "cascade_validation" option to `true` on the parent form. - * Changed implementation of choice lists +#### BC Breaks in Themes and HTML - ArrayChoiceList was replaced. If you have custom classes that extend this - class, you must now extend SimpleChoiceList. + * FormType and FieldType were merged and require you to adapt your form + themes. + + The block `field_widget` and all references to it should be renamed to + `form_widget_simple`: + + Before: + + ``` + {% block url_widget %} + {% spaceless %} + {% set type = type|default('url') %} + {{ block('field_widget') }} + {% endspaceless %} + {% endblock url_widget %} + ``` + + After: + + ``` + {% block url_widget %} + {% spaceless %} + {% set type = type|default('url') %} + {{ block('form_widget_simple') }} + {% endspaceless %} + {% endblock url_widget %} + ``` + + All other `field_*` blocks and references to them should be renamed to + `form_*`. If you previously defined both a `field_*` and a `form_*` + block, you can merge them into a single `form_*` block and check the new + Boolean variable `compound` instead: + + Before: + + ``` + {% block form_errors %} + {% spaceless %} + ... form code ... + {% endspaceless %} + {% endblock form_errors %} + + {% block field_errors %} + {% spaceless %} + ... field code ... + {% endspaceless %} + {% endblock field_errors %} + ``` + + After: + + ``` + {% block form_errors %} + {% spaceless %} + {% if compound %} + ... form code ... + {% else %} + ... field code ... + {% endif %} + {% endspaceless %} + {% endblock form_errors %} + ``` + + Furthermore, the block `generic_label` was merged into `form_label`. You + should now override `form_label` in order to customize labels. + + Last but not least, the block `widget_choice_options` was renamed to + `choice_widget_options` to be consistent with the rest of the default + theme. + + * The strategy for generating the `id` and `name` HTML attributes for + checkboxes and radio buttons in a choice field has changed. + + Instead of appending the choice value, a generated integer is now appended + by default. Take care if your JavaScript relies on that. If you want to + read the actual choice value, read the `value` attribute instead. + + * In the choice field type's template, the structure of the `choices` variable + has changed. + + The `choices` variable now contains `ChoiceView` objects with two getters, + `getValue()` and `getLabel()`, to access the choice data. + + Before: + + ``` + {% for choice, label in choices %} + + {% endfor %} + ``` + + After: + + ``` + {% for choice in choices %} + + {% endfor %} + ``` + +#### Other BC Breaks + + * The order of the first two arguments of the methods `createNamed` and + `createNamedBuilder` in `FormFactoryInterface` was reversed to be + consistent with the rest of the component. You should scan your code + for occurrences of these methods and reverse the parameters. + + Before: + + ``` + $form = $factory->createNamed('text', 'firstName'); + ``` + + After: + + ``` + $form = $factory->createNamed('firstName', 'text'); + ``` + + * The implementation of `ChoiceList` was changed heavily. As a result, + `ArrayChoiceList` was replaced. If you have custom classes that extend + this class, you must now extend `SimpleChoiceList` and pass choices + to the parent constructor. Before: @@ -190,7 +501,8 @@ ``` If you need to load the choices lazily -- that is, as soon as they are - accessed for the first time -- you can extend LazyChoiceList instead. + accessed for the first time -- you can extend `LazyChoiceList` instead + and load the choices by overriding `loadChoiceList()`. ``` class MyChoiceList extends LazyChoiceList @@ -204,81 +516,20 @@ } ``` - PaddedChoiceList, MonthChoiceList and TimezoneChoiceList were removed. - Their functionality was merged into DateType, TimeType and TimezoneType. + `PaddedChoiceList`, `MonthChoiceList` and `TimezoneChoiceList` were removed. + Their functionality was merged into `DateType`, `TimeType` and `TimezoneType`. - EntityChoiceList was adapted. The methods `getEntities()`, + `EntityChoiceList` was adapted. The methods `getEntities()`, `getEntitiesByKeys()`, `getIdentifier()` and `getIdentifierValues()` were removed or made private. Instead of the first two, you can now use `getChoices()` and `getChoicesByValues()`. For the latter two, no replacement exists. - * The strategy for generating the `id` and `name` HTML attributes for - checkboxes and radio buttons in a choice field has changed. - - Instead of appending the choice value, a generated integer is now appended - by default. Take care if your JavaScript relies on that. - - * In the choice field type's template, the structure of the `choices` variable - has changed. - - The `choices` variable now contains ChoiceView objects with two getters, - `getValue()` and `getLabel()`, to access the choice data. - - Before: - - ``` - {% for choice, label in choices %} - - {% endfor %} - ``` - - After: - - ``` - {% for choice in choices %} - - {% endfor %} - ``` - - * In the collection type's template, the default name of the prototype field - has changed from `$$name$$` to `__name__`. - - For custom names, dollar signs are no longer prepended and appended. You are - advised to prepend and append two underscores wherever you specify a value - for the field's `prototype_name` option. - - Before: - - ``` - $builder->add('tags', 'collection', array('prototype' => 'proto')); - - // results in the name "$$proto$$" in the template - ``` - - After: - - ``` - $builder->add('tags', 'collection', array('prototype' => '__proto__')); - - // results in the name "__proto__" in the template - ``` - - * The `read_only` field attribute now renders as `readonly="readonly"`, use - `disabled` instead for `disabled="disabled"`. - - * Form and field names must now start with a letter, digit or underscore - and only contain letters, digits, underscores, hyphens and colons - - * `EntitiesToArrayTransformer` and `EntityToIdTransformer` have been removed. - The former has been replaced by `CollectionToArrayTransformer` in combination + * `EntitiesToArrayTransformer` and `EntityToIdTransformer` were removed. + The former was replaced by `CollectionToArrayTransformer` in combination with `EntityChoiceList`, the latter is not required in the core anymore. - * The following transformers have been renamed: + * The following transformers were renamed: * `ArrayToBooleanChoicesTransformer` to `ChoicesToBooleanArrayTransformer` * `ScalarToBooleanChoicesTransformer` to `ChoiceToBooleanArrayTransformer` @@ -287,36 +538,61 @@ to be consistent with the naming in `ChoiceListInterface`. - * `FormUtil::toArrayKey()` and `FormUtil::toArrayKeys()` have been removed. + * `FormUtil::toArrayKey()` and `FormUtil::toArrayKeys()` were removed. They were merged into ChoiceList and have no public equivalent anymore. - * The options passed to the `getParent()` method of form types no longer - contain default options. They only contain the options passed by the user. + * The `add()`, `remove()`, `setParent()`, `bind()` and `setData()` methods in + the Form class now throw an exception if the form is already bound. - You should check if options exist before attempting to read their value. + If you used these methods on bound forms, you should consider moving your + logic to an event listener that observes `FormEvents::PRE_BIND` or + `FormEvents::BIND`. + +#### Deprecations + + * The following methods of `FormTypeInterface` and `FormTypeExtensionInterface` + are deprecated and will be removed in Symfony 2.3: + + * `getDefaultOptions` + * `getAllowedOptionValues` + + You should use the newly added `setDefaultOptions` instead, which gives you + access to the OptionsResolverInterface instance and with that a lot more power. Before: ``` - public function getParent(array $options) + public function getDefaultOptions(array $options) { - return 'single_text' === $options['widget'] ? 'text' : 'choice'; + return array( + 'gender' => 'male', + ); + } + + public function getAllowedOptionValues(array $options) + { + return array( + 'gender' => array('male', 'female'), + ); } ``` After: ``` - public function getParent(array $options) + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return isset($options['widget']) && 'single_text' === $options['widget'] ? 'text' : 'choice'; + $resolver->setDefaults(array( + 'gender' => 'male', + )); + + $resolver->setAllowedValues(array( + 'gender' => array('male', 'female'), + )); } ``` - * The methods `getDefaultOptions()` and `getAllowedOptionValues()` of form - types no longer receive an option array. - - You can specify options that depend on other options using closures instead. + You can specify options that depend on other options using closures. Before: @@ -336,109 +612,87 @@ After: ``` - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( - 'empty_data' => function (Options $options, $previousValue) { - return $options['multiple'] ? array() : $previousValue; + $resolver->setDefaults(array( + 'empty_data' => function (Options $options, $value) { + return $options['multiple'] ? array() : $value; } - ); + )); } ``` - The second argument `$previousValue` does not have to be specified if not - needed. + The second argument `$value` contains the current default value and + does not have to be specified if not needed. - * The `add()`, `remove()`, `setParent()`, `bind()` and `setData()` methods in - the Form class now throw an exception if the form is already bound. + * The following methods in `FormBuilder` were deprecated and have a new + equivalent: - If you used these methods on bound forms, you should consider moving your - logic to an event listener that observes one of the following events: - `FormEvents::PRE_BIND`, `FormEvents::BIND_CLIENT_DATA` or - `FormEvents::BIND_NORM_DATA`. + * `prependClientTransformer`: `addViewTransformer` + * `appendClientTransformer`: no new equivalent, consider using `addViewTransformer` + * `getClientTransformers`: `getViewTransformers` + * `resetClientTransformers`: `resetViewTransformers` + * `prependNormTransformer`: no new equivalent, consider using `addModelTransformer` + * `appendNormTransformer`: `addModelTransformer` + * `getNormTransformers`: `getModelTransformers` + * `resetNormTransformers`: `resetModelTransformers` - * The interface FormValidatorInterface was deprecated and will be removed + The deprecated methods will be removed in Symfony 2.3. You are advised to + update your application. + + Before: + + ``` + $builder->prependClientTransformer(new MyTransformer()); + ``` + + After: + + ``` + $builder->addViewTransformer(new MyTransformer()); + ``` + + * The following events were deprecated and have a new equivalent: + + * `FormEvents::SET_DATA`: `FormEvents::PRE_SET_DATA` + * `FormEvents::BIND_CLIENT_DATA`: `FormEvents::PRE_BIND` + * `FormEvents::BIND_NORM_DATA`: `FormEvents::BIND` + + The deprecated events will be removed in Symfony 2.3. + + Furthermore, the event classes `DataEvent` and `FilterDataEvent` were + deprecated and replaced by the generic `FormEvent`. You are advised to + code your listeners against the new event now. The deprecated events will + be removed in Symfony 2.3. + + Before: + + ``` + $builder->addListener(FormEvents::BIND_CLIENT_DATA, function (FilterDataEvent $event) { + // ... + }); + ``` + + After: + + ``` + $builder->addListener(FormEvents::PRE_BIND, function (FormEvent $event) { + // ... + }); + ``` + + * The interface `FormValidatorInterface` was deprecated and will be removed in Symfony 2.3. If you implemented custom validators using this interface, you can - substitute them by event listeners listening to the FormEvents::POST_BIND - (or any other of the BIND events). In case you used the CallbackValidator + substitute them by event listeners listening to the `FormEvents::POST_BIND` + (or any other of the `*BIND` events). In case you used the CallbackValidator class, you should now pass the callback directly to `addEventListener`. - * Since FormType and FieldType were merged, you need to adapt your form - themes. - - The "field_widget" and all references to it should be renamed to - "form_widget_single_control": - - Before: - - ``` - {% block url_widget %} - {% spaceless %} - {% set type = type|default('url') %} - {{ block('field_widget') }} - {% endspaceless %} - {% endblock url_widget %} - ``` - - After: - - ``` - {% block url_widget %} - {% spaceless %} - {% set type = type|default('url') %} - {{ block('form_widget_single_control') }} - {% endspaceless %} - {% endblock url_widget %} - ``` - - All other "field_*" blocks and references to them should be renamed to - "form_*". If you previously defined both a "field_*" and a "form_*" - block, you can merge them into a single "form_*" block and check the new - Boolean variable "single_control": - - Before: - - ``` - {% block form_errors %} - {% spaceless %} - ... form code ... - {% endspaceless %} - {% endblock form_errors %} - - {% block field_errors %} - {% spaceless %} - ... field code ... - {% endspaceless %} - {% endblock field_errors %} - ``` - - After: - - ``` - {% block form_errors %} - {% spaceless %} - {% if single_control %} - ... field code ... - {% else %} - ... form code ... - {% endif %} - {% endspaceless %} - {% endblock form_errors %} - ``` - - Furthermore, the block "generic_label" was merged into "form_label". You - should now override "form_label" in order to customize labels. - - Last but not least, the block "widget_choice_options" was renamed to - "choice_widget_options" to be consistent with the rest of the default - theme. - - * The method `guessMinLength()` of FormTypeGuesserInterface was deprecated + * The method `guessMinLength()` of `FormTypeGuesserInterface` was deprecated and will be removed in Symfony 2.3. You should use the new method `guessPattern()` instead which may return any regular expression that - is inserted in the HTML5 attribute "pattern". + is inserted in the HTML5 attribute `pattern`. Before: @@ -480,52 +734,18 @@ )); ``` - * The "data_class" option now *must* be set if a form maps to an object. If - you leave it empty, the form will expect an array or a scalar value and - fail with a corresponding exception. - - Likewise, if a form maps to an array, the option *must* be left empty now. - - * The mapping of property paths to arrays has changed. - - Previously, a property path "street" mapped to both a field `$street` of - a class (or its accessors `getStreet()` and `setStreet()`) and an index - `['street']` of an array or an object implementing `\ArrayAccess`. - - Now, the property path "street" only maps to a class field (or accessors), - while the property path "[street]" only maps to indices. - - If you defined property paths manually in the "property_path" option, you - should revise them and adjust them if necessary. - - Before: - - ``` - $builder->add('name', 'text', array( - 'property_path' => 'address.street', - )); - ``` - - After (if the address object is an array): - - ``` - $builder->add('name', 'text', array( - 'property_path' => 'address[street]', - )); - ``` - - If address is an object in this case, the code given in "Before" - works without changes. - - * The following methods in `Form` are deprecated and will be removed in + * The following methods in `Form` were deprecated and will be removed in Symfony 2.3: * `getTypes` * `getErrorBubbling` * `getNormTransformers` * `getClientTransformers` - - You can access these methods on the `FormConfigInterface` object instead. + * `getAttribute` + * `hasAttribute` + * `getClientData` + * `getChildren` + * `hasChildren` Before: @@ -539,7 +759,25 @@ $form->getConfig()->getErrorBubbling(); ``` - * The option "validation_constraint" is deprecated and will be removed + The method `getClientData` has a new equivalent that is named `getViewData`. + You can access all other methods on the `FormConfigInterface` object instead. + + Instead of `getChildren` and `hasChildren`, you should now use `all` and + `count`. + + Before: + + ``` + if ($form->hasChildren()) { + ``` + + After: + + ``` + if (count($form) > 0) { + ``` + + * The option "validation_constraint" was deprecated and will be removed in Symfony 2.3. You should use the option "constraints" instead, where you can pass one or more constraints for a form. diff --git a/src/Symfony/Bridge/Doctrine/Form/EventListener/MergeDoctrineCollectionListener.php b/src/Symfony/Bridge/Doctrine/Form/EventListener/MergeDoctrineCollectionListener.php index d3e567d69a..d3201d210b 100644 --- a/src/Symfony/Bridge/Doctrine/Form/EventListener/MergeDoctrineCollectionListener.php +++ b/src/Symfony/Bridge/Doctrine/Form/EventListener/MergeDoctrineCollectionListener.php @@ -12,7 +12,7 @@ namespace Symfony\Bridge\Doctrine\Form\EventListener; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -30,10 +30,10 @@ class MergeDoctrineCollectionListener implements EventSubscriberInterface { // Higher priority than core MergeCollectionListener so that this one // is called before - return array(FormEvents::BIND_NORM_DATA => array('onBindNormData', 10)); + return array(FormEvents::BIND => array('onBind', 10)); } - public function onBindNormData(FilterDataEvent $event) + public function onBind(FormEvent $event) { $collection = $event->getForm()->getData(); $data = $event->getData(); diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php index da3ce52964..cdec0e710b 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php @@ -13,13 +13,14 @@ namespace Symfony\Bridge\Doctrine\Form\Type; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ObjectManager; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityLoaderInterface; use Symfony\Bridge\Doctrine\Form\EventListener\MergeDoctrineCollectionListener; use Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer; use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; abstract class DoctrineType extends AbstractType { @@ -33,7 +34,7 @@ abstract class DoctrineType extends AbstractType $this->registry = $registry; } - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { if ($options['multiple']) { $builder @@ -43,7 +44,7 @@ abstract class DoctrineType extends AbstractType } } - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { $registry = $this->registry; $type = $this; @@ -71,7 +72,7 @@ abstract class DoctrineType extends AbstractType ); }; - return array( + $resolver->setDefaults(array( 'em' => null, 'class' => null, 'property' => null, @@ -80,7 +81,7 @@ abstract class DoctrineType extends AbstractType 'choices' => null, 'choice_list' => $choiceList, 'group_by' => null, - ); + )); } /** @@ -93,7 +94,7 @@ abstract class DoctrineType extends AbstractType */ abstract public function getLoader(ObjectManager $manager, $queryBuilder, $class); - public function getParent(array $options) + public function getParent() { return 'choice'; } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index d7a2f11069..38f4dc6695 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -108,14 +108,14 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'required' => false, 'property' => 'name' )); - $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->get('choices')); + $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->getVar('choices')); } public function testSetDataToUninitializedEntityWithNonRequiredToString() @@ -125,13 +125,13 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'required' => false, )); - $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->get('choices')); + $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->getVar('choices')); } public function testSetDataToUninitializedEntityWithNonRequiredQueryBuilder() @@ -142,7 +142,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2)); $qb = $this->em->createQueryBuilder()->select('e')->from(self::SINGLE_IDENT_CLASS, 'e'); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'required' => false, @@ -150,7 +150,7 @@ class EntityTypeTest extends TypeTestCase 'query_builder' => $qb )); - $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->get('choices')); + $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->getVar('choices')); } /** @@ -158,7 +158,7 @@ class EntityTypeTest extends TypeTestCase */ public function testConfigureQueryBuilderWithNonQueryBuilderAndNonClosure() { - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'query_builder' => new \stdClass(), @@ -170,7 +170,7 @@ class EntityTypeTest extends TypeTestCase */ public function testConfigureQueryBuilderWithClosureReturningNonQueryBuilder() { - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'query_builder' => function () { @@ -183,7 +183,7 @@ class EntityTypeTest extends TypeTestCase public function testSetDataSingleNull() { - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => false, 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, @@ -196,7 +196,7 @@ class EntityTypeTest extends TypeTestCase public function testSetDataMultipleExpandedNull() { - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => true, 'expanded' => true, 'em' => 'default', @@ -210,7 +210,7 @@ class EntityTypeTest extends TypeTestCase public function testSetDataMultipleNonExpandedNull() { - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => true, 'expanded' => false, 'em' => 'default', @@ -224,7 +224,7 @@ class EntityTypeTest extends TypeTestCase public function testSubmitSingleExpandedNull() { - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => false, 'expanded' => true, 'em' => 'default', @@ -238,7 +238,7 @@ class EntityTypeTest extends TypeTestCase public function testSubmitSingleNonExpandedNull() { - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => false, 'expanded' => false, 'em' => 'default', @@ -252,7 +252,7 @@ class EntityTypeTest extends TypeTestCase public function testSubmitMultipleNull() { - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => true, 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, @@ -270,7 +270,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => false, 'expanded' => false, 'em' => 'default', @@ -292,7 +292,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => false, 'expanded' => false, 'em' => 'default', @@ -316,7 +316,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => true, 'expanded' => false, 'em' => 'default', @@ -341,7 +341,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => true, 'expanded' => false, 'em' => 'default', @@ -372,7 +372,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => true, 'expanded' => false, 'em' => 'default', @@ -398,7 +398,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => true, 'expanded' => false, 'em' => 'default', @@ -428,7 +428,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => false, 'expanded' => true, 'em' => 'default', @@ -454,7 +454,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => true, 'expanded' => true, 'em' => 'default', @@ -484,7 +484,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, // not all persisted entities should be displayed @@ -494,7 +494,7 @@ class EntityTypeTest extends TypeTestCase $field->bind('2'); - $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->get('choices')); + $this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->getVar('choices')); $this->assertTrue($field->isSynchronized()); $this->assertSame($entity2, $field->getData()); $this->assertSame('2', $field->getClientData()); @@ -509,7 +509,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($item1, $item2, $item3, $item4)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::ITEM_GROUP_CLASS, 'choices' => array($item1, $item2, $item3, $item4), @@ -524,7 +524,7 @@ class EntityTypeTest extends TypeTestCase 'Group1' => array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), 'Group2' => array(3 => new ChoiceView('3', 'Baz')), '4' => new ChoiceView('4', 'Boo!') - ), $field->createView()->get('choices')); + ), $field->createView()->getVar('choices')); } public function testDisallowChoicesThatAreNotIncluded_choicesSingleIdentifier() @@ -535,7 +535,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'choices' => array($entity1, $entity2), @@ -556,7 +556,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::COMPOSITE_IDENT_CLASS, 'choices' => array($entity1, $entity2), @@ -579,7 +579,7 @@ class EntityTypeTest extends TypeTestCase $repository = $this->em->getRepository(self::SINGLE_IDENT_CLASS); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'query_builder' => $repository->createQueryBuilder('e') @@ -601,7 +601,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'query_builder' => function ($repository) { @@ -625,7 +625,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1, $entity2, $entity3)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'em' => 'default', 'class' => self::COMPOSITE_IDENT_CLASS, 'query_builder' => function ($repository) { @@ -647,7 +647,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => false, 'expanded' => false, 'em' => 'default', @@ -668,7 +668,7 @@ class EntityTypeTest extends TypeTestCase $this->persist(array($entity1)); - $field = $this->factory->createNamed('entity', 'name', null, array( + $field = $this->factory->createNamed('name', 'entity', null, array( 'multiple' => false, 'expanded' => false, 'em' => 'default', diff --git a/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php b/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php index 3e2c7b4f78..8e5c151f66 100644 --- a/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php +++ b/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php @@ -14,8 +14,9 @@ namespace Symfony\Bridge\Propel1\Form\Type; use Symfony\Bridge\Propel1\Form\ChoiceList\ModelChoiceList; use Symfony\Bridge\Propel1\Form\DataTransformer\CollectionToArrayTransformer; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; /** * ModelType class. @@ -24,14 +25,14 @@ use Symfony\Component\OptionsResolver\Options; */ class ModelType extends AbstractType { - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { if ($options['multiple']) { $builder->prependClientTransformer(new CollectionToArrayTransformer()); } } - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { $choiceList = function (Options $options) { return new ModelChoiceList( @@ -43,7 +44,7 @@ class ModelType extends AbstractType ); }; - return array( + $resolver->setDefaults(array( 'template' => 'choice', 'multiple' => false, 'expanded' => false, @@ -54,10 +55,10 @@ class ModelType extends AbstractType 'choice_list' => $choiceList, 'group_by' => null, 'by_reference' => false, - ); + )); } - public function getParent(array $options) + public function getParent() { return 'choice'; } diff --git a/src/Symfony/Bridge/Twig/Extension/FormExtension.php b/src/Symfony/Bridge/Twig/Extension/FormExtension.php index dfe4414d71..3a4c7ce926 100644 --- a/src/Symfony/Bridge/Twig/Extension/FormExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/FormExtension.php @@ -98,7 +98,7 @@ class FormExtension extends \Twig_Extension public function isChoiceSelected(FormView $view, ChoiceView $choice) { - return FormUtil::isChoiceSelected($choice->getValue(), $view->get('value')); + return FormUtil::isChoiceSelected($choice->getValue(), $view->getVar('value')); } /** @@ -228,7 +228,7 @@ class FormExtension extends \Twig_Extension } } - $custom = '_'.$view->get('id'); + $custom = '_'.$view->getVar('id'); $rendering = $custom.$section; $blocks = $this->getBlocks($view); @@ -237,11 +237,11 @@ class FormExtension extends \Twig_Extension $types = $this->varStack[$rendering]['types']; $this->varStack[$rendering]['variables'] = array_replace_recursive($this->varStack[$rendering]['variables'], $variables); } else { - $types = $view->get('types'); + $types = $view->getVar('types'); $types[] = $custom; $typeIndex = count($types) - 1; $this->varStack[$rendering] = array( - 'variables' => array_replace_recursive($view->all(), $variables), + 'variables' => array_replace_recursive($view->getVars(), $variables), 'types' => $types, ); } diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index e26610f5d3..bff18c6e1a 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -2,20 +2,20 @@ {% block form_widget %} {% spaceless %} - {% if single_control %} - {{ block('form_widget_single_control') }} - {% else %} + {% if compound %} {{ block('form_widget_compound') }} + {% else %} + {{ block('form_widget_simple') }} {% endif %} {% endspaceless %} {% endblock form_widget %} -{% block form_widget_single_control %} +{% block form_widget_simple %} {% spaceless %} {% set type = type|default('text') %} {% endspaceless %} -{% endblock form_widget_single_control %} +{% endblock form_widget_simple %} {% block form_widget_compound %} {% spaceless %} @@ -112,7 +112,7 @@ {% block datetime_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% else %}
{{ form_errors(form.date) }} @@ -127,7 +127,7 @@ {% block date_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% else %}
{{ date_pattern|replace({ @@ -143,7 +143,7 @@ {% block time_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% else %}
{{ form_widget(form.hour, { 'attr': { 'size': '1' } }) }}:{{ form_widget(form.minute, { 'attr': { 'size': '1' } }) }}{% if with_seconds %}:{{ form_widget(form.second, { 'attr': { 'size': '1' } }) }}{% endif %} @@ -156,62 +156,62 @@ {% spaceless %} {# type="number" doesn't work with floats #} {% set type = type|default('text') %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% endspaceless %} {% endblock number_widget %} {% block integer_widget %} {% spaceless %} {% set type = type|default('number') %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% endspaceless %} {% endblock integer_widget %} {% block money_widget %} {% spaceless %} - {{ money_pattern|replace({ '{{ widget }}': block('form_widget_single_control') })|raw }} + {{ money_pattern|replace({ '{{ widget }}': block('form_widget_simple') })|raw }} {% endspaceless %} {% endblock money_widget %} {% block url_widget %} {% spaceless %} {% set type = type|default('url') %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% endspaceless %} {% endblock url_widget %} {% block search_widget %} {% spaceless %} {% set type = type|default('search') %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% endspaceless %} {% endblock search_widget %} {% block percent_widget %} {% spaceless %} {% set type = type|default('text') %} - {{ block('form_widget_single_control') }} % + {{ block('form_widget_simple') }} % {% endspaceless %} {% endblock percent_widget %} {% block password_widget %} {% spaceless %} {% set type = type|default('password') %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% endspaceless %} {% endblock password_widget %} {% block hidden_widget %} {% spaceless %} {% set type = type|default('hidden') %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% endspaceless %} {% endblock hidden_widget %} {% block email_widget %} {% spaceless %} {% set type = type|default('email') %} - {{ block('form_widget_single_control') }} + {{ block('form_widget_simple') }} {% endspaceless %} {% endblock email_widget %} @@ -219,7 +219,7 @@ {% block form_label %} {% spaceless %} - {% if single_control %} + {% if not compound %} {% set label_attr = label_attr|merge({'for': id}) %} {% endif %} {% if required %} @@ -245,7 +245,7 @@ If the child is a compound form, the errors are rendered inside the container. See also block form_rows. #} - {% if single_control %} + {% if not compound %} {{ form_errors(form) }} {% endif %} {{ form_widget(form) }} @@ -320,7 +320,7 @@ {% block generic_label %}{{ block('form_label') }}{% endblock %} {% block widget_choice_options %}{{ block('choice_widget_options') }}{% endblock %} -{% block field_widget %}{{ block('form_widget_single_control') }}{% endblock %} +{% block field_widget %}{{ block('form_widget_simple') }}{% endblock %} {% block field_label %}{{ block('form_label') }}{% endblock %} {% block field_row %}{{ block('form_row') }}{% endblock %} {% block field_enctype %}{{ block('form_enctype') }}{% endblock %} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig index b3a9558283..fbfe96adcf 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig @@ -7,7 +7,7 @@ {{ form_label(form, label|default(null)) }} - {% if single_control %} + {% if not compound %} {{ form_errors(form) }} {% endif %} {{ form_widget(form) }} @@ -18,7 +18,7 @@ {% block form_errors %} {% spaceless %} - {% if single_control %} + {% if not compound %} {{ parent() }} {% else %} {% if errors|length > 0 %} diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php index eb214a57d5..5b6e4460e8 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php @@ -69,7 +69,7 @@ class FormExtensionDivLayoutTest extends AbstractDivLayoutTest public function testThemeBlockInheritanceUsingUse() { $view = $this->factory - ->createNamed('email', 'name') + ->createNamed('name', 'email') ->createView() ; @@ -84,7 +84,7 @@ class FormExtensionDivLayoutTest extends AbstractDivLayoutTest public function testThemeBlockInheritanceUsingExtend() { $view = $this->factory - ->createNamed('email', 'name') + ->createNamed('name', 'email') ->createView() ; diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig b/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig index 36f8636ad2..da1c1b649b 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig +++ b/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig @@ -1,6 +1,6 @@ -{% block form_widget_single_control %} +{% block form_widget_simple %} {% spaceless %} {% set type = type|default('text') %} {% endspaceless %} -{% endblock form_widget_single_control %} +{% endblock form_widget_simple %} diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/theme_extends.html.twig b/src/Symfony/Bridge/Twig/Tests/Extension/theme_extends.html.twig index 12b9da872d..8c719867ec 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/theme_extends.html.twig +++ b/src/Symfony/Bridge/Twig/Tests/Extension/theme_extends.html.twig @@ -1,8 +1,8 @@ {% extends 'form_div_layout.html.twig' %} -{% block form_widget_single_control %} +{% block form_widget_simple %} {% spaceless %} {% set type = type|default('text') %} {% endspaceless %} -{% endblock form_widget_single_control %} +{% endblock form_widget_simple %} diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/theme_use.html.twig b/src/Symfony/Bridge/Twig/Tests/Extension/theme_use.html.twig index 1b7f6b59cf..d485b8d0e7 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/theme_use.html.twig +++ b/src/Symfony/Bridge/Twig/Tests/Extension/theme_use.html.twig @@ -1,8 +1,8 @@ {% use 'form_div_layout.html.twig' %} -{% block form_widget_single_control %} +{% block form_widget_simple %} {% spaceless %} {% set type = type|default('text') %} {% endspaceless %} -{% endblock form_widget_single_control %} +{% endblock form_widget_simple %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php index 338e8edfed..439443c7b0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/date_widget.html.php @@ -1,5 +1,5 @@ - renderBlock('form_widget_single_control'); ?> + renderBlock('form_widget_simple'); ?>
renderBlock('widget_container_attributes') ?>> - renderBlock('form_widget_single_control'); ?> + renderBlock('form_widget_simple'); ?>
renderBlock('widget_container_attributes') ?>> widget($form['date']).' '.$view['form']->widget($form['time']) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php index 80409c0a30..0ef4d9dcde 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/email_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control', array('type' => isset($type) ? $type : 'email')) ?> +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : 'email')) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php index 9bce25bd9d..2621130b14 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/field_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control') ?> +renderBlock('form_widget_simple') ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_enctype.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_enctype.html.php index 424d425969..5a5e4b19fa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_enctype.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_enctype.html.php @@ -1 +1 @@ -get('multipart')): ?>enctype="multipart/form-data" +getVar('multipart')): ?>enctype="multipart/form-data" diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php index e236122065..c8f7947173 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_label.html.php @@ -1,3 +1,3 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php index 977a272257..6f994156aa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php @@ -1,6 +1,6 @@
label($form, isset($label) ? $label : null) ?> - + errors($form) ?> widget($form) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php index 98d1a80be7..0e634184e3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget.html.php @@ -1,5 +1,5 @@ - -renderBlock('form_widget_single_control')?> - + renderBlock('form_widget_compound')?> + +renderBlock('form_widget_simple')?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_single_control.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_simple.html.php similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_single_control.html.php rename to src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_simple.html.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php index d7395a4857..7dc71ae228 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/hidden_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control', array('type' => isset($type) ? $type : "hidden")) ?> +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "hidden")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php index dc2866fd20..14000a5ee5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/integer_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control', array('type' => isset($type) ? $type : "number")) ?> +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "number")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php index 17279721c5..6c84a871aa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control'), $money_pattern) ?> +renderBlock('form_widget_simple'), $money_pattern) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php index 3d6fd62209..c3344d8bd7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/number_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control', array('type' => isset($type) ? $type : "text")) ?> +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php index 716e46cf60..ab0bcafae5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/password_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control', array('type' => isset($type) ? $type : "password")) ?> +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "password")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php index 5446968baf..38b51c091d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control', array('type' => isset($type) ? $type : "text")) ?> % +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "text")) ?> % diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php index ca3b00917f..e071e95ec0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/search_widget.html.php @@ -1 +1 @@ -renderBlock('form_widget_single_control', array('type' => isset($type) ? $type : "search")) ?> +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "search")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php index 8d34459b56..fb7f94c3eb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php @@ -1,5 +1,5 @@ - renderBlock('form_widget_single_control'); ?> + renderBlock('form_widget_simple'); ?>
renderBlock('widget_container_attributes') ?>> renderBlock('form_widget_single_control', array('type' => isset($type) ? $type : "url")) ?> +renderBlock('form_widget_simple', array('type' => isset($type) ? $type : "url")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_errors.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_errors.html.php index 5149209e35..154b6e2c02 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_errors.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_errors.html.php @@ -1,4 +1,4 @@ - +
    diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php index 5526a03fe9..03daaf19fc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php @@ -3,7 +3,7 @@ label($form, isset($label) ? $label : null) ?> - + errors($form) ?> widget($form) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php index a15dfe84f1..0b0c82edbb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php @@ -66,7 +66,7 @@ class FormHelper extends Helper public function isChoiceSelected(FormView $view, ChoiceView $choice) { - return FormUtil::isChoiceSelected($choice->getValue(), $view->get('value')); + return FormUtil::isChoiceSelected($choice->getValue(), $view->getVar('value')); } /** @@ -79,7 +79,7 @@ class FormHelper extends Helper */ public function setTheme(FormView $view, $themes) { - $this->themes[$view->get('id')] = (array) $themes; + $this->themes[$view->getVar('id')] = (array) $themes; $this->templates = array(); } @@ -237,7 +237,7 @@ class FormHelper extends Helper $template = null; - $custom = '_'.$view->get('id'); + $custom = '_'.$view->getVar('id'); $rendering = $custom.$section; if (isset($this->varStack[$rendering])) { @@ -245,10 +245,10 @@ class FormHelper extends Helper $types = $this->varStack[$rendering]['types']; $variables = array_replace_recursive($this->varStack[$rendering]['variables'], $variables); } else { - $types = $view->get('types'); + $types = $view->getVar('types'); $types[] = $custom; $typeIndex = count($types) - 1; - $variables = array_replace_recursive($view->all(), $variables); + $variables = array_replace_recursive($view->getVars(), $variables); $this->varStack[$rendering]['types'] = $types; } @@ -330,7 +330,7 @@ class FormHelper extends Helper protected function lookupTemplate(FormView $view, $block) { $file = $block.'.html.php'; - $id = $view->get('id'); + $id = $view->getVar('id'); if (!isset($this->templates[$id][$block])) { $template = false; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_single_control.html.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_simple.html.php similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_single_control.html.php rename to src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_simple.html.php diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php index e4ccb6c5fd..21389efd07 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php @@ -12,12 +12,13 @@ namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Form; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\SecurityContextInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; /** * Form type for use with the Security component's form-based authentication @@ -28,7 +29,7 @@ use Symfony\Component\Security\Core\SecurityContextInterface; */ class UserLoginFormType extends AbstractType { - private $reqeust; + private $request; /** * @param Request $request A request instance @@ -41,7 +42,7 @@ class UserLoginFormType extends AbstractType /** * @see Symfony\Component\Form\AbstractType::buildForm() */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('username', 'text') @@ -56,7 +57,7 @@ class UserLoginFormType extends AbstractType * request; however, we can match the expected behavior by checking the * session for an authentication error and last username. */ - $builder->addEventListener(FormEvents::SET_DATA, function (FilterDataEvent $event) use ($request) { + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($request) { if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) { $error = $request->attributes->get(SecurityContextInterface::AUTHENTICATION_ERROR); } else { @@ -74,17 +75,17 @@ class UserLoginFormType extends AbstractType } /** - * @see Symfony\Component\Form\AbstractType::getDefaultOptions() + * @see Symfony\Component\Form\AbstractType::setDefaultOptions() */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { /* Note: the form's intention must correspond to that for the form login * listener in order for the CSRF token to validate successfully. */ - return array( + $resolver->setDefaults(array( 'intention' => 'authenticate', - ); + )); } /** diff --git a/src/Symfony/Component/Form/AbstractType.php b/src/Symfony/Component/Form/AbstractType.php index 7b3a8e6ae3..281ee07f4d 100644 --- a/src/Symfony/Component/Form/AbstractType.php +++ b/src/Symfony/Component/Form/AbstractType.php @@ -12,7 +12,11 @@ namespace Symfony\Component\Form; use Symfony\Component\Form\Exception\UnexpectedTypeException; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; +/** + * @author Bernhard Schussek + */ abstract class AbstractType implements FormTypeInterface { /** @@ -24,21 +28,21 @@ abstract class AbstractType implements FormTypeInterface /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { } /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { } /** * {@inheritdoc} */ - public function buildViewBottomUp(FormView $view, FormInterface $form) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) { } @@ -53,13 +57,32 @@ abstract class AbstractType implements FormTypeInterface /** * {@inheritdoc} */ + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults($this->getDefaultOptions()); + $resolver->addAllowedValues($this->getAllowedOptionValues()); + } + + /** + * Returns the default options for this type. + * + * @return array The default options + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. + * Use {@link setDefaultOptions()} instead. + */ public function getDefaultOptions() { return array(); } /** - * {@inheritdoc} + * Returns the allowed option values for each option (if any). + * + * @return array The allowed option values + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. + * Use {@link setDefaultOptions()} instead. */ public function getAllowedOptionValues() { @@ -69,7 +92,7 @@ abstract class AbstractType implements FormTypeInterface /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'form'; } diff --git a/src/Symfony/Component/Form/AbstractTypeExtension.php b/src/Symfony/Component/Form/AbstractTypeExtension.php index d70054f097..b946bf4b97 100644 --- a/src/Symfony/Component/Form/AbstractTypeExtension.php +++ b/src/Symfony/Component/Form/AbstractTypeExtension.php @@ -11,39 +11,63 @@ namespace Symfony\Component\Form; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; + +/** + * @author Bernhard Schussek + */ abstract class AbstractTypeExtension implements FormTypeExtensionInterface { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { } /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { } /** * {@inheritdoc} */ - public function buildViewBottomUp(FormView $view, FormInterface $form) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) { } /** * {@inheritdoc} */ + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults($this->getDefaultOptions()); + $resolver->addAllowedValues($this->getAllowedOptionValues()); + } + + /** + * Overrides the default options form the extended type. + * + * @return array + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. + * Use {@link setDefaultOptions()} instead. + */ public function getDefaultOptions() { return array(); } /** - * {@inheritdoc} + * Returns the allowed option values for each option (if any). + * + * @return array The allowed option values + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. + * Use {@link setDefaultOptions()} instead. */ public function getAllowedOptionValues() { diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 14ac7cca1c..2d0e527291 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -43,7 +43,6 @@ CHANGELOG * forms now don't create an empty object anymore if they are completely empty and not required. The empty value for such forms is null. * added constant Guess::VERY_HIGH_CONFIDENCE - * [BC BREAK] FormType::getParent() does not see default options anymore * [BC BREAK] The methods `add`, `remove`, `setParent`, `bind` and `setData` in class Form now throw an exception if the form is already bound * fields of constrained classes without a NotBlank or NotNull constraint are @@ -52,15 +51,14 @@ CHANGELOG "single_text" unless "with_seconds" is set to true * checkboxes of in an expanded multiple-choice field don't include the choice in their name anymore. Their names terminate with "[]" now. - * [BC BREAK] FormType::getDefaultOptions() and FormType::getAllowedOptionValues() - don't receive an options array anymore. * deprecated FormValidatorInterface and substituted its implementations by event subscribers * simplified CSRF protection and removed the csrf type * deprecated FieldType and merged it into FormType + * added new option "compound" that lets you switch between field and form behavior * [BC BREAK] renamed theme blocks * "field_*" to "form_*" - * "field_widget" to "form_widget_single_control" + * "field_widget" to "form_widget_simple" * "widget_choice_options" to "choice_widget_options" * "generic_label" to "form_label" * added theme blocks "form_widget_compound", "choice_widget_expanded" and @@ -78,13 +76,66 @@ CHANGELOG * errors are not mapped to unsynchronized forms anymore * [BC BREAK] changed Form constructor to accept a single `FormConfigInterface` object * [BC BREAK] changed argument order in the FormBuilder constructor + * added Form method `getViewData` * deprecated Form methods * `getTypes` * `getErrorBubbling` * `getNormTransformers` * `getClientTransformers` + * `getAttribute` + * `hasAttribute` + * `getClientData` + * added FormBuilder methods + * `addViewTransformer` + * `getViewTransformers` + * `resetViewTransformers` + * `addModelTransformer` + * `getModelTransformers` + * `resetModelTransformers` + * deprecated FormBuilder methods + * `prependClientTransformer` + * `appendClientTransformer` + * `getClientTransformers` + * `resetClientTransformers` + * `prependNormTransformer` + * `appendNormTransformer` + * `getNormTransformers` + * `resetNormTransformers` * deprecated the option "validation_constraint" in favor of the new option "constraints" * removed superfluous methods from DataMapperInterface * `mapFormToData` * `mapDataToForm` + * [BC BREAK] FormType::getDefaultOptions() and FormType::getAllowedOptionValues() + don't receive an options array anymore. + * added `setDefaultOptions` to FormTypeInterface and FormTypeExtensionInterface + which accepts an OptionsResolverInterface instance + * deprecated the methods `getDefaultOptions` and `getAllowedOptionValues` + in FormTypeInterface and FormTypeExtensionInterface + * options passed during construction can now be accessed from FormConfigInterface + * added FormBuilderInterface, FormViewInterface and FormConfigEditorInterface + * [BC BREAK] the methods in FormTypeInterface and FormTypeExtensionInterface now + receive FormBuilderInterface and FormViewInterface instead of FormBuilder and + FormView + * [BC BREAK] the method `buildViewBottomUp` was renamed to `finishView` in + FormTypeInterface and FormTypeExtensionInterface + * [BC BREAK] the options array is now passed as last argument of the + methods + * `buildView` + * `finishView` + in FormTypeInterface and FormTypeExtensionInterface + * [BC BREAK] no options are passed to `getParent` of FormTypeInterface anymore + * deprecated DataEvent and FilterDataEvent in favor of the new FormEvent which is + now passed to all events thrown by the component + * FormEvents::BIND now replaces FormEvents::BIND_NORM_DATA + * FormEvents::PRE_SET_DATA now replaces FormEvents::SET_DATA + * FormEvents::PRE_BIND now replaces FormEvents::BIND_CLIENT_DATA + * deprecated FormEvents::SET_DATA, FormEvents::BIND_CLIENT_DATA and + FormEvents::BIND_NORM_DATA + * [BC BREAK] reversed the order of the first two arguments to `createNamed` + and `createNamedBuilder` in `FormFactoryInterface` + * [BC BREAK] adapted methods of FormView to match the naming used in + FormInterface and FormBuilder + * deprecated `getChildren` in Form and FormBuilder in favor of `all` + * deprecated `hasChildren` in Form and FormBuilder in favor of `count` + * FormBuilder now implements \IteratorAggregate diff --git a/src/Symfony/Component/Form/DataMapperInterface.php b/src/Symfony/Component/Form/DataMapperInterface.php index 587a4abd78..75841865cd 100644 --- a/src/Symfony/Component/Form/DataMapperInterface.php +++ b/src/Symfony/Component/Form/DataMapperInterface.php @@ -11,15 +11,28 @@ namespace Symfony\Component\Form; +/** + * @author Bernhard Schussek + */ interface DataMapperInterface { /** - * @param dataClass $data - * @param array $forms + * Maps properties of some data to a list of forms. * - * @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported + * @param mixed $data Structured data. + * @param array $forms A list of {@link FormInterface} instances. + * + * @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported. */ function mapDataToForms($data, array $forms); + /** + * Maps the data of a list of forms into the properties of some data. + * + * @param array $forms A list of {@link FormInterface} instances. + * @param mixed $data Structured data. + * + * @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported. + */ function mapFormsToData(array $forms, &$data); } diff --git a/src/Symfony/Component/Form/Event/DataEvent.php b/src/Symfony/Component/Form/Event/DataEvent.php index d9a7de9251..7bdc053edd 100644 --- a/src/Symfony/Component/Form/Event/DataEvent.php +++ b/src/Symfony/Component/Form/Event/DataEvent.php @@ -14,6 +14,12 @@ namespace Symfony\Component\Form\Event; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\Form\FormInterface; +/** + * @author Bernhard Schussek + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Code against + * {@link \Symfony\Component\Form\FormEvent} instead. + */ class DataEvent extends Event { private $form; @@ -50,4 +56,14 @@ class DataEvent extends Event { return $this->data; } + + /** + * Allows updating with some filtered data + * + * @param mixed $data + */ + public function setData($data) + { + $this->data = $data; + } } diff --git a/src/Symfony/Component/Form/Event/FilterDataEvent.php b/src/Symfony/Component/Form/Event/FilterDataEvent.php index bc152dbae1..d20f483c69 100644 --- a/src/Symfony/Component/Form/Event/FilterDataEvent.php +++ b/src/Symfony/Component/Form/Event/FilterDataEvent.php @@ -11,15 +11,12 @@ namespace Symfony\Component\Form\Event; +/** + * @author Bernhard Schussek + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Code against + * {@link \Symfony\Component\Form\FormEvent} instead. + */ class FilterDataEvent extends DataEvent { - /** - * Allows updating with some filtered data - * - * @param mixed $data - */ - public function setData($data) - { - $this->data = $data; - } } diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php index f7302e33dc..4ddec0db97 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Form\Extension\Core\EventListener; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface; @@ -36,7 +36,7 @@ class FixCheckboxInputListener implements EventSubscriberInterface $this->choiceList = $choiceList; } - public function onBindClientData(FilterDataEvent $event) + public function preBind(FormEvent $event) { $values = (array) $event->getData(); $indices = $this->choiceList->getIndicesForValues($values); @@ -46,6 +46,6 @@ class FixCheckboxInputListener implements EventSubscriberInterface static public function getSubscribedEvents() { - return array(FormEvents::BIND_CLIENT_DATA => 'onBindClientData'); + return array(FormEvents::PRE_BIND => 'preBind'); } } diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php index 1378b2e2f7..43e8a3b73a 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Form\Extension\Core\EventListener; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface; @@ -36,7 +36,7 @@ class FixRadioInputListener implements EventSubscriberInterface $this->choiceList = $choiceList; } - public function onBindClientData(FilterDataEvent $event) + public function preBind(FormEvent $event) { $value = $event->getData(); $index = current($this->choiceList->getIndicesForValues(array($value))); @@ -46,6 +46,6 @@ class FixRadioInputListener implements EventSubscriberInterface static public function getSubscribedEvents() { - return array(FormEvents::BIND_CLIENT_DATA => 'onBindClientData'); + return array(FormEvents::PRE_BIND => 'preBind'); } } diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php index b0d532cdf6..ee2cd95ac4 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixUrlProtocolListener.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Form\Extension\Core\EventListener; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -29,7 +29,7 @@ class FixUrlProtocolListener implements EventSubscriberInterface $this->defaultProtocol = $defaultProtocol; } - public function onBindNormData(FilterDataEvent $event) + public function onBind(FormEvent $event) { $data = $event->getData(); @@ -40,6 +40,6 @@ class FixUrlProtocolListener implements EventSubscriberInterface static public function getSubscribedEvents() { - return array(FormEvents::BIND_NORM_DATA => 'onBindNormData'); + return array(FormEvents::BIND => 'onBind'); } } diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php index ff4ed80d34..5d76a78904 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php @@ -13,7 +13,7 @@ namespace Symfony\Component\Form\Extension\Core\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\Exception\UnexpectedTypeException; /** @@ -50,15 +50,13 @@ class MergeCollectionListener implements EventSubscriberInterface static public function getSubscribedEvents() { return array( - FormEvents::BIND_NORM_DATA => 'onBindNormData', + FormEvents::BIND => 'onBind', ); } - public function onBindNormData(FilterDataEvent $event) + public function onBind(FormEvent $event) { $dataToMergeInto = $event->getForm()->getNormData(); - - $form = $event->getForm(); $data = $event->getData(); if (null === $data) { diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php index d934680c9c..a953d9e215 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php @@ -12,8 +12,7 @@ namespace Symfony\Component\Form\Extension\Core\EventListener; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\DataEvent; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -67,11 +66,11 @@ class ResizeFormListener implements EventSubscriberInterface FormEvents::PRE_SET_DATA => 'preSetData', FormEvents::PRE_BIND => 'preBind', // (MergeCollectionListener, MergeDoctrineCollectionListener) - FormEvents::BIND_NORM_DATA => array('onBindNormData', 50), + FormEvents::BIND => array('onBind', 50), ); } - public function preSetData(DataEvent $event) + public function preSetData(FormEvent $event) { $form = $event->getForm(); $data = $event->getData(); @@ -91,13 +90,13 @@ class ResizeFormListener implements EventSubscriberInterface // Then add all rows again in the correct order foreach ($data as $name => $value) { - $form->add($this->factory->createNamed($this->type, $name, null, array_replace(array( + $form->add($this->factory->createNamed($name, $this->type, null, array_replace(array( 'property_path' => '['.$name.']', ), $this->options))); } } - public function preBind(DataEvent $event) + public function preBind(FormEvent $event) { $form = $event->getForm(); $data = $event->getData(); @@ -123,7 +122,7 @@ class ResizeFormListener implements EventSubscriberInterface if ($this->allowAdd) { foreach ($data as $name => $value) { if (!$form->has($name)) { - $form->add($this->factory->createNamed($this->type, $name, null, array_replace(array( + $form->add($this->factory->createNamed($name, $this->type, null, array_replace(array( 'property_path' => '['.$name.']', ), $this->options))); } @@ -131,7 +130,7 @@ class ResizeFormListener implements EventSubscriberInterface } } - public function onBindNormData(FilterDataEvent $event) + public function onBind(FormEvent $event) { $form = $event->getForm(); $data = $event->getData(); diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php index 220ad24781..4ee3249054 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Form\Extension\Core\EventListener; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -22,7 +22,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; */ class TrimListener implements EventSubscriberInterface { - public function onBindClientData(FilterDataEvent $event) + public function preBind(FormEvent $event) { $data = $event->getData(); @@ -33,6 +33,6 @@ class TrimListener implements EventSubscriberInterface static public function getSubscribedEvents() { - return array(FormEvents::BIND_CLIENT_DATA => 'onBindClientData'); + return array(FormEvents::PRE_BIND => 'preBind'); } } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php b/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php index bab646003d..5314c140a1 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php @@ -12,23 +12,24 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class BirthdayType extends AbstractType { /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'years' => range(date('Y') - 120, date('Y')), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'date'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php b/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php index b99b5892ae..3feb6bd3ad 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php @@ -12,55 +12,55 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\Extension\Core\DataTransformer\BooleanToStringTransformer; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormViewInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class CheckboxType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->appendClientTransformer(new BooleanToStringTransformer($options['value'])) - ->setAttribute('value', $options['value']) + ->addViewTransformer(new BooleanToStringTransformer($options['value'])) ; } /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { - $view - ->set('value', $form->getAttribute('value')) - ->set('checked', null !== $form->getClientData()) - ; + $view->addVars(array( + 'value' => $options['value'], + 'checked' => null !== $form->getViewData(), + )); } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { $emptyData = function (FormInterface $form, $clientData) { return $clientData; }; - return array( - 'value' => '1', - 'empty_data' => $emptyData, - 'single_control' => true, - ); + $resolver->setDefaults(array( + 'value' => '1', + 'empty_data' => $emptyData, + 'compound' => false, + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index 7658e52c4c..d5a3adaf84 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -12,9 +12,9 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormViewInterface; use Symfony\Component\Form\Exception\FormException; use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; @@ -27,18 +27,15 @@ use Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToBooleanArrayTr use Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToValuesTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToBooleanArrayTransformer; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class ChoiceType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { - if ($options['choice_list'] && !$options['choice_list'] instanceof ChoiceListInterface) { - throw new FormException('The "choice_list" must be an instance of "Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface".'); - } - if (!$options['choice_list'] && !is_array($options['choices']) && !$options['choices'] instanceof \Traversable) { throw new FormException('Either the option "choices" or "choice_list" must be set.'); } @@ -46,46 +43,23 @@ class ChoiceType extends AbstractType if ($options['expanded']) { $this->addSubForms($builder, $options['choice_list']->getPreferredViews(), $options); $this->addSubForms($builder, $options['choice_list']->getRemainingViews(), $options); - } - // empty value - if ($options['multiple'] || $options['expanded']) { - // never use and empty value for these cases - $emptyValue = null; - } elseif (false === $options['empty_value']) { - // an empty value should be added but the user decided otherwise - $emptyValue = null; - } else { - // empty value has been set explicitly - $emptyValue = $options['empty_value']; - } - - $builder - ->setAttribute('choice_list', $options['choice_list']) - ->setAttribute('preferred_choices', $options['preferred_choices']) - ->setAttribute('multiple', $options['multiple']) - ->setAttribute('expanded', $options['expanded']) - ->setAttribute('required', $options['required']) - ->setAttribute('empty_value', $emptyValue) - ; - - if ($options['expanded']) { if ($options['multiple']) { $builder - ->appendClientTransformer(new ChoicesToBooleanArrayTransformer($options['choice_list'])) + ->addViewTransformer(new ChoicesToBooleanArrayTransformer($options['choice_list'])) ->addEventSubscriber(new FixCheckboxInputListener($options['choice_list']), 10) ; } else { $builder - ->appendClientTransformer(new ChoiceToBooleanArrayTransformer($options['choice_list'])) + ->addViewTransformer(new ChoiceToBooleanArrayTransformer($options['choice_list'])) ->addEventSubscriber(new FixRadioInputListener($options['choice_list']), 10) ; } } else { if ($options['multiple']) { - $builder->appendClientTransformer(new ChoicesToValuesTransformer($options['choice_list'])); + $builder->addViewTransformer(new ChoicesToValuesTransformer($options['choice_list'])); } else { - $builder->appendClientTransformer(new ChoiceToValueTransformer($options['choice_list'])); + $builder->addViewTransformer(new ChoiceToValueTransformer($options['choice_list'])); } } @@ -99,43 +73,41 @@ class ChoiceType extends AbstractType /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { - $choiceList = $form->getAttribute('choice_list'); + $view->addVars(array( + 'multiple' => $options['multiple'], + 'expanded' => $options['expanded'], + 'preferred_choices' => $options['choice_list']->getPreferredViews(), + 'choices' => $options['choice_list']->getRemainingViews(), + 'separator' => '-------------------', + 'empty_value' => $options['empty_value'], + )); - $view - ->set('multiple', $form->getAttribute('multiple')) - ->set('expanded', $form->getAttribute('expanded')) - ->set('preferred_choices', $choiceList->getPreferredViews()) - ->set('choices', $choiceList->getRemainingViews()) - ->set('separator', '-------------------') - ->set('empty_value', $form->getAttribute('empty_value')) - ; - - if ($view->get('multiple') && !$view->get('expanded')) { + if ($options['multiple'] && !$options['expanded']) { // Add "[]" to the name in case a select tag with multiple options is // displayed. Otherwise only one of the selected options is sent in the // POST request. - $view->set('full_name', $view->get('full_name').'[]'); + $view->setVar('full_name', $view->getVar('full_name').'[]'); } } /** * {@inheritdoc} */ - public function buildViewBottomUp(FormView $view, FormInterface $form) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) { - if ($view->get('expanded')) { + if ($options['expanded']) { // Radio buttons should have the same name as the parent - $childName = $view->get('full_name'); + $childName = $view->getVar('full_name'); // Checkboxes should append "[]" to allow multiple selection - if ($view->get('multiple')) { + if ($options['multiple']) { $childName .= '[]'; } - foreach ($view->getChildren() as $childView) { - $childView->set('full_name', $childName); + foreach ($view as $childView) { + $childView->setVar('full_name', $childName); } } } @@ -143,7 +115,7 @@ class ChoiceType extends AbstractType /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { $choiceList = function (Options $options) { return new SimpleChoiceList( @@ -165,11 +137,24 @@ class ChoiceType extends AbstractType return $options['required'] ? null : ''; }; - $singleControl = function (Options $options) { - return !$options['expanded']; + $emptyValueFilter = function (Options $options, $emptyValue) { + if ($options['multiple'] || $options['expanded']) { + // never use an empty value for these cases + return null; + } elseif (false === $emptyValue) { + // an empty value should be added but the user decided otherwise + return null; + } + + // empty value has been set explicitly + return $emptyValue; }; - return array( + $compound = function (Options $options) { + return $options['expanded']; + }; + + $resolver->setDefaults(array( 'multiple' => false, 'expanded' => false, 'choice_list' => $choiceList, @@ -178,14 +163,22 @@ class ChoiceType extends AbstractType 'empty_data' => $emptyData, 'empty_value' => $emptyValue, 'error_bubbling' => false, - 'single_control' => $singleControl, - ); + 'compound' => $compound, + )); + + $resolver->setFilters(array( + 'empty_value' => $emptyValueFilter, + )); + + $resolver->setAllowedTypes(array( + 'choice_list' => array('null', 'Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface'), + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } @@ -201,11 +194,11 @@ class ChoiceType extends AbstractType /** * Adds the sub fields for an expanded choice field. * - * @param FormBuilder $builder The form builder. - * @param array $choiceViews The choice view objects. - * @param array $options The build options. + * @param FormBuilderInterface $builder The form builder. + * @param array $choiceViews The choice view objects. + * @param array $options The build options. */ - private function addSubForms(FormBuilder $builder, array $choiceViews, array $options) + private function addSubForms(FormBuilderInterface $builder, array $choiceViews, array $options) { foreach ($choiceViews as $i => $choiceView) { if (is_array($choiceView)) { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php b/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php index d3832243ec..6b0d1ec1ee 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php @@ -12,17 +12,18 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormViewInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class CollectionType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { if ($options['allow_add'] && $options['prototype']) { $prototype = $builder->create($options['prototype_name'], $options['type'], array_replace(array( @@ -39,51 +40,47 @@ class CollectionType extends AbstractType $options['allow_delete'] ); - $builder - ->addEventSubscriber($resizeListener) - ->setAttribute('allow_add', $options['allow_add']) - ->setAttribute('allow_delete', $options['allow_delete']) - ; + $builder->addEventSubscriber($resizeListener); } /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { - $view - ->set('allow_add', $form->getAttribute('allow_add')) - ->set('allow_delete', $form->getAttribute('allow_delete')) - ; + $view->addVars(array( + 'allow_add' => $options['allow_add'], + 'allow_delete' => $options['allow_delete'], + )); - if ($form->hasAttribute('prototype')) { - $view->set('prototype', $form->getAttribute('prototype')->createView($view)); + if ($form->getConfig()->hasAttribute('prototype')) { + $view->setVar('prototype', $form->getConfig()->getAttribute('prototype')->createView($view)); } } /** * {@inheritdoc} */ - public function buildViewBottomUp(FormView $view, FormInterface $form) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) { - if ($form->hasAttribute('prototype') && $view->get('prototype')->get('multipart')) { - $view->set('multipart', true); + if ($form->getConfig()->hasAttribute('prototype') && $view->getVar('prototype')->getVar('multipart')) { + $view->setVar('multipart', true); } } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'allow_add' => false, 'allow_delete' => false, 'prototype' => true, 'prototype_name' => '__name__', 'type' => 'text', 'options' => array(), - ); + )); } /** diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php index e2cbc43ed7..4d5f29b995 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php @@ -13,23 +13,24 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Locale\Locale; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class CountryType extends AbstractType { /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'choices' => Locale::getDisplayCountries(\Locale::getDefault()), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'choice'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php index 820c6cbbcc..35c645dc36 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php @@ -13,8 +13,8 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormBuilder; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormViewInterface; use Symfony\Component\Form\ReversedTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer; @@ -22,13 +22,14 @@ use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransf use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\ArrayToPartsTransformer; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class DateTimeType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $parts = array('year', 'month', 'day', 'hour', 'minute'); $timeParts = array('hour', 'minute'); @@ -42,7 +43,7 @@ class DateTimeType extends AbstractType } if ('single_text' === $options['widget']) { - $builder->appendClientTransformer(new DateTimeToStringTransformer($options['data_timezone'], $options['user_timezone'], $format)); + $builder->addViewTransformer(new DateTimeToStringTransformer($options['data_timezone'], $options['user_timezone'], $format)); } else { // Only pass a subset of the options to children $dateOptions = array_intersect_key($options, array_flip(array( @@ -85,7 +86,7 @@ class DateTimeType extends AbstractType $timeOptions['input'] = 'array'; $builder - ->appendClientTransformer(new DataTransformerChain(array( + ->addViewTransformer(new DataTransformerChain(array( new DateTimeToArrayTransformer($options['data_timezone'], $options['user_timezone'], $parts), new ArrayToPartsTransformer(array( 'date' => array('year', 'month', 'day'), @@ -110,32 +111,30 @@ class DateTimeType extends AbstractType new DateTimeToArrayTransformer($options['data_timezone'], $options['data_timezone'], $parts) )); } - - $builder->setAttribute('widget', $options['widget']); } /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { - $view->set('widget', $form->getAttribute('widget')); + $view->setVar('widget', $options['widget']); - if ('single_text' === $form->getAttribute('widget')) { - $view->set('type', 'datetime'); + if ('single_text' === $options['widget']) { + $view->setVar('type', 'datetime'); } } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - $singleControl = function (Options $options) { - return $options['widget'] === 'single_text'; + $compound = function (Options $options) { + return $options['widget'] !== 'single_text'; }; - return array( + $resolver->setDefaults(array( 'input' => 'datetime', 'data_timezone' => null, 'user_timezone' => null, @@ -163,16 +162,10 @@ class DateTimeType extends AbstractType // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, - 'single_control' => $singleControl, - ); - } + 'compound' => $compound, + )); - /** - * {@inheritdoc} - */ - public function getAllowedOptionValues() - { - return array( + $resolver->setAllowedValues(array( 'input' => array( 'datetime', 'string', @@ -198,13 +191,13 @@ class DateTimeType extends AbstractType 'text', 'choice', ), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index 58f1112a7d..347d3f61a0 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -13,27 +13,30 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Exception\CreationException; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormViewInterface; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer; use Symfony\Component\Form\ReversedTransformer; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class DateType extends AbstractType { + const DEFAULT_FORMAT = \IntlDateFormatter::MEDIUM; + /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $format = $options['format']; $pattern = null; - $allowedFormatOptionValues = array( + $allowedFormats = array( \IntlDateFormatter::FULL, \IntlDateFormatter::LONG, \IntlDateFormatter::MEDIUM, @@ -41,11 +44,9 @@ class DateType extends AbstractType ); // If $format is not in the allowed options, it's considered as the pattern of the formatter if it is a string - if (!in_array($format, $allowedFormatOptionValues, true)) { + if (!in_array($format, $allowedFormats, true)) { if (is_string($format)) { - $defaultOptions = $this->getDefaultOptions(); - - $format = $defaultOptions['format']; + $format = self::DEFAULT_FORMAT; $pattern = $options['format']; } else { throw new CreationException('The "format" option must be one of the IntlDateFormatter constants (FULL, LONG, MEDIUM, SHORT) or a string representing a custom pattern'); @@ -62,7 +63,7 @@ class DateType extends AbstractType ); if ('single_text' === $options['widget']) { - $builder->appendClientTransformer(new DateTimeToLocalizedStringTransformer($options['data_timezone'], $options['user_timezone'], $format, \IntlDateFormatter::NONE, \IntlDateFormatter::GREGORIAN, $pattern)); + $builder->addViewTransformer(new DateTimeToLocalizedStringTransformer($options['data_timezone'], $options['user_timezone'], $format, \IntlDateFormatter::NONE, \IntlDateFormatter::GREGORIAN, $pattern)); } else { $yearOptions = $monthOptions = $dayOptions = array(); @@ -109,7 +110,7 @@ class DateType extends AbstractType ->add('year', $options['widget'], $yearOptions) ->add('month', $options['widget'], $monthOptions) ->add('day', $options['widget'], $dayOptions) - ->appendClientTransformer(new DateTimeToArrayTransformer( + ->addViewTransformer(new DateTimeToArrayTransformer( $options['data_timezone'], $options['user_timezone'], array('year', 'month', 'day') )) ; @@ -129,24 +130,22 @@ class DateType extends AbstractType )); } - $builder - ->setAttribute('formatter', $formatter) - ->setAttribute('widget', $options['widget']); + $builder->setAttribute('formatter', $formatter); } /** * {@inheritdoc} */ - public function buildViewBottomUp(FormView $view, FormInterface $form) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) { - $view->set('widget', $form->getAttribute('widget')); + $view->setVar('widget', $options['widget']); - if ('single_text' === $form->getAttribute('widget')) { - $view->set('type', 'date'); + if ('single_text' === $options['widget']) { + $view->setVar('type', 'date'); } - if ($view->hasChildren()) { - $pattern = $form->getAttribute('formatter')->getPattern(); + if (count($view) > 0) { + $pattern = $form->getConfig()->getAttribute('formatter')->getPattern(); // set right order with respect to locale (e.g.: de_DE=dd.MM.yy; en_US=M/d/yy) // lookup various formats at http://userguide.icu-project.org/formatparse/datetime @@ -157,26 +156,26 @@ class DateType extends AbstractType $pattern = '{{ year }}-{{ month }}-{{ day }}'; } - $view->set('date_pattern', $pattern); + $view->setVar('date_pattern', $pattern); } } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - $singleControl = function (Options $options) { - return $options['widget'] === 'single_text'; + $compound = function (Options $options) { + return $options['widget'] !== 'single_text'; }; - return array( + $resolver->setDefaults(array( 'years' => range(date('Y') - 5, date('Y') + 5), 'months' => range(1, 12), 'days' => range(1, 31), 'widget' => 'choice', 'input' => 'datetime', - 'format' => \IntlDateFormatter::MEDIUM, + 'format' => self::DEFAULT_FORMAT, 'data_timezone' => null, 'user_timezone' => null, 'empty_value' => null, @@ -189,16 +188,10 @@ class DateType extends AbstractType // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, - 'single_control' => $singleControl, - ); - } + 'compound' => $compound, + )); - /** - * {@inheritdoc} - */ - public function getAllowedOptionValues() - { - return array( + $resolver->setAllowedValues(array( 'input' => array( 'datetime', 'string', @@ -210,13 +203,13 @@ class DateType extends AbstractType 'text', 'choice', ), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php b/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php index 0afad854d1..26652ef660 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php @@ -18,7 +18,7 @@ class EmailType extends AbstractType /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'text'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index d57176ec67..373c5fcdbc 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -13,45 +13,46 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormViewInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class FileType extends AbstractType { /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) + { + $view->addVars(array( + 'type' => 'file', + 'value' => '', + )); + } + + /** + * {@inheritdoc} + */ + public function finishView(FormViewInterface $view, FormInterface $form, array $options) { $view - ->set('type', 'file') - ->set('value', '') + ->setVar('multipart', true) ; } /** * {@inheritdoc} */ - public function buildViewBottomUp(FormView $view, FormInterface $form) + public function setDefaultOptions(OptionsResolverInterface $resolver) { - $view - ->set('multipart', true) - ; + $resolver->setDefaults(array( + 'compound' => false, + )); } /** * {@inheritdoc} */ - public function getDefaultOptions() - { - return array( - 'single_control' => true, - ); - } - - /** - * {@inheritdoc} - */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index 212675ee1a..f7a9887218 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -14,30 +14,24 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Util\PropertyPath; use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormFactoryInterface; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormViewInterface; use Symfony\Component\Form\Extension\Core\EventListener\TrimListener; use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\Exception\FormException; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class FormType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { - if (!is_array($options['attr'])) { - throw new FormException('The "attr" option must be an "array".'); - } - - if (!is_array($options['label_attr'])) { - throw new FormException('The "label_attr" option must be an "array".'); - } - $builder ->setRequired($options['required']) ->setDisabled($options['disabled']) @@ -48,14 +42,6 @@ class FormType extends AbstractType ->setMapped($options['mapped']) ->setByReference($options['by_reference']) ->setVirtual($options['virtual']) - ->setAttribute('read_only', $options['read_only']) - ->setAttribute('max_length', $options['max_length']) - ->setAttribute('pattern', $options['pattern']) - ->setAttribute('label', $options['label'] ?: $this->humanize($builder->getName())) - ->setAttribute('attr', $options['attr']) - ->setAttribute('label_attr', $options['label_attr']) - ->setAttribute('translation_domain', $options['translation_domain']) - ->setAttribute('single_control', $options['single_control']) ->setData($options['data']) ->setDataMapper(new PropertyPathMapper()) ; @@ -68,18 +54,18 @@ class FormType extends AbstractType /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { $name = $form->getName(); - $readOnly = $form->getAttribute('read_only'); + $readOnly = $options['read_only']; if ($view->hasParent()) { if ('' === $name) { throw new FormException('Form node with empty name can be used only as root form node.'); } - if ('' !== ($parentFullName = $view->getParent()->get('full_name'))) { - $id = sprintf('%s_%s', $view->getParent()->get('id'), $name); + if ('' !== ($parentFullName = $view->getParent()->getVar('full_name'))) { + $id = sprintf('%s_%s', $view->getParent()->getVar('id'), $name); $fullName = sprintf('%s[%s]', $parentFullName, $name); } else { $id = $name; @@ -87,7 +73,7 @@ class FormType extends AbstractType } // Complex fields are read-only if themselves or their parent is. - $readOnly = $readOnly || $view->getParent()->get('read_only'); + $readOnly = $readOnly || $view->getParent()->getVar('read_only'); } else { $id = $name; $fullName = $name; @@ -103,59 +89,55 @@ class FormType extends AbstractType $types[] = $type->getName(); } - $view - ->set('form', $view) - ->set('id', $id) - ->set('name', $name) - ->set('full_name', $fullName) - ->set('read_only', $readOnly) - ->set('errors', $form->getErrors()) - ->set('valid', $form->isBound() ? $form->isValid() : true) - ->set('value', $form->getClientData()) - ->set('disabled', $form->isDisabled()) - ->set('required', $form->isRequired()) - ->set('max_length', $form->getAttribute('max_length')) - ->set('pattern', $form->getAttribute('pattern')) - ->set('size', null) - ->set('label', $form->getAttribute('label')) - ->set('multipart', false) - ->set('attr', $form->getAttribute('attr')) - ->set('label_attr', $form->getAttribute('label_attr')) - ->set('single_control', $form->getAttribute('single_control')) - ->set('types', $types) - ->set('translation_domain', $form->getAttribute('translation_domain')) - ; + $view->addVars(array( + 'form' => $view, + 'id' => $id, + 'name' => $name, + 'full_name' => $fullName, + 'read_only' => $readOnly, + 'errors' => $form->getErrors(), + 'valid' => $form->isBound() ? $form->isValid() : true, + 'value' => $form->getViewData(), + 'disabled' => $form->isDisabled(), + 'required' => $form->isRequired(), + 'max_length' => $options['max_length'], + 'pattern' => $options['pattern'], + 'size' => null, + 'label' => $options['label'] ?: $this->humanize($form->getName()), + 'multipart' => false, + 'attr' => $options['attr'], + 'label_attr' => $options['label_attr'], + 'compound' => $options['compound'], + 'types' => $types, + 'translation_domain' => $options['translation_domain'], + )); } /** * {@inheritdoc} */ - public function buildViewBottomUp(FormView $view, FormInterface $form) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) { $multipart = false; - foreach ($view->getChildren() as $child) { - if ($child->get('multipart')) { + foreach ($view as $child) { + if ($child->getVar('multipart')) { $multipart = true; break; } } - $view->set('multipart', $multipart); + $view->setVar('multipart', $multipart); } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { // Derive "data_class" option from passed "data" object $dataClass = function (Options $options) { - if (is_object($options['data'])) { - return get_class($options['data']); - } - - return null; + return is_object($options['data']) ? get_class($options['data']) : null; }; // Derive "empty_data" closure from "data_class" option @@ -164,27 +146,19 @@ class FormType extends AbstractType if (null !== $class) { return function (FormInterface $form) use ($class) { - if ($form->isEmpty() && !$form->isRequired()) { - return null; - } - - return new $class(); + return $form->isEmpty() && !$form->isRequired() ? null : new $class(); }; } return function (FormInterface $form) { - if ($form->hasChildren()) { - return array(); - } - - return ''; + return count($form) > 0 ? array() : ''; }; }; // For any form that is not represented by a single HTML control, // errors should bubble up by default $errorBubbling = function (Options $options) { - return !$options['single_control']; + return $options['compound']; }; // BC clause: former property_path=false now equals mapped=false @@ -192,7 +166,7 @@ class FormType extends AbstractType return false !== $options['property_path']; }; - return array( + $resolver->setDefaults(array( 'data' => null, 'data_class' => $dataClass, 'empty_data' => $emptyData, @@ -210,9 +184,14 @@ class FormType extends AbstractType 'attr' => array(), 'label_attr' => array(), 'virtual' => false, - 'single_control' => false, + 'compound' => true, 'translation_domain' => 'messages', - ); + )); + + $resolver->setAllowedTypes(array( + 'attr' => 'array', + 'label_attr' => 'array', + )); } /** @@ -220,13 +199,13 @@ class FormType extends AbstractType */ public function createBuilder($name, FormFactoryInterface $factory, array $options) { - return new FormBuilder($name, $options['data_class'], new EventDispatcher(), $factory); + return new FormBuilder($name, $options['data_class'], new EventDispatcher(), $factory, $options); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return null; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php b/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php index 49562d9fd8..fc1533648b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php @@ -12,27 +12,28 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class HiddenType extends AbstractType { /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( // hidden fields cannot have a required attribute 'required' => false, // Pass errors to the parent 'error_bubbling' => true, - 'single_control' => true, - ); + 'compound' => false, + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php b/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php index 293c01d3cd..c3ab0546da 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php @@ -12,17 +12,18 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\DataTransformer\IntegerToLocalizedStringTransformer; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class IntegerType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->appendClientTransformer( + $builder->addViewTransformer( new IntegerToLocalizedStringTransformer( $options['precision'], $options['grouping'], @@ -33,24 +34,18 @@ class IntegerType extends AbstractType /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( // default precision is locale specific (usually around 3) - 'precision' => null, - 'grouping' => false, + 'precision' => null, + 'grouping' => false, // Integer cast rounds towards 0, so do the same when displaying fractions - 'rounding_mode' => \NumberFormatter::ROUND_DOWN, - 'single_control' => true, - ); - } + 'rounding_mode' => \NumberFormatter::ROUND_DOWN, + 'compound' => false, + )); - /** - * {@inheritdoc} - */ - public function getAllowedOptionValues() - { - return array( + $resolver->setAllowedValues(array( 'rounding_mode' => array( \NumberFormatter::ROUND_FLOOR, \NumberFormatter::ROUND_DOWN, @@ -60,13 +55,13 @@ class IntegerType extends AbstractType \NumberFormatter::ROUND_UP, \NumberFormatter::ROUND_CEILING, ), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php index 6ca038f85d..1255ea9afc 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php @@ -13,23 +13,24 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Locale\Locale; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class LanguageType extends AbstractType { /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'choices' => Locale::getDisplayLanguages(\Locale::getDefault()), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'choice'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php index 17a7eb4419..e9793aae30 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php @@ -13,23 +13,24 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Locale\Locale; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class LocaleType extends AbstractType { /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'choices' => Locale::getDisplayLocales(\Locale::getDefault()), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'choice'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php index 560cbe59b5..8d4f414ad2 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php @@ -13,9 +13,10 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\DataTransformer\MoneyToLocalizedStringTransformer; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormViewInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class MoneyType extends AbstractType { @@ -24,45 +25,44 @@ class MoneyType extends AbstractType /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->appendClientTransformer(new MoneyToLocalizedStringTransformer( + ->addViewTransformer(new MoneyToLocalizedStringTransformer( $options['precision'], $options['grouping'], null, $options['divisor'] )) - ->setAttribute('currency', $options['currency']) ; } /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { - $view->set('money_pattern', self::getPattern($form->getAttribute('currency'))); + $view->setVar('money_pattern', self::getPattern($options['currency'])); } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( - 'precision' => 2, - 'grouping' => false, - 'divisor' => 1, - 'currency' => 'EUR', - 'single_control' => true, - ); + $resolver->setDefaults(array( + 'precision' => 2, + 'grouping' => false, + 'divisor' => 1, + 'currency' => 'EUR', + 'compound' => false, + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php b/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php index 993df32809..93a3d9824e 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php @@ -12,17 +12,18 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class NumberType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->appendClientTransformer(new NumberToLocalizedStringTransformer( + $builder->addViewTransformer(new NumberToLocalizedStringTransformer( $options['precision'], $options['grouping'], $options['rounding_mode'] @@ -32,23 +33,17 @@ class NumberType extends AbstractType /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( // default precision is locale specific (usually around 3) - 'precision' => null, - 'grouping' => false, - 'rounding_mode' => \NumberFormatter::ROUND_HALFUP, - 'single_control' => true, - ); - } + 'precision' => null, + 'grouping' => false, + 'rounding_mode' => \NumberFormatter::ROUND_HALFUP, + 'compound' => false, + )); - /** - * {@inheritdoc} - */ - public function getAllowedOptionValues() - { - return array( + $resolver->setAllowedValues(array( 'rounding_mode' => array( \NumberFormatter::ROUND_FLOOR, \NumberFormatter::ROUND_DOWN, @@ -58,13 +53,13 @@ class NumberType extends AbstractType \NumberFormatter::ROUND_UP, \NumberFormatter::ROUND_CEILING, ), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/PasswordType.php b/src/Symfony/Component/Form/Extension/Core/Type/PasswordType.php index d2ffed8d1d..cf3f3d8405 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/PasswordType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/PasswordType.php @@ -13,43 +13,36 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormBuilder; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormViewInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class PasswordType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { - $builder->setAttribute('always_empty', $options['always_empty']); - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form) - { - if ($form->getAttribute('always_empty') || !$form->isBound()) { - $view->set('value', ''); + if ($options['always_empty'] || !$form->isBound()) { + $view->setVar('value', ''); } } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'always_empty' => true, - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'text'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php b/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php index 0ee0af39e3..52ca820e93 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php @@ -12,48 +12,43 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\DataTransformer\PercentToLocalizedStringTransformer; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class PercentType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { - $builder->appendClientTransformer(new PercentToLocalizedStringTransformer($options['precision'], $options['type'])); + $builder->addViewTransformer(new PercentToLocalizedStringTransformer($options['precision'], $options['type'])); } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( - 'precision' => 0, - 'type' => 'fractional', - 'single_control' => true, - ); - } + $resolver->setDefaults(array( + 'precision' => 0, + 'type' => 'fractional', + 'compound' => false, + )); - /** - * {@inheritdoc} - */ - public function getAllowedOptionValues() - { - return array( + $resolver->setAllowedValues(array( 'type' => array( 'fractional', 'integer', ), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/RadioType.php b/src/Symfony/Component/Form/Extension/Core/Type/RadioType.php index db22b41a70..dfa7c7d53b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/RadioType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/RadioType.php @@ -18,7 +18,7 @@ class RadioType extends AbstractType /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'checkbox'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php b/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php index fe48eed52c..d8104cf681 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php @@ -12,23 +12,24 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\DataTransformer\ValueToDuplicatesTransformer; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class RepeatedType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { // Overwrite required option for child fields $options['first_options']['required'] = $options['required']; $options['second_options']['required'] = $options['required']; $builder - ->appendClientTransformer(new ValueToDuplicatesTransformer(array( + ->addViewTransformer(new ValueToDuplicatesTransformer(array( $options['first_name'], $options['second_name'], ))) @@ -40,9 +41,9 @@ class RepeatedType extends AbstractType /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'type' => 'text', 'options' => array(), 'first_options' => array(), @@ -50,7 +51,7 @@ class RepeatedType extends AbstractType 'first_name' => 'first', 'second_name' => 'second', 'error_bubbling' => false, - ); + )); } /** diff --git a/src/Symfony/Component/Form/Extension/Core/Type/SearchType.php b/src/Symfony/Component/Form/Extension/Core/Type/SearchType.php index 2f5c417a65..bf82972d56 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/SearchType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/SearchType.php @@ -18,7 +18,7 @@ class SearchType extends AbstractType /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'text'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php index f454160d3e..5b68169b8f 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php @@ -12,35 +12,36 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\DataTransformer\ValueToStringTransformer; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class TextType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->appendClientTransformer(new ValueToStringTransformer()) + ->addViewTransformer(new ValueToStringTransformer()) ; } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( - 'single_control' => true, - ); + $resolver->setDefaults(array( + 'compound' => false, + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php index ce8618181b..31fe058132 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormViewInterface; use Symfony\Component\Form\FormInterface; class TextareaType extends AbstractType @@ -20,15 +20,15 @@ class TextareaType extends AbstractType /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { - $view->set('pattern', null); + $view->setVar('pattern', null); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'text'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index 69ef413241..b8925be2f9 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -13,20 +13,21 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\ReversedTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormViewInterface; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class TimeType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $parts = array('hour', 'minute'); $format = 'H:i'; @@ -36,17 +37,11 @@ class TimeType extends AbstractType } if ('single_text' === $options['widget']) { - $builder->appendClientTransformer(new DateTimeToStringTransformer($options['data_timezone'], $options['user_timezone'], $format)); + $builder->addViewTransformer(new DateTimeToStringTransformer($options['data_timezone'], $options['user_timezone'], $format)); } else { $hourOptions = $minuteOptions = $secondOptions = array(); if ('choice' === $options['widget']) { - if (is_array($options['empty_value'])) { - $options['empty_value'] = array_merge(array('hour' => null, 'minute' => null, 'second' => null), $options['empty_value']); - } else { - $options['empty_value'] = array('hour' => $options['empty_value'], 'minute' => $options['empty_value'], 'second' => $options['empty_value']); - } - $hours = $minutes = array(); foreach ($options['hours'] as $hour) { @@ -97,7 +92,7 @@ class TimeType extends AbstractType $builder->add('second', $options['widget'], $secondOptions); } - $builder->appendClientTransformer(new DateTimeToArrayTransformer($options['data_timezone'], $options['user_timezone'], $parts, 'text' === $options['widget'])); + $builder->addViewTransformer(new DateTimeToArrayTransformer($options['data_timezone'], $options['user_timezone'], $parts, 'text' === $options['widget'])); } if ('string' === $options['input']) { @@ -113,38 +108,48 @@ class TimeType extends AbstractType new DateTimeToArrayTransformer($options['data_timezone'], $options['data_timezone'], $parts) )); } - - $builder - ->setAttribute('widget', $options['widget']) - ->setAttribute('with_seconds', $options['with_seconds']) - ; } /** * {@inheritdoc} */ - public function buildView(FormView $view, FormInterface $form) + public function buildView(FormViewInterface $view, FormInterface $form, array $options) { - $view - ->set('widget', $form->getAttribute('widget')) - ->set('with_seconds', $form->getAttribute('with_seconds')) - ; + $view->addVars(array( + 'widget' => $options['widget'], + 'with_seconds' => $options['with_seconds'], + )); - if ('single_text' === $form->getAttribute('widget')) { - $view->set('type', 'time'); + if ('single_text' === $options['widget']) { + $view->setVar('type', 'time'); } } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - $singleControl = function (Options $options) { - return $options['widget'] === 'single_text'; + $compound = function (Options $options) { + return $options['widget'] !== 'single_text'; }; - return array( + $emptyValueFilter = function (Options $options, $emptyValue) { + if (is_array($emptyValue)) { + return array_merge( + array('hour' => null, 'minute' => null, 'second' => null), + $emptyValue + ); + } + + return array( + 'hour' => $emptyValue, + 'minute' => $emptyValue, + 'second' => $emptyValue + ); + }; + + $resolver->setDefaults(array( 'hours' => range(0, 23), 'minutes' => range(0, 59), 'seconds' => range(0, 59), @@ -163,16 +168,14 @@ class TimeType extends AbstractType // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, - 'single_control' => $singleControl, - ); - } + 'compound' => $compound, + )); - /** - * {@inheritdoc} - */ - public function getAllowedOptionValues() - { - return array( + $resolver->setFilters(array( + 'empty_value' => $emptyValueFilter, + )); + + $resolver->setAllowedValues(array( 'input' => array( 'datetime', 'string', @@ -184,13 +187,13 @@ class TimeType extends AbstractType 'text', 'choice', ), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'field'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php index a7894ee86b..178170f4a3 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class TimezoneType extends AbstractType { @@ -24,17 +25,17 @@ class TimezoneType extends AbstractType /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'choices' => self::getTimezones(), - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'choice'; } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php b/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php index 5a7e768e8e..27749b1a8c 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/UrlType.php @@ -12,15 +12,16 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class UrlType extends AbstractType { /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder->addEventSubscriber(new FixUrlProtocolListener($options['default_protocol'])); } @@ -28,17 +29,17 @@ class UrlType extends AbstractType /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'default_protocol' => 'http', - ); + )); } /** * {@inheritdoc} */ - public function getParent(array $options) + public function getParent() { return 'text'; } diff --git a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php index da8a07d1af..a440dcd6a7 100644 --- a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php +++ b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php @@ -14,7 +14,7 @@ namespace Symfony\Component\Form\Extension\Csrf\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormError; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; /** @@ -47,7 +47,7 @@ class CsrfValidationListener implements EventSubscriberInterface static public function getSubscribedEvents() { return array( - FormEvents::BIND_CLIENT_DATA => 'onBindClientData', + FormEvents::PRE_BIND => 'preBind', ); } @@ -58,12 +58,12 @@ class CsrfValidationListener implements EventSubscriberInterface $this->intention = $intention; } - public function onBindClientData(FilterDataEvent $event) + public function preBind(FormEvent $event) { $form = $event->getForm(); $data = $event->getData(); - if ($form->isRoot() && !$form->getAttribute('single_control')) { + if ($form->isRoot() && $form->getConfig()->getOption('compound')) { if (!isset($data[$this->fieldName]) || !$this->csrfProvider->isCsrfTokenValid($this->intention, $data[$this->fieldName])) { $form->addError(new FormError('The CSRF token is invalid. Please try to resubmit the form')); } diff --git a/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php b/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php index 71486c485a..c7eb63ada4 100644 --- a/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php +++ b/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php @@ -14,9 +14,10 @@ namespace Symfony\Component\Form\Extension\Csrf\Type; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener; -use Symfony\Component\Form\FormBuilder; -use Symfony\Component\Form\FormView; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormViewInterface; use Symfony\Component\Form\FormInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; /** * @author Bernhard Schussek @@ -40,17 +41,13 @@ class FormTypeCsrfExtension extends AbstractTypeExtension * @param FormBuilder $builder The form builder * @param array $options The options */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { if (!$options['csrf_protection']) { return; } - // use a low priority so higher priority listeners don't remove the field $builder - ->setAttribute('csrf_field_name', $options['csrf_field_name']) - ->setAttribute('csrf_provider', $options['csrf_provider']) - ->setAttribute('csrf_intention', $options['intention']) ->setAttribute('csrf_factory', $builder->getFormFactory()) ->addEventSubscriber(new CsrfValidationListener($options['csrf_field_name'], $options['csrf_provider'], $options['intention'])) ; @@ -62,33 +59,31 @@ class FormTypeCsrfExtension extends AbstractTypeExtension * @param FormView $view The form view * @param FormInterface $form The form */ - public function buildViewBottomUp(FormView $view, FormInterface $form) + public function finishView(FormViewInterface $view, FormInterface $form, array $options) { - if (!$view->hasParent() && !$form->getAttribute('single_control') && $form->hasAttribute('csrf_field_name')) { - $name = $form->getAttribute('csrf_field_name'); - $csrfProvider = $form->getAttribute('csrf_provider'); - $intention = $form->getAttribute('csrf_intention'); - $factory = $form->getAttribute('csrf_factory'); - $data = $csrfProvider->generateCsrfToken($intention); - $csrfForm = $factory->createNamed('hidden', $name, $data, array( - 'property_path' => false, + if ($options['csrf_protection'] && !$view->hasParent() && $options['compound']) { + $factory = $form->getConfig()->getAttribute('csrf_factory'); + $data = $options['csrf_provider']->generateCsrfToken($options['intention']); + + $csrfForm = $factory->createNamed($options['csrf_field_name'], 'hidden', $data, array( + 'mapped' => false, )); - $view->addChild($csrfForm->createView($view)); + $view->add($csrfForm->createView($view)); } } /** * {@inheritDoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'csrf_protection' => $this->defaultEnabled, 'csrf_field_name' => $this->defaultFieldName, 'csrf_provider' => $this->defaultCsrfProvider, 'intention' => 'unknown', - ); + )); } /** diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index 586bde759f..81da771bd9 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -34,11 +34,7 @@ class FormValidator extends ConstraintValidator */ public function __construct(ServerParams $params = null) { - if (null === $params) { - $params = new ServerParams(); - } - - $this->serverParams = $params; + $this->serverParams = $params ?: new ServerParams(); } /** @@ -55,6 +51,7 @@ class FormValidator extends ConstraintValidator $path = $this->context->getPropertyPath(); $graphWalker = $this->context->getGraphWalker(); $groups = $this->getValidationGroups($form); + $config = $form->getConfig(); if (!empty($path)) { $path .= '.'; @@ -72,22 +69,22 @@ class FormValidator extends ConstraintValidator // Validate the data against the constraints defined // in the form - $constraints = $form->getAttribute('constraints'); + $constraints = $config->getOption('constraints'); foreach ($constraints as $constraint) { foreach ($groups as $group) { $graphWalker->walkConstraint($constraint, $form->getData(), $group, $path . 'data'); } } } else { - $clientDataAsString = is_scalar($form->getClientData()) - ? (string) $form->getClientData() - : gettype($form->getClientData()); + $clientDataAsString = is_scalar($form->getViewData()) + ? (string) $form->getViewData() + : gettype($form->getViewData()); // Mark the form with an error if it is not synchronized $this->context->addViolation( - $form->getAttribute('invalid_message'), + $config->getOption('invalid_message'), array('{{ value }}' => $clientDataAsString), - $form->getClientData(), + $form->getViewData(), null, Form::ERR_INVALID ); @@ -96,7 +93,7 @@ class FormValidator extends ConstraintValidator // Mark the form with an error if it contains extra fields if (count($form->getExtraData()) > 0) { $this->context->addViolation( - $form->getAttribute('extra_fields_message'), + $config->getOption('extra_fields_message'), array('{{ extra_fields }}' => implode('", "', array_keys($form->getExtraData()))), $form->getExtraData() ); @@ -106,31 +103,14 @@ class FormValidator extends ConstraintValidator $length = $this->serverParams->getContentLength(); if ($form->isRoot() && null !== $length) { - $max = strtoupper(trim($this->serverParams->getPostMaxSize())); + $max = $this->serverParams->getPostMaxSize(); - if ('' !== $max) { - $maxLength = (int) $max; - - switch (substr($max, -1)) { - // The 'G' modifier is available since PHP 5.1.0 - case 'G': - $maxLength *= pow(1024, 3); - break; - case 'M': - $maxLength *= pow(1024, 2); - break; - case 'K': - $maxLength *= 1024; - break; - } - - if ($length > $maxLength) { - $this->context->addViolation( - $form->getAttribute('post_max_size_message'), - array('{{ max }}' => $max), - $length - ); - } + if (null !== $max && $length > $max) { + $this->context->addViolation( + $config->getOption('post_max_size_message'), + array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize()), + $length + ); } } } @@ -158,14 +138,10 @@ class FormValidator extends ConstraintValidator // Non-root forms are validated if validation cascading // is enabled in all ancestor forms - $parent = $form->getParent(); - - while (null !== $parent) { - if (!$parent->getAttribute('cascade_validation')) { + while (null !== ($form = $form->getParent())) { + if (!$form->getConfig()->getOption('cascade_validation')) { return false; } - - $parent = $parent->getParent(); } return true; @@ -180,33 +156,20 @@ class FormValidator extends ConstraintValidator */ private function getValidationGroups(FormInterface $form) { - $groups = null; - - if ($form->hasAttribute('validation_groups')) { - $groups = $form->getAttribute('validation_groups'); - - if (is_callable($groups)) { - $groups = (array) call_user_func($groups, $form); - } - } - - $currentForm = $form; - while (!$groups && $currentForm->hasParent()) { - $currentForm = $currentForm->getParent(); - - if ($currentForm->hasAttribute('validation_groups')) { - $groups = $currentForm->getAttribute('validation_groups'); + do { + $groups = $form->getConfig()->getOption('validation_groups'); + if (null !== $groups) { if (is_callable($groups)) { - $groups = (array) call_user_func($groups, $currentForm); + $groups = call_user_func($groups, $form); } + + return (array) $groups; } - } - if (null === $groups) { - $groups = array('Default'); - } + $form = $form->getParent(); + } while (null !== $form); - return (array) $groups; + return array(Constraint::DEFAULT_GROUP); } } diff --git a/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php b/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php index 2ad34d621e..6dfd5c2e36 100644 --- a/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php +++ b/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php @@ -12,18 +12,11 @@ namespace Symfony\Component\Form\Extension\Validator\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\Validator\ConstraintViolation; -use Symfony\Component\Form\Extension\Validator\Constraints\Form; use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapperInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormError; +use Symfony\Component\Validator\ValidatorInterface; use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\Event\DataEvent; -use Symfony\Component\Form\Exception\FormException; -use Symfony\Component\Form\Util\PropertyPath; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ValidatorInterface; -use Symfony\Component\Validator\ExecutionContext; +use Symfony\Component\Form\Extension\Validator\Constraints\Form; /** * @author Bernhard Schussek diff --git a/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php b/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php index 0135b943e8..4b48760224 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php +++ b/src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php @@ -12,11 +12,12 @@ namespace Symfony\Component\Form\Extension\Validator\Type; use Symfony\Component\Form\AbstractTypeExtension; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper; use Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener; use Symfony\Component\Validator\ValidatorInterface; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; /** * @author Bernhard Schussek @@ -42,44 +43,40 @@ class FormTypeValidatorExtension extends AbstractTypeExtension /** * {@inheritdoc} */ - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { - if (empty($options['validation_groups'])) { - $options['validation_groups'] = null; - } else { - $options['validation_groups'] = is_callable($options['validation_groups']) - ? $options['validation_groups'] - : (array) $options['validation_groups']; - } - - // Objects, when casted to an array, are split into their properties - $constraints = is_object($options['constraints']) - ? array($options['constraints']) - : (array) $options['constraints']; - - $builder - ->setAttribute('error_mapping', $options['error_mapping']) - ->setAttribute('validation_groups', $options['validation_groups']) - ->setAttribute('constraints', $constraints) - ->setAttribute('cascade_validation', $options['cascade_validation']) - ->setAttribute('invalid_message', $options['invalid_message']) - ->setAttribute('extra_fields_message', $options['extra_fields_message']) - ->setAttribute('post_max_size_message', $options['post_max_size_message']) - ->addEventSubscriber(new ValidationListener($this->validator, $this->violationMapper)) - ; + $builder->addEventSubscriber(new ValidationListener($this->validator, $this->violationMapper)); } /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { // BC clause $constraints = function (Options $options) { return $options['validation_constraint']; }; - return array( + // Make sure that validation groups end up as null, closure or array + $validationGroupsFilter = function (Options $options, $groups) { + if (empty($groups)) { + return null; + } + + if (is_callable($groups)) { + return $groups; + } + + return (array) $groups; + }; + + // Constraint should always be converted to an array + $constraintsFilter = function (Options $options, $constraints) { + return is_object($constraints) ? array($constraints) : (array) $constraints; + }; + + $resolver->setDefaults(array( 'error_mapping' => array(), 'validation_groups' => null, // "validation_constraint" is deprecated. Use "constraints". @@ -89,7 +86,12 @@ class FormTypeValidatorExtension extends AbstractTypeExtension 'invalid_message' => 'This value is not valid.', 'extra_fields_message' => 'This form should not contain extra fields.', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', - ); + )); + + $resolver->setFilters(array( + 'validation_groups' => $validationGroupsFilter, + 'constraints' => $constraintsFilter, + )); } /** diff --git a/src/Symfony/Component/Form/Extension/Validator/Type/RepeatedTypeValidatorExtension.php b/src/Symfony/Component/Form/Extension/Validator/Type/RepeatedTypeValidatorExtension.php index 3945c247b8..858ff0fae1 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Type/RepeatedTypeValidatorExtension.php +++ b/src/Symfony/Component/Form/Extension/Validator/Type/RepeatedTypeValidatorExtension.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Form\Extension\Validator\Type; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; /** * @author Bernhard Schussek @@ -22,16 +23,16 @@ class RepeatedTypeValidatorExtension extends AbstractTypeExtension /** * {@inheritdoc} */ - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { // Map errors to the first field $errorMapping = function (Options $options) { return array('.' => $options['first_name']); }; - return array( + $resolver->setDefaults(array( 'error_mapping' => $errorMapping, - ); + )); } /** diff --git a/src/Symfony/Component/Form/Extension/Validator/Util/ServerParams.php b/src/Symfony/Component/Form/Extension/Validator/Util/ServerParams.php index 58c8e2407e..cac6047ce2 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Util/ServerParams.php +++ b/src/Symfony/Component/Form/Extension/Validator/Util/ServerParams.php @@ -17,13 +17,40 @@ namespace Symfony\Component\Form\Extension\Validator\Util; class ServerParams { /** - * Returns the "post_max_size" ini setting. + * Returns maximum post size in bytes. * - * @return string The value of the ini setting. + * @return null|integer The maximum post size in bytes */ public function getPostMaxSize() { - return ini_get('post_max_size'); + $iniMax = $this->getNormalizedIniPostMaxSize(); + + if ('' === $iniMax) { + return null; + } + + $max = (int) $iniMax; + + switch (substr($iniMax, -1)) { + case 'G': + $max *= 1024; + case 'M': + $max *= 1024; + case 'K': + $max *= 1024; + } + + return $max; + } + + /** + * Returns the normalized "post_max_size" ini setting. + * + * @return string + */ + public function getNormalizedIniPostMaxSize() + { + return strtoupper(trim(ini_get('post_max_size'))); } /** diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php index 736f532184..182f78dac4 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php +++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php @@ -109,12 +109,12 @@ class ViolationMapper implements ViolationMapperInterface } // Follow dot rules until we have the final target - $mapping = $this->scope->getAttribute('error_mapping'); + $mapping = $this->scope->getConfig()->getAttribute('error_mapping'); while ($this->isValidScope() && isset($mapping['.'])) { $dotRule = new MappingRule($this->scope, '.', $mapping['.']); $this->scope = $dotRule->getTarget(); - $mapping = $this->scope->getAttribute('error_mapping'); + $mapping = $this->scope->getConfig()->getAttribute('error_mapping'); } // Only add the error if the form is synchronized @@ -279,9 +279,9 @@ class ViolationMapper implements ViolationMapperInterface { $this->scope = $form; $this->children = new \RecursiveIteratorIterator( - new VirtualFormAwareIterator($form->getChildren()) + new VirtualFormAwareIterator($form->all()) ); - foreach ($form->getAttribute('error_mapping') as $propertyPath => $targetPath) { + foreach ($form->getConfig()->getAttribute('error_mapping') as $propertyPath => $targetPath) { // Dot rules are considered at the very end if ('.' !== $propertyPath) { $this->rules[] = new MappingRule($form, $propertyPath, $targetPath); diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index b9fe51376d..d4d880de0a 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Form; -use Symfony\Component\Form\Event\DataEvent; -use Symfony\Component\Form\Event\FilterDataEvent; use Symfony\Component\Form\Exception\FormException; use Symfony\Component\Form\Exception\AlreadyBoundException; use Symfony\Component\Form\Exception\UnexpectedTypeException; @@ -89,10 +87,10 @@ class Form implements \IteratorAggregate, FormInterface private $bound = false; /** - * The form data in application format + * The form data in model format * @var mixed */ - private $appData; + private $modelData; /** * The form data in normalized format @@ -101,10 +99,10 @@ class Form implements \IteratorAggregate, FormInterface private $normData; /** - * The form data in client format + * The form data in view format * @var mixed */ - private $clientData; + private $viewData; /** * The bound values that don't belong to any children @@ -113,7 +111,7 @@ class Form implements \IteratorAggregate, FormInterface private $extraData = array(); /** - * Whether the data in application, normalized and client format is + * Whether the data in model, normalized and view format is * synchronized. Data may not be synchronized if transformation errors * occur. * @var Boolean @@ -288,6 +286,9 @@ class Form implements \IteratorAggregate, FormInterface * @param string $name The name of the attribute. * * @return Boolean Whether the attribute exists. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link getConfig()} and {@link FormConfigInterface::hasAttribute()} instead. */ public function hasAttribute($name) { @@ -300,6 +301,9 @@ class Form implements \IteratorAggregate, FormInterface * @param string $name The name of the attribute * * @return mixed The attribute value. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link getConfig()} and {@link FormConfigInterface::getAttribute()} instead. */ public function getAttribute($name) { @@ -309,75 +313,74 @@ class Form implements \IteratorAggregate, FormInterface /** * Updates the form with default data. * - * @param array $appData The data formatted as expected for the underlying object + * @param array $modelData The data formatted as expected for the underlying object * * @return Form The current form */ - public function setData($appData) + public function setData($modelData) { if ($this->bound) { throw new AlreadyBoundException('You cannot change the data of a bound form'); } - if (is_object($appData) && !$this->config->getByReference()) { - $appData = clone $appData; + if (is_object($modelData) && !$this->config->getByReference()) { + $modelData = clone $modelData; } - $event = new DataEvent($this, $appData); - $this->config->getEventDispatcher()->dispatch(FormEvents::PRE_SET_DATA, $event); - // Hook to change content of the data - $event = new FilterDataEvent($this, $appData); + $event = new FormEvent($this, $modelData); + $this->config->getEventDispatcher()->dispatch(FormEvents::PRE_SET_DATA, $event); + // BC until 2.3 $this->config->getEventDispatcher()->dispatch(FormEvents::SET_DATA, $event); - $appData = $event->getData(); + $modelData = $event->getData(); // Treat data as strings unless a value transformer exists - if (!$this->config->getClientTransformers() && !$this->config->getNormTransformers() && is_scalar($appData)) { - $appData = (string) $appData; + if (!$this->config->getViewTransformers() && !$this->config->getModelTransformers() && is_scalar($modelData)) { + $modelData = (string) $modelData; } // Synchronize representations - must not change the content! - $normData = $this->appToNorm($appData); - $clientData = $this->normToClient($normData); + $normData = $this->modelToNorm($modelData); + $viewData = $this->normToView($normData); - // Validate if client data matches data class (unless empty) - if (!empty($clientData)) { + // Validate if view data matches data class (unless empty) + if (!empty($viewData)) { $dataClass = $this->config->getDataClass(); - if (null === $dataClass && is_object($clientData) && !$clientData instanceof \ArrayAccess) { + if (null === $dataClass && is_object($viewData) && !$viewData instanceof \ArrayAccess) { $expectedType = 'scalar, array or an instance of \ArrayAccess'; throw new FormException( - 'The form\'s client data is expected to be of type ' . $expectedType . ', ' . - 'but is an instance of class ' . get_class($clientData) . '. You ' . + 'The form\'s view data is expected to be of type ' . $expectedType . ', ' . + 'but is an instance of class ' . get_class($viewData) . '. You ' . 'can avoid this error by setting the "data_class" option to ' . - '"' . get_class($clientData) . '" or by adding a client transformer ' . - 'that transforms ' . get_class($clientData) . ' to ' . $expectedType . '.' + '"' . get_class($viewData) . '" or by adding a view transformer ' . + 'that transforms ' . get_class($viewData) . ' to ' . $expectedType . '.' ); } - if (null !== $dataClass && !$clientData instanceof $dataClass) { + if (null !== $dataClass && !$viewData instanceof $dataClass) { throw new FormException( - 'The form\'s client data is expected to be an instance of class ' . - $dataClass . ', but has the type ' . gettype($clientData) . '. You ' . + 'The form\'s view data is expected to be an instance of class ' . + $dataClass . ', but has the type ' . gettype($viewData) . '. You ' . 'can avoid this error by setting the "data_class" option to ' . - 'null or by adding a client transformer that transforms ' . - gettype($clientData) . ' to ' . $dataClass . '.' + 'null or by adding a view transformer that transforms ' . + gettype($viewData) . ' to ' . $dataClass . '.' ); } } - $this->appData = $appData; + $this->modelData = $modelData; $this->normData = $normData; - $this->clientData = $clientData; + $this->viewData = $viewData; $this->synchronized = true; if (count($this->children) > 0 && $this->config->getDataMapper()) { // Update child forms from the data - $this->config->getDataMapper()->mapDataToForms($clientData, $this->children); + $this->config->getDataMapper()->mapDataToForms($viewData, $this->children); } - $event = new DataEvent($this, $appData); + $event = new FormEvent($this, $modelData); $this->config->getEventDispatcher()->dispatch(FormEvents::POST_SET_DATA, $event); return $this; @@ -390,7 +393,7 @@ class Form implements \IteratorAggregate, FormInterface */ public function getData() { - return $this->appData; + return $this->modelData; } /** @@ -398,9 +401,22 @@ class Form implements \IteratorAggregate, FormInterface * * @return string */ + public function getViewData() + { + return $this->viewData; + } + + /** + * Alias of {@link getViewData()}. + * + * @return string + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link getViewData()} instead. + */ public function getClientData() { - return $this->clientData; + return $this->getViewData(); } /** @@ -416,13 +432,13 @@ class Form implements \IteratorAggregate, FormInterface /** * Binds data to the form, transforms and validates it. * - * @param string|array $clientData The data + * @param string|array $submittedData The data * * @return Form The current form * * @throws UnexpectedTypeException */ - public function bind($clientData) + public function bind($submittedData) { if ($this->bound) { throw new AlreadyBoundException('A form can only be bound once'); @@ -438,43 +454,45 @@ class Form implements \IteratorAggregate, FormInterface // whether an empty value has been submitted or whether no value has // been submitted at all. This is important for processing checkboxes // and radio buttons with empty values. - if (is_scalar($clientData)) { - $clientData = (string) $clientData; + if (is_scalar($submittedData)) { + $submittedData = (string) $submittedData; } // Initialize errors in the very beginning so that we don't lose any // errors added during listeners $this->errors = array(); - $event = new DataEvent($this, $clientData); - $this->config->getEventDispatcher()->dispatch(FormEvents::PRE_BIND, $event); - - $appData = null; + $modelData = null; $normData = null; $extraData = array(); $synchronized = false; // Hook to change content of the data bound by the browser - $event = new FilterDataEvent($this, $clientData); + $event = new FormEvent($this, $submittedData); + $this->config->getEventDispatcher()->dispatch(FormEvents::PRE_BIND, $event); + // BC until 2.3 $this->config->getEventDispatcher()->dispatch(FormEvents::BIND_CLIENT_DATA, $event); - $clientData = $event->getData(); + $submittedData = $event->getData(); + + // Build the data in the view format + $viewData = $submittedData; if (count($this->children) > 0) { - if (null === $clientData || '' === $clientData) { - $clientData = array(); + if (null === $viewData || '' === $viewData) { + $viewData = array(); } - if (!is_array($clientData)) { - throw new UnexpectedTypeException($clientData, 'array'); + if (!is_array($viewData)) { + throw new UnexpectedTypeException($viewData, 'array'); } foreach ($this->children as $name => $child) { - if (!isset($clientData[$name])) { - $clientData[$name] = null; + if (!isset($viewData[$name])) { + $viewData[$name] = null; } } - foreach ($clientData as $name => $value) { + foreach ($viewData as $name => $value) { if ($this->has($name)) { $this->children[$name]->bind($value); } else { @@ -482,31 +500,32 @@ class Form implements \IteratorAggregate, FormInterface } } - // If we have a data mapper, use old client data and merge + // If we have a data mapper, use old view data and merge // data from the children into it later if ($this->config->getDataMapper()) { - $clientData = $this->getClientData(); + $viewData = $this->getViewData(); } } - if (null === $clientData || '' === $clientData) { + if (null === $viewData || '' === $viewData) { $emptyData = $this->config->getEmptyData(); if ($emptyData instanceof \Closure) { - $emptyData = $emptyData($this, $clientData); + /* @var \Closure $emptyData */ + $emptyData = $emptyData($this, $viewData); } - $clientData = $emptyData; + $viewData = $emptyData; } - // Merge form data from children into existing client data - if (count($this->children) > 0 && $this->config->getDataMapper() && null !== $clientData) { - $this->config->getDataMapper()->mapFormsToData($this->children, $clientData); + // Merge form data from children into existing view data + if (count($this->children) > 0 && $this->config->getDataMapper() && null !== $viewData) { + $this->config->getDataMapper()->mapFormsToData($this->children, $viewData); } try { // Normalize data to unified representation - $normData = $this->clientToNorm($clientData); + $normData = $this->viewToNorm($viewData); $synchronized = true; } catch (TransformationFailedException $e) { } @@ -514,23 +533,26 @@ class Form implements \IteratorAggregate, FormInterface if ($synchronized) { // Hook to change content of the data into the normalized // representation - $event = new FilterDataEvent($this, $normData); + $event = new FormEvent($this, $normData); + $this->config->getEventDispatcher()->dispatch(FormEvents::BIND, $event); + // BC until 2.3 $this->config->getEventDispatcher()->dispatch(FormEvents::BIND_NORM_DATA, $event); $normData = $event->getData(); + // Synchronize representations - must not change the content! - $appData = $this->normToApp($normData); - $clientData = $this->normToClient($normData); + $modelData = $this->normToModel($normData); + $viewData = $this->normToView($normData); } $this->bound = true; - $this->appData = $appData; + $this->modelData = $modelData; $this->normData = $normData; - $this->clientData = $clientData; + $this->viewData = $viewData; $this->extraData = $extraData; $this->synchronized = $synchronized; - $event = new DataEvent($this, $clientData); + $event = new FormEvent($this, $viewData); $this->config->getEventDispatcher()->dispatch(FormEvents::POST_BIND, $event); foreach ($this->config->getValidators() as $validator) { @@ -566,7 +588,7 @@ class Form implements \IteratorAggregate, FormInterface // Form bound without name $params = $request->request->all(); $files = $request->files->all(); - } elseif ($this->hasChildren()) { + } elseif (count($this->children) > 0) { // Form bound with name and children $params = $request->request->get($name, array()); $files = $request->files->get($name, array()); @@ -667,7 +689,7 @@ class Form implements \IteratorAggregate, FormInterface } } - return array() === $this->appData || null === $this->appData || '' === $this->appData; + return array() === $this->modelData || null === $this->modelData || '' === $this->modelData; } /** @@ -735,14 +757,12 @@ class Form implements \IteratorAggregate, FormInterface $errors .= str_repeat(' ', $level).'ERROR: '.$error->getMessage()."\n"; } - if ($this->hasChildren()) { - foreach ($this->children as $key => $child) { - $errors .= str_repeat(' ', $level).$key.":\n"; - if ($err = $child->getErrorsAsString($level + 4)) { - $errors .= $err; - } else { - $errors .= str_repeat(' ', $level + 4)."No errors\n"; - } + foreach ($this->children as $key => $child) { + $errors .= str_repeat(' ', $level).$key.":\n"; + if ($err = $child->getErrorsAsString($level + 4)) { + $errors .= $err; + } else { + $errors .= str_repeat(' ', $level + 4)."No errors\n"; } } @@ -755,11 +775,11 @@ class Form implements \IteratorAggregate, FormInterface * @return array An array of DataTransformerInterface * * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use - * {@link getConfig()} and {@link FormConfigInterface::getNormTransformers()} instead. + * {@link getConfig()} and {@link FormConfigInterface::getModelTransformers()} instead. */ public function getNormTransformers() { - return $this->config->getNormTransformers(); + return $this->config->getModelTransformers(); } /** @@ -768,27 +788,41 @@ class Form implements \IteratorAggregate, FormInterface * @return array An array of DataTransformerInterface * * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use - * {@link getConfig()} and {@link FormConfigInterface::getClientTransformers()} instead. + * {@link getConfig()} and {@link FormConfigInterface::getViewTransformers()} instead. */ public function getClientTransformers() { - return $this->config->getClientTransformers(); + return $this->config->getViewTransformers(); + } + + /** + * {@inheritdoc} + */ + public function all() + { + return $this->children; } /** * Returns all children in this group. * * @return array + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link all()} instead. */ public function getChildren() { - return $this->children; + return $this->all(); } /** * Returns whether the form has children. * * @return Boolean + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link count()} instead. */ public function hasChildren() { @@ -809,7 +843,7 @@ class Form implements \IteratorAggregate, FormInterface $child->setParent($this); if ($this->config->getDataMapper()) { - $this->config->getDataMapper()->mapDataToForms($this->getClientData(), array($child)); + $this->config->getDataMapper()->mapDataToForms($this->getViewData(), array($child)); } return $this; @@ -919,13 +953,9 @@ class Form implements \IteratorAggregate, FormInterface } /** - * Creates a view. - * - * @param FormView $parent The parent view - * - * @return FormView The view + * {@inheritdoc} */ - public function createView(FormView $parent = null) + public function createView(FormViewInterface $parent = null) { if (null === $parent && $this->parent) { $parent = $this->parent->createView(); @@ -936,24 +966,25 @@ class Form implements \IteratorAggregate, FormInterface $view->setParent($parent); $types = (array) $this->config->getTypes(); + $options = $this->config->getOptions(); foreach ($types as $type) { - $type->buildView($view, $this); + $type->buildView($view, $this, $options); foreach ($type->getExtensions() as $typeExtension) { - $typeExtension->buildView($view, $this); + $typeExtension->buildView($view, $this, $options); } } foreach ($this->children as $child) { - $view->addChild($child->createView($view)); + $view->add($child->createView($view)); } foreach ($types as $type) { - $type->buildViewBottomUp($view, $this); + $type->finishView($view, $this, $options); foreach ($type->getExtensions() as $typeExtension) { - $typeExtension->buildViewBottomUp($view, $this); + $typeExtension->finishView($view, $this, $options); } } @@ -967,9 +998,9 @@ class Form implements \IteratorAggregate, FormInterface * * @return string */ - private function appToNorm($value) + private function modelToNorm($value) { - foreach ($this->config->getNormTransformers() as $transformer) { + foreach ($this->config->getModelTransformers() as $transformer) { $value = $transformer->transform($value); } @@ -983,9 +1014,9 @@ class Form implements \IteratorAggregate, FormInterface * * @return mixed */ - private function normToApp($value) + private function normToModel($value) { - $transformers = $this->config->getNormTransformers(); + $transformers = $this->config->getModelTransformers(); for ($i = count($transformers) - 1; $i >= 0; --$i) { $value = $transformers[$i]->reverseTransform($value); @@ -1001,15 +1032,15 @@ class Form implements \IteratorAggregate, FormInterface * * @return string */ - private function normToClient($value) + private function normToView($value) { - if (!$this->config->getClientTransformers()) { + if (!$this->config->getViewTransformers()) { // Scalar values should always be converted to strings to // facilitate differentiation between empty ("") and zero (0). return null === $value || is_scalar($value) ? (string) $value : $value; } - foreach ($this->config->getClientTransformers() as $transformer) { + foreach ($this->config->getViewTransformers() as $transformer) { $value = $transformer->transform($value); } @@ -1023,9 +1054,9 @@ class Form implements \IteratorAggregate, FormInterface * * @return mixed */ - private function clientToNorm($value) + private function viewToNorm($value) { - $transformers = $this->config->getClientTransformers(); + $transformers = $this->config->getViewTransformers(); if (!$transformers) { return '' === $value ? null : $value; diff --git a/src/Symfony/Component/Form/FormBuilder.php b/src/Symfony/Component/Form/FormBuilder.php index 560b16e884..fb6f5d6dc8 100644 --- a/src/Symfony/Component/Form/FormBuilder.php +++ b/src/Symfony/Component/Form/FormBuilder.php @@ -22,7 +22,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; * * @author Bernhard Schussek */ -class FormBuilder extends FormConfig +class FormBuilder extends FormConfig implements \IteratorAggregate, FormBuilderInterface { /** * The form factory. @@ -61,17 +61,15 @@ class FormBuilder extends FormConfig * @param EventDispatcherInterface $dispatcher * @param FormFactoryInterface $factory */ - public function __construct($name, $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factory) + public function __construct($name, $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factory, array $options = array()) { - parent::__construct($name, $dataClass, $dispatcher); + parent::__construct($name, $dataClass, $dispatcher, $options); $this->factory = $factory; } /** - * Returns the associated form factory. - * - * @return FormFactoryInterface The factory + * {@inheritdoc} */ public function getFormFactory() { @@ -79,17 +77,7 @@ class FormBuilder extends FormConfig } /** - * Adds a new field to this group. A field must have a unique name within - * the group. Otherwise the existing field is overwritten. - * - * If you add a nested group, this group should also be represented in the - * object hierarchy. - * - * @param string|FormBuilder $child - * @param string|FormTypeInterface $type - * @param array $options - * - * @return FormBuilder The builder object. + * {@inheritdoc} */ public function add($child, $type = null, array $options = array()) { @@ -124,13 +112,7 @@ class FormBuilder extends FormConfig } /** - * Creates a form builder. - * - * @param string $name The name of the form or the name of the property - * @param string|FormTypeInterface $type The type of the form or null if name is a property - * @param array $options The options - * - * @return FormBuilder The created builder. + * {@inheritdoc} */ public function create($name, $type = null, array $options = array()) { @@ -139,20 +121,14 @@ class FormBuilder extends FormConfig } if (null !== $type) { - return $this->getFormFactory()->createNamedBuilder($type, $name, null, $options, $this); + return $this->getFormFactory()->createNamedBuilder($name, $type, null, $options, $this); } return $this->getFormFactory()->createBuilderForProperty($this->getDataClass(), $name, null, $options, $this); } /** - * Returns a child by name. - * - * @param string $name The name of the child - * - * @return FormBuilder The builder for the child - * - * @throws FormException if the given child does not exist + * {@inheritdoc} */ public function get($name) { @@ -168,11 +144,7 @@ class FormBuilder extends FormConfig } /** - * Removes the field with the given name. - * - * @param string $name - * - * @return FormBuilder The builder object. + * {@inheritdoc} */ public function remove($name) { @@ -189,11 +161,7 @@ class FormBuilder extends FormConfig } /** - * Returns whether a field with the given name exists. - * - * @param string $name - * - * @return Boolean + * {@inheritdoc} */ public function has($name) { @@ -209,9 +177,7 @@ class FormBuilder extends FormConfig } /** - * Returns the children. - * - * @return array + * {@inheritdoc} */ public function all() { @@ -221,9 +187,15 @@ class FormBuilder extends FormConfig } /** - * Creates the form. - * - * @return Form The form + * {@inheritdoc} + */ + public function count() + { + return count($this->children); + } + + /** + * {@inheritdoc} */ public function getForm() { @@ -244,9 +216,7 @@ class FormBuilder extends FormConfig } /** - * Returns the parent builder. - * - * @return FormBuilder The parent builder + * {@inheritdoc} */ public function getParent() { @@ -254,19 +224,23 @@ class FormBuilder extends FormConfig } /** - * Sets the parent builder. - * - * @param FormBuilder $parent The parent builder - * - * @return FormBuilder The builder object. + * {@inheritdoc} */ - public function setParent(FormBuilder $parent = null) + public function setParent(FormBuilderInterface $parent = null) { $this->parent = $parent; return $this; } + /** + * {@inheritdoc} + */ + public function hasParent() + { + return null !== $this->parent; + } + /** * Converts an unresolved child into a {@link FormBuilder} instance. * @@ -295,4 +269,12 @@ class FormBuilder extends FormConfig $this->unresolvedChildren = array(); } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + return new \ArrayIterator($this->children); + } } diff --git a/src/Symfony/Component/Form/FormBuilderInterface.php b/src/Symfony/Component/Form/FormBuilderInterface.php new file mode 100644 index 0000000000..4554934abc --- /dev/null +++ b/src/Symfony/Component/Form/FormBuilderInterface.php @@ -0,0 +1,116 @@ + + * + * 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 + */ +interface FormBuilderInterface extends FormConfigEditorInterface, \Traversable, \Countable +{ + /** + * Adds a new field to this group. A field must have a unique name within + * the group. Otherwise the existing field is overwritten. + * + * If you add a nested group, this group should also be represented in the + * object hierarchy. + * + * @param string|FormBuilderInterface $child + * @param string|FormTypeInterface $type + * @param array $options + * + * @return FormBuilderInterface The builder object. + */ + function add($child, $type = null, array $options = array()); + + /** + * Creates a form builder. + * + * @param string $name The name of the form or the name of the property + * @param string|FormTypeInterface $type The type of the form or null if name is a property + * @param array $options The options + * + * @return FormBuilderInterface The created builder. + */ + function create($name, $type = null, array $options = array()); + + /** + * Returns a child by name. + * + * @param string $name The name of the child + * + * @return FormBuilderInterface The builder for the child + * + * @throws Exception\FormException if the given child does not exist + */ + function get($name); + /** + * Removes the field with the given name. + * + * @param string $name + * + * @return FormBuilderInterface The builder object. + */ + function remove($name); + + /** + * Returns whether a field with the given name exists. + * + * @param string $name + * + * @return Boolean + */ + function has($name); + + /** + * Returns the children. + * + * @return array + */ + function all(); + + /** + * Returns the associated form factory. + * + * @return FormFactoryInterface The factory + */ + function getFormFactory(); + + /** + * Creates the form. + * + * @return Form The form + */ + function getForm(); + + /** + * Sets the parent builder. + * + * @param FormBuilderInterface $parent The parent builder + * + * @return FormBuilderInterface The builder object. + */ + function setParent(FormBuilderInterface $parent = null); + + /** + * Returns the parent builder. + * + * @return FormBuilderInterface The parent builder + */ + function getParent(); + + /** + * Returns whether the builder has a parent. + * + * @return Boolean + */ + function hasParent(); +} diff --git a/src/Symfony/Component/Form/FormConfig.php b/src/Symfony/Component/Form/FormConfig.php index eae045323c..447adc795e 100644 --- a/src/Symfony/Component/Form/FormConfig.php +++ b/src/Symfony/Component/Form/FormConfig.php @@ -21,7 +21,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; * * @author Bernhard Schussek */ -class FormConfig implements FormConfigInterface +class FormConfig implements FormConfigEditorInterface { /** * @var EventDispatcherInterface @@ -61,12 +61,12 @@ class FormConfig implements FormConfigInterface /** * @var array */ - private $clientTransformers = array(); + private $viewTransformers = array(); /** * @var array */ - private $normTransformers = array(); + private $modelTransformers = array(); /** * @var DataMapperInterface @@ -113,6 +113,11 @@ class FormConfig implements FormConfigInterface */ private $dataClass; + /** + * @var array + */ + private $options; + /** * Creates an empty form configuration. * @@ -124,7 +129,7 @@ class FormConfig implements FormConfigInterface * @throws \InvalidArgumentException If the data class is not a valid class or if * the name contains invalid characters. */ - public function __construct($name, $dataClass, EventDispatcherInterface $dispatcher) + public function __construct($name, $dataClass, EventDispatcherInterface $dispatcher, array $options = array()) { $name = (string) $name; @@ -137,18 +142,11 @@ class FormConfig implements FormConfigInterface $this->name = $name; $this->dataClass = $dataClass; $this->dispatcher = $dispatcher; + $this->options = $options; } /** - * Adds an event listener to an event on this form. - * - * @param string $eventName The name of the event to listen to. - * @param callable $listener The listener to execute. - * @param integer $priority The priority of the listener. Listeners - * with a higher priority are called before - * listeners with a lower priority. - * - * @return self The configuration object. + * {@inheritdoc} */ public function addEventListener($eventName, $listener, $priority = 0) { @@ -158,11 +156,7 @@ class FormConfig implements FormConfigInterface } /** - * Adds an event subscriber for events on this form. - * - * @param EventSubscriberInterface $subscriber The subscriber to attach. - * - * @return self The configuration object. + * {@inheritdoc} */ public function addEventSubscriber(EventSubscriberInterface $subscriber) { @@ -172,13 +166,7 @@ class FormConfig implements FormConfigInterface } /** - * Adds a validator to the form. - * - * @param FormValidatorInterface $validator The validator. - * - * @return self The configuration object. - * - * @deprecated Deprecated since version 2.1, to be removed in 2.3. + * {@inheritdoc} */ public function addValidator(FormValidatorInterface $validator) { @@ -188,41 +176,85 @@ class FormConfig implements FormConfigInterface } /** - * Appends a transformer to the client transformer chain - * - * @param DataTransformerInterface $clientTransformer - * - * @return self The configuration object. + * {@inheritdoc} */ - public function appendClientTransformer(DataTransformerInterface $clientTransformer) + public function addViewTransformer(DataTransformerInterface $viewTransformer) { - $this->clientTransformers[] = $clientTransformer; + $this->viewTransformers[] = $viewTransformer; return $this; } + /** + * {@inheritdoc} + */ + public function resetViewTransformers() + { + $this->viewTransformers = array(); + + return $this; + } + + /** + * Alias of {@link addViewTransformer()}. + * + * @param DataTransformerInterface $viewTransformer + * + * @return self The configuration object. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link addViewTransformer()} instead. + */ + public function appendClientTransformer(DataTransformerInterface $viewTransformer) + { + return $this->addViewTransformer($viewTransformer); + } + /** * Prepends a transformer to the client transformer chain. * - * @param DataTransformerInterface $clientTransformer + * @param DataTransformerInterface $viewTransformer * * @return self The configuration object. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. */ - public function prependClientTransformer(DataTransformerInterface $clientTransformer) + public function prependClientTransformer(DataTransformerInterface $viewTransformer) { - array_unshift($this->clientTransformers, $clientTransformer); + array_unshift($this->viewTransformers, $viewTransformer); return $this; } /** - * Clears the client transformers. + * Alias of {@link resetViewTransformers()}. * * @return self The configuration object. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link resetViewTransformers()} instead. */ public function resetClientTransformers() { - $this->clientTransformers = array(); + return $this->resetViewTransformers(); + } + + /** + * {@inheritdoc} + */ + public function addModelTransformer(DataTransformerInterface $modelTransformer) + { + array_unshift($this->modelTransformers, $modelTransformer); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function resetModelTransformers() + { + $this->modelTransformers = array(); return $this; } @@ -230,41 +262,45 @@ class FormConfig implements FormConfigInterface /** * Appends a transformer to the normalization transformer chain * - * @param DataTransformerInterface $normTransformer + * @param DataTransformerInterface $modelTransformer * * @return self The configuration object. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. */ - public function appendNormTransformer(DataTransformerInterface $normTransformer) + public function appendNormTransformer(DataTransformerInterface $modelTransformer) { - $this->normTransformers[] = $normTransformer; + $this->modelTransformers[] = $modelTransformer; return $this; } /** - * Prepends a transformer to the normalization transformer chain + * Alias of {@link addModelTransformer()}. * - * @param DataTransformerInterface $normTransformer + * @param DataTransformerInterface $modelTransformer * * @return self The configuration object. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link addModelTransformer()} instead. */ - public function prependNormTransformer(DataTransformerInterface $normTransformer) + public function prependNormTransformer(DataTransformerInterface $modelTransformer) { - array_unshift($this->normTransformers, $normTransformer); - - return $this; + return $this->addModelTransformer($modelTransformer); } /** - * Clears the normalization transformers. + * Alias of {@link resetModelTransformers()}. * * @return self The configuration object. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link resetModelTransformers()} instead. */ public function resetNormTransformers() { - $this->normTransformers = array(); - - return $this; + return $this->resetModelTransformers(); } /** @@ -326,23 +362,47 @@ class FormConfig implements FormConfigInterface /** * {@inheritdoc} */ + public function getViewTransformers() + { + return $this->viewTransformers; + } + + /** + * Alias of {@link getViewTransformers()}. + * + * @return array The view transformers. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link getViewTransformers()} instead. + */ public function getClientTransformers() { - return $this->clientTransformers; + return $this->getViewTransformers(); } /** * {@inheritdoc} */ - public function getNormTransformers() + public function getModelTransformers() { - return $this->normTransformers; + return $this->modelTransformers; } /** - * Returns the data mapper of the form. + * Alias of {@link getModelTransformers()}. * - * @return DataMapperInterface The data mapper. + * @return array The model transformers. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link getModelTransformers()} instead. + */ + public function getNormTransformers() + { + return $this->getModelTransformers(); + } + + /** + * {@inheritdoc} */ public function getDataMapper() { @@ -408,9 +468,9 @@ class FormConfig implements FormConfigInterface /** * {@inheritdoc} */ - public function getAttribute($name) + public function getAttribute($name, $default = null) { - return isset($this->attributes[$name]) ? $this->attributes[$name] : null; + return isset($this->attributes[$name]) ? $this->attributes[$name] : $default; } /** @@ -430,12 +490,31 @@ class FormConfig implements FormConfigInterface } /** - * Sets the value for an attribute. - * - * @param string $name The name of the attribute - * @param string $value The value of the attribute - * - * @return self The configuration object. + * {@inheritdoc} + */ + public function getOptions() + { + return $this->options; + } + + /** + * {@inheritdoc} + */ + public function hasOption($name) + { + return isset($this->options[$name]); + } + + /** + * {@inheritdoc} + */ + public function getOption($name, $default = null) + { + return isset($this->options[$name]) ? $this->options[$name] : $default; + } + + /** + * {@inheritdoc} */ public function setAttribute($name, $value) { @@ -445,11 +524,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets the attributes. - * - * @param array $attributes The attributes. - * - * @return self The configuration object. + * {@inheritdoc} */ public function setAttributes(array $attributes) { @@ -459,11 +534,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets the data mapper used by the form. - * - * @param DataMapperInterface $dataMapper - * - * @return self The configuration object. + * {@inheritdoc} */ public function setDataMapper(DataMapperInterface $dataMapper = null) { @@ -473,11 +544,7 @@ class FormConfig implements FormConfigInterface } /** - * Set whether the form is disabled. - * - * @param Boolean $disabled Whether the form is disabled - * - * @return self The configuration object. + * {@inheritdoc} */ public function setDisabled($disabled) { @@ -487,11 +554,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets the data used for the client data when no value is bound. - * - * @param mixed $emptyData The empty data. - * - * @return self The configuration object. + * {@inheritdoc} */ public function setEmptyData($emptyData) { @@ -501,11 +564,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets whether errors bubble up to the parent. - * - * @param Boolean $errorBubbling - * - * @return self The configuration object. + * {@inheritdoc} */ public function setErrorBubbling($errorBubbling) { @@ -515,11 +574,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets whether this field is required to be filled out when bound. - * - * @param Boolean $required - * - * @return self The configuration object. + * {@inheritdoc} */ public function setRequired($required) { @@ -529,13 +584,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets the property path that the form should be mapped to. - * - * @param string|PropertyPath $propertyPath The property path or null if the path - * should be set automatically based on - * the form's name. - * - * @return self The configuration object. + * {@inheritdoc} */ public function setPropertyPath($propertyPath) { @@ -549,12 +598,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets whether the form should be mapped to an element of its - * parent's data. - * - * @param Boolean $mapped Whether the form should be mapped. - * - * @return self The configuration object. + * {@inheritdoc} */ public function setMapped($mapped) { @@ -564,12 +608,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets whether the form's data should be modified by reference. - * - * @param Boolean $byReference Whether the data should be - modified by reference. - * - * @return self The configuration object. + * {@inheritdoc} */ public function setByReference($byReference) { @@ -579,11 +618,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets whether the form should be virtual. - * - * @param Boolean $virtual Whether the form should be virtual. - * - * @return self The configuration object. + * {@inheritdoc} */ public function setVirtual($virtual) { @@ -593,11 +628,7 @@ class FormConfig implements FormConfigInterface } /** - * Set the types. - * - * @param array $types An array FormTypeInterface - * - * @return self The configuration object. + * {@inheritdoc} */ public function setTypes(array $types) { @@ -607,11 +638,7 @@ class FormConfig implements FormConfigInterface } /** - * Sets the initial data of the form. - * - * @param array $data The data of the form in application format. - * - * @return self The configuration object. + * {@inheritdoc} */ public function setData($data) { diff --git a/src/Symfony/Component/Form/FormConfigEditorInterface.php b/src/Symfony/Component/Form/FormConfigEditorInterface.php new file mode 100644 index 0000000000..2a16de5e5d --- /dev/null +++ b/src/Symfony/Component/Form/FormConfigEditorInterface.php @@ -0,0 +1,207 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * @author Bernhard Schussek + */ +interface FormConfigEditorInterface extends FormConfigInterface +{ + /** + * Adds an event listener to an event on this form. + * + * @param string $eventName The name of the event to listen to. + * @param callable $listener The listener to execute. + * @param integer $priority The priority of the listener. Listeners + * with a higher priority are called before + * listeners with a lower priority. + * + * @return self The configuration object. + */ + function addEventListener($eventName, $listener, $priority = 0); + + /** + * Adds an event subscriber for events on this form. + * + * @param EventSubscriberInterface $subscriber The subscriber to attach. + * + * @return self The configuration object. + */ + function addEventSubscriber(EventSubscriberInterface $subscriber); + + /** + * Adds a validator to the form. + * + * @param FormValidatorInterface $validator The validator. + * + * @return self The configuration object. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. + */ + function addValidator(FormValidatorInterface $validator); + + /** + * Appends a transformer to the client transformer chain + * + * @param DataTransformerInterface $viewTransformer + * + * @return self The configuration object. + */ + function addViewTransformer(DataTransformerInterface $viewTransformer); + + /** + * Clears the client transformers. + * + * @return self The configuration object. + */ + function resetViewTransformers(); + + /** + * Prepends a transformer to the normalization transformer chain + * + * @param DataTransformerInterface $modelTransformer + * + * @return self The configuration object. + */ + function addModelTransformer(DataTransformerInterface $modelTransformer); + + /** + * Clears the normalization transformers. + * + * @return self The configuration object. + */ + function resetModelTransformers(); + + /** + * Sets the value for an attribute. + * + * @param string $name The name of the attribute + * @param string $value The value of the attribute + * + * @return self The configuration object. + */ + function setAttribute($name, $value); + + /** + * Sets the attributes. + * + * @param array $attributes The attributes. + * + * @return self The configuration object. + */ + function setAttributes(array $attributes); + + /** + * Sets the data mapper used by the form. + * + * @param DataMapperInterface $dataMapper + * + * @return self The configuration object. + */ + function setDataMapper(DataMapperInterface $dataMapper = null); + + /** + * Set whether the form is disabled. + * + * @param Boolean $disabled Whether the form is disabled + * + * @return self The configuration object. + */ + function setDisabled($disabled); + + /** + * Sets the data used for the client data when no value is bound. + * + * @param mixed $emptyData The empty data. + * + * @return self The configuration object. + */ + function setEmptyData($emptyData); + + /** + * Sets whether errors bubble up to the parent. + * + * @param Boolean $errorBubbling + * + * @return self The configuration object. + */ + function setErrorBubbling($errorBubbling); + + /** + * Sets whether this field is required to be filled out when bound. + * + * @param Boolean $required + * + * @return self The configuration object. + */ + function setRequired($required); + + /** + * Sets the property path that the form should be mapped to. + * + * @param string|PropertyPath $propertyPath The property path or null if the path + * should be set automatically based on + * the form's name. + * + * @return self The configuration object. + */ + function setPropertyPath($propertyPath); + + /** + * Sets whether the form should be mapped to an element of its + * parent's data. + * + * @param Boolean $mapped Whether the form should be mapped. + * + * @return self The configuration object. + */ + function setMapped($mapped); + + /** + * Sets whether the form's data should be modified by reference. + * + * @param Boolean $byReference Whether the data should be + modified by reference. + * + * @return self The configuration object. + */ + function setByReference($byReference); + + /** + * Sets whether the form should be virtual. + * + * @param Boolean $virtual Whether the form should be virtual. + * + * @return self The configuration object. + */ + function setVirtual($virtual); + + /** + * Set the types. + * + * @param array $types An array FormTypeInterface + * + * @return self The configuration object. + */ + function setTypes(array $types); + + /** + * Sets the initial data of the form. + * + * @param array $data The data of the form in application format. + * + * @return self The configuration object. + */ + function setData($data); +} diff --git a/src/Symfony/Component/Form/FormConfigInterface.php b/src/Symfony/Component/Form/FormConfigInterface.php index 554a104667..ee284bb5fa 100644 --- a/src/Symfony/Component/Form/FormConfigInterface.php +++ b/src/Symfony/Component/Form/FormConfigInterface.php @@ -77,14 +77,14 @@ interface FormConfigInterface * * @return array An array of {@link DataTransformerInterface} instances. */ - function getClientTransformers(); + function getViewTransformers(); /** * Returns the view transformers of the form. * * @return array An array of {@link DataTransformerInterface} instances. */ - function getNormTransformers(); + function getModelTransformers(); /** * Returns the data mapper of the form. @@ -149,11 +149,12 @@ interface FormConfigInterface /** * Returns the value of the given attribute. * - * @param string $name The attribute name. + * @param string $name The attribute name. + * @param mixed $default The value returned if the attribute does not exist. * * @return mixed The attribute value. */ - function getAttribute($name); + function getAttribute($name, $default = null); /** * Returns the initial data of the form. @@ -168,4 +169,30 @@ interface FormConfigInterface * @return string The data class or null. */ function getDataClass(); + + /** + * Returns all options passed during the construction of the form. + * + * @return array The passed options. + */ + function getOptions(); + + /** + * Returns whether a specific option exists. + * + * @param string $name The option name, + * + * @return Boolean Whether the option exists. + */ + function hasOption($name); + + /** + * Returns the value of a specific option. + * + * @param string $name The option name. + * @param mixed $default The value returned if the option does not exist. + * + * @return mixed The option value. + */ + function getOption($name, $default = null); } diff --git a/src/Symfony/Component/Form/FormEvent.php b/src/Symfony/Component/Form/FormEvent.php new file mode 100644 index 0000000000..ed3fc77006 --- /dev/null +++ b/src/Symfony/Component/Form/FormEvent.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form; + +use Symfony\Component\Form\Event\FilterDataEvent; + +/** + * @author Bernhard Schussek + */ +class FormEvent extends FilterDataEvent +{ +} diff --git a/src/Symfony/Component/Form/FormEvents.php b/src/Symfony/Component/Form/FormEvents.php index 08f10c4a43..430ea08560 100644 --- a/src/Symfony/Component/Form/FormEvents.php +++ b/src/Symfony/Component/Form/FormEvents.php @@ -18,15 +18,33 @@ final class FormEvents { const PRE_BIND = 'form.pre_bind'; + const BIND = 'form.bind'; + const POST_BIND = 'form.post_bind'; const PRE_SET_DATA = 'form.pre_set_data'; const POST_SET_DATA = 'form.post_set_data'; + /** + * @deprecated Deprecated since version 2.1, to be removed in 2.3. + * Use {@link PRE_BIND} instead. + */ const BIND_CLIENT_DATA = 'form.bind_client_data'; + /** + * @deprecated Deprecated since version 2.1, to be removed in 2.3. + * Use {@link BIND} instead. + */ const BIND_NORM_DATA = 'form.bind_norm_data'; + /** + * @deprecated Deprecated since version 2.1, to be removed in 2.3. + * Use {@link PRE_SET_DATA} instead. + */ const SET_DATA = 'form.set_data'; + + private function __construct() + { + } } diff --git a/src/Symfony/Component/Form/FormFactory.php b/src/Symfony/Component/Form/FormFactory.php index 4a5d13ace4..fc199f4e17 100644 --- a/src/Symfony/Component/Form/FormFactory.php +++ b/src/Symfony/Component/Form/FormFactory.php @@ -109,7 +109,7 @@ class FormFactory implements FormFactoryInterface /** * {@inheritdoc} */ - public function create($type, $data = null, array $options = array(), FormBuilder $parent = null) + public function create($type, $data = null, array $options = array(), FormBuilderInterface $parent = null) { return $this->createBuilder($type, $data, $options, $parent)->getForm(); } @@ -117,15 +117,15 @@ class FormFactory implements FormFactoryInterface /** * {@inheritdoc} */ - public function createNamed($type, $name, $data = null, array $options = array(), FormBuilder $parent = null) + public function createNamed($name, $type, $data = null, array $options = array(), FormBuilderInterface $parent = null) { - return $this->createNamedBuilder($type, $name, $data, $options, $parent)->getForm(); + return $this->createNamedBuilder($name, $type, $data, $options, $parent)->getForm(); } /** * {@inheritdoc} */ - public function createForProperty($class, $property, $data = null, array $options = array(), FormBuilder $parent = null) + public function createForProperty($class, $property, $data = null, array $options = array(), FormBuilderInterface $parent = null) { return $this->createBuilderForProperty($class, $property, $data, $options, $parent)->getForm(); } @@ -133,17 +133,17 @@ class FormFactory implements FormFactoryInterface /** * {@inheritdoc} */ - public function createBuilder($type, $data = null, array $options = array(), FormBuilder $parent = null) + public function createBuilder($type, $data = null, array $options = array(), FormBuilderInterface $parent = null) { $name = is_object($type) ? $type->getName() : $type; - return $this->createNamedBuilder($type, $name, $data, $options, $parent); + return $this->createNamedBuilder($name, $type, $data, $options, $parent); } /** * {@inheritdoc} */ - public function createNamedBuilder($type, $name, $data = null, array $options = array(), FormBuilder $parent = null) + public function createNamedBuilder($name, $type, $data = null, array $options = array(), FormBuilderInterface $parent = null) { if (!array_key_exists('data', $options)) { $options['data'] = $data; @@ -151,7 +151,6 @@ class FormFactory implements FormFactoryInterface $builder = null; $types = array(); - $knownOptions = array(); $optionsResolver = new OptionsResolver(); // Bottom-up determination of the type hierarchy @@ -185,16 +184,12 @@ class FormFactory implements FormFactoryInterface // Merge the default options of all types to an array of default // options. Default options of children override default options // of parents. - $typeOptions = $type->getDefaultOptions(); - $optionsResolver->setDefaults($typeOptions); - $optionsResolver->addAllowedValues($type->getAllowedOptionValues()); - $knownOptions = array_merge($knownOptions, array_keys($typeOptions)); + /* @var FormTypeInterface $type */ + $type->setDefaultOptions($optionsResolver); foreach ($type->getExtensions() as $typeExtension) { - $extensionOptions = $typeExtension->getDefaultOptions(); - $optionsResolver->setDefaults($extensionOptions); - $optionsResolver->addAllowedValues($typeExtension->getAllowedOptionValues()); - $knownOptions = array_merge($knownOptions, array_keys($extensionOptions)); + /* @var FormTypeExtensionInterface $typeExtension */ + $typeExtension->setDefaultOptions($optionsResolver); } } @@ -202,7 +197,13 @@ class FormFactory implements FormFactoryInterface $type = end($types); // Validate options required by the factory - $diff = array_diff(self::$requiredOptions, $knownOptions); + $diff = array(); + + foreach (self::$requiredOptions as $requiredOption) { + if (!$optionsResolver->isKnown($requiredOption)) { + $diff[] = $requiredOption; + } + } if (count($diff) > 0) { throw new TypeDefinitionException(sprintf('Type "%s" should support the option(s) "%s"', $type->getName(), implode('", "', $diff))); @@ -216,7 +217,7 @@ class FormFactory implements FormFactoryInterface } if (!$builder) { - throw new TypeDefinitionException(sprintf('Type "%s" or any of its parents should return a FormBuilder instance from createBuilder()', $type->getName())); + throw new TypeDefinitionException(sprintf('Type "%s" or any of its parents should return a FormBuilderInterface instance from createBuilder()', $type->getName())); } $builder->setTypes($types); @@ -238,7 +239,7 @@ class FormFactory implements FormFactoryInterface /** * {@inheritdoc} */ - public function createBuilderForProperty($class, $property, $data = null, array $options = array(), FormBuilder $parent = null) + public function createBuilderForProperty($class, $property, $data = null, array $options = array(), FormBuilderInterface $parent = null) { if (!$this->guesser) { $this->loadGuesser(); @@ -279,7 +280,7 @@ class FormFactory implements FormFactoryInterface $options = array_merge($typeGuess->getOptions(), $options); } - return $this->createNamedBuilder($type, $property, $data, $options, $parent); + return $this->createNamedBuilder($property, $type, $data, $options, $parent); } /** diff --git a/src/Symfony/Component/Form/FormFactoryInterface.php b/src/Symfony/Component/Form/FormFactoryInterface.php index 84037527f0..6b242b3459 100644 --- a/src/Symfony/Component/Form/FormFactoryInterface.php +++ b/src/Symfony/Component/Form/FormFactoryInterface.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Form; +/** + * @author Bernhard Schussek + */ interface FormFactoryInterface { /** @@ -21,47 +24,47 @@ interface FormFactoryInterface * @param string|FormTypeInterface $type The type of the form * @param mixed $data The initial data * @param array $options The options - * @param FormBuilder $parent The parent builder + * @param FormBuilderInterface $parent The parent builder * * @return FormInterface The form named after the type * * @throws Exception\FormException if any given option is not applicable to the given type */ - function create($type, $data = null, array $options = array(), FormBuilder $parent = null); + function create($type, $data = null, array $options = array(), FormBuilderInterface $parent = null); /** * Returns a form. * * @see createNamedBuilder() * - * @param string|FormTypeInterface $type The type of the form * @param string $name The name of the form + * @param string|FormTypeInterface $type The type of the form * @param mixed $data The initial data * @param array $options The options - * @param FormBuilder $parent The parent builder + * @param FormBuilderInterface $parent The parent builder * * @return FormInterface The form * * @throws Exception\FormException if any given option is not applicable to the given type */ - function createNamed($type, $name, $data = null, array $options = array(), FormBuilder $parent = null); + function createNamed($name, $type, $data = null, array $options = array(), FormBuilderInterface $parent = null); /** * Returns a form for a property of a class. * * @see createBuilderForProperty() * - * @param string $class The fully qualified class name - * @param string $property The name of the property to guess for - * @param mixed $data The initial data - * @param array $options The options for the builder - * @param FormBuilder $parent The parent builder + * @param string $class The fully qualified class name + * @param string $property The name of the property to guess for + * @param mixed $data The initial data + * @param array $options The options for the builder + * @param FormBuilderInterface $parent The parent builder * * @return FormInterface The form named after the property * * @throws Exception\FormException if any given option is not applicable to the form type */ - function createForProperty($class, $property, $data = null, array $options = array(), FormBuilder $parent = null); + function createForProperty($class, $property, $data = null, array $options = array(), FormBuilderInterface $parent = null); /** * Returns a form builder. @@ -69,28 +72,28 @@ interface FormFactoryInterface * @param string|FormTypeInterface $type The type of the form * @param mixed $data The initial data * @param array $options The options - * @param FormBuilder $parent The parent builder + * @param FormBuilderInterface $parent The parent builder * - * @return FormBuilder The form builder + * @return FormBuilderInterface The form builder * * @throws Exception\FormException if any given option is not applicable to the given type */ - function createBuilder($type, $data = null, array $options = array(), FormBuilder $parent = null); + function createBuilder($type, $data = null, array $options = array(), FormBuilderInterface $parent = null); /** * Returns a form builder. * - * @param string|FormTypeInterface $type The type of the form * @param string $name The name of the form + * @param string|FormTypeInterface $type The type of the form * @param mixed $data The initial data * @param array $options The options - * @param FormBuilder $parent The parent builder + * @param FormBuilderInterface $parent The parent builder * - * @return FormBuilder The form builder + * @return FormBuilderInterface The form builder * * @throws Exception\FormException if any given option is not applicable to the given type */ - function createNamedBuilder($type, $name, $data = null, array $options = array(), FormBuilder $parent = null); + function createNamedBuilder($name, $type, $data = null, array $options = array(), FormBuilderInterface $parent = null); /** * Returns a form builder for a property of a class. @@ -98,17 +101,17 @@ interface FormFactoryInterface * If any of the 'max_length', 'required' and type options can be guessed, * and are not provided in the options argument, the guessed value is used. * - * @param string $class The fully qualified class name - * @param string $property The name of the property to guess for - * @param mixed $data The initial data - * @param array $options The options for the builder - * @param FormBuilder $parent The parent builder + * @param string $class The fully qualified class name + * @param string $property The name of the property to guess for + * @param mixed $data The initial data + * @param array $options The options for the builder + * @param FormBuilderInterface $parent The parent builder * - * @return FormBuilder The form builder named after the property + * @return FormBuilderInterface The form builder named after the property * * @throws Exception\FormException if any given option is not applicable to the form type */ - function createBuilderForProperty($class, $property, $data = null, array $options = array(), FormBuilder $parent = null); + function createBuilderForProperty($class, $property, $data = null, array $options = array(), FormBuilderInterface $parent = null); /** * Returns a type by name. diff --git a/src/Symfony/Component/Form/FormInterface.php b/src/Symfony/Component/Form/FormInterface.php index 66f119bf62..915ab19d9a 100644 --- a/src/Symfony/Component/Form/FormInterface.php +++ b/src/Symfony/Component/Form/FormInterface.php @@ -82,14 +82,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable * * @return array An array of FormInterface instances */ - function getChildren(); - - /** - * Return whether the form has children. - * - * @return Boolean - */ - function hasChildren(); + function all(); /** * Returns all errors. @@ -101,11 +94,11 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Updates the field with default data. * - * @param array $appData The data formatted as expected for the underlying object + * @param array $modelData The data formatted as expected for the underlying object * * @return FormInterface The form instance */ - function setData($appData); + function setData($modelData); /** * Returns the data in the format needed for the underlying object. @@ -128,7 +121,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable * * @return string */ - function getClientData(); + function getViewData(); /** * Returns the extra data. @@ -228,20 +221,6 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable */ function bind($data); - /** - * Returns whether the form has an attribute with the given name. - * - * @param string $name The name of the attribute - */ - function hasAttribute($name); - - /** - * Returns the value of the attributes with the given name. - * - * @param string $name The name of the attribute - */ - function getAttribute($name); - /** * Returns the root of the form tree. * @@ -259,9 +238,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Creates a view. * - * @param FormView $parent The parent view + * @param FormViewInterface $parent The parent view * - * @return FormView The view + * @return FormViewInterface The view */ - function createView(FormView $parent = null); + function createView(FormViewInterface $parent = null); } diff --git a/src/Symfony/Component/Form/FormTypeExtensionInterface.php b/src/Symfony/Component/Form/FormTypeExtensionInterface.php index 24fb8a871d..b83cf02268 100644 --- a/src/Symfony/Component/Form/FormTypeExtensionInterface.php +++ b/src/Symfony/Component/Form/FormTypeExtensionInterface.php @@ -11,61 +11,60 @@ namespace Symfony\Component\Form; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; + +/** + * @author Bernhard Schussek + */ interface FormTypeExtensionInterface { /** * Builds the form. * - * This method gets called after the extended type has built the form to + * This method is called after the extended type has built the form to * further modify it. * * @see FormTypeInterface::buildForm() * - * @param FormBuilder $builder The form builder - * @param array $options The options + * @param FormBuilderInterface $builder The form builder + * @param array $options The options */ - function buildForm(FormBuilder $builder, array $options); + function buildForm(FormBuilderInterface $builder, array $options); /** * Builds the view. * - * This method gets called after the extended type has built the view to + * This method is called after the extended type has built the view to * further modify it. * * @see FormTypeInterface::buildView() * - * @param FormView $view The view - * @param FormInterface $form The form + * @param FormViewInterface $view The view + * @param FormInterface $form The form + * @param array $options The options */ - function buildView(FormView $view, FormInterface $form); + function buildView(FormViewInterface $view, FormInterface $form, array $options); /** - * Builds the view. + * Finishes the view. * - * This method gets called after the extended type has built the view to + * This method is called after the extended type has finished the view to * further modify it. * - * @see FormTypeInterface::buildViewBottomUp() + * @see FormTypeInterface::finishView() * - * @param FormView $view The view - * @param FormInterface $form The form + * @param FormViewInterface $view The view + * @param FormInterface $form The form + * @param array $options The options */ - function buildViewBottomUp(FormView $view, FormInterface $form); + function finishView(FormViewInterface $view, FormInterface $form, array $options); /** - * Overrides the default options form the extended type. + * Overrides the default options from the extended type. * - * @return array + * @param OptionsResolverInterface $resolver The resolver for the options. */ - function getDefaultOptions(); - - /** - * Returns the allowed option values for each option (if any). - * - * @return array The allowed option values - */ - function getAllowedOptionValues(); - + function setDefaultOptions(OptionsResolverInterface $resolver); /** * Returns the name of the type being extended. diff --git a/src/Symfony/Component/Form/FormTypeGuesserInterface.php b/src/Symfony/Component/Form/FormTypeGuesserInterface.php index d38d4dc5fc..5750336020 100644 --- a/src/Symfony/Component/Form/FormTypeGuesserInterface.php +++ b/src/Symfony/Component/Form/FormTypeGuesserInterface.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Form; +/** + * @author Bernhard Schussek + */ interface FormTypeGuesserInterface { /** @@ -19,7 +22,7 @@ interface FormTypeGuesserInterface * @param string $class The fully qualified class name * @param string $property The name of the property to guess for * - * @return TypeGuess A guess for the field's type and options + * @return Guess\TypeGuess A guess for the field's type and options */ function guessType($class, $property); @@ -29,7 +32,7 @@ interface FormTypeGuesserInterface * @param string $class The fully qualified class name * @param string $property The name of the property to guess for * - * @return Guess A guess for the field's required setting + * @return Guess\Guess A guess for the field's required setting */ function guessRequired($class, $property); @@ -39,7 +42,7 @@ interface FormTypeGuesserInterface * @param string $class The fully qualified class name * @param string $property The name of the property to guess for * - * @return Guess A guess for the field's maximum length + * @return Guess\Guess A guess for the field's maximum length */ function guessMaxLength($class, $property); @@ -49,7 +52,7 @@ interface FormTypeGuesserInterface * @param string $class The fully qualified class name * @param string $property The name of the property to guess for * - * @return Guess A guess for the field's minimum length + * @return Guess\Guess A guess for the field's minimum length * * @deprecated Deprecated since version 2.1, to be removed in 2.3. */ @@ -67,7 +70,7 @@ interface FormTypeGuesserInterface * @param string $class The fully qualified class name * @param string $property The name of the property to guess for * - * @return Guess A guess for the field's required pattern + * @return Guess\Guess A guess for the field's required pattern */ function guessPattern($class, $property); } diff --git a/src/Symfony/Component/Form/FormTypeInterface.php b/src/Symfony/Component/Form/FormTypeInterface.php index 1c5eb9ad56..22f874c156 100644 --- a/src/Symfony/Component/Form/FormTypeInterface.php +++ b/src/Symfony/Component/Form/FormTypeInterface.php @@ -11,52 +11,62 @@ namespace Symfony\Component\Form; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; + +/** + * @author Bernhard Schussek + */ interface FormTypeInterface { /** * Builds the form. * - * This method gets called for each type in the hierarchy starting form the - * top most type. - * Type extensions can further modify the form. + * This method is called for each type in the hierarchy starting form the + * top most type. Type extensions can further modify the form. * * @see FormTypeExtensionInterface::buildForm() * - * @param FormBuilder $builder The form builder - * @param array $options The options + * @param FormBuilderInterface $builder The form builder + * @param array $options The options */ - function buildForm(FormBuilder $builder, array $options); + function buildForm(FormBuilderInterface $builder, array $options); /** * Builds the form view. * - * This method gets called for each type in the hierarchy starting form the - * top most type. - * Type extensions can further modify the view. + * This method is called for each type in the hierarchy starting form the + * top most type. Type extensions can further modify the view. + * + * A view of a form is built before the views of the child forms are built. + * This means that you cannot access child views in this method. If you need + * to do so, move your logic to {@link finishView()} instead. * * @see FormTypeExtensionInterface::buildView() * - * @param FormView $view The view - * @param FormInterface $form The form + * @param FormViewInterface $view The view + * @param FormInterface $form The form + * @param array $options The options */ - function buildView(FormView $view, FormInterface $form); + function buildView(FormViewInterface $view, FormInterface $form, array $options); /** - * Builds the form view. + * Finishes the form view. * * This method gets called for each type in the hierarchy starting form the - * top most type. - * Type extensions can further modify the view. + * top most type. Type extensions can further modify the view. * - * Children views have been built when this method gets called so you get - * a chance to modify them. + * When this method is called, views of the form's children have already + * been built and finished and can be accessed. You should only implement + * such logic in this method that actually accesses child views. For everything + * else you are recommended to implement {@link buildView()} instead. * - * @see FormTypeExtensionInterface::buildViewBottomUp() + * @see FormTypeExtensionInterface::finishView() * - * @param FormView $view The view - * @param FormInterface $form The form + * @param FormViewInterface $view The view + * @param FormInterface $form The form + * @param array $options The options */ - function buildViewBottomUp(FormView $view, FormInterface $form); + function finishView(FormViewInterface $view, FormInterface $form, array $options); /** * Returns a builder for the current type. @@ -68,32 +78,23 @@ interface FormTypeInterface * @param FormFactoryInterface $factory The form factory * @param array $options The options * - * @return FormBuilder|null A form builder or null when the type does not have a builder + * @return FormBuilderInterface|null A form builder or null when the type does not have a builder */ function createBuilder($name, FormFactoryInterface $factory, array $options); /** - * Returns the default options for this type. + * Sets the default options for this type. * - * @return array The default options + * @param OptionsResolverInterface $resolver The resolver for the options. */ - function getDefaultOptions(); - - /** - * Returns the allowed option values for each option (if any). - * - * @return array The allowed option values - */ - function getAllowedOptionValues(); + function setDefaultOptions(OptionsResolverInterface $resolver); /** * Returns the name of the parent type. * - * @param array $options - * - * @return string|null The name of the parent type if any otherwise null + * @return string|null The name of the parent type if any, null otherwise. */ - function getParent(array $options); + function getParent(); /** * Returns the name of this type. diff --git a/src/Symfony/Component/Form/FormView.php b/src/Symfony/Component/Form/FormView.php index 2e5b6c7a61..ad0ac4d2b2 100644 --- a/src/Symfony/Component/Form/FormView.php +++ b/src/Symfony/Component/Form/FormView.php @@ -11,14 +11,10 @@ namespace Symfony\Component\Form; -use ArrayAccess; -use IteratorAggregate; -use Countable; - /** * @author Bernhard Schussek */ -class FormView implements ArrayAccess, IteratorAggregate, Countable +class FormView implements \IteratorAggregate, FormViewInterface { private $name; @@ -47,18 +43,18 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable $this->name = $name; } + /** + * {@inheritdoc} + */ public function getName() { return $this->name; } /** - * @param string $name - * @param mixed $value - * - * @return FormView The current view + * {@inheritdoc} */ - public function set($name, $value) + public function setVar($name, $value) { $this->vars[$name] = $value; @@ -66,24 +62,19 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * @param $name - * - * @return Boolean + * {@inheritdoc} */ - public function has($name) + public function hasVar($name) { return array_key_exists($name, $this->vars); } /** - * @param $name - * @param $default - * - * @return mixed + * {@inheritdoc} */ - public function get($name, $default = null) + public function getVar($name, $default = null) { - if (false === $this->has($name)) { + if (false === $this->hasVar($name)) { return $default; } @@ -91,21 +82,21 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * @return array + * {@inheritdoc} */ - public function all() + public function addVars(array $vars) { - return $this->vars; + $this->vars = array_replace($this->vars, $vars); + + return $this; } /** - * Alias of all so it is possible to do `form.vars.foo` - * - * @return array + * {@inheritdoc} */ public function getVars() { - return $this->all(); + return $this->vars; } /** @@ -124,9 +115,7 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Returns whether the attached form is rendered. - * - * @return Boolean Whether the form is rendered + * {@inheritdoc} */ public function isRendered() { @@ -150,9 +139,7 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Marks the attached form as rendered - * - * @return FormView The current view + * {@inheritdoc} */ public function setRendered() { @@ -162,13 +149,9 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Sets the parent view. - * - * @param FormView $parent The parent view - * - * @return FormView The current view + * {@inheritdoc} */ - public function setParent(FormView $parent = null) + public function setParent(FormViewInterface $parent = null) { $this->parent = $parent; @@ -176,9 +159,7 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Returns the parent view. - * - * @return FormView The parent view + * {@inheritdoc} */ public function getParent() { @@ -186,9 +167,7 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Returns whether this view has a parent. - * - * @return Boolean Whether this view has a parent + * {@inheritdoc} */ public function hasParent() { @@ -196,13 +175,9 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Adds a child view. - * - * @param FormView $child The child view to add. - * - * @return FormView The current view + * {@inheritdoc} */ - public function addChild(FormView $child) + public function add(FormViewInterface $child) { $this->children[$child->getName()] = $child; @@ -210,13 +185,9 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Removes a child view. - * - * @param string $name The name of the removed child view. - * - * @return FormView The current view + * {@inheritdoc} */ - public function removeChild($name) + public function remove($name) { unset($this->children[$name]); @@ -224,31 +195,32 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Returns the children. - * - * @return array The children as instances of FormView + * {@inheritdoc} */ - public function getChildren() + public function all() { return $this->children; } /** - * Returns a given child. - * - * @param string $name The name of the child - * - * @return FormView The child view + * {@inheritdoc} */ - public function getChild($name) + public function get($name) { + if (!isset($this->children[$name])) { + throw new \InvalidArgumentException(sprintf('Child "%s" does not exist.', $name)); + } + return $this->children[$name]; } /** - * Returns whether this view has children. + * Returns whether this view has any children. * - * @return Boolean Whether this view has children + * @return Boolean Whether the view has children. + * + * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use + * {@link count()} instead. */ public function hasChildren() { @@ -256,13 +228,9 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable } /** - * Returns whether this view has a given child. - * - * @param string $name The name of the child - * - * @return Boolean Whether the child with the given name exists + * {@inheritdoc} */ - public function hasChild($name) + public function has($name) { return isset($this->children[$name]); } @@ -276,7 +244,7 @@ class FormView implements ArrayAccess, IteratorAggregate, Countable */ public function offsetGet($name) { - return $this->getChild($name); + return $this->get($name); } /** diff --git a/src/Symfony/Component/Form/FormViewInterface.php b/src/Symfony/Component/Form/FormViewInterface.php new file mode 100644 index 0000000000..1e71aba064 --- /dev/null +++ b/src/Symfony/Component/Form/FormViewInterface.php @@ -0,0 +1,150 @@ + + * + * 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 + */ +interface FormViewInterface extends \ArrayAccess, \Traversable, \Countable +{ + /** + * Returns the name of the form. + * + * @return string The form name. + */ + function getName(); + + /** + * Returns whether the view was already rendered. + * + * @return Boolean Whether this view's widget is rendered. + */ + function isRendered(); + + /** + * Marks the view as rendered. + * + * @return FormViewInterface The view object. + */ + function setRendered(); + + /** + * Sets the parent view. + * + * @param FormViewInterface $parent The parent view. + * + * @return FormViewInterface The view object. + */ + function setParent(FormViewInterface $parent = null); + + /** + * Returns the parent view. + * + * @return FormViewInterface The parent view. + */ + function getParent(); + + /** + * Returns whether this view has a parent. + * + * @return Boolean Whether this view has a parent + */ + function hasParent(); + + /** + * Adds a child view. + * + * @param FormViewInterface $child The child view to add. + * + * @return FormViewInterface The view object. + */ + function add(FormViewInterface $child); + + /** + * Removes a child view. + * + * @param string $name The name of the removed child view. + * + * @return FormViewInterface The view object. + */ + function remove($name); + + /** + * Returns the children. + * + * @return array The children as instances of FormView + */ + function all(); + + /** + * Returns a given child. + * + * @param string $name The name of the child + * + * @return FormViewInterface The child view + */ + function get($name); + + /** + * Returns whether this view has a given child. + * + * @param string $name The name of the child + * + * @return Boolean Whether the child with the given name exists + */ + function has($name); + + /** + * Sets a view variable. + * + * @param string $name The variable name. + * @param string $value The variable value. + * + * @return FormViewInterface The view object. + */ + function setVar($name, $value); + + /** + * Adds a list of view variables. + * + * @param array $values An array of variable names and values. + * + * @return FormViewInterface The view object. + */ + function addVars(array $values); + + /** + * Returns whether a view variable exists. + * + * @param string $name The variable name. + * + * @return Boolean Whether the variable exists. + */ + function hasVar($name); + + /** + * Returns the value of a view variable. + * + * @param string $name The variable name. + * @param mixed $default The value to return if the variable is not set. + * + * @return mixed The variable value. + */ + function getVar($name, $default = null); + + /** + * Returns the values of all view variables. + * + * @return array The values of all variables. + */ + function getVars(); +} diff --git a/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php index 6f0675cba5..0841f62016 100644 --- a/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php @@ -17,7 +17,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest { public function testRow() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $form->addError(new FormError('Error!')); $view = $form->createView(); $html = $this->renderRow($view); @@ -37,7 +37,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRowOverrideVariables() { - $view = $this->factory->createNamed('text', 'name')->createView(); + $view = $this->factory->createNamed('name', 'text')->createView(); $html = $this->renderRow($view, array('label' => 'foo&bar')); $this->assertMatchesXpath($html, @@ -52,7 +52,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRepeatedRow() { - $form = $this->factory->createNamed('repeated', 'name'); + $form = $this->factory->createNamed('name', 'repeated'); $form->addError(new FormError('Error!')); $view = $form->createView(); $html = $this->renderRow($view); @@ -77,7 +77,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRest() { - $view = $this->factory->createNamedBuilder('form', 'name') + $view = $this->factory->createNamedBuilder('name', 'form') ->add('field1', 'text') ->add('field2', 'repeated') ->add('field3', 'text') @@ -118,17 +118,17 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRestWithChildrenForms() { - $child1 = $this->factory->createNamedBuilder('form', 'child1') + $child1 = $this->factory->createNamedBuilder('child1', 'form') ->add('field1', 'text') ->add('field2', 'text') ->getForm(); - $child2 = $this->factory->createNamedBuilder('form', 'child2') + $child2 = $this->factory->createNamedBuilder('child2', 'form') ->add('field1', 'text') ->add('field2', 'text') ->getForm(); - $view = $this->factory->createNamedBuilder('form', 'parent') + $view = $this->factory->createNamedBuilder('parent', 'form') ->getForm() ->add($child1) ->add($child2) @@ -178,7 +178,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRestAndRepeatedWithRow() { - $view = $this->factory->createNamedBuilder('form', 'name') + $view = $this->factory->createNamedBuilder('name', 'form') ->add('first', 'text') ->add('password', 'repeated') ->getForm() @@ -204,7 +204,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRestAndRepeatedWithRowPerChild() { - $view = $this->factory->createNamedBuilder('form', 'name') + $view = $this->factory->createNamedBuilder('name', 'form') ->add('first', 'text') ->add('password', 'repeated') ->getForm() @@ -232,7 +232,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRestAndRepeatedWithWidgetPerChild() { - $view = $this->factory->createNamedBuilder('form', 'name') + $view = $this->factory->createNamedBuilder('name', 'form') ->add('first', 'text') ->add('password', 'repeated') ->getForm() @@ -262,7 +262,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testCollection() { - $form = $this->factory->createNamed('collection', 'name', array('a', 'b'), array( + $form = $this->factory->createNamed('name', 'collection', array('a', 'b'), array( 'type' => 'text', )); @@ -279,7 +279,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testEmptyCollection() { - $form = $this->factory->createNamed('collection', 'name', array(), array( + $form = $this->factory->createNamed('name', 'collection', array(), array( 'type' => 'text', )); @@ -333,7 +333,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testForm() { - $form = $this->factory->createNamedBuilder('form', 'name') + $form = $this->factory->createNamedBuilder('name', 'form') ->add('firstName', 'text') ->add('lastName', 'text') ->getForm(); @@ -361,9 +361,9 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest // https://github.com/symfony/symfony/issues/2308 public function testNestedFormError() { - $form = $this->factory->createNamedBuilder('form', 'name') + $form = $this->factory->createNamedBuilder('name', 'form') ->add($this->factory - ->createNamedBuilder('form', 'child', null, array('error_bubbling' => false)) + ->createNamedBuilder('child', 'form', null, array('error_bubbling' => false)) ->add('grandChild', 'form') ) ->getForm(); @@ -386,11 +386,11 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest ->method('generateCsrfToken') ->will($this->returnValue('foo&bar')); - $form = $this->factory->createNamedBuilder('form', 'name') + $form = $this->factory->createNamedBuilder('name', 'form') ->add($this->factory // No CSRF protection on nested forms - ->createNamedBuilder('form', 'child') - ->add($this->factory->createNamedBuilder('text', 'grandchild')) + ->createNamedBuilder('child', 'form') + ->add($this->factory->createNamedBuilder('grandchild', 'text')) ) ->getForm(); @@ -407,7 +407,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRepeated() { - $form = $this->factory->createNamed('repeated', 'name', 'foobar', array( + $form = $this->factory->createNamed('name', 'repeated', 'foobar', array( 'type' => 'text', )); @@ -433,7 +433,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testRepeatedWithCustomOptions() { - $form = $this->factory->createNamed('repeated', 'name', null, array( + $form = $this->factory->createNamed('name', 'repeated', null, array( // the global required value cannot be overriden 'first_options' => array('label' => 'Test', 'required' => false), 'second_options' => array('label' => 'Test2') @@ -461,7 +461,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testSearchInputName() { - $form = $this->factory->createNamedBuilder('form', 'full') + $form = $this->factory->createNamedBuilder('full', 'form') ->add('name', 'search') ->getForm(); @@ -482,7 +482,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testLabelHasNoId() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $html = $this->renderRow($form->createView()); $this->assertMatchesXpath($html, @@ -501,7 +501,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest public function testThemeBlockInheritance($theme) { $view = $this->factory - ->createNamed('email', 'name') + ->createNamed('name', 'email') ->createView() ; @@ -518,11 +518,11 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest */ public function testThemeInheritance($parentTheme, $childTheme) { - $child = $this->factory->createNamedBuilder('form', 'child') + $child = $this->factory->createNamedBuilder('child', 'form') ->add('field', 'text') ->getForm(); - $view = $this->factory->createNamedBuilder('form', 'parent') + $view = $this->factory->createNamedBuilder('parent', 'form') ->add('field', 'text') ->getForm() ->add($child) diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index b986975e6e..0217442bff 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -114,7 +114,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testEnctype() { - $form = $this->factory->createNamedBuilder('form', 'name') + $form = $this->factory->createNamedBuilder('name', 'form') ->add('file', 'file') ->getForm(); @@ -123,7 +123,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testNoEnctype() { - $form = $this->factory->createNamedBuilder('form', 'name') + $form = $this->factory->createNamedBuilder('name', 'form') ->add('text', 'text') ->getForm(); @@ -132,7 +132,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLabel() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $view = $form->createView(); $this->renderWidget($view, array('label' => 'foo')); $html = $this->renderLabel($view); @@ -147,7 +147,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLabelOnForm() { - $form = $this->factory->createNamed('date', 'name'); + $form = $this->factory->createNamed('name', 'date'); $view = $form->createView(); $this->renderWidget($view, array('label' => 'foo')); $html = $this->renderLabel($view); @@ -162,7 +162,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLabelWithCustomTextPassedAsOption() { - $form = $this->factory->createNamed('text', 'name', null, array( + $form = $this->factory->createNamed('name', 'text', null, array( 'label' => 'Custom label', )); $html = $this->renderLabel($form->createView()); @@ -177,7 +177,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLabelWithCustomTextPassedDirectly() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $html = $this->renderLabel($form->createView(), 'Custom label'); $this->assertMatchesXpath($html, @@ -190,7 +190,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLabelWithCustomTextPassedAsOptionAndDirectly() { - $form = $this->factory->createNamed('text', 'name', null, array( + $form = $this->factory->createNamed('name', 'text', null, array( 'label' => 'Custom label', )); $html = $this->renderLabel($form->createView(), 'Overridden label'); @@ -205,7 +205,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLabelDoesNotRenderFieldAttributes() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $html = $this->renderLabel($form->createView(), null, array( 'attr' => array( 'class' => 'my&class' @@ -222,7 +222,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLabelWithCustomOptionsPassedDirectly() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $html = $this->renderLabel($form->createView(), null, array( 'label_attr' => array( 'class' => 'my&class' @@ -239,7 +239,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLabelWithCustomTextAndCustomOptionsPassedDirectly() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $html = $this->renderLabel($form->createView(), 'Custom label', array( 'label_attr' => array( 'class' => 'my&class' @@ -257,7 +257,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testErrors() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $form->addError(new FormError('Error 1')); $form->addError(new FormError('Error 2')); $view = $form->createView(); @@ -276,7 +276,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testWidgetById() { - $form = $this->factory->createNamed('text', 'text_id'); + $form = $this->factory->createNamed('text_id', 'text'); $html = $this->renderWidget($form->createView()); $this->assertMatchesXpath($html, @@ -293,7 +293,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testCheckedCheckbox() { - $form = $this->factory->createNamed('checkbox', 'name', true); + $form = $this->factory->createNamed('name', 'checkbox', true); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -307,7 +307,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testUncheckedCheckbox() { - $form = $this->factory->createNamed('checkbox', 'name', false); + $form = $this->factory->createNamed('name', 'checkbox', false); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -320,7 +320,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testCheckboxWithValue() { - $form = $this->factory->createNamed('checkbox', 'name', false, array( + $form = $this->factory->createNamed('name', 'checkbox', false, array( 'value' => 'foo&bar', )); @@ -335,7 +335,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoice() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'multiple' => false, 'expanded' => false, @@ -356,7 +356,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceWithPreferred() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'preferred_choices' => array('&b'), 'multiple' => false, @@ -380,7 +380,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceWithPreferredAndNoSeparator() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'preferred_choices' => array('&b'), 'multiple' => false, @@ -402,7 +402,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceWithPreferredAndBlankSeparator() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'preferred_choices' => array('&b'), 'multiple' => false, @@ -425,7 +425,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testChoiceWithOnlyPreferred() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'preferred_choices' => array('&a', '&b'), 'multiple' => false, @@ -441,7 +441,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceNonRequired() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'required' => false, 'multiple' => false, @@ -464,7 +464,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceNonRequiredNoneSelected() { - $form = $this->factory->createNamed('choice', 'name', null, array( + $form = $this->factory->createNamed('name', 'choice', null, array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'required' => false, 'multiple' => false, @@ -487,7 +487,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceWithNonRequiredEmptyValue() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'multiple' => false, 'expanded' => false, @@ -511,7 +511,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceRequiredWithEmptyValue() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'required' => true, 'multiple' => false, @@ -535,7 +535,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceRequiredWithEmptyValueViaView() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'required' => true, 'multiple' => false, @@ -558,7 +558,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceGrouped() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array( 'Group&1' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'Group&2' => array('&c' => 'Choice&C'), @@ -588,7 +588,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testMultipleChoice() { - $form = $this->factory->createNamed('choice', 'name', array('&a'), array( + $form = $this->factory->createNamed('name', 'choice', array('&a'), array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'multiple' => true, 'expanded' => false, @@ -609,7 +609,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testMultipleChoiceSkipEmptyValue() { - $form = $this->factory->createNamed('choice', 'name', array('&a'), array( + $form = $this->factory->createNamed('name', 'choice', array('&a'), array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'multiple' => true, 'expanded' => false, @@ -631,7 +631,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testMultipleChoiceNonRequired() { - $form = $this->factory->createNamed('choice', 'name', array('&a'), array( + $form = $this->factory->createNamed('name', 'choice', array('&a'), array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'required' => false, 'multiple' => true, @@ -653,7 +653,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceExpanded() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'multiple' => false, 'expanded' => true, @@ -675,7 +675,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceExpandedSkipEmptyValue() { - $form = $this->factory->createNamed('choice', 'name', '&a', array( + $form = $this->factory->createNamed('name', 'choice', '&a', array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'), 'multiple' => false, 'expanded' => true, @@ -698,7 +698,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSingleChoiceExpandedWithBooleanValue() { - $form = $this->factory->createNamed('choice', 'name', true, array( + $form = $this->factory->createNamed('name', 'choice', true, array( 'choices' => array('1' => 'Choice&A', '0' => 'Choice&B'), 'multiple' => false, 'expanded' => true, @@ -720,7 +720,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testMultipleChoiceExpanded() { - $form = $this->factory->createNamed('choice', 'name', array('&a', '&c'), array( + $form = $this->factory->createNamed('name', 'choice', array('&a', '&c'), array( 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B', '&c' => 'Choice&C'), 'multiple' => true, 'expanded' => true, @@ -745,7 +745,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testCountry() { - $form = $this->factory->createNamed('country', 'name', 'AT'); + $form = $this->factory->createNamed('name', 'country', 'AT'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/select @@ -758,7 +758,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testCountryWithEmptyValue() { - $form = $this->factory->createNamed('country', 'name', 'AT', array( + $form = $this->factory->createNamed('name', 'country', 'AT', array( 'empty_value' => 'Select&Country', 'required' => false, )); @@ -775,7 +775,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateTime() { - $form = $this->factory->createNamed('datetime', 'name', '2011-02-03 04:05:06', array( + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( 'input' => 'string', 'with_seconds' => false, )); @@ -814,7 +814,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateTimeWithEmptyValueGlobal() { - $form = $this->factory->createNamed('datetime', 'name', null, array( + $form = $this->factory->createNamed('name', 'datetime', null, array( 'input' => 'string', 'empty_value' => 'Change&Me', 'required' => false, @@ -854,7 +854,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateTimeWithEmptyValueOnTime() { - $form = $this->factory->createNamed('datetime', 'name', '2011-02-03', array( + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03', array( 'input' => 'string', 'empty_value' => array('hour' => 'Change&Me', 'minute' => 'Change&Me'), 'required' => false, @@ -894,7 +894,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateTimeWithSeconds() { - $form = $this->factory->createNamed('datetime', 'name', '2011-02-03 04:05:06', array( + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( 'input' => 'string', 'with_seconds' => true, )); @@ -936,7 +936,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateTimeSingleText() { - $form = $this->factory->createNamed('datetime', 'name', '2011-02-03 04:05:06', array( + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( 'input' => 'string', 'date_widget' => 'single_text', 'time_widget' => 'single_text', @@ -962,7 +962,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateTimeWithWidgetSingleText() { - $form = $this->factory->createNamed('datetime', 'name', '2011-02-03 04:05:06', array( + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( 'input' => 'string', 'widget' => 'single_text', )); @@ -978,7 +978,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateTimeWithWidgetSingleTextIgnoreDateAndTimeWidgets() { - $form = $this->factory->createNamed('datetime', 'name', '2011-02-03 04:05:06', array( + $form = $this->factory->createNamed('name', 'datetime', '2011-02-03 04:05:06', array( 'input' => 'string', 'date_widget' => 'choice', 'time_widget' => 'choice', @@ -996,7 +996,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateChoice() { - $form = $this->factory->createNamed('date', 'name', '2011-02-03', array( + $form = $this->factory->createNamed('name', 'date', '2011-02-03', array( 'input' => 'string', 'widget' => 'choice', )); @@ -1021,7 +1021,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateChoiceWithEmptyValueGlobal() { - $form = $this->factory->createNamed('date', 'name', null, array( + $form = $this->factory->createNamed('name', 'date', null, array( 'input' => 'string', 'widget' => 'choice', 'empty_value' => 'Change&Me', @@ -1048,7 +1048,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateChoiceWithEmptyValueOnYear() { - $form = $this->factory->createNamed('date', 'name', null, array( + $form = $this->factory->createNamed('name', 'date', null, array( 'input' => 'string', 'widget' => 'choice', 'required' => false, @@ -1075,7 +1075,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateText() { - $form = $this->factory->createNamed('date', 'name', '2011-02-03', array( + $form = $this->factory->createNamed('name', 'date', '2011-02-03', array( 'input' => 'string', 'widget' => 'text', )); @@ -1103,7 +1103,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDateSingleText() { - $form = $this->factory->createNamed('date', 'name', '2011-02-03', array( + $form = $this->factory->createNamed('name', 'date', '2011-02-03', array( 'input' => 'string', 'widget' => 'single_text', )); @@ -1130,7 +1130,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testBirthDay() { - $form = $this->factory->createNamed('birthday', 'name', '2000-02-03', array( + $form = $this->factory->createNamed('name', 'birthday', '2000-02-03', array( 'input' => 'string', )); @@ -1154,7 +1154,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testBirthDayWithEmptyValue() { - $form = $this->factory->createNamed('birthday', 'name', '1950-01-01', array( + $form = $this->factory->createNamed('name', 'birthday', '1950-01-01', array( 'input' => 'string', 'empty_value' => '', 'required' => false, @@ -1183,7 +1183,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testEmail() { - $form = $this->factory->createNamed('email', 'name', 'foo&bar'); + $form = $this->factory->createNamed('name', 'email', 'foo&bar'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1197,7 +1197,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testEmailWithMaxLength() { - $form = $this->factory->createNamed('email', 'name', 'foo&bar', array( + $form = $this->factory->createNamed('name', 'email', 'foo&bar', array( 'max_length' => 123, )); @@ -1213,7 +1213,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testFile() { - $form = $this->factory->createNamed('file', 'name'); + $form = $this->factory->createNamed('name', 'file'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1224,7 +1224,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testHidden() { - $form = $this->factory->createNamed('hidden', 'name', 'foo&bar'); + $form = $this->factory->createNamed('name', 'hidden', 'foo&bar'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1237,7 +1237,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testReadOnly() { - $form = $this->factory->createNamed('text', 'name', null, array( + $form = $this->factory->createNamed('name', 'text', null, array( 'read_only' => true, )); @@ -1252,7 +1252,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testDisabled() { - $form = $this->factory->createNamed('text', 'name', null, array( + $form = $this->factory->createNamed('name', 'text', null, array( 'disabled' => true, )); @@ -1267,7 +1267,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testInteger() { - $form = $this->factory->createNamed('integer', 'name', 123); + $form = $this->factory->createNamed('name', 'integer', 123); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1280,7 +1280,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLanguage() { - $form = $this->factory->createNamed('language', 'name', 'de'); + $form = $this->factory->createNamed('name', 'language', 'de'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/select @@ -1293,7 +1293,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testLocale() { - $form = $this->factory->createNamed('locale', 'name', 'de_AT'); + $form = $this->factory->createNamed('name', 'locale', 'de_AT'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/select @@ -1306,7 +1306,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testMoney() { - $form = $this->factory->createNamed('money', 'name', 1234.56, array( + $form = $this->factory->createNamed('name', 'money', 1234.56, array( 'currency' => 'EUR', )); @@ -1322,7 +1322,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testNumber() { - $form = $this->factory->createNamed('number', 'name', 1234.56); + $form = $this->factory->createNamed('name', 'number', 1234.56); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1335,7 +1335,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testPassword() { - $form = $this->factory->createNamed('password', 'name', 'foo&bar'); + $form = $this->factory->createNamed('name', 'password', 'foo&bar'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1347,7 +1347,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testPasswordBoundNotAlwaysEmpty() { - $form = $this->factory->createNamed('password', 'name', null, array( + $form = $this->factory->createNamed('name', 'password', null, array( 'always_empty' => false, )); $form->bind('foo&bar'); @@ -1363,7 +1363,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testPasswordWithMaxLength() { - $form = $this->factory->createNamed('password', 'name', 'foo&bar', array( + $form = $this->factory->createNamed('name', 'password', 'foo&bar', array( 'max_length' => 123, )); @@ -1378,7 +1378,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testPercent() { - $form = $this->factory->createNamed('percent', 'name', 0.1); + $form = $this->factory->createNamed('name', 'percent', 0.1); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1392,7 +1392,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testCheckedRadio() { - $form = $this->factory->createNamed('radio', 'name', true); + $form = $this->factory->createNamed('name', 'radio', true); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1406,7 +1406,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testUncheckedRadio() { - $form = $this->factory->createNamed('radio', 'name', false); + $form = $this->factory->createNamed('name', 'radio', false); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1419,7 +1419,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testRadioWithValue() { - $form = $this->factory->createNamed('radio', 'name', false, array( + $form = $this->factory->createNamed('name', 'radio', false, array( 'value' => 'foo&bar', )); @@ -1434,7 +1434,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTextarea() { - $form = $this->factory->createNamed('textarea', 'name', 'foo&bar', array( + $form = $this->factory->createNamed('name', 'textarea', 'foo&bar', array( 'pattern' => 'foo', )); @@ -1449,7 +1449,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testText() { - $form = $this->factory->createNamed('text', 'name', 'foo&bar'); + $form = $this->factory->createNamed('name', 'text', 'foo&bar'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1463,7 +1463,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTextWithMaxLength() { - $form = $this->factory->createNamed('text', 'name', 'foo&bar', array( + $form = $this->factory->createNamed('name', 'text', 'foo&bar', array( 'max_length' => 123, )); @@ -1479,7 +1479,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testSearch() { - $form = $this->factory->createNamed('search', 'name', 'foo&bar'); + $form = $this->factory->createNamed('name', 'search', 'foo&bar'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1493,7 +1493,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTime() { - $form = $this->factory->createNamed('time', 'name', '04:05:06', array( + $form = $this->factory->createNamed('name', 'time', '04:05:06', array( 'input' => 'string', 'with_seconds' => false, )); @@ -1517,7 +1517,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTimeWithSeconds() { - $form = $this->factory->createNamed('time', 'name', '04:05:06', array( + $form = $this->factory->createNamed('name', 'time', '04:05:06', array( 'input' => 'string', 'with_seconds' => true, )); @@ -1548,7 +1548,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTimeText() { - $form = $this->factory->createNamed('time', 'name', '04:05:06', array( + $form = $this->factory->createNamed('name', 'time', '04:05:06', array( 'input' => 'string', 'widget' => 'text', )); @@ -1578,7 +1578,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTimeSingleText() { - $form = $this->factory->createNamed('time', 'name', '04:05:06', array( + $form = $this->factory->createNamed('name', 'time', '04:05:06', array( 'input' => 'string', 'widget' => 'single_text', )); @@ -1594,7 +1594,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTimeWithEmptyValueGlobal() { - $form = $this->factory->createNamed('time', 'name', null, array( + $form = $this->factory->createNamed('name', 'time', null, array( 'input' => 'string', 'empty_value' => 'Change&Me', 'required' => false, @@ -1619,7 +1619,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTimeWithEmptyValueOnYear() { - $form = $this->factory->createNamed('time', 'name', null, array( + $form = $this->factory->createNamed('name', 'time', null, array( 'input' => 'string', 'required' => false, 'empty_value' => array('hour' => 'Change&Me'), @@ -1655,7 +1655,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTimezone() { - $form = $this->factory->createNamed('timezone', 'name', 'Europe/Vienna'); + $form = $this->factory->createNamed('name', 'timezone', 'Europe/Vienna'); $this->assertWidgetMatchesXpath($form->createView(), array(), '/select @@ -1673,7 +1673,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testTimezoneWithEmptyValue() { - $form = $this->factory->createNamed('timezone', 'name', null, array( + $form = $this->factory->createNamed('name', 'timezone', null, array( 'empty_value' => 'Select&Timezone', 'required' => false, )); @@ -1690,7 +1690,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testUrl() { $url = 'http://www.google.com?foo1=bar1&foo2=bar2'; - $form = $this->factory->createNamed('url', 'name', $url); + $form = $this->factory->createNamed('name', 'url', $url); $this->assertWidgetMatchesXpath($form->createView(), array(), '/input @@ -1703,7 +1703,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testCollectionPrototype() { - $form = $this->factory->createNamedBuilder('form', 'name', array('items' => array('one', 'two', 'three'))) + $form = $this->factory->createNamedBuilder('name', 'form', array('items' => array('one', 'two', 'three'))) ->add('items', 'collection', array('allow_add' => true)) ->getForm() ->createView(); @@ -1721,7 +1721,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase public function testEmptyRootFormName() { - $form = $this->factory->createNamedBuilder('form', '', '') + $form = $this->factory->createNamedBuilder('', 'form', '') ->add('child', 'text') ->getForm(); diff --git a/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php index 9bf77d9c59..62ac603bb9 100644 --- a/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php @@ -17,7 +17,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest { public function testRow() { - $form = $this->factory->createNamed('text', 'name'); + $form = $this->factory->createNamed('name', 'text'); $form->addError(new FormError('Error!')); $view = $form->createView(); $html = $this->renderRow($view); @@ -41,7 +41,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest public function testRepeatedRow() { - $form = $this->factory->createNamed('repeated', 'name'); + $form = $this->factory->createNamed('name', 'repeated'); $html = $this->renderRow($form->createView()); $this->assertMatchesXpath($html, @@ -71,7 +71,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest public function testRepeatedRowWithErrors() { - $form = $this->factory->createNamed('repeated', 'name'); + $form = $this->factory->createNamed('name', 'repeated'); $form->addError(new FormError('Error!')); $view = $form->createView(); $html = $this->renderRow($view); @@ -107,7 +107,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest public function testRest() { - $view = $this->factory->createNamedBuilder('form', 'name') + $view = $this->factory->createNamedBuilder('name', 'form') ->add('field1', 'text') ->add('field2', 'repeated') ->add('field3', 'text') @@ -154,7 +154,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest public function testCollection() { - $form = $this->factory->createNamed('collection', 'name', array('a', 'b'), array( + $form = $this->factory->createNamed('name', 'collection', array('a', 'b'), array( 'type' => 'text', )); @@ -172,7 +172,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest public function testEmptyCollection() { - $form = $this->factory->createNamed('collection', 'name', array(), array( + $form = $this->factory->createNamed('name', 'collection', array(), array( 'type' => 'text', )); @@ -186,7 +186,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest public function testForm() { - $view = $this->factory->createNamedBuilder('form', 'name') + $view = $this->factory->createNamedBuilder('name', 'form') ->add('firstName', 'text') ->add('lastName', 'text') ->getForm() @@ -223,9 +223,9 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest // https://github.com/symfony/symfony/issues/2308 public function testNestedFormError() { - $form = $this->factory->createNamedBuilder('form', 'name') + $form = $this->factory->createNamedBuilder('name', 'form') ->add($this->factory - ->createNamedBuilder('form', 'child', null, array('error_bubbling' => false)) + ->createNamedBuilder('child', 'form', null, array('error_bubbling' => false)) ->add('grandChild', 'form') ) ->getForm(); @@ -250,11 +250,11 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest ->method('generateCsrfToken') ->will($this->returnValue('foo&bar')); - $form = $this->factory->createNamedBuilder('form', 'name') + $form = $this->factory->createNamedBuilder('name', 'form') ->add($this->factory // No CSRF protection on nested forms - ->createNamedBuilder('form', 'child') - ->add($this->factory->createNamedBuilder('text', 'grandchild')) + ->createNamedBuilder('child', 'form') + ->add($this->factory->createNamedBuilder('grandchild', 'text')) ) ->getForm(); @@ -274,7 +274,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest public function testRepeated() { - $form = $this->factory->createNamed('repeated', 'name', 'foobar', array( + $form = $this->factory->createNamed('name', 'repeated', 'foobar', array( 'type' => 'text', )); @@ -308,7 +308,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest public function testRepeatedWithCustomOptions() { - $form = $this->factory->createNamed('repeated', 'name', 'foobar', array( + $form = $this->factory->createNamed('name', 'repeated', 'foobar', array( 'type' => 'password', 'first_options' => array('label' => 'Test', 'required' => false), 'second_options' => array('label' => 'Test2') diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php index 040e9899dc..c5b73538bc 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php @@ -18,33 +18,6 @@ use Symfony\Component\Form\FormConfigInterface; use Symfony\Component\Form\Util\PropertyPath; use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; -abstract class PropertyPathMapperTest_Form implements FormInterface -{ - private $attributes = array(); - - private $data; - - public function setAttribute($name, $value) - { - $this->attributes[$name] = $value; - } - - public function getAttribute($name) - { - return isset($this->attributes[$name]) ? $this->attributes[$name] : null; - } - - public function setData($data) - { - $this->data = $data; - } - - public function getData() - { - return $this->data; - } -} - class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase { /** diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php index 3d9b26551d..9f2d0d21a6 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\Extension\Core\EventListener\FixRadioInputListener; use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; @@ -42,9 +42,9 @@ class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase { $data = '1'; $form = $this->getMock('Symfony\Component\Form\Tests\FormInterface'); - $event = new FilterDataEvent($form, $data); + $event = new FormEvent($form, $data); - $this->listener->onBindClientData($event); + $this->listener->preBind($event); $this->assertEquals(array(1 => '1'), $event->getData()); } @@ -53,9 +53,9 @@ class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase { $data = '0'; $form = $this->getMock('Symfony\Component\Form\Tests\FormInterface'); - $event = new FilterDataEvent($form, $data); + $event = new FormEvent($form, $data); - $this->listener->onBindClientData($event); + $this->listener->preBind($event); $this->assertEquals(array(0 => '0'), $event->getData()); } @@ -64,9 +64,9 @@ class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase { $data = ''; $form = $this->getMock('Symfony\Component\Form\Tests\FormInterface'); - $event = new FilterDataEvent($form, $data); + $event = new FormEvent($form, $data); - $this->listener->onBindClientData($event); + $this->listener->preBind($event); $this->assertEquals(array(), $event->getData()); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php index 9a2341dd22..ab0bdf3a44 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener; class FixUrlProtocolListenerTest extends \PHPUnit_Framework_TestCase @@ -27,10 +27,10 @@ class FixUrlProtocolListenerTest extends \PHPUnit_Framework_TestCase { $data = "www.symfony.com"; $form = $this->getMock('Symfony\Component\Form\Tests\FormInterface'); - $event = new FilterDataEvent($form, $data); + $event = new FormEvent($form, $data); $filter = new FixUrlProtocolListener('http'); - $filter->onBindNormData($event); + $filter->onBind($event); $this->assertEquals('http://www.symfony.com', $event->getData()); } @@ -39,10 +39,10 @@ class FixUrlProtocolListenerTest extends \PHPUnit_Framework_TestCase { $data = "http://www.symfony.com"; $form = $this->getMock('Symfony\Component\Form\Tests\FormInterface'); - $event = new FilterDataEvent($form, $data); + $event = new FormEvent($form, $data); $filter = new FixUrlProtocolListener('http'); - $filter->onBindNormData($event); + $filter->onBind($event); $this->assertEquals('http://www.symfony.com', $event->getData()); } @@ -51,10 +51,10 @@ class FixUrlProtocolListenerTest extends \PHPUnit_Framework_TestCase { $data = "ftp://www.symfony.com"; $form = $this->getMock('Symfony\Component\Form\Tests\FormInterface'); - $event = new FilterDataEvent($form, $data); + $event = new FormEvent($form, $data); $filter = new FixUrlProtocolListener('http'); - $filter->onBindNormData($event); + $filter->onBind($event); $this->assertEquals('ftp://www.symfony.com', $event->getData()); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php index 81982169c9..c156b9ec2a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\Extension\Core\EventListener\MergeCollectionListener; use Symfony\Component\Form\FormBuilder; @@ -85,8 +85,8 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase $this->form->setData($originalData); - $event = new FilterDataEvent($this->form, $newData); - $listener->onBindNormData($event); + $event = new FormEvent($this->form, $newData); + $listener->onBind($event); // The original object was modified if (is_object($originalData)) { @@ -109,8 +109,8 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase $this->form->setData($originalData); - $event = new FilterDataEvent($this->form, $newData); - $listener->onBindNormData($event); + $event = new FormEvent($this->form, $newData); + $listener->onBind($event); // The original object was modified if (is_object($originalData)) { @@ -134,8 +134,8 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase $this->form->setData($originalData); - $event = new FilterDataEvent($this->form, $newData); - $listener->onBindNormData($event); + $event = new FormEvent($this->form, $newData); + $listener->onBind($event); // We still have the original object if (is_object($originalData)) { @@ -158,8 +158,8 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase $this->form->setData($originalData); - $event = new FilterDataEvent($this->form, $newData); - $listener->onBindNormData($event); + $event = new FormEvent($this->form, $newData); + $listener->onBind($event); // The original object was modified if (is_object($originalData)) { @@ -183,8 +183,8 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase $this->form->setData($originalData); - $event = new FilterDataEvent($this->form, $newData); - $listener->onBindNormData($event); + $event = new FormEvent($this->form, $newData); + $listener->onBind($event); // We still have the original object if (is_object($originalData)) { @@ -202,9 +202,9 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase public function testRequireArrayOrTraversable($allowAdd, $allowDelete) { $newData = 'no array or traversable'; - $event = new FilterDataEvent($this->form, $newData); + $event = new FormEvent($this->form, $newData); $listener = new MergeCollectionListener($allowAdd, $allowDelete); - $listener->onBindNormData($event); + $listener->onBind($event); } public function testDealWithNullData() @@ -216,8 +216,8 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase $this->form->setData($originalData); - $event = new FilterDataEvent($this->form, $newData); - $listener->onBindNormData($event); + $event = new FormEvent($this->form, $newData); + $listener->onBind($event); $this->assertSame($originalData, $event->getData()); } @@ -234,8 +234,8 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase $this->form->setData($originalData); - $event = new FilterDataEvent($this->form, $newData); - $listener->onBindNormData($event); + $event = new FormEvent($this->form, $newData); + $listener->onBind($event); $this->assertSame($newData, $event->getData()); } @@ -252,8 +252,8 @@ abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase $this->form->setData($originalData); - $event = new FilterDataEvent($this->form, $newData); - $listener->onBindNormData($event); + $event = new FormEvent($this->form, $newData); + $listener->onBind($event); $this->assertNull($event->getData()); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php index d6a306f5cb..bc2c650995 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php @@ -11,8 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; -use Symfony\Component\Form\Event\DataEvent; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener; use Symfony\Component\Form\FormBuilder; @@ -62,15 +61,15 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->factory->expects($this->at(0)) ->method('createNamed') - ->with('text', 1, null, array('property_path' => '[1]', 'max_length' => 10)) + ->with(1, 'text', null, array('property_path' => '[1]', 'max_length' => 10)) ->will($this->returnValue($this->getForm('1'))); $this->factory->expects($this->at(1)) ->method('createNamed') - ->with('text', 2, null, array('property_path' => '[2]', 'max_length' => 10)) + ->with(2, 'text', null, array('property_path' => '[2]', 'max_length' => 10)) ->will($this->returnValue($this->getForm('2'))); $data = array(1 => 'string', 2 => 'string'); - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array('max_length' => '10'), false, false); $listener->preSetData($event); @@ -85,7 +84,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase public function testPreSetDataRequiresArrayOrTraversable() { $data = 'no array or traversable'; - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, false); $listener->preSetData($event); } @@ -95,7 +94,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->factory->expects($this->never())->method('createNamed'); $data = null; - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, false); $listener->preSetData($event); } @@ -106,11 +105,11 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->factory->expects($this->once()) ->method('createNamed') - ->with('text', 1, null, array('property_path' => '[1]', 'max_length' => 10)) + ->with(1, 'text', null, array('property_path' => '[1]', 'max_length' => 10)) ->will($this->returnValue($this->getForm('1'))); $data = array(0 => 'string', 1 => 'string'); - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array('max_length' => 10), true, false); $listener->preBind($event); @@ -124,7 +123,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getForm('1')); $data = array(0 => 'string'); - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, true); $listener->preBind($event); @@ -138,7 +137,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getForm('0')); $data = array(); - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, true); $listener->preBind($event); @@ -151,7 +150,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getForm('1')); $data = array(0 => 'string', 2 => 'string'); - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, false); $listener->preBind($event); @@ -166,7 +165,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase public function testPreBindRequiresArrayOrTraversable() { $data = 'no array or traversable'; - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, false); $listener->preBind($event); } @@ -176,7 +175,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getForm('1')); $data = null; - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, true); $listener->preBind($event); @@ -189,7 +188,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getForm('1')); $data = ''; - $event = new DataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, true); $listener->preBind($event); @@ -201,9 +200,9 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getForm('1')); $data = array(0 => 'first', 1 => 'second', 2 => 'third'); - $event = new FilterDataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, true); - $listener->onBindNormData($event); + $listener->onBind($event); $this->assertEquals(array(1 => 'second'), $event->getData()); } @@ -213,9 +212,9 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getForm('1')); $data = array(0 => 'first', 1 => 'second', 2 => 'third'); - $event = new FilterDataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, false); - $listener->onBindNormData($event); + $listener->onBind($event); $this->assertEquals($data, $event->getData()); } @@ -226,9 +225,9 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase public function testOnBindNormDataRequiresArrayOrTraversable() { $data = 'no array or traversable'; - $event = new FilterDataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, false); - $listener->onBindNormData($event); + $listener->onBind($event); } public function testOnBindNormDataDealsWithNullData() @@ -236,9 +235,9 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getForm('1')); $data = null; - $event = new FilterDataEvent($this->form, $data); + $event = new FormEvent($this->form, $data); $listener = new ResizeFormListener($this->factory, 'text', array(), false, true); - $listener->onBindNormData($event); + $listener->onBind($event); $this->assertEquals(array(), $event->getData()); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php index 7f70a061c0..e5c3f96ef4 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\Extension\Core\EventListener\TrimListener; class TrimListenerTest extends \PHPUnit_Framework_TestCase @@ -27,10 +27,10 @@ class TrimListenerTest extends \PHPUnit_Framework_TestCase { $data = " Foo! "; $form = $this->getMock('Symfony\Component\Form\Tests\FormInterface'); - $event = new FilterDataEvent($form, $data); + $event = new FormEvent($form, $data); $filter = new TrimListener(); - $filter->onBindClientData($event); + $filter->preBind($event); $this->assertEquals('Foo!', $event->getData()); } @@ -39,10 +39,10 @@ class TrimListenerTest extends \PHPUnit_Framework_TestCase { $data = 1234; $form = $this->getMock('Symfony\Component\Form\Tests\FormInterface'); - $event = new FilterDataEvent($form, $data); + $event = new FormEvent($form, $data); $filter = new TrimListener(); - $filter->onBindClientData($event); + $filter->preBind($event); $this->assertSame(1234, $event->getData()); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php index 5cf494572a..1fd366ef54 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php @@ -20,7 +20,7 @@ class CheckboxTypeTest extends TypeTestCase $form = $this->factory->create('checkbox', null, array('value' => 'foobar')); $view = $form->createView(); - $this->assertEquals('foobar', $view->get('value')); + $this->assertEquals('foobar', $view->getVar('value')); } public function testCheckedIfDataTrue() @@ -29,7 +29,7 @@ class CheckboxTypeTest extends TypeTestCase $form->setData(true); $view = $form->createView(); - $this->assertTrue($view->get('checked')); + $this->assertTrue($view->getVar('checked')); } public function testCheckedIfDataTrueWithEmptyValue() @@ -38,7 +38,7 @@ class CheckboxTypeTest extends TypeTestCase $form->setData(true); $view = $form->createView(); - $this->assertTrue($view->get('checked')); + $this->assertTrue($view->getVar('checked')); } public function testNotCheckedIfDataFalse() @@ -47,7 +47,7 @@ class CheckboxTypeTest extends TypeTestCase $form->setData(false); $view = $form->createView(); - $this->assertFalse($view->get('checked')); + $this->assertFalse($view->getVar('checked')); } public function testBindWithValueChecked() @@ -58,7 +58,7 @@ class CheckboxTypeTest extends TypeTestCase $form->bind('foobar'); $this->assertTrue($form->getData()); - $this->assertEquals('foobar', $form->getClientData()); + $this->assertEquals('foobar', $form->getViewData()); } public function testBindWithRandomValueChecked() @@ -69,7 +69,7 @@ class CheckboxTypeTest extends TypeTestCase $form->bind('krixikraxi'); $this->assertTrue($form->getData()); - $this->assertEquals('foobar', $form->getClientData()); + $this->assertEquals('foobar', $form->getViewData()); } public function testBindWithValueUnchecked() @@ -80,7 +80,7 @@ class CheckboxTypeTest extends TypeTestCase $form->bind(null); $this->assertFalse($form->getData()); - $this->assertNull($form->getClientData()); + $this->assertNull($form->getViewData()); } public function testBindWithEmptyValueChecked() @@ -91,7 +91,7 @@ class CheckboxTypeTest extends TypeTestCase $form->bind(''); $this->assertTrue($form->getData()); - $this->assertSame('', $form->getClientData()); + $this->assertSame('', $form->getViewData()); } public function testBindWithEmptyValueUnchecked() @@ -102,7 +102,7 @@ class CheckboxTypeTest extends TypeTestCase $form->bind(null); $this->assertFalse($form->getData()); - $this->assertNull($form->getClientData()); + $this->assertNull($form->getViewData()); } /** @@ -122,12 +122,12 @@ class CheckboxTypeTest extends TypeTestCase $form = $this->builder ->create('expedited_shipping', 'checkbox') - ->prependNormTransformer($transformer) + ->addModelTransformer($transformer) ->getForm(); $form->setData($data); $view = $form->createView(); - $this->assertEquals($expected, $view->get('checked')); + $this->assertEquals($expected, $view->getVar('checked')); } public function provideTransformedData() diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index fbda65a3b6..9fe68784d2 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -74,17 +74,17 @@ class ChoiceTypeTest extends TypeTestCase */ public function testChoicesOptionExpectsArray() { - $form = $this->factory->create('choice', null, array( + $this->factory->create('choice', null, array( 'choices' => new \ArrayObject(), )); } /** - * @expectedException Symfony\Component\Form\Exception\FormException + * @expectedException Symfony\Component\OptionsResolver\Exception\InvalidOptionsException */ public function testChoiceListOptionExpectsChoiceListInterface() { - $form = $this->factory->create('choice', null, array( + $this->factory->create('choice', null, array( 'choice_list' => array('foo' => 'foo'), )); } @@ -94,7 +94,7 @@ class ChoiceTypeTest extends TypeTestCase */ public function testEitherChoiceListOrChoicesMustBeSet() { - $form = $this->factory->create('choice', null, array( + $this->factory->create('choice', null, array( )); } @@ -180,7 +180,7 @@ class ChoiceTypeTest extends TypeTestCase $form->bind('b'); $this->assertEquals('b', $form->getData()); - $this->assertEquals('b', $form->getClientData()); + $this->assertEquals('b', $form->getViewData()); } public function testBindSingleNonExpandedObjectChoices() @@ -203,7 +203,7 @@ class ChoiceTypeTest extends TypeTestCase $form->bind('2'); $this->assertEquals($this->objectChoices[1], $form->getData()); - $this->assertEquals('2', $form->getClientData()); + $this->assertEquals('2', $form->getViewData()); } public function testBindMultipleNonExpanded() @@ -217,7 +217,7 @@ class ChoiceTypeTest extends TypeTestCase $form->bind(array('a', 'b')); $this->assertEquals(array('a', 'b'), $form->getData()); - $this->assertEquals(array('a', 'b'), $form->getClientData()); + $this->assertEquals(array('a', 'b'), $form->getViewData()); } public function testBindMultipleNonExpandedObjectChoices() @@ -239,7 +239,7 @@ class ChoiceTypeTest extends TypeTestCase $form->bind(array('2', '3')); $this->assertEquals(array($this->objectChoices[1], $this->objectChoices[2]), $form->getData()); - $this->assertEquals(array('2', '3'), $form->getClientData()); + $this->assertEquals(array('2', '3'), $form->getViewData()); } public function testBindSingleExpanded() @@ -258,11 +258,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertFalse($form[2]->getData()); $this->assertFalse($form[3]->getData()); $this->assertFalse($form[4]->getData()); - $this->assertNull($form[0]->getClientData()); - $this->assertSame('b', $form[1]->getClientData()); - $this->assertNull($form[2]->getClientData()); - $this->assertNull($form[3]->getClientData()); - $this->assertNull($form[4]->getClientData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('b', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } public function testBindSingleExpandedNothingChecked() @@ -281,11 +281,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertFalse($form[2]->getData()); $this->assertFalse($form[3]->getData()); $this->assertFalse($form[4]->getData()); - $this->assertNull($form[0]->getClientData()); - $this->assertNull($form[1]->getClientData()); - $this->assertNull($form[2]->getClientData()); - $this->assertNull($form[3]->getClientData()); - $this->assertNull($form[4]->getClientData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } public function testBindSingleExpandedWithFalseDoesNotHaveExtraChildren() @@ -318,8 +318,8 @@ class ChoiceTypeTest extends TypeTestCase $this->assertNull($form->getData()); $this->assertTrue($form[0]->getData()); $this->assertFalse($form[1]->getData()); - $this->assertSame('', $form[0]->getClientData()); - $this->assertNull($form[1]->getClientData()); + $this->assertSame('', $form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); } public function testBindSingleExpandedObjectChoices() @@ -346,11 +346,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertFalse($form[2]->getData()); $this->assertFalse($form[3]->getData()); $this->assertFalse($form[4]->getData()); - $this->assertNull($form[0]->getClientData()); - $this->assertSame('2', $form[1]->getClientData()); - $this->assertNull($form[2]->getClientData()); - $this->assertNull($form[3]->getClientData()); - $this->assertNull($form[4]->getClientData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('2', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } public function testBindSingleExpandedNumericChoices() @@ -369,11 +369,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertFalse($form[2]->getData()); $this->assertFalse($form[3]->getData()); $this->assertFalse($form[4]->getData()); - $this->assertNull($form[0]->getClientData()); - $this->assertSame('1', $form[1]->getClientData()); - $this->assertNull($form[2]->getClientData()); - $this->assertNull($form[3]->getClientData()); - $this->assertNull($form[4]->getClientData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('1', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } public function testBindMultipleExpanded() @@ -392,11 +392,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertTrue($form[2]->getData()); $this->assertFalse($form[3]->getData()); $this->assertFalse($form[4]->getData()); - $this->assertSame('a', $form[0]->getClientData()); - $this->assertNull($form[1]->getClientData()); - $this->assertSame('c', $form[2]->getClientData()); - $this->assertNull($form[3]->getClientData()); - $this->assertNull($form[4]->getClientData()); + $this->assertSame('a', $form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertSame('c', $form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } public function testBindMultipleExpandedEmpty() @@ -415,11 +415,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertFalse($form[2]->getData()); $this->assertFalse($form[3]->getData()); $this->assertFalse($form[4]->getData()); - $this->assertNull($form[0]->getClientData()); - $this->assertNull($form[1]->getClientData()); - $this->assertNull($form[2]->getClientData()); - $this->assertNull($form[3]->getClientData()); - $this->assertNull($form[4]->getClientData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } public function testBindMultipleExpandedWithEmptyChild() @@ -440,9 +440,9 @@ class ChoiceTypeTest extends TypeTestCase $this->assertTrue($form[0]->getData()); $this->assertFalse($form[1]->getData()); $this->assertTrue($form[2]->getData()); - $this->assertSame('', $form[0]->getClientData()); - $this->assertNull($form[1]->getClientData()); - $this->assertSame('2', $form[2]->getClientData()); + $this->assertSame('', $form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertSame('2', $form[2]->getViewData()); } public function testBindMultipleExpandedObjectChoices() @@ -469,11 +469,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertFalse($form[2]->getData()); $this->assertFalse($form[3]->getData()); $this->assertFalse($form[4]->getData()); - $this->assertSame('1', $form[0]->getClientData()); - $this->assertSame('2', $form[1]->getClientData()); - $this->assertNull($form[2]->getClientData()); - $this->assertNull($form[3]->getClientData()); - $this->assertNull($form[4]->getClientData()); + $this->assertSame('1', $form[0]->getViewData()); + $this->assertSame('2', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } public function testBindMultipleExpandedNumericChoices() @@ -492,11 +492,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertTrue($form[2]->getData()); $this->assertFalse($form[3]->getData()); $this->assertFalse($form[4]->getData()); - $this->assertNull($form[0]->getClientData()); - $this->assertSame('1', $form[1]->getClientData()); - $this->assertSame('2', $form[2]->getClientData()); - $this->assertNull($form[3]->getClientData()); - $this->assertNull($form[4]->getClientData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('1', $form[1]->getViewData()); + $this->assertSame('2', $form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } /* @@ -514,7 +514,7 @@ class ChoiceTypeTest extends TypeTestCase $form->setData(false); $this->assertFalse($form->getData()); - $this->assertEquals('0', $form->getClientData()); + $this->assertEquals('0', $form->getViewData()); } public function testSetDataMultipleNonExpandedAcceptsBoolean() @@ -528,7 +528,7 @@ class ChoiceTypeTest extends TypeTestCase $form->setData(array(false, true)); $this->assertEquals(array(false, true), $form->getData()); - $this->assertEquals(array('0', '1'), $form->getClientData()); + $this->assertEquals(array('0', '1'), $form->getViewData()); } public function testPassRequiredToView() @@ -538,7 +538,7 @@ class ChoiceTypeTest extends TypeTestCase )); $view = $form->createView(); - $this->assertTrue($view->get('required')); + $this->assertTrue($view->getVar('required')); } public function testPassNonRequiredToView() @@ -549,7 +549,7 @@ class ChoiceTypeTest extends TypeTestCase )); $view = $form->createView(); - $this->assertFalse($view->get('required')); + $this->assertFalse($view->getVar('required')); } public function testPassMultipleToView() @@ -560,7 +560,7 @@ class ChoiceTypeTest extends TypeTestCase )); $view = $form->createView(); - $this->assertTrue($view->get('multiple')); + $this->assertTrue($view->getVar('multiple')); } public function testPassExpandedToView() @@ -571,7 +571,7 @@ class ChoiceTypeTest extends TypeTestCase )); $view = $form->createView(); - $this->assertTrue($view->get('expanded')); + $this->assertTrue($view->getVar('expanded')); } public function testNotPassedEmptyValueToViewIsNull() @@ -582,7 +582,7 @@ class ChoiceTypeTest extends TypeTestCase )); $view = $form->createView(); - $this->assertNull($view->get('empty_value')); + $this->assertNull($view->getVar('empty_value')); } public function testPassEmptyValueToViewIsEmpty() @@ -594,7 +594,7 @@ class ChoiceTypeTest extends TypeTestCase )); $view = $form->createView(); - $this->assertEmpty($view->get('empty_value')); + $this->assertEmpty($view->getVar('empty_value')); } /** @@ -611,7 +611,7 @@ class ChoiceTypeTest extends TypeTestCase )); $view = $form->createView(); - $this->assertEquals($viewValue, $view->get('empty_value')); + $this->assertEquals($viewValue, $view->getVar('empty_value')); } public function getOptionsWithEmptyValue() @@ -642,7 +642,7 @@ class ChoiceTypeTest extends TypeTestCase new ChoiceView('b', 'B'), new ChoiceView('c', 'C'), new ChoiceView('d', 'D'), - ), $view->get('choices')); + ), $view->getVar('choices')); } public function testPassPreferredChoicesToView() @@ -657,11 +657,11 @@ class ChoiceTypeTest extends TypeTestCase $this->assertEquals(array( 0 => new ChoiceView('a', 'A'), 2 => new ChoiceView('c', 'C'), - ), $view->get('choices')); + ), $view->getVar('choices')); $this->assertEquals(array( 1 => new ChoiceView('b', 'B'), 3 => new ChoiceView('d', 'D'), - ), $view->get('preferred_choices')); + ), $view->getVar('preferred_choices')); } public function testPassHierarchicalChoicesToView() @@ -680,7 +680,7 @@ class ChoiceTypeTest extends TypeTestCase 'Doctrine' => array( 4 => new ChoiceView('e', 'Roman'), ), - ), $view->get('choices')); + ), $view->getVar('choices')); $this->assertEquals(array( 'Symfony' => array( 1 => new ChoiceView('b', 'Fabien'), @@ -688,25 +688,25 @@ class ChoiceTypeTest extends TypeTestCase 'Doctrine' => array( 3 => new ChoiceView('d', 'Jon'), ), - ), $view->get('preferred_choices')); + ), $view->getVar('preferred_choices')); } public function testAdjustFullNameForMultipleNonExpanded() { - $form = $this->factory->createNamed('choice', 'name', null, array( + $form = $this->factory->createNamed('name', 'choice', null, array( 'multiple' => true, 'expanded' => false, 'choices' => $this->choices, )); $view = $form->createView(); - $this->assertSame('name[]', $view->get('full_name')); + $this->assertSame('name[]', $view->getVar('full_name')); } // https://github.com/symfony/symfony/issues/3298 public function testInitializeWithEmptyChoices() { - $this->factory->createNamed('choice', 'name', null, array( + $this->factory->createNamed('name', 'choice', null, array( 'choices' => array(), )); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php index 5461258e95..eb5e99b3cc 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php @@ -39,15 +39,15 @@ class CollectionTypeTest extends TypeTestCase $this->assertCount(2, $form); $this->assertEquals('foo@foo.com', $form[0]->getData()); $this->assertEquals('foo@bar.com', $form[1]->getData()); - $this->assertEquals(20, $form[0]->getAttribute('max_length')); - $this->assertEquals(20, $form[1]->getAttribute('max_length')); + $this->assertEquals(20, $form[0]->getConfig()->getOption('max_length')); + $this->assertEquals(20, $form[1]->getConfig()->getOption('max_length')); $form->setData(array('foo@baz.com')); $this->assertInstanceOf('Symfony\Component\Form\Form', $form[0]); $this->assertFalse(isset($form[1])); $this->assertCount(1, $form); $this->assertEquals('foo@baz.com', $form[0]->getData()); - $this->assertEquals(20, $form[0]->getAttribute('max_length')); + $this->assertEquals(20, $form[0]->getConfig()->getOption('max_length')); } public function testThrowsExceptionIfObjectIsNotTraversable() @@ -138,7 +138,7 @@ class CollectionTypeTest extends TypeTestCase )) ; - $this->assertTrue($form->createView()->get('multipart')); + $this->assertTrue($form->createView()->getVar('multipart')); } public function testGetDataDoesNotContainsProtypeNameBeforeDataAreSet() @@ -174,7 +174,7 @@ class CollectionTypeTest extends TypeTestCase 'allow_add' => true, )); - $this->assertSame('__name__', $form->getAttribute('prototype')->getName(), '__name__ is the default'); + $this->assertSame('__name__', $form->getConfig()->getAttribute('prototype')->getName(), '__name__ is the default'); $form = $this->factory->create('collection', null, array( 'type' => 'form', @@ -183,7 +183,7 @@ class CollectionTypeTest extends TypeTestCase 'prototype_name' => '__test__', )); - $this->assertSame('__test__', $form->getAttribute('prototype')->getName()); + $this->assertSame('__test__', $form->getConfig()->getAttribute('prototype')->getName()); } public function testPrototypeDefaultLabel() @@ -195,6 +195,6 @@ class CollectionTypeTest extends TypeTestCase 'prototype_name' => '__test__', )); - $this->assertSame('__test__label__', $form->createView()->get('prototype')->get('label')); + $this->assertSame('__test__label__', $form->createView()->getVar('prototype')->getVar('label')); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php index a61f48e7af..4ad3598417 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php @@ -21,7 +21,7 @@ class CountryTypeTest extends LocalizedTestCase $form = $this->factory->create('country'); $view = $form->createView(); - $choices = $view->get('choices'); + $choices = $view->getVar('choices'); // Don't check objects for identity $this->assertContains(new ChoiceView('DE', 'Deutschland'), $choices, '', false, false); @@ -35,7 +35,7 @@ class CountryTypeTest extends LocalizedTestCase { $form = $this->factory->create('country', 'country'); $view = $form->createView(); - $choices = $view->get('choices'); + $choices = $view->getVar('choices'); foreach ($choices as $choice) { if ('ZZ' === $choice->getValue()) { diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php index a075d55868..9c7cbe6a6f 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php @@ -173,7 +173,7 @@ class DateTimeTypeTest extends LocalizedTestCase $outputTime->setTimezone(new \DateTimeZone('America/New_York')); $this->assertDateTimeEquals($outputTime, $form->getData()); - $this->assertEquals('2010-06-02 03:04', $form->getClientData()); + $this->assertEquals('2010-06-02 03:04', $form->getViewData()); } public function testSubmit_stringSingleText() @@ -188,7 +188,7 @@ class DateTimeTypeTest extends LocalizedTestCase $form->bind('2010-06-02 03:04:05'); $this->assertEquals('2010-06-02 03:04:00', $form->getData()); - $this->assertEquals('2010-06-02 03:04', $form->getClientData()); + $this->assertEquals('2010-06-02 03:04', $form->getViewData()); } public function testSubmit_stringSingleText_withSeconds() @@ -204,7 +204,7 @@ class DateTimeTypeTest extends LocalizedTestCase $form->bind('2010-06-02 03:04:05'); $this->assertEquals('2010-06-02 03:04:05', $form->getData()); - $this->assertEquals('2010-06-02 03:04:05', $form->getClientData()); + $this->assertEquals('2010-06-02 03:04:05', $form->getViewData()); } public function testSubmit_differentPattern() @@ -241,6 +241,6 @@ class DateTimeTypeTest extends LocalizedTestCase )); $view = $form->createView(); - $this->assertEquals('datetime', $view->get('type')); + $this->assertEquals('datetime', $view->getVar('type')); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php index 41aaf6b953..705a64a943 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php @@ -54,7 +54,7 @@ class DateTypeTest extends LocalizedTestCase $form->bind('2.6.2010'); $this->assertDateTimeEquals(new \DateTime('2010-06-02 UTC'), $form->getData()); - $this->assertEquals('02.06.2010', $form->getClientData()); + $this->assertEquals('02.06.2010', $form->getViewData()); } public function testSubmitFromSingleTextString() @@ -69,7 +69,7 @@ class DateTypeTest extends LocalizedTestCase $form->bind('2.6.2010'); $this->assertEquals('2010-06-02', $form->getData()); - $this->assertEquals('02.06.2010', $form->getClientData()); + $this->assertEquals('02.06.2010', $form->getViewData()); } public function testSubmitFromSingleTextTimestamp() @@ -86,7 +86,7 @@ class DateTypeTest extends LocalizedTestCase $dateTime = new \DateTime('2010-06-02 UTC'); $this->assertEquals($dateTime->format('U'), $form->getData()); - $this->assertEquals('02.06.2010', $form->getClientData()); + $this->assertEquals('02.06.2010', $form->getViewData()); } public function testSubmitFromSingleTextRaw() @@ -107,7 +107,7 @@ class DateTypeTest extends LocalizedTestCase ); $this->assertEquals($output, $form->getData()); - $this->assertEquals('02.06.2010', $form->getClientData()); + $this->assertEquals('02.06.2010', $form->getViewData()); } public function testSubmitFromText() @@ -129,7 +129,7 @@ class DateTypeTest extends LocalizedTestCase $dateTime = new \DateTime('2010-06-02 UTC'); $this->assertDateTimeEquals($dateTime, $form->getData()); - $this->assertEquals($text, $form->getClientData()); + $this->assertEquals($text, $form->getViewData()); } public function testSubmitFromChoice() @@ -151,7 +151,7 @@ class DateTypeTest extends LocalizedTestCase $dateTime = new \DateTime('2010-06-02 UTC'); $this->assertDateTimeEquals($dateTime, $form->getData()); - $this->assertEquals($text, $form->getClientData()); + $this->assertEquals($text, $form->getViewData()); } public function testSubmitFromChoiceEmpty() @@ -172,7 +172,7 @@ class DateTypeTest extends LocalizedTestCase $form->bind($text); $this->assertNull($form->getData()); - $this->assertEquals($text, $form->getClientData()); + $this->assertEquals($text, $form->getViewData()); } public function testSubmitFromInputDateTimeDifferentPattern() @@ -188,7 +188,7 @@ class DateTypeTest extends LocalizedTestCase $form->bind('06*2010*02'); $this->assertDateTimeEquals(new \DateTime('2010-06-02 UTC'), $form->getData()); - $this->assertEquals('06*2010*02', $form->getClientData()); + $this->assertEquals('06*2010*02', $form->getViewData()); } public function testSubmitFromInputStringDifferentPattern() @@ -204,7 +204,7 @@ class DateTypeTest extends LocalizedTestCase $form->bind('06*2010*02'); $this->assertEquals('2010-06-02', $form->getData()); - $this->assertEquals('06*2010*02', $form->getClientData()); + $this->assertEquals('06*2010*02', $form->getViewData()); } public function testSubmitFromInputTimestampDifferentPattern() @@ -222,7 +222,7 @@ class DateTypeTest extends LocalizedTestCase $dateTime = new \DateTime('2010-06-02 UTC'); $this->assertEquals($dateTime->format('U'), $form->getData()); - $this->assertEquals('06*2010*02', $form->getClientData()); + $this->assertEquals('06*2010*02', $form->getViewData()); } public function testSubmitFromInputRawDifferentPattern() @@ -244,7 +244,7 @@ class DateTypeTest extends LocalizedTestCase ); $this->assertEquals($output, $form->getData()); - $this->assertEquals('06*2010*02', $form->getClientData()); + $this->assertEquals('06*2010*02', $form->getViewData()); } /** @@ -262,7 +262,7 @@ class DateTypeTest extends LocalizedTestCase $form->setData('2010-06-02'); // This would be what would be outputed if '0' was mistaken for \IntlDateFormatter::FULL - $this->assertNotEquals('Mittwoch, 02. Juni 2010', $form->getClientData()); + $this->assertNotEquals('Mittwoch, 02. Juni 2010', $form->getViewData()); } /** @@ -296,7 +296,7 @@ class DateTypeTest extends LocalizedTestCase $form->setData('2010-06-02'); - $this->assertEquals('01.06.2010', $form->getClientData()); + $this->assertEquals('01.06.2010', $form->getViewData()); } public function testSetData_differentTimezonesDateTime() @@ -313,7 +313,7 @@ class DateTypeTest extends LocalizedTestCase $form->setData($dateTime); $this->assertDateTimeEquals($dateTime, $form->getData()); - $this->assertEquals('01.06.2010', $form->getClientData()); + $this->assertEquals('01.06.2010', $form->getViewData()); } public function testYearsOption() @@ -327,7 +327,7 @@ class DateTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('2010', '2010'), new ChoiceView('2011', '2011'), - ), $view->getChild('year')->get('choices')); + ), $view->get('year')->getVar('choices')); } public function testMonthsOption() @@ -341,7 +341,7 @@ class DateTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('6', '06'), new ChoiceView('7', '07'), - ), $view->getChild('month')->get('choices')); + ), $view->get('month')->getVar('choices')); } public function testMonthsOptionNumericIfFormatContainsNoMonth() @@ -356,7 +356,7 @@ class DateTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('6', '06'), new ChoiceView('7', '07'), - ), $view->getChild('month')->get('choices')); + ), $view->get('month')->getVar('choices')); } public function testMonthsOptionShortFormat() @@ -371,7 +371,7 @@ class DateTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('1', 'Jän'), new ChoiceView('4', 'Apr') - ), $view->getChild('month')->get('choices')); + ), $view->get('month')->getVar('choices')); } public function testMonthsOptionLongFormat() @@ -386,7 +386,7 @@ class DateTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('1', 'Jänner'), new ChoiceView('4', 'April'), - ), $view->getChild('month')->get('choices')); + ), $view->get('month')->getVar('choices')); } public function testMonthsOptionLongFormatWithDifferentTimezone() @@ -401,7 +401,7 @@ class DateTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('1', 'Jänner'), new ChoiceView('4', 'April'), - ), $view->getChild('month')->get('choices')); + ), $view->get('month')->getVar('choices')); } public function testIsDayWithinRangeReturnsTrueIfWithin() @@ -415,7 +415,7 @@ class DateTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('6', '06'), new ChoiceView('7', '07'), - ), $view->getChild('day')->get('choices')); + ), $view->get('day')->getVar('choices')); } public function testIsPartiallyFilledReturnsFalseIfSingleText() @@ -495,7 +495,7 @@ class DateTypeTest extends LocalizedTestCase $form = $this->factory->create('date'); $view = $form->createView(); - $this->assertSame('{{ day }}.{{ month }}.{{ year }}', $view->get('date_pattern')); + $this->assertSame('{{ day }}.{{ month }}.{{ year }}', $view->getVar('date_pattern')); } public function testPassDatePatternToViewDifferentPattern() @@ -506,7 +506,7 @@ class DateTypeTest extends LocalizedTestCase $view = $form->createView(); - $this->assertSame('{{ month }}*{{ year }}*{{ day }}', $view->get('date_pattern')); + $this->assertSame('{{ month }}*{{ year }}*{{ day }}', $view->getVar('date_pattern')); } public function testDontPassDatePatternIfText() @@ -516,7 +516,7 @@ class DateTypeTest extends LocalizedTestCase )); $view = $form->createView(); - $this->assertNull($view->get('date_pattern')); + $this->assertNull($view->getVar('date_pattern')); } public function testPassWidgetToView() @@ -526,7 +526,7 @@ class DateTypeTest extends LocalizedTestCase )); $view = $form->createView(); - $this->assertSame('single_text', $view->get('widget')); + $this->assertSame('single_text', $view->getVar('widget')); } // Bug fix @@ -544,6 +544,6 @@ class DateTypeTest extends LocalizedTestCase )); $view = $form->createView(); - $this->assertEquals('date', $view->get('type')); + $this->assertEquals('date', $view->getVar('type')); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php index e4a311845f..d98513072f 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php @@ -23,7 +23,7 @@ class FileTypeTest extends TypeTestCase )); $view = $form->createView(); - $this->assertEquals('', $view->get('value')); + $this->assertEquals('', $view->getVar('value')); } private function createUploadedFileMock($name, $originalName, $valid) diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php index 4c9be8af24..77286d0366 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php @@ -81,7 +81,7 @@ class FormTypeTest extends TypeTestCase $form->bind(' a '); - $this->assertEquals('a', $form->getClientData()); + $this->assertEquals('a', $form->getViewData()); $this->assertEquals('reverse[a]', $form->getData()); } @@ -96,78 +96,78 @@ class FormTypeTest extends TypeTestCase $form->bind(' a '); - $this->assertEquals(' a ', $form->getClientData()); + $this->assertEquals(' a ', $form->getViewData()); $this->assertEquals('reverse[ a ]', $form->getData()); } public function testPassIdAndNameToView() { - $form = $this->factory->createNamed('form', 'name'); + $form = $this->factory->createNamed('name', 'form'); $view = $form->createView(); - $this->assertEquals('name', $view->get('id')); - $this->assertEquals('name', $view->get('name')); - $this->assertEquals('name', $view->get('full_name')); + $this->assertEquals('name', $view->getVar('id')); + $this->assertEquals('name', $view->getVar('name')); + $this->assertEquals('name', $view->getVar('full_name')); } public function testStripLeadingUnderscoresAndDigitsFromId() { - $form = $this->factory->createNamed('form', '_09name'); + $form = $this->factory->createNamed('_09name', 'form'); $view = $form->createView(); - $this->assertEquals('name', $view->get('id')); - $this->assertEquals('_09name', $view->get('name')); - $this->assertEquals('_09name', $view->get('full_name')); + $this->assertEquals('name', $view->getVar('id')); + $this->assertEquals('_09name', $view->getVar('name')); + $this->assertEquals('_09name', $view->getVar('full_name')); } public function testPassIdAndNameToViewWithParent() { - $parent = $this->factory->createNamed('form', 'parent'); - $parent->add($this->factory->createNamed('form', 'child')); + $parent = $this->factory->createNamed('parent', 'form'); + $parent->add($this->factory->createNamed('child', 'form')); $view = $parent->createView(); - $this->assertEquals('parent_child', $view['child']->get('id')); - $this->assertEquals('child', $view['child']->get('name')); - $this->assertEquals('parent[child]', $view['child']->get('full_name')); + $this->assertEquals('parent_child', $view['child']->getVar('id')); + $this->assertEquals('child', $view['child']->getVar('name')); + $this->assertEquals('parent[child]', $view['child']->getVar('full_name')); } public function testPassIdAndNameToViewWithGrandParent() { - $parent = $this->factory->createNamed('form', 'parent'); - $parent->add($this->factory->createNamed('form', 'child')); - $parent['child']->add($this->factory->createNamed('form', 'grand_child')); + $parent = $this->factory->createNamed('parent', 'form'); + $parent->add($this->factory->createNamed('child', 'form')); + $parent['child']->add($this->factory->createNamed('grand_child', 'form')); $view = $parent->createView(); - $this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->get('id')); - $this->assertEquals('grand_child', $view['child']['grand_child']->get('name')); - $this->assertEquals('parent[child][grand_child]', $view['child']['grand_child']->get('full_name')); + $this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->getVar('id')); + $this->assertEquals('grand_child', $view['child']['grand_child']->getVar('name')); + $this->assertEquals('parent[child][grand_child]', $view['child']['grand_child']->getVar('full_name')); } public function testNonReadOnlyFormWithReadOnlyParentBeingReadOnly() { - $parent = $this->factory->createNamed('form', 'parent', null, array('read_only' => true)); - $child = $this->factory->createNamed('form', 'child'); + $parent = $this->factory->createNamed('parent', 'form', null, array('read_only' => true)); + $child = $this->factory->createNamed('child', 'form'); $view = $parent->add($child)->createView(); - $this->assertTrue($view['child']->get('read_only')); + $this->assertTrue($view['child']->getVar('read_only')); } public function testReadOnlyFormWithNonReadOnlyParentBeingReadOnly() { - $parent = $this->factory->createNamed('form', 'parent'); - $child = $this->factory->createNamed('form', 'child', null, array('read_only' => true)); + $parent = $this->factory->createNamed('parent', 'form'); + $child = $this->factory->createNamed('child', 'form', null, array('read_only' => true)); $view = $parent->add($child)->createView(); - $this->assertTrue($view['child']->get('read_only')); + $this->assertTrue($view['child']->getVar('read_only')); } public function testNonReadOnlyFormWithNonReadOnlyParentBeingNonReadOnly() { - $parent = $this->factory->createNamed('form', 'parent'); - $child = $this->factory->createNamed('form', 'child'); + $parent = $this->factory->createNamed('parent', 'form'); + $child = $this->factory->createNamed('child', 'form'); $view = $parent->add($child)->createView(); - $this->assertFalse($view['child']->get('read_only')); + $this->assertFalse($view['child']->getVar('read_only')); } public function testPassMaxLengthToView() @@ -175,7 +175,7 @@ class FormTypeTest extends TypeTestCase $form = $this->factory->create('form', null, array('max_length' => 10)); $view = $form->createView(); - $this->assertSame(10, $view->get('max_length')); + $this->assertSame(10, $view->getVar('max_length')); } public function testPassTranslationDomainToView() @@ -183,23 +183,23 @@ class FormTypeTest extends TypeTestCase $form = $this->factory->create('form', null, array('translation_domain' => 'test')); $view = $form->createView(); - $this->assertSame('test', $view->get('translation_domain')); + $this->assertSame('test', $view->getVar('translation_domain')); } public function testPassDefaultLabelToView() { - $form = $this->factory->createNamed('form', '__test___field'); + $form = $this->factory->createNamed('__test___field', 'form'); $view = $form->createView(); - $this->assertSame('Test field', $view->get('label')); + $this->assertSame('Test field', $view->getVar('label')); } public function testPassLabelToView() { - $form = $this->factory->createNamed('form', '__test___field', null, array('label' => 'My label')); + $form = $this->factory->createNamed('__test___field', 'form', null, array('label' => 'My label')); $view = $form->createView(); - $this->assertSame('My label', $view->get('label')); + $this->assertSame('My label', $view->getVar('label')); } public function testDefaultTranslationDomain() @@ -207,7 +207,7 @@ class FormTypeTest extends TypeTestCase $form = $this->factory->create('form'); $view = $form->createView(); - $this->assertSame('messages', $view->get('translation_domain')); + $this->assertSame('messages', $view->getVar('translation_domain')); } public function testBindWithEmptyDataCreatesObjectIfClassAvailable() @@ -216,8 +216,8 @@ class FormTypeTest extends TypeTestCase 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', 'required' => false, )); - $form->add($this->factory->createNamed('form', 'firstName')); - $form->add($this->factory->createNamed('form', 'lastName')); + $form->add($this->factory->createNamed('firstName', 'form')); + $form->add($this->factory->createNamed('lastName', 'form')); $form->setData(null); // partially empty, still an object is created @@ -237,8 +237,8 @@ class FormTypeTest extends TypeTestCase 'data' => new Author(), 'required' => false, )); - $form->add($this->factory->createNamed('form', 'firstName')); - $form->add($this->factory->createNamed('form', 'lastName')); + $form->add($this->factory->createNamed('firstName', 'form')); + $form->add($this->factory->createNamed('lastName', 'form')); $form->setData(null); // partially empty, still an object is created @@ -257,7 +257,7 @@ class FormTypeTest extends TypeTestCase 'data_class' => null, 'required' => false, )); - $form->add($this->factory->createNamed('form', 'firstName')); + $form->add($this->factory->createNamed('firstName', 'form')); $form->setData(null); $form->bind(array('firstName' => 'Bernhard')); @@ -271,8 +271,8 @@ class FormTypeTest extends TypeTestCase 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', 'required' => false, )); - $form->add($this->factory->createNamed('form', 'firstName')); - $form->add($this->factory->createNamed('form', 'lastName')); + $form->add($this->factory->createNamed('firstName', 'form')); + $form->add($this->factory->createNamed('lastName', 'form')); $form->setData(null); $form->bind(array('firstName' => '', 'lastName' => '')); @@ -286,8 +286,8 @@ class FormTypeTest extends TypeTestCase 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', 'required' => true, )); - $form->add($this->factory->createNamed('form', 'firstName')); - $form->add($this->factory->createNamed('form', 'lastName')); + $form->add($this->factory->createNamed('firstName', 'form')); + $form->add($this->factory->createNamed('lastName', 'form')); $form->setData(null); $form->bind(array('firstName' => '', 'lastName' => '')); @@ -301,7 +301,7 @@ class FormTypeTest extends TypeTestCase public function testBindWithEmptyDataStoresArrayIfNoClassAvailable() { $form = $this->factory->create('form'); - $form->add($this->factory->createNamed('form', 'firstName')); + $form->add($this->factory->createNamed('firstName', 'form')); $form->setData(null); $form->bind(array('firstName' => 'Bernhard')); @@ -333,7 +333,7 @@ class FormTypeTest extends TypeTestCase 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', 'empty_data' => $author, )); - $form->add($this->factory->createNamed('form', 'firstName')); + $form->add($this->factory->createNamed('firstName', 'form')); $form->bind(array('firstName' => 'Bernhard')); @@ -341,13 +341,6 @@ class FormTypeTest extends TypeTestCase $this->assertEquals('Bernhard', $author->firstName); } - public function testGetAttributesIsEmpty() - { - $form = $this->factory->create('form', null, array('attr' => array())); - - $this->assertCount(0, $form->getAttribute('attr')); - } - /** * @see https://github.com/symfony/symfony/issues/1986 */ @@ -358,7 +351,7 @@ class FormTypeTest extends TypeTestCase $this->assertFalse($form->isEmpty()); - $this->assertSame('0', $view->get('value')); + $this->assertSame('0', $view->getVar('value')); $this->assertSame('0', $form->getData()); $form = $this->factory->create('form', null, array('data' => '0')); @@ -366,7 +359,7 @@ class FormTypeTest extends TypeTestCase $this->assertFalse($form->isEmpty()); - $this->assertSame('0', $view->get('value')); + $this->assertSame('0', $view->getVar('value')); $this->assertSame('0', $form->getData()); $form = $this->factory->create('form', null, array('data' => '00000')); @@ -374,21 +367,21 @@ class FormTypeTest extends TypeTestCase $this->assertFalse($form->isEmpty()); - $this->assertSame('00000', $view->get('value')); + $this->assertSame('00000', $view->getVar('value')); $this->assertSame('00000', $form->getData()); } /** - * @expectedException Symfony\Component\Form\Exception\FormException + * @expectedException Symfony\Component\OptionsResolver\Exception\InvalidOptionsException */ public function testAttributesException() { - $form = $this->factory->create('form', null, array('attr' => '')); + $this->factory->create('form', null, array('attr' => '')); } public function testNameCanBeEmptyString() { - $form = $this->factory->createNamed('form', ''); + $form = $this->factory->createNamed('', 'form'); $this->assertEquals('', $form->getName()); } @@ -514,7 +507,7 @@ class FormTypeTest extends TypeTestCase $form = $this->factory->create('form'); $view = $form->createView(); - $this->assertFalse($view->get('multipart')); + $this->assertFalse($view->getVar('multipart')); } public function testPassMultipartTrueIfAnyChildIsMultipartToView() @@ -524,7 +517,7 @@ class FormTypeTest extends TypeTestCase $form->add($this->factory->create('file')); $view = $form->createView(); - $this->assertTrue($view->get('multipart')); + $this->assertTrue($view->getVar('multipart')); } public function testCreateViewDoNoMarkItAsRendered() @@ -536,32 +529,32 @@ class FormTypeTest extends TypeTestCase $this->assertFalse($view->isRendered()); } - public function testErrorBubblingIfNoSingleControl() + public function testErrorBubblingIfCompound() { $form = $this->factory->create('form', null, array( - 'single_control' => false, + 'compound' => true, )); - $this->assertTrue($form->getErrorBubbling()); + $this->assertTrue($form->getConfig()->getErrorBubbling()); } - public function testNoErrorBubblingIfSingleControl() + public function testNoErrorBubblingIfNotCompound() { $form = $this->factory->create('form', null, array( - 'single_control' => true, + 'compound' => false, )); - $this->assertFalse($form->getErrorBubbling()); + $this->assertFalse($form->getConfig()->getErrorBubbling()); } public function testOverrideErrorBubbling() { $form = $this->factory->create('form', null, array( - 'single_control' => true, + 'compound' => false, 'error_bubbling' => true, )); - $this->assertTrue($form->getErrorBubbling()); + $this->assertTrue($form->getConfig()->getErrorBubbling()); } public function testPropertyPath() @@ -576,7 +569,7 @@ class FormTypeTest extends TypeTestCase public function testPropertyPathNullImpliesDefault() { - $form = $this->factory->createNamed('form', 'name', null, array( + $form = $this->factory->createNamed('name', 'form', null, array( 'property_path' => null, )); @@ -587,7 +580,7 @@ class FormTypeTest extends TypeTestCase // BC public function testPropertyPathFalseImpliesDefaultNotMapped() { - $form = $this->factory->createNamed('form', 'name', null, array( + $form = $this->factory->createNamed('name', 'form', null, array( 'property_path' => false, )); @@ -610,7 +603,7 @@ class FormTypeTest extends TypeTestCase { $form = $this->factory->create('form'); $view = $form->createView(); - $this->assertTrue($view->get('valid')); + $this->assertTrue($view->getVar('valid')); } public function testViewNotValidBound() @@ -619,6 +612,6 @@ class FormTypeTest extends TypeTestCase $form->bind(array()); $form->addError(new FormError('An error')); $view = $form->createView(); - $this->assertFalse($view->get('valid')); + $this->assertFalse($view->getVar('valid')); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php index 705d4d104a..435749a16b 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php @@ -20,6 +20,6 @@ class IntegerTypeTest extends LocalizedTestCase $form->bind('1.678'); $this->assertSame(1, $form->getData()); - $this->assertSame('1', $form->getClientData()); + $this->assertSame('1', $form->getViewData()); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php index df4822c72e..53417086b8 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php @@ -21,8 +21,7 @@ class LanguageTypeTest extends LocalizedTestCase $form = $this->factory->create('language'); $view = $form->createView(); - $choices = $view->get('choices'); - $labels = $view->get('choice_labels'); + $choices = $view->getVar('choices'); $this->assertContains(new ChoiceView('en', 'Englisch'), $choices, '', false, false); $this->assertContains(new ChoiceView('en_GB', 'Britisches Englisch'), $choices, '', false, false); @@ -35,7 +34,7 @@ class LanguageTypeTest extends LocalizedTestCase { $form = $this->factory->create('language', 'language'); $view = $form->createView(); - $choices = $view->get('choices'); + $choices = $view->getVar('choices'); $this->assertNotContains(new ChoiceView('mul', 'Mehrsprachig'), $choices, '', false, false); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php index 23a28b25e3..2e523a5df1 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php @@ -21,7 +21,7 @@ class LocaleTypeTest extends LocalizedTestCase $form = $this->factory->create('locale'); $view = $form->createView(); - $choices = $view->get('choices'); + $choices = $view->getVar('choices'); $this->assertContains(new ChoiceView('en', 'Englisch'), $choices, '', false, false); $this->assertContains(new ChoiceView('en_GB', 'Englisch (Vereinigtes Königreich)'), $choices, '', false, false); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php index c4fd530bff..42f982642a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php @@ -20,7 +20,7 @@ class MoneyTypeTest extends LocalizedTestCase $form = $this->factory->create('money'); $view = $form->createView(); - $this->assertSame('{{ widget }} €', $view->get('money_pattern')); + $this->assertSame('{{ widget }} €', $view->getVar('money_pattern')); } public function testMoneyPatternWorksForYen() @@ -29,6 +29,6 @@ class MoneyTypeTest extends LocalizedTestCase $form = $this->factory->create('money', null, array('currency' => 'JPY')); $view = $form->createView(); - $this->assertTrue((Boolean) strstr($view->get('money_pattern'), '¥')); + $this->assertTrue((Boolean) strstr($view->getVar('money_pattern'), '¥')); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php index 7372752766..ab3f56155c 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php @@ -26,7 +26,7 @@ class NumberTypeTest extends LocalizedTestCase $form->setData('12345.67890'); $view = $form->createView(); - $this->assertSame('12345,679', $view->get('value')); + $this->assertSame('12345,679', $view->getVar('value')); } public function testDefaultFormattingWithGrouping() @@ -35,7 +35,7 @@ class NumberTypeTest extends LocalizedTestCase $form->setData('12345.67890'); $view = $form->createView(); - $this->assertSame('12.345,679', $view->get('value')); + $this->assertSame('12.345,679', $view->getVar('value')); } public function testDefaultFormattingWithPrecision() @@ -44,7 +44,7 @@ class NumberTypeTest extends LocalizedTestCase $form->setData('12345.67890'); $view = $form->createView(); - $this->assertSame('12345,68', $view->get('value')); + $this->assertSame('12345,68', $view->getVar('value')); } public function testDefaultFormattingWithRounding() @@ -53,6 +53,6 @@ class NumberTypeTest extends LocalizedTestCase $form->setData('12345.54321'); $view = $form->createView(); - $this->assertSame('12346', $view->get('value')); + $this->assertSame('12346', $view->getVar('value')); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php index cf38ba9305..7abe8f7d28 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php @@ -20,7 +20,7 @@ class PasswordTypeTest extends TypeTestCase $form->setData('pAs5w0rd'); $view = $form->createView(); - $this->assertSame('', $view->get('value')); + $this->assertSame('', $view->getVar('value')); } public function testEmptyIfBound() @@ -29,7 +29,7 @@ class PasswordTypeTest extends TypeTestCase $form->bind('pAs5w0rd'); $view = $form->createView(); - $this->assertSame('', $view->get('value')); + $this->assertSame('', $view->getVar('value')); } public function testNotEmptyIfBoundAndNotAlwaysEmpty() @@ -38,6 +38,6 @@ class PasswordTypeTest extends TypeTestCase $form->bind('pAs5w0rd'); $view = $form->createView(); - $this->assertSame('pAs5w0rd', $view->get('value')); + $this->assertSame('pAs5w0rd', $view->getVar('value')); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php index 6d9139633e..b324a49150 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php @@ -41,8 +41,8 @@ class RepeatedTypeTest extends TypeTestCase 'options' => array('label' => 'Global'), )); - $this->assertEquals('Global', $form['first']->getAttribute('label')); - $this->assertEquals('Global', $form['second']->getAttribute('label')); + $this->assertEquals('Global', $form['first']->getConfig()->getOption('label')); + $this->assertEquals('Global', $form['second']->getConfig()->getOption('label')); $this->assertTrue($form['first']->isRequired()); $this->assertTrue($form['second']->isRequired()); } @@ -56,8 +56,8 @@ class RepeatedTypeTest extends TypeTestCase 'second_options' => array('label' => 'Test2') )); - $this->assertEquals('Test', $form['first']->getAttribute('label')); - $this->assertEquals('Test2', $form['second']->getAttribute('label')); + $this->assertEquals('Test', $form['first']->getConfig()->getOption('label')); + $this->assertEquals('Test2', $form['second']->getConfig()->getOption('label')); $this->assertTrue($form['first']->isRequired()); $this->assertTrue($form['second']->isRequired()); } @@ -81,8 +81,8 @@ class RepeatedTypeTest extends TypeTestCase 'second_options' => array('label' => 'Second label') )); - $this->assertEquals('Label', $form['first']->getAttribute('label')); - $this->assertEquals('Second label', $form['second']->getAttribute('label')); + $this->assertEquals('Label', $form['first']->getConfig()->getOption('label')); + $this->assertEquals('Second label', $form['second']->getConfig()->getOption('label')); $this->assertTrue($form['first']->isRequired()); $this->assertTrue($form['second']->isRequired()); } @@ -93,10 +93,10 @@ class RepeatedTypeTest extends TypeTestCase $this->form->bind($input); - $this->assertEquals('foo', $this->form['first']->getClientData()); - $this->assertEquals('bar', $this->form['second']->getClientData()); + $this->assertEquals('foo', $this->form['first']->getViewData()); + $this->assertEquals('bar', $this->form['second']->getViewData()); $this->assertFalse($this->form->isSynchronized()); - $this->assertEquals($input, $this->form->getClientData()); + $this->assertEquals($input, $this->form->getViewData()); $this->assertNull($this->form->getData()); } @@ -106,10 +106,10 @@ class RepeatedTypeTest extends TypeTestCase $this->form->bind($input); - $this->assertEquals('foo', $this->form['first']->getClientData()); - $this->assertEquals('foo', $this->form['second']->getClientData()); + $this->assertEquals('foo', $this->form['first']->getViewData()); + $this->assertEquals('foo', $this->form['second']->getViewData()); $this->assertTrue($this->form->isSynchronized()); - $this->assertEquals($input, $this->form->getClientData()); + $this->assertEquals($input, $this->form->getViewData()); $this->assertEquals('foo', $this->form->getData()); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php index a686cc3bc3..1342535ede 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php @@ -33,7 +33,7 @@ class TimeTypeTest extends LocalizedTestCase $dateTime = new \DateTime('1970-01-01 03:04:00 UTC'); $this->assertEquals($dateTime, $form->getData()); - $this->assertEquals($input, $form->getClientData()); + $this->assertEquals($input, $form->getViewData()); } public function testSubmit_string() @@ -52,7 +52,7 @@ class TimeTypeTest extends LocalizedTestCase $form->bind($input); $this->assertEquals('03:04:00', $form->getData()); - $this->assertEquals($input, $form->getClientData()); + $this->assertEquals($input, $form->getViewData()); } public function testSubmit_timestamp() @@ -73,7 +73,7 @@ class TimeTypeTest extends LocalizedTestCase $dateTime = new \DateTime('1970-01-01 03:04:00 UTC'); $this->assertEquals($dateTime->format('U'), $form->getData()); - $this->assertEquals($input, $form->getClientData()); + $this->assertEquals($input, $form->getViewData()); } public function testSubmit_array() @@ -92,7 +92,7 @@ class TimeTypeTest extends LocalizedTestCase $form->bind($input); $this->assertEquals($input, $form->getData()); - $this->assertEquals($input, $form->getClientData()); + $this->assertEquals($input, $form->getViewData()); } public function testSubmit_datetimeSingleText() @@ -107,7 +107,7 @@ class TimeTypeTest extends LocalizedTestCase $form->bind('03:04:05'); $this->assertEquals(new \DateTime('03:04:00 UTC'), $form->getData()); - $this->assertEquals('03:04', $form->getClientData()); + $this->assertEquals('03:04', $form->getViewData()); } public function testSubmit_arraySingleText() @@ -127,7 +127,7 @@ class TimeTypeTest extends LocalizedTestCase $form->bind('03:04'); $this->assertEquals($data, $form->getData()); - $this->assertEquals('03:04', $form->getClientData()); + $this->assertEquals('03:04', $form->getViewData()); } public function testSubmit_arraySingleTextWithSeconds() @@ -149,7 +149,7 @@ class TimeTypeTest extends LocalizedTestCase $form->bind('03:04:05'); $this->assertEquals($data, $form->getData()); - $this->assertEquals('03:04:05', $form->getClientData()); + $this->assertEquals('03:04:05', $form->getViewData()); } public function testSubmit_stringSingleText() @@ -164,7 +164,7 @@ class TimeTypeTest extends LocalizedTestCase $form->bind('03:04:05'); $this->assertEquals('03:04:00', $form->getData()); - $this->assertEquals('03:04', $form->getClientData()); + $this->assertEquals('03:04', $form->getViewData()); } public function testSetData_withSeconds() @@ -178,7 +178,7 @@ class TimeTypeTest extends LocalizedTestCase $form->setData(new \DateTime('03:04:05 UTC')); - $this->assertEquals(array('hour' => 3, 'minute' => 4, 'second' => 5), $form->getClientData()); + $this->assertEquals(array('hour' => 3, 'minute' => 4, 'second' => 5), $form->getViewData()); } public function testSetData_differentTimezones() @@ -204,7 +204,7 @@ class TimeTypeTest extends LocalizedTestCase 'second' => (int)$outputTime->format('s') ); - $this->assertEquals($displayedData, $form->getClientData()); + $this->assertEquals($displayedData, $form->getViewData()); } public function testSetData_differentTimezonesDateTime() @@ -231,7 +231,7 @@ class TimeTypeTest extends LocalizedTestCase ); $this->assertDateTimeEquals($dateTime, $form->getData()); - $this->assertEquals($displayedData, $form->getClientData()); + $this->assertEquals($displayedData, $form->getViewData()); } public function testHoursOption() @@ -245,7 +245,7 @@ class TimeTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('6', '06'), new ChoiceView('7', '07'), - ), $view->getChild('hour')->get('choices')); + ), $view->get('hour')->getVar('choices')); } public function testIsMinuteWithinRange_returnsTrueIfWithin() @@ -259,7 +259,7 @@ class TimeTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('6', '06'), new ChoiceView('7', '07'), - ), $view->getChild('minute')->get('choices')); + ), $view->get('minute')->getVar('choices')); } public function testIsSecondWithinRange_returnsTrueIfWithin() @@ -274,7 +274,7 @@ class TimeTypeTest extends LocalizedTestCase $this->assertEquals(array( new ChoiceView('6', '06'), new ChoiceView('7', '07'), - ), $view->getChild('second')->get('choices')); + ), $view->get('second')->getVar('choices')); } public function testIsPartiallyFilled_returnsFalseIfCompletelyEmpty() @@ -414,6 +414,6 @@ class TimeTypeTest extends LocalizedTestCase )); $view = $form->createView(); - $this->assertEquals('time', $view->get('type')); + $this->assertEquals('time', $view->getVar('type')); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php index 8bbbad5dce..2550303e65 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php @@ -19,8 +19,7 @@ class TimezoneTypeTest extends TypeTestCase { $form = $this->factory->create('timezone'); $view = $form->createView(); - $choices = $view->get('choices'); - $labels = $view->get('choice_labels'); + $choices = $view->getVar('choices'); $this->assertArrayHasKey('Africa', $choices); $this->assertContains(new ChoiceView('Africa/Kinshasa', 'Kinshasa'), $choices['Africa'], '', false, false); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php index 28730d5a44..a2b107f90c 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php @@ -20,7 +20,7 @@ class UrlTypeTest extends LocalizedTestCase $form->bind('www.domain.com'); $this->assertSame('http://www.domain.com', $form->getData()); - $this->assertSame('http://www.domain.com', $form->getClientData()); + $this->assertSame('http://www.domain.com', $form->getViewData()); } public function testSubmitAddsNoDefaultProtocolIfAlreadyIncluded() @@ -32,7 +32,7 @@ class UrlTypeTest extends LocalizedTestCase $form->bind('ftp://www.domain.com'); $this->assertSame('ftp://www.domain.com', $form->getData()); - $this->assertSame('ftp://www.domain.com', $form->getClientData()); + $this->assertSame('ftp://www.domain.com', $form->getViewData()); } public function testSubmitAddsNoDefaultProtocolIfEmpty() @@ -44,7 +44,7 @@ class UrlTypeTest extends LocalizedTestCase $form->bind(''); $this->assertSame('', $form->getData()); - $this->assertSame('', $form->getClientData()); + $this->assertSame('', $form->getViewData()); } public function testSubmitAddsNoDefaultProtocolIfSetToNull() @@ -56,6 +56,6 @@ class UrlTypeTest extends LocalizedTestCase $form->bind('www.domain.com'); $this->assertSame('www.domain.com', $form->getData()); - $this->assertSame('www.domain.com', $form->getClientData()); + $this->assertSame('www.domain.com', $form->getViewData()); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php index 0fdea7d438..8470d20753 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php @@ -12,13 +12,13 @@ namespace Symfony\Component\Form\Tests\Extension\Csrf\Type; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Csrf\CsrfExtension; use Symfony\Component\Form\Tests\Extension\Core\Type\TypeTestCase; class FormTypeCsrfExtensionTest_ChildType extends AbstractType { - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { // The form needs a child in order to trigger CSRF protection by // default @@ -56,45 +56,45 @@ class FormTypeCsrfExtensionTest extends TypeTestCase )); } - public function testCsrfProtectionByDefaultIfRootAndNotSingleControl() + public function testCsrfProtectionByDefaultIfRootAndCompound() { $view = $this->factory ->create('form', null, array( 'csrf_field_name' => 'csrf', - 'single_control' => false, + 'compound' => true, )) ->createView(); - $this->assertTrue($view->hasChild('csrf')); + $this->assertTrue($view->has('csrf')); } - public function testNoCsrfProtectionByDefaultIfNotSingleControlButNotRoot() + public function testNoCsrfProtectionByDefaultIfCompoundButNotRoot() { $view = $this->factory - ->createNamedBuilder('form', 'root') + ->createNamedBuilder('root', 'form') ->add($this->factory ->createNamedBuilder('form', 'form', null, array( 'csrf_field_name' => 'csrf', - 'single_control' => false, + 'compound' => true, )) ) ->getForm() ->createView() - ->getChild('form'); + ->get('form'); - $this->assertFalse($view->hasChild('csrf')); + $this->assertFalse($view->has('csrf')); } - public function testNoCsrfProtectionByDefaultIfRootButSingleControl() + public function testNoCsrfProtectionByDefaultIfRootButNotCompound() { $view = $this->factory ->create('form', null, array( 'csrf_field_name' => 'csrf', - 'single_control' => true, + 'compound' => false, )) ->createView(); - $this->assertFalse($view->hasChild('csrf')); + $this->assertFalse($view->has('csrf')); } public function testCsrfProtectionCanBeDisabled() @@ -103,11 +103,11 @@ class FormTypeCsrfExtensionTest extends TypeTestCase ->create('form', null, array( 'csrf_field_name' => 'csrf', 'csrf_protection' => false, - 'single_control' => false, + 'compound' => true, )) ->createView(); - $this->assertFalse($view->hasChild('csrf')); + $this->assertFalse($view->has('csrf')); } public function testGenerateCsrfToken() @@ -122,11 +122,11 @@ class FormTypeCsrfExtensionTest extends TypeTestCase 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'single_control' => false, + 'compound' => true, )) ->createView(); - $this->assertEquals('token', $view->getChild('csrf')->get('value')); + $this->assertEquals('token', $view->get('csrf')->getVar('value')); } public function provideBoolean() @@ -140,7 +140,7 @@ class FormTypeCsrfExtensionTest extends TypeTestCase /** * @dataProvider provideBoolean */ - public function testValidateTokenOnBindIfRootAndNotSingleControl($valid) + public function testValidateTokenOnBindIfRootAndCompound($valid) { $this->csrfProvider->expects($this->once()) ->method('isCsrfTokenValid') @@ -152,7 +152,7 @@ class FormTypeCsrfExtensionTest extends TypeTestCase 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'single_control' => false, + 'compound' => true, )); $form->bind(array( @@ -167,7 +167,7 @@ class FormTypeCsrfExtensionTest extends TypeTestCase $this->assertSame($valid, $form->isValid()); } - public function testFailIfRootAndNotSingleControlAndTokenMissing() + public function testFailIfRootAndCompoundAndTokenMissing() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); @@ -177,7 +177,7 @@ class FormTypeCsrfExtensionTest extends TypeTestCase 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'single_control' => false, + 'compound' => true, )); $form->bind(array( @@ -192,19 +192,19 @@ class FormTypeCsrfExtensionTest extends TypeTestCase $this->assertFalse($form->isValid()); } - public function testDontValidateTokenIfNotSingleControlButNoRoot() + public function testDontValidateTokenIfCompoundButNoRoot() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); $form = $this->factory - ->createNamedBuilder('form', 'root') + ->createNamedBuilder('root', 'form') ->add($this->factory ->createNamedBuilder('form', 'form', null, array( 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'single_control' => false, + 'compound' => true, )) ) ->getForm() @@ -216,7 +216,7 @@ class FormTypeCsrfExtensionTest extends TypeTestCase )); } - public function testDontValidateTokenIfRootButSingleControl() + public function testDontValidateTokenIfRootButNotCompound() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); @@ -226,7 +226,7 @@ class FormTypeCsrfExtensionTest extends TypeTestCase 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'single_control' => true, + 'compound' => false, )); $form->bind(array( @@ -246,9 +246,9 @@ class FormTypeCsrfExtensionTest extends TypeTestCase 'allow_add' => true, )) ->createView() - ->get('prototype'); + ->getVar('prototype'); - $this->assertFalse($prototypeView->hasChild('csrf')); + $this->assertFalse($prototypeView->has('csrf')); $this->assertCount(1, $prototypeView); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php index 209ebdf66d..9a545c129d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -55,7 +55,10 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); $this->factory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); - $this->serverParams = $this->getMock('Symfony\Component\Form\Extension\Validator\Util\ServerParams'); + $this->serverParams = $this->getMock( + 'Symfony\Component\Form\Extension\Validator\Util\ServerParams', + array('getNormalizedIniPostMaxSize', 'getContentLength') + ); $this->validator = new FormValidator($this->serverParams); } @@ -64,8 +67,8 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $context = $this->getExecutionContext(); $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', array('group1', 'group2')) + $options = array('validation_groups' => array('group1', 'group2')); + $form = $this->getBuilder('name', '\stdClass', $options) ->setData($object) ->getForm(); @@ -88,9 +91,11 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $constraint1 = $this->getMock('Symfony\Component\Validator\Constraint'); $constraint2 = $this->getMock('Symfony\Component\Validator\Constraint'); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', array('group1', 'group2')) - ->setAttribute('constraints', array($constraint1, $constraint2)) + $options = array( + 'validation_groups' => array('group1', 'group2'), + 'constraints' => array($constraint1, $constraint2), + ); + $form = $this->getBuilder('name', '\stdClass', $options) ->setData($object) ->getForm(); @@ -126,12 +131,9 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); - $parent = $this->getBuilder() - ->setAttribute('cascade_validation', false) - ->getForm(); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', array('group1', 'group2')) - ->getForm(); + $parent = $this->getBuilder('parent', null, array('cascade_validation' => false))->getForm(); + $options = array('validation_groups' => array('group1', 'group2')); + $form = $this->getBuilder('name', '\stdClass', $options)->getForm(); $parent->add($form); $form->setData($object); @@ -151,12 +153,12 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $constraint1 = $this->getMock('Symfony\Component\Validator\Constraint'); $constraint2 = $this->getMock('Symfony\Component\Validator\Constraint'); - $parent = $this->getBuilder() - ->setAttribute('cascade_validation', false) - ->getForm(); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', array('group1', 'group2')) - ->setAttribute('constraints', array($constraint1, $constraint2)) + $parent = $this->getBuilder('parent', null, array('cascade_validation' => false))->getForm(); + $options = array( + 'validation_groups' => array('group1', 'group2'), + 'constraints' => array($constraint1, $constraint2), + ); + $form = $this->getBuilder('name', '\stdClass', $options) ->setData($object) ->getForm(); $parent->add($form); @@ -184,10 +186,9 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); - $form = $this->getBuilder('name', '\stdClass') + $form = $this->getBuilder('name', '\stdClass', array('invalid_message' => 'Invalid!')) ->setData($object) - ->setAttribute('invalid_message', 'Invalid!') - ->appendClientTransformer(new CallbackTransformer( + ->addViewTransformer(new CallbackTransformer( function ($data) { return $data; }, function () { throw new TransformationFailedException(); } )) @@ -214,11 +215,13 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $constraint1 = $this->getMock('Symfony\Component\Validator\Constraint'); $constraint2 = $this->getMock('Symfony\Component\Validator\Constraint'); - $form = $this->getBuilder('name', '\stdClass') + $options = array( + 'validation_groups' => array('group1', 'group2'), + 'constraints' => array($constraint1, $constraint2), + ); + $form = $this->getBuilder('name', '\stdClass', $options) ->setData($object) - ->setAttribute('validation_groups', array('group1', 'group2')) - ->setAttribute('constraints', array($constraint1, $constraint2)) - ->appendClientTransformer(new CallbackTransformer( + ->addViewTransformer(new CallbackTransformer( function ($data) { return $data; }, function () { throw new TransformationFailedException(); } )) @@ -239,8 +242,8 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $context = $this->getExecutionContext(); $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', array($this, 'getValidationGroups')) + $options = array('validation_groups' => array($this, 'getValidationGroups')); + $form = $this->getBuilder('name', '\stdClass', $options) ->setData($object) ->getForm(); @@ -260,10 +263,10 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $context = $this->getExecutionContext(); $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', function(FormInterface $form){ - return array('group1', 'group2'); - }) + $options = array('validation_groups' => function(FormInterface $form){ + return array('group1', 'group2'); + }); + $form = $this->getBuilder('name', '\stdClass', $options) ->setData($object) ->getForm(); @@ -284,13 +287,12 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); - $parent = $this->getBuilder() - ->setAttribute('validation_groups', 'group') - ->setAttribute('cascade_validation', true) - ->getForm(); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', null) - ->getForm(); + $parentOptions = array( + 'validation_groups' => 'group', + 'cascade_validation' => true, + ); + $parent = $this->getBuilder('parent', null, $parentOptions)->getForm(); + $form = $this->getBuilder('name', '\stdClass')->getForm(); $parent->add($form); $form->setData($object); @@ -309,13 +311,12 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); - $parent = $this->getBuilder() - ->setAttribute('validation_groups', array($this, 'getValidationGroups')) - ->setAttribute('cascade_validation', true) - ->getForm(); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', null) - ->getForm(); + $parentOptions = array( + 'validation_groups' => array($this, 'getValidationGroups'), + 'cascade_validation' => true, + ); + $parent = $this->getBuilder('parent', null, $parentOptions)->getForm(); + $form = $this->getBuilder('name', '\stdClass')->getForm(); $parent->add($form); $form->setData($object); @@ -337,15 +338,14 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); - $parent = $this->getBuilder() - ->setAttribute('validation_groups', function(FormInterface $form){ + $parentOptions = array( + 'validation_groups' => function(FormInterface $form){ return array('group1', 'group2'); - }) - ->setAttribute('cascade_validation', true) - ->getForm(); - $form = $this->getBuilder('name', '\stdClass') - ->setAttribute('validation_groups', null) - ->getForm(); + }, + 'cascade_validation' => true, + ); + $parent = $this->getBuilder('parent', null, $parentOptions)->getForm(); + $form = $this->getBuilder('name', '\stdClass')->getForm(); $parent->add($form); $form->setData($object); @@ -398,9 +398,8 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase { $context = $this->getExecutionContext(); - $form = $this->getBuilder() + $form = $this->getBuilder('parent', null, array('extra_fields_message' => 'Extra!')) ->add($this->getBuilder('child')) - ->setAttribute('extra_fields_message', 'Extra!') ->getForm(); $form->bind(array('foo' => 'bar')); @@ -412,152 +411,53 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $this->assertEquals('Extra!', $context->getViolations()->get(0)->getMessage()); } - public function testViolationIfPostMaxSizeExceeded_GigaUpper() + + /** + * @dataProvider getPostMaxSizeFixtures + */ + public function testPostMaxSizeViolation($contentLength, $iniMax, $nbViolation, $msg) { - $this->serverParams->expects($this->any()) + $this->serverParams->expects($this->once()) ->method('getContentLength') - ->will($this->returnValue(pow(1024, 3) + 1)); + ->will($this->returnValue($contentLength)); $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1G')); + ->method('getNormalizedIniPostMaxSize') + ->will($this->returnValue($iniMax)); $context = $this->getExecutionContext(); - $form = $this->getBuilder() - ->setAttribute('post_max_size_message', 'Max {{ max }}!') - ->getForm(); + $options = array('post_max_size_message' => 'Max {{ max }}!'); + $form = $this->getBuilder('name', null, $options)->getForm(); $this->validator->initialize($context); $this->validator->validate($form, new Form()); - $this->assertCount(1, $context->getViolations()); - $this->assertEquals('Max 1G!', $context->getViolations()->get(0)->getMessage()); + $this->assertCount($nbViolation, $context->getViolations()); + if (null !== $msg) { + $this->assertEquals($msg, $context->getViolations()->get(0)->getMessage()); + } } - public function testViolationIfPostMaxSizeExceeded_GigaLower() + public function getPostMaxSizeFixtures() { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(pow(1024, 3) + 1)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1g')); - - $context = $this->getExecutionContext(); - $form = $this->getBuilder() - ->setAttribute('post_max_size_message', 'Max {{ max }}!') - ->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(1, $context->getViolations()); - $this->assertEquals('Max 1G!', $context->getViolations()->get(0)->getMessage()); - } - - public function testNoViolationIfPostMaxSizeNotExceeded_Giga() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(pow(1024, 3))); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1G')); - - $context = $this->getExecutionContext(); - $form = $this->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(0, $context->getViolations()); - } - - public function testViolationIfPostMaxSizeExceeded_Mega() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(pow(1024, 2) + 1)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1M')); - - $context = $this->getExecutionContext(); - $form = $this->getBuilder() - ->setAttribute('post_max_size_message', 'Max {{ max }}!') - ->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(1, $context->getViolations()); - $this->assertEquals('Max 1M!', $context->getViolations()->get(0)->getMessage()); - } - - public function testNoViolationIfPostMaxSizeNotExceeded_Mega() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(pow(1024, 2))); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1M')); - - $context = $this->getExecutionContext(); - $form = $this->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(0, $context->getViolations()); - } - - public function testViolationIfPostMaxSizeExceeded_Kilo() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(1025)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1K')); - - $context = $this->getExecutionContext(); - $form = $this->getBuilder() - ->setAttribute('post_max_size_message', 'Max {{ max }}!') - ->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(1, $context->getViolations()); - $this->assertEquals('Max 1K!', $context->getViolations()->get(0)->getMessage()); - } - - public function testNoViolationIfPostMaxSizeNotExceeded_Kilo() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(1024)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1K')); - - $context = $this->getExecutionContext(); - $form = $this->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(0, $context->getViolations()); + return array( + array(pow(1024, 3) + 1, '1G', 1, 'Max 1G!'), + array(pow(1024, 3), '1G', 0, null), + array(pow(1024, 2) + 1, '1M', 1, 'Max 1M!'), + array(pow(1024, 2), '1M', 0, null), + array(1024 + 1, '1K', 1, 'Max 1K!'), + array(1024, '1K', 0, null), + array(null, '1K', 0, null), + array(1024, '', 0, null), + ); } public function testNoViolationIfNotRoot() { - $this->serverParams->expects($this->any()) + $this->serverParams->expects($this->once()) ->method('getContentLength') ->will($this->returnValue(1025)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1K')); + $this->serverParams->expects($this->never()) + ->method('getNormalizedIniPostMaxSize'); $context = $this->getExecutionContext(); $parent = $this->getForm(); @@ -570,81 +470,6 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase $this->assertCount(0, $context->getViolations()); } - public function testNoViolationIfContentLengthNull() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(null)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue('1K')); - - $context = $this->getExecutionContext(); - $form = $this->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(0, $context->getViolations()); - } - - public function testTrimPostMaxSize() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(1025)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue(' 1K ')); - - $context = $this->getExecutionContext(); - $form = $this->getBuilder() - ->setAttribute('post_max_size_message', 'Max {{ max }}!') - ->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(1, $context->getViolations()); - $this->assertEquals('Max 1K!', $context->getViolations()->get(0)->getMessage()); - } - - public function testNoViolationIfPostMaxSizeEmpty() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(1025)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue(' ')); - - $context = $this->getExecutionContext(); - $form = $this->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(0, $context->getViolations()); - } - - public function testNoViolationIfPostMaxSizeNull() - { - $this->serverParams->expects($this->any()) - ->method('getContentLength') - ->will($this->returnValue(1025)); - $this->serverParams->expects($this->any()) - ->method('getPostMaxSize') - ->will($this->returnValue(null)); - - $context = $this->getExecutionContext(); - $form = $this->getForm(); - - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(0, $context->getViolations()); - } - /** * Access has to be public, as this method is called via callback array * in {@link testValidateFormDataCanHandleCallbackValidationGroups()} @@ -679,12 +504,13 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase /** * @return FormBuilder */ - private function getBuilder($name = 'name', $dataClass = null) + private function getBuilder($name = 'name', $dataClass = null, array $options = array()) { - $builder = new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory); - $builder->setAttribute('constraints', array()); + $options = array_replace(array( + 'constraints' => array(), + ), $options); - return $builder; + return new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory, $options); } private function getForm($name = 'name', $dataClass = null) diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php index 5cd0ea753b..13faefe956 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php @@ -19,16 +19,16 @@ class FormTypeValidatorExtensionTest extends TypeTestCase { $form = $this->factory->create('form'); - $this->assertNull($form->getAttribute('validation_groups')); + $this->assertNull($form->getConfig()->getOption('validation_groups')); } - public function testValidationGroupsCanBeSetToString() + public function testValidationGroupsTransformedToArray() { $form = $this->factory->create('form', null, array( 'validation_groups' => 'group', )); - $this->assertEquals(array('group'), $form->getAttribute('validation_groups')); + $this->assertEquals(array('group'), $form->getConfig()->getOption('validation_groups')); } public function testValidationGroupsCanBeSetToArray() @@ -37,7 +37,7 @@ class FormTypeValidatorExtensionTest extends TypeTestCase 'validation_groups' => array('group1', 'group2'), )); - $this->assertEquals(array('group1', 'group2'), $form->getAttribute('validation_groups')); + $this->assertEquals(array('group1', 'group2'), $form->getConfig()->getOption('validation_groups')); } public function testValidationGroupsCanBeSetToCallback() @@ -46,7 +46,7 @@ class FormTypeValidatorExtensionTest extends TypeTestCase 'validation_groups' => array($this, 'testValidationGroupsCanBeSetToCallback'), )); - $this->assertTrue(is_callable($form->getAttribute('validation_groups'))); + $this->assertTrue(is_callable($form->getConfig()->getOption('validation_groups'))); } public function testValidationGroupsCanBeSetToClosure() @@ -55,7 +55,7 @@ class FormTypeValidatorExtensionTest extends TypeTestCase 'validation_groups' => function(FormInterface $form){ return null; }, )); - $this->assertTrue(is_callable($form->getAttribute('validation_groups'))); + $this->assertTrue(is_callable($form->getConfig()->getOption('validation_groups'))); } public function testBindValidatesData() diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php index 068dfb0a88..252b23c9c5 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php @@ -75,7 +75,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase $config->setAttribute('error_mapping', $errorMapping); if (!$synchronized) { - $config->appendClientTransformer(new CallbackTransformer( + $config->addViewTransformer(new CallbackTransformer( function ($normData) { return $normData; }, function () { throw new TransformationFailedException(); } )); diff --git a/src/Symfony/Component/Form/Tests/Fixtures/AuthorType.php b/src/Symfony/Component/Form/Tests/Fixtures/AuthorType.php index 5d9ee35c65..147f6e4867 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/AuthorType.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/AuthorType.php @@ -3,11 +3,12 @@ namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; class AuthorType extends AbstractType { - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('firstName') @@ -20,10 +21,10 @@ class AuthorType extends AbstractType return 'author'; } - public function getDefaultOptions() + public function setDefaultOptions(OptionsResolverInterface $resolver) { - return array( + $resolver->setDefaults(array( 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', - ); + )); } } diff --git a/src/Symfony/Component/Form/Tests/Fixtures/FixedFilterListener.php b/src/Symfony/Component/Form/Tests/Fixtures/FixedFilterListener.php index 545d7283bd..60f9ffdfb6 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/FixedFilterListener.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/FixedFilterListener.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\Event\FilterDataEvent; +use Symfony\Component\Form\FormEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class FixedFilterListener implements EventSubscriberInterface @@ -22,45 +22,45 @@ class FixedFilterListener implements EventSubscriberInterface public function __construct(array $mapping) { $this->mapping = array_merge(array( - 'onBindClientData' => array(), - 'onBindNormData' => array(), - 'onSetData' => array(), + 'preBind' => array(), + 'onBind' => array(), + 'preSetData' => array(), ), $mapping); } - public function onBindClientData(FilterDataEvent $event) + public function preBind(FormEvent $event) { $data = $event->getData(); - if (isset($this->mapping['onBindClientData'][$data])) { - $event->setData($this->mapping['onBindClientData'][$data]); + if (isset($this->mapping['preBind'][$data])) { + $event->setData($this->mapping['preBind'][$data]); } } - public function onBindNormData(FilterDataEvent $event) + public function onBind(FormEvent $event) { $data = $event->getData(); - if (isset($this->mapping['onBindNormData'][$data])) { - $event->setData($this->mapping['onBindNormData'][$data]); + if (isset($this->mapping['onBind'][$data])) { + $event->setData($this->mapping['onBind'][$data]); } } - public function onSetData(FilterDataEvent $event) + public function preSetData(FormEvent $event) { $data = $event->getData(); - if (isset($this->mapping['onSetData'][$data])) { - $event->setData($this->mapping['onSetData'][$data]); + if (isset($this->mapping['preSetData'][$data])) { + $event->setData($this->mapping['preSetData'][$data]); } } public static function getSubscribedEvents() { return array( - FormEvents::BIND_CLIENT_DATA => 'onBindClientData', - FormEvents::BIND_NORM_DATA => 'onBindNormData', - FormEvents::SET_DATA => 'onSetData', + FormEvents::PRE_BIND => 'preBind', + FormEvents::BIND => 'onBind', + FormEvents::PRE_SET_DATA => 'preSetData', ); } } diff --git a/src/Symfony/Component/Form/Tests/Fixtures/FooType.php b/src/Symfony/Component/Form/Tests/Fixtures/FooType.php index 7c8b0dd964..feae68900f 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/FooType.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/FooType.php @@ -13,12 +13,13 @@ namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\EventDispatcher\EventDispatcher; class FooType extends AbstractType { - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder->setAttribute('foo', 'x'); $builder->setAttribute('data_option', $options['data']); @@ -51,7 +52,7 @@ class FooType extends AbstractType ); } - public function getParent(array $options) + public function getParent() { return null; } diff --git a/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBarExtension.php b/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBarExtension.php index 31f9293634..c5f92e1191 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBarExtension.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBarExtension.php @@ -12,11 +12,11 @@ namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\AbstractTypeExtension; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; class FooTypeBarExtension extends AbstractTypeExtension { - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder->setAttribute('bar', 'x'); } diff --git a/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBazExtension.php b/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBazExtension.php index 33d328639e..2e36475449 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBazExtension.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/FooTypeBazExtension.php @@ -12,11 +12,11 @@ namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\AbstractTypeExtension; -use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormBuilderInterface; class FooTypeBazExtension extends AbstractTypeExtension { - public function buildForm(FormBuilder $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { $builder->setAttribute('baz', 'x'); } diff --git a/src/Symfony/Component/Form/Tests/FormBuilderTest.php b/src/Symfony/Component/Form/Tests/FormBuilderTest.php index 68db15fd40..89ca355e08 100644 --- a/src/Symfony/Component/Form/Tests/FormBuilderTest.php +++ b/src/Symfony/Component/Form/Tests/FormBuilderTest.php @@ -82,7 +82,7 @@ class FormBuilderTest extends \PHPUnit_Framework_TestCase { $this->factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'foo') + ->with('foo', 'text') ->will($this->returnValue(new FormBuilder('foo', null, $this->dispatcher, $this->factory))); $this->assertCount(0, $this->builder->all()); @@ -120,7 +120,7 @@ class FormBuilderTest extends \PHPUnit_Framework_TestCase { $this->factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'foo', null, array()) + ->with('foo', 'text', null, array()) ; $builder = $this->builder->create('foo'); @@ -140,7 +140,7 @@ class FormBuilderTest extends \PHPUnit_Framework_TestCase $this->factory->expects($this->once()) ->method('createNamedBuilder') - ->with($expectedType, $expectedName, null, $expectedOptions) + ->with($expectedName, $expectedType, null, $expectedOptions) ->will($this->returnValue($this->getFormBuilder())); $this->builder->add($expectedName, $expectedType, $expectedOptions); @@ -192,7 +192,7 @@ class FormBuilderTest extends \PHPUnit_Framework_TestCase $this->factory ->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'bar', null, array(), $this->builder) + ->with('bar', 'text', null, array(), $this->builder) ; $this->factory diff --git a/src/Symfony/Component/Form/Tests/FormFactoryTest.php b/src/Symfony/Component/Form/Tests/FormFactoryTest.php index e4f59b751a..b3dd506495 100644 --- a/src/Symfony/Component/Form/Tests/FormFactoryTest.php +++ b/src/Symfony/Component/Form/Tests/FormFactoryTest.php @@ -118,7 +118,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type = new FooType(); $this->extension1->addType($type); - $builder = $this->factory->createNamedBuilder('foo', 'bar'); + $builder = $this->factory->createNamedBuilder('bar', 'foo'); $this->assertTrue($builder instanceof FormBuilder); $this->assertEquals('bar', $builder->getName()); @@ -135,7 +135,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $this->extension2->addTypeExtension($ext2); $this->extension2->addType($type); - $builder = $this->factory->createNamedBuilder('foo', 'bar'); + $builder = $this->factory->createNamedBuilder('bar', 'foo'); $this->assertTrue($builder->hasAttribute('foo')); $this->assertTrue($builder->hasAttribute('bar')); @@ -147,7 +147,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type = new FooType(); $this->extension1->addType($type); - $builder = $this->factory->createNamedBuilder('foo', 'bar', 'xyz'); + $builder = $this->factory->createNamedBuilder('bar', 'foo', 'xyz'); // see FooType::buildForm() $this->assertEquals('xyz', $builder->getAttribute('data_option')); @@ -158,7 +158,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type = new FooType(); $this->extension1->addType($type); - $builder = $this->factory->createNamedBuilder('foo', 'bar', 'xyz', array( + $builder = $this->factory->createNamedBuilder('bar', 'foo', 'xyz', array( 'data' => 'abc', )); @@ -178,19 +178,10 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type->expects($this->any()) ->method('getExtensions') ->will($this->returnValue(array())); - $type->expects($this->any()) - ->method('getAllowedOptionValues') - ->will($this->returnValue(array())); - $type->expects($this->any()) - ->method('getDefaultOptions') - ->will($this->returnValue(array( - 'required' => false, - 'max_length' => null, - ))); $this->extension1->addType($type); - $this->factory->createNamedBuilder('foo', 'bar'); + $this->factory->createNamedBuilder('bar', 'foo'); } /** @@ -205,19 +196,10 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type->expects($this->any()) ->method('getExtensions') ->will($this->returnValue(array())); - $type->expects($this->any()) - ->method('getAllowedOptionValues') - ->will($this->returnValue(array())); - $type->expects($this->any()) - ->method('getDefaultOptions') - ->will($this->returnValue(array( - 'data' => null, - 'max_length' => null, - ))); $this->extension1->addType($type); - $this->factory->createNamedBuilder('foo', 'bar'); + $this->factory->createNamedBuilder('bar', 'foo'); } /** @@ -232,19 +214,10 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type->expects($this->any()) ->method('getExtensions') ->will($this->returnValue(array())); - $type->expects($this->any()) - ->method('getAllowedOptionValues') - ->will($this->returnValue(array())); - $type->expects($this->any()) - ->method('getDefaultOptions') - ->will($this->returnValue(array( - 'data' => null, - 'required' => false, - ))); $this->extension1->addType($type); - $this->factory->createNamedBuilder('foo', 'bar'); + $this->factory->createNamedBuilder('bar', 'foo'); } /** @@ -259,23 +232,13 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type->expects($this->any()) ->method('getExtensions') ->will($this->returnValue(array())); - $type->expects($this->any()) - ->method('getAllowedOptionValues') - ->will($this->returnValue(array())); - $type->expects($this->any()) - ->method('getDefaultOptions') - ->will($this->returnValue(array( - 'data' => null, - 'required' => false, - 'max_length' => null, - ))); $type->expects($this->any()) ->method('createBuilder') ->will($this->returnValue(null)); $this->extension1->addType($type); - $this->factory->createNamedBuilder('foo', 'bar'); + $this->factory->createNamedBuilder('bar', 'foo'); } /** @@ -286,7 +249,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type = new FooType(); $this->extension1->addType($type); - $this->factory->createNamedBuilder('foo', 'bar', null, array( + $this->factory->createNamedBuilder('bar', 'foo', null, array( 'invalid' => 'xyz', )); } @@ -299,7 +262,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type = new FooType(); $this->extension1->addType($type); - $this->factory->createNamedBuilder('foo', 'bar', null, array( + $this->factory->createNamedBuilder('bar', 'foo', null, array( 'a_or_b' => 'c', )); } @@ -311,7 +274,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $this->extension1->addTypeExtension(new FooTypeBarExtension()); // no exception this time - $this->factory->createNamedBuilder('foo', 'bar', null, array( + $this->factory->createNamedBuilder('bar', 'foo', null, array( 'a_or_b' => 'c', )); } @@ -321,7 +284,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $type = new FooType(); $this->assertFalse($this->factory->hasType('foo')); - $builder = $this->factory->createNamedBuilder($type, 'bar'); + $builder = $this->factory->createNamedBuilder('bar', $type); $this->assertTrue($builder instanceof FormBuilder); $this->assertTrue($this->factory->hasType('foo')); @@ -333,7 +296,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase */ public function testCreateNamedBuilderThrowsUnderstandableException() { - $this->factory->createNamedBuilder(new \StdClass, 'name'); + $this->factory->createNamedBuilder('name', new \stdClass()); } public function testCreateUsesTypeNameAsName() @@ -370,7 +333,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $factory->expects($this->once()) ->method('createNamedBuilder') - ->with('password', 'firstName', null, array('max_length' => 7)) + ->with('firstName', 'password', null, array('max_length' => 7)) ->will($this->returnValue('builderInstance')); $builder = $factory->createBuilderForProperty('Application\Author', 'firstName'); @@ -389,7 +352,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'firstName') + ->with('firstName', 'text') ->will($this->returnValue('builderInstance')); $builder = $factory->createBuilderForProperty('Application\Author', 'firstName'); @@ -412,7 +375,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'firstName', null, array('max_length' => 11)) + ->with('firstName', 'text', null, array('max_length' => 11)) ->will($this->returnValue('builderInstance')); $builder = $factory->createBuilderForProperty( @@ -447,7 +410,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'firstName', null, array('max_length' => 20)) + ->with('firstName', 'text', null, array('max_length' => 20)) ->will($this->returnValue('builderInstance')); $builder = $factory->createBuilderForProperty( @@ -480,7 +443,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'firstName', null, array('pattern' => '.{5,}')) + ->with('firstName', 'text', null, array('pattern' => '.{5,}')) ->will($this->returnValue('builderInstance')); $builder = $factory->createBuilderForProperty( @@ -515,7 +478,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'firstName', null, array('pattern' => '.{5,10}')) + ->with('firstName', 'text', null, array('pattern' => '.{5,10}')) ->will($this->returnValue('builderInstance')); $builder = $factory->createBuilderForProperty( @@ -548,7 +511,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'firstName', null, array('required' => false)) + ->with('firstName', 'text', null, array('required' => false)) ->will($this->returnValue('builderInstance')); $builder = $factory->createBuilderForProperty( @@ -581,7 +544,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase $factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'firstName', null, array('pattern' => '/[a-zA-Z]/')) + ->with('firstName', 'text', null, array('pattern' => '/[a-zA-Z]/')) ->will($this->returnValue('builderInstance')); $builder = $factory->createBuilderForProperty( @@ -602,7 +565,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase ->getMock() ; - $builder = $this->factory->createNamedBuilder('foo', 'bar', null, array(), $parentBuilder); + $builder = $this->factory->createNamedBuilder('bar', 'foo', null, array(), $parentBuilder); $this->assertNotEquals($builder, $builder->getParent()); $this->assertEquals($parentBuilder, $builder->getParent()); @@ -612,7 +575,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase { $factory = new FormFactory(array(new \Symfony\Component\Form\Extension\Core\CoreExtension())); - $form = $factory->createNamedBuilder(new AuthorType(), 'author')->getForm(); + $form = $factory->createNamedBuilder('author', new AuthorType())->getForm(); $form->bind(array('firstName' => 'John', 'lastName' => 'Smith')); $author = new Author(); diff --git a/src/Symfony/Component/Form/Tests/FormTest.php b/src/Symfony/Component/Form/Tests/FormTest.php index e0188d9085..63dc7c5a6b 100644 --- a/src/Symfony/Component/Form/Tests/FormTest.php +++ b/src/Symfony/Component/Form/Tests/FormTest.php @@ -55,21 +55,21 @@ class FormTest extends \PHPUnit_Framework_TestCase public function testDataIsInitializedEmpty() { - $norm = new FixedDataTransformer(array( + $model = new FixedDataTransformer(array( '' => 'foo', )); - $client = new FixedDataTransformer(array( + $view = new FixedDataTransformer(array( 'foo' => 'bar', )); $config = new FormConfig('name', null, $this->dispatcher); - $config->appendClientTransformer($client); - $config->appendNormTransformer($norm); + $config->addViewTransformer($view); + $config->addModelTransformer($model); $form = new Form($config); $this->assertNull($form->getData()); $this->assertSame('foo', $form->getNormData()); - $this->assertSame('bar', $form->getClientData()); + $this->assertSame('bar', $form->getViewData()); } public function testValidIfAllChildrenAreValid() @@ -296,7 +296,7 @@ class FormTest extends \PHPUnit_Framework_TestCase { $this->factory->expects($this->once()) ->method('createNamedBuilder') - ->with('text', 'name', null, array()) + ->with('name', 'text', null, array()) ->will($this->returnValue($this->getBuilder('name'))); $form = $this->getBuilder('person') @@ -376,7 +376,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->form->add($child); $this->assertSame($this->form, $child->getParent()); - $this->assertSame(array('foo' => $child), $this->form->getChildren()); + $this->assertSame(array('foo' => $child), $this->form->all()); } /** @@ -440,7 +440,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->form->add($this->getBuilder('foo')->getForm()); $this->form->add($this->getBuilder('bar')->getForm()); - $this->assertSame($this->form->getChildren(), iterator_to_array($this->form)); + $this->assertSame($this->form->all(), iterator_to_array($this->form)); } public function testBound() @@ -488,15 +488,15 @@ class FormTest extends \PHPUnit_Framework_TestCase // use real event dispatcher now $form = $this->getBuilder('name', new EventDispatcher()) ->addEventSubscriber(new FixedFilterListener(array( - 'onSetData' => array( + 'preSetData' => array( 'app' => 'filtered', ), ))) - ->appendNormTransformer(new FixedDataTransformer(array( + ->addModelTransformer(new FixedDataTransformer(array( '' => '', 'filtered' => 'norm', ))) - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', 'norm' => 'client', ))) @@ -506,17 +506,17 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertEquals('filtered', $form->getData()); $this->assertEquals('norm', $form->getNormData()); - $this->assertEquals('client', $form->getClientData()); + $this->assertEquals('client', $form->getViewData()); } - public function testSetDataExecutesClientTransformersInOrder() + public function testSetDataExecutesViewTransformersInOrder() { $form = $this->getBuilder() - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', 'first' => 'second', ))) - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', 'second' => 'third', ))) @@ -524,20 +524,20 @@ class FormTest extends \PHPUnit_Framework_TestCase $form->setData('first'); - $this->assertEquals('third', $form->getClientData()); + $this->assertEquals('third', $form->getViewData()); } - public function testSetDataExecutesNormTransformersInOrder() + public function testSetDataExecutesModelTransformersInReverseOrder() { $form = $this->getBuilder() - ->appendNormTransformer(new FixedDataTransformer(array( - '' => '', - 'first' => 'second', - ))) - ->appendNormTransformer(new FixedDataTransformer(array( + ->addModelTransformer(new FixedDataTransformer(array( '' => '', 'second' => 'third', ))) + ->addModelTransformer(new FixedDataTransformer(array( + '' => '', + 'first' => 'second', + ))) ->getForm(); $form->setData('first'); @@ -557,17 +557,17 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertSame('1', $form->getData()); $this->assertSame('1', $form->getNormData()); - $this->assertSame('1', $form->getClientData()); + $this->assertSame('1', $form->getViewData()); } /* * Data in client format should, if possible, always be a string to * facilitate differentiation between '0' and '' */ - public function testSetDataConvertsScalarToStringIfOnlyNormTransformer() + public function testSetDataConvertsScalarToStringIfOnlyModelTransformer() { $form = $this->getBuilder() - ->appendNormTransformer(new FixedDataTransformer(array( + ->addModelTransformer(new FixedDataTransformer(array( '' => '', 1 => 23, ))) @@ -577,7 +577,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertSame(1, $form->getData()); $this->assertSame(23, $form->getNormData()); - $this->assertSame('23', $form->getClientData()); + $this->assertSame('23', $form->getViewData()); } /* @@ -592,7 +592,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertNull($form->getData()); $this->assertNull($form->getNormData()); - $this->assertSame('', $form->getClientData()); + $this->assertSame('', $form->getViewData()); } public function testBindConvertsEmptyToNullIfNoTransformer() @@ -603,7 +603,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertNull($form->getData()); $this->assertNull($form->getNormData()); - $this->assertSame('', $form->getClientData()); + $this->assertSame('', $form->getViewData()); } public function testBindExecutesTransformationChain() @@ -611,20 +611,20 @@ class FormTest extends \PHPUnit_Framework_TestCase // use real event dispatcher now $form = $this->getBuilder('name', new EventDispatcher()) ->addEventSubscriber(new FixedFilterListener(array( - 'onBindClientData' => array( + 'preBind' => array( 'client' => 'filteredclient', ), - 'onBindNormData' => array( + 'onBind' => array( 'norm' => 'filterednorm', ), ))) - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', // direction is reversed! 'norm' => 'filteredclient', 'filterednorm' => 'cleanedclient' ))) - ->appendNormTransformer(new FixedDataTransformer(array( + ->addModelTransformer(new FixedDataTransformer(array( '' => '', // direction is reversed! 'app' => 'filterednorm', @@ -635,17 +635,17 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertEquals('app', $form->getData()); $this->assertEquals('filterednorm', $form->getNormData()); - $this->assertEquals('cleanedclient', $form->getClientData()); + $this->assertEquals('cleanedclient', $form->getViewData()); } - public function testBindExecutesClientTransformersInReverseOrder() + public function testBindExecutesViewTransformersInReverseOrder() { $form = $this->getBuilder() - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', 'third' => 'second', ))) - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', 'second' => 'first', ))) @@ -656,17 +656,17 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertEquals('third', $form->getNormData()); } - public function testBindExecutesNormTransformersInReverseOrder() + public function testBindExecutesModelTransformersInOrder() { $form = $this->getBuilder() - ->appendNormTransformer(new FixedDataTransformer(array( - '' => '', - 'third' => 'second', - ))) - ->appendNormTransformer(new FixedDataTransformer(array( + ->addModelTransformer(new FixedDataTransformer(array( '' => '', 'second' => 'first', ))) + ->addModelTransformer(new FixedDataTransformer(array( + '' => '', + 'third' => 'second', + ))) ->getForm(); $form->bind('first'); @@ -694,7 +694,7 @@ class FormTest extends \PHPUnit_Framework_TestCase ->will($this->throwException(new TransformationFailedException())); $form = $this->getBuilder() - ->appendClientTransformer($transformer) + ->addViewTransformer($transformer) ->getForm(); $form->bind('foobar'); @@ -706,7 +706,7 @@ class FormTest extends \PHPUnit_Framework_TestCase { $form = $this->getBuilder() ->setEmptyData('foo') - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', // direction is reversed! 'bar' => 'foo', @@ -729,7 +729,7 @@ class FormTest extends \PHPUnit_Framework_TestCase return 'foo'; }) - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', // direction is reversed! 'bar' => 'foo', @@ -746,7 +746,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $mapper = $this->getDataMapper(); $form = $this->getBuilder() ->setDataMapper($mapper) - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', 'foo' => 'bar', ))) @@ -766,7 +766,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $mapper = $this->getDataMapper(); $form = $this->getBuilder() ->setDataMapper($mapper) - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', 'foo' => 'bar', ))) @@ -788,7 +788,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $mapper = $this->getDataMapper(); $form = $this->getBuilder() ->setDataMapper($mapper) - ->appendClientTransformer(new FixedDataTransformer(array( + ->addViewTransformer(new FixedDataTransformer(array( '' => '', 'foo' => 'bar', ))) @@ -1104,7 +1104,7 @@ class FormTest extends \PHPUnit_Framework_TestCase ->will($this->returnCallback(function (FormView $view, Form $form) use ($test, &$calls) { $calls[] = 'type1::buildView'; $test->assertTrue($view->hasParent()); - $test->assertFalse($view->hasChildren()); + $test->assertEquals(0, count($view)); })); $type1Extension->expects($this->once()) @@ -1112,7 +1112,7 @@ class FormTest extends \PHPUnit_Framework_TestCase ->will($this->returnCallback(function (FormView $view, Form $form) use ($test, &$calls) { $calls[] = 'type1ext::buildView'; $test->assertTrue($view->hasParent()); - $test->assertFalse($view->hasChildren()); + $test->assertEquals(0, count($view)); })); $type2->expects($this->once()) @@ -1120,7 +1120,7 @@ class FormTest extends \PHPUnit_Framework_TestCase ->will($this->returnCallback(function (FormView $view, Form $form) use ($test, &$calls) { $calls[] = 'type2::buildView'; $test->assertTrue($view->hasParent()); - $test->assertFalse($view->hasChildren()); + $test->assertEquals(0, count($view)); })); $type2Extension->expects($this->once()) @@ -1128,35 +1128,35 @@ class FormTest extends \PHPUnit_Framework_TestCase ->will($this->returnCallback(function (FormView $view, Form $form) use ($test, &$calls) { $calls[] = 'type2ext::buildView'; $test->assertTrue($view->hasParent()); - $test->assertFalse($view->hasChildren()); + $test->assertEquals(0, count($view)); })); $type1->expects($this->once()) - ->method('buildViewBottomUp') + ->method('finishView') ->will($this->returnCallback(function (FormView $view, Form $form) use ($test, &$calls) { - $calls[] = 'type1::buildViewBottomUp'; - $test->assertTrue($view->hasChildren()); + $calls[] = 'type1::finishView'; + $test->assertGreaterThan(0, count($view)); })); $type1Extension->expects($this->once()) - ->method('buildViewBottomUp') + ->method('finishView') ->will($this->returnCallback(function (FormView $view, Form $form) use ($test, &$calls) { - $calls[] = 'type1ext::buildViewBottomUp'; - $test->assertTrue($view->hasChildren()); + $calls[] = 'type1ext::finishView'; + $test->assertGreaterThan(0, count($view)); })); $type2->expects($this->once()) - ->method('buildViewBottomUp') + ->method('finishView') ->will($this->returnCallback(function (FormView $view, Form $form) use ($test, &$calls) { - $calls[] = 'type2::buildViewBottomUp'; - $test->assertTrue($view->hasChildren()); + $calls[] = 'type2::finishView'; + $test->assertGreaterThan(0, count($view)); })); $type2Extension->expects($this->once()) - ->method('buildViewBottomUp') + ->method('finishView') ->will($this->returnCallback(function (FormView $view, Form $form) use ($test, &$calls) { - $calls[] = 'type2ext::buildViewBottomUp'; - $test->assertTrue($view->hasChildren()); + $calls[] = 'type2ext::finishView'; + $test->assertGreaterThan(0, count($view)); })); $form = $this->getBuilder()->setTypes(array($type1, $type2))->getForm(); @@ -1170,10 +1170,10 @@ class FormTest extends \PHPUnit_Framework_TestCase 1 => 'type1ext::buildView', 2 => 'type2::buildView', 3 => 'type2ext::buildView', - 4 => 'type1::buildViewBottomUp', - 5 => 'type1ext::buildViewBottomUp', - 6 => 'type2::buildViewBottomUp', - 7 => 'type2ext::buildViewBottomUp', + 4 => 'type1::finishView', + 5 => 'type1ext::finishView', + 6 => 'type2::finishView', + 7 => 'type2ext::finishView', ), $calls); } @@ -1259,7 +1259,7 @@ class FormTest extends \PHPUnit_Framework_TestCase public function testClientDataMustNotBeObjectIfDataClassIsNull() { $config = new FormConfig('name', null, $this->dispatcher); - $config->appendClientTransformer(new FixedDataTransformer(array( + $config->addViewTransformer(new FixedDataTransformer(array( '' => '', 'foo' => new \stdClass(), ))); @@ -1272,7 +1272,7 @@ class FormTest extends \PHPUnit_Framework_TestCase { $arrayAccess = $this->getMock('\ArrayAccess'); $config = new FormConfig('name', null, $this->dispatcher); - $config->appendClientTransformer(new FixedDataTransformer(array( + $config->addViewTransformer(new FixedDataTransformer(array( '' => '', 'foo' => $arrayAccess, ))); @@ -1280,7 +1280,7 @@ class FormTest extends \PHPUnit_Framework_TestCase $form->setData('foo'); - $this->assertSame($arrayAccess, $form->getClientData()); + $this->assertSame($arrayAccess, $form->getViewData()); } /** @@ -1289,7 +1289,7 @@ class FormTest extends \PHPUnit_Framework_TestCase public function testClientDataMustBeObjectIfDataClassIsSet() { $config = new FormConfig('name', 'stdClass', $this->dispatcher); - $config->appendClientTransformer(new FixedDataTransformer(array( + $config->addViewTransformer(new FixedDataTransformer(array( '' => '', 'foo' => array('bar' => 'baz'), ))); diff --git a/src/Symfony/Component/Form/UnmodifiableFormConfig.php b/src/Symfony/Component/Form/UnmodifiableFormConfig.php index 3fdb963923..27bc13044a 100644 --- a/src/Symfony/Component/Form/UnmodifiableFormConfig.php +++ b/src/Symfony/Component/Form/UnmodifiableFormConfig.php @@ -112,6 +112,11 @@ class UnmodifiableFormConfig implements FormConfigInterface */ private $dataClass; + /** + * @var array + */ + private $options; + /** * Creates an unmodifiable copy of a given configuration. * @@ -131,8 +136,8 @@ class UnmodifiableFormConfig implements FormConfigInterface $this->byReference = $config->getByReference(); $this->virtual = $config->getVirtual(); $this->types = $config->getTypes(); - $this->clientTransformers = $config->getClientTransformers(); - $this->normTransformers = $config->getNormTransformers(); + $this->clientTransformers = $config->getViewTransformers(); + $this->normTransformers = $config->getModelTransformers(); $this->dataMapper = $config->getDataMapper(); $this->validators = $config->getValidators(); $this->required = $config->getRequired(); @@ -142,6 +147,7 @@ class UnmodifiableFormConfig implements FormConfigInterface $this->attributes = $config->getAttributes(); $this->data = $config->getData(); $this->dataClass = $config->getDataClass(); + $this->options = $config->getOptions(); } /** @@ -203,7 +209,7 @@ class UnmodifiableFormConfig implements FormConfigInterface /** * {@inheritdoc} */ - public function getClientTransformers() + public function getViewTransformers() { return $this->clientTransformers; } @@ -211,7 +217,7 @@ class UnmodifiableFormConfig implements FormConfigInterface /** * {@inheritdoc} */ - public function getNormTransformers() + public function getModelTransformers() { return $this->normTransformers; } @@ -285,9 +291,9 @@ class UnmodifiableFormConfig implements FormConfigInterface /** * {@inheritdoc} */ - public function getAttribute($name) + public function getAttribute($name, $default = null) { - return isset($this->attributes[$name]) ? $this->attributes[$name] : null; + return isset($this->attributes[$name]) ? $this->attributes[$name] : $default; } /** @@ -305,4 +311,28 @@ class UnmodifiableFormConfig implements FormConfigInterface { return $this->dataClass; } + + /** + * {@inheritdoc} + */ + public function getOptions() + { + return $this->options; + } + + /** + * {@inheritdoc} + */ + public function hasOption($name) + { + return isset($this->options[$name]); + } + + /** + * {@inheritdoc} + */ + public function getOption($name, $default = null) + { + return isset($this->options[$name]) ? $this->options[$name] : $default; + } } diff --git a/src/Symfony/Component/Form/Util/PropertyPath.php b/src/Symfony/Component/Form/Util/PropertyPath.php index d4d6aa7034..ca9aa6547d 100644 --- a/src/Symfony/Component/Form/Util/PropertyPath.php +++ b/src/Symfony/Component/Form/Util/PropertyPath.php @@ -353,9 +353,9 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface /** * Reads the a property from an object or array. * - * @param object|array $objectOrArray The object or array to read from. - * @param string $property The property to read. - * @param integer $isIndex Whether to interpret the property as index. + * @param object|array $objectOrArray The object or array to read from. + * @param string $property The property to read. + * @param Boolean $isIndex Whether to interpret the property as index. * * @return mixed The value of the read property * @@ -425,11 +425,11 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface /** * Sets the value of the property at the given index in the path * - * @param object|array $objectOrArray The object or array to write to. - * @param string $property The property to write. - * @param string $singular The singular form of the property name or null. - * @param integer $isIndex Whether to interpret the property as index. - * @param mixed $value The value to write. + * @param object|array $objectOrArray The object or array to write to. + * @param string $property The property to write. + * @param string $singular The singular form of the property name or null. + * @param Boolean $isIndex Whether to interpret the property as index. + * @param mixed $value The value to write. * * @throws InvalidPropertyException If the property does not exist. * @throws PropertyAccessDeniedException If the property cannot be accessed due to @@ -445,107 +445,46 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface $objectOrArray[$property] = $value; } elseif (is_object($objectOrArray)) { $reflClass = new ReflectionClass($objectOrArray); - $setter = 'set'.$this->camelize($property); - $addMethod = null; - $removeMethod = null; - $plural = null; - // Check if the parent has matching methods to add/remove items if (is_array($value) || $value instanceof Traversable) { - if (null !== $singular) { - $addMethod = 'add' . ucfirst($singular); - $removeMethod = 'remove' . ucfirst($singular); + $methods = $this->findAdderAndRemover($reflClass, $singular); + if (null !== $methods) { + // At this point the add and remove methods have been found + $itemsToAdd = is_object($value) ? clone $value : $value; + $itemToRemove = array(); + $previousValue = $this->readProperty($objectOrArray, $property, $isIndex); - if (!$this->isAccessible($reflClass, $addMethod, 1)) { - throw new InvalidPropertyException(sprintf( - 'The public method "%s" with exactly one required parameter was not found on class %s', - $addMethod, - $reflClass->getName() - )); - } + if (is_array($previousValue) || $previousValue instanceof Traversable) { + foreach ($previousValue as $previousItem) { + foreach ($value as $key => $item) { + if ($item === $previousItem) { + // Item found, don't add + unset($itemsToAdd[$key]); - if (!$this->isAccessible($reflClass, $removeMethod, 1)) { - throw new InvalidPropertyException(sprintf( - 'The public method "%s" with exactly one required parameter was not found on class %s', - $removeMethod, - $reflClass->getName() - )); - } - } else { - // The plural form is the last element of the property path - $plural = ucfirst($this->elements[$this->length - 1]); + // Next $previousItem + continue 2; + } + } - // Any of the two methods is required, but not yet known - $singulars = (array) FormUtil::singularify($plural); - - foreach ($singulars as $singular) { - $addMethodName = 'add' . $singular; - $removeMethodName = 'remove' . $singular; - - if ($this->isAccessible($reflClass, $addMethodName, 1)) { - $addMethod = $addMethodName; - } - - if ($this->isAccessible($reflClass, $removeMethodName, 1)) { - $removeMethod = $removeMethodName; - } - - if ($addMethod && !$removeMethod) { - throw new InvalidPropertyException(sprintf( - 'Found the public method "%s", but did not find a public "%s" on class %s', - $addMethodName, - $removeMethodName, - $reflClass->getName() - )); - } - - if ($removeMethod && !$addMethod) { - throw new InvalidPropertyException(sprintf( - 'Found the public method "%s", but did not find a public "%s" on class %s', - $removeMethodName, - $addMethodName, - $reflClass->getName() - )); - } - - if ($addMethod && $removeMethod) { - break; + // Item not found, add to remove list + $itemToRemove[] = $previousItem; } } + + foreach ($itemToRemove as $item) { + call_user_func(array($objectOrArray, $methods[1]), $item); + } + + foreach ($itemsToAdd as $item) { + call_user_func(array($objectOrArray, $methods[0]), $item); + } + + return; } } - // Collection with matching adder/remover in $objectOrArray - if ($addMethod && $removeMethod) { - $itemsToAdd = is_object($value) ? clone $value : $value; - $itemToRemove = array(); - $previousValue = $this->readProperty($objectOrArray, $property, $isIndex); - - if (is_array($previousValue) || $previousValue instanceof Traversable) { - foreach ($previousValue as $previousItem) { - foreach ($value as $key => $item) { - if ($item === $previousItem) { - // Item found, don't add - unset($itemsToAdd[$key]); - - // Next $previousItem - continue 2; - } - } - - // Item not found, add to remove list - $itemToRemove[] = $previousItem; - } - } - - foreach ($itemToRemove as $item) { - $objectOrArray->$removeMethod($item); - } - - foreach ($itemsToAdd as $item) { - $objectOrArray->$addMethod($item); - } - } elseif ($reflClass->hasMethod($setter)) { + $setter = 'set'.$this->camelize($property); + if ($reflClass->hasMethod($setter)) { if (!$reflClass->getMethod($setter)->isPublic()) { throw new PropertyAccessDeniedException(sprintf('Method "%s()" is not public in class "%s"', $setter, $reflClass->getName())); } @@ -583,6 +522,81 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface return preg_replace_callback('/(^|_|\.)+(.)/', function ($match) { return ('.' === $match[1] ? '_' : '').strtoupper($match[2]); }, $string); } + /** + * Searches for add and remove methods. + * + * @param \ReflectionClass $reflClass The reflection class for the given object + * @param string $singular The singular form of the property name or null. + * + * @return array|null An array containin the adder and remover when found, null otherwise. + * + * @throws InvalidPropertyException If the property does not exist. + */ + private function findAdderAndRemover(\ReflectionClass $reflClass, $singular) + { + if (null !== $singular) { + $addMethod = 'add' . ucfirst($singular); + $removeMethod = 'remove' . ucfirst($singular); + + if (!$this->isAccessible($reflClass, $addMethod, 1)) { + throw new InvalidPropertyException(sprintf( + 'The public method "%s" with exactly one required parameter was not found on class %s', + $addMethod, + $reflClass->getName() + )); + } + + if (!$this->isAccessible($reflClass, $removeMethod, 1)) { + throw new InvalidPropertyException(sprintf( + 'The public method "%s" with exactly one required parameter was not found on class %s', + $removeMethod, + $reflClass->getName() + )); + } + + return array($addMethod, $removeMethod); + } else { + // The plural form is the last element of the property path + $plural = ucfirst($this->elements[$this->length - 1]); + + // Any of the two methods is required, but not yet known + $singulars = (array) FormUtil::singularify($plural); + + foreach ($singulars as $singular) { + $methodsFound = 0; + $addMethodFound = false; + $addMethodName = 'add' . $singular; + $removeMethodName = 'remove' . $singular; + + if ($this->isAccessible($reflClass, $addMethodName, 1)) { + $addMethod = $addMethodName; + $addMethodFound = true; + $methodsFound++; + } + + if ($this->isAccessible($reflClass, $removeMethodName, 1)) { + $removeMethod = $removeMethodName; + $methodsFound++; + } + + if (2 == $methodsFound) { + return array($addMethod, $removeMethod); + } + + if (1 == $methodsFound) { + throw new InvalidPropertyException(sprintf( + 'Found the public method "%s", but did not find a public "%s" on class %s', + $addMethodFound ? $addMethodName : $removeMethodName, + $addMethodFound ? $removeMethodName : $addMethodName, + $reflClass->getName() + )); + } + } + } + + return null; + } + /** * Returns whether a method is public and has a specific number of required parameters. * diff --git a/src/Symfony/Component/OptionsResolver/Options.php b/src/Symfony/Component/OptionsResolver/Options.php index 079e0a4050..21bca78676 100644 --- a/src/Symfony/Component/OptionsResolver/Options.php +++ b/src/Symfony/Component/OptionsResolver/Options.php @@ -120,10 +120,10 @@ class Options implements \ArrayAccess, \Iterator, \Countable * Passed closures should have the following signature: * * - * function (Options $options, $previousValue) + * function (Options $options, $value) * * - * The second parameter passed to the closure is the previous default + * The second parameter passed to the closure is the current default * value of the option. * * @param string $option The option name. diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index 0feeeddfa7..1ead9c2820 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -21,7 +21,7 @@ use Symfony\Component\OptionsResolver\Exception\MissingOptionsException; * @author Bernhard Schussek * @author Tobias Schultze */ -class OptionsResolver +class OptionsResolver implements OptionsResolverInterface { /** * The default option values. @@ -47,6 +47,18 @@ class OptionsResolver */ private $allowedValues = array(); + /** + * A list of accepted types for each option. + * @var array + */ + private $allowedTypes = array(); + + /** + * A list of filters transforming each resolved options. + * @var array + */ + private $filters = array(); + /** * Creates a new instance. */ @@ -56,16 +68,7 @@ class OptionsResolver } /** - * Sets default option values. - * - * @param array $defaultValues A list of option names as keys and default values - * as values. The option values may be closures - * of the following signatures: - * - * - function (Options $options) - * - function (Options $options, $previousValue) - * - * @return OptionsResolver The resolver instance. + * {@inheritdoc} */ public function setDefaults(array $defaultValues) { @@ -79,20 +82,7 @@ class OptionsResolver } /** - * Replaces default option values. - * - * Old defaults are erased, which means that closures passed here can't - * access the previous default value. This may be useful to improve - * performance if the previous default value is calculated by an expensive - * closure. - * - * @param array $defaultValues A list of option names as keys and default values - * as values. The option values may be closures - * of the following signature: - * - * - function (Options $options) - * - * @return OptionsResolver The resolver instance. + * {@inheritdoc} */ public function replaceDefaults(array $defaultValues) { @@ -106,20 +96,7 @@ class OptionsResolver } /** - * Sets optional options. - * - * This method declares a valid option names without setting default values for - * them. If these options are not passed to {@link resolve()} and no default has - * been set for them, they will be missing in the final options array. This can - * be helpful if you want to determine whether an option has been set or not - * because otherwise {@link resolve()} would trigger an exception for unknown - * options. - * - * @param array $optionNames A list of option names. - * - * @return OptionsResolver The resolver instance. - * - * @throws OptionDefinitionException When trying to pass default values. + * {@inheritdoc} */ public function setOptional(array $optionNames) { @@ -135,16 +112,7 @@ class OptionsResolver } /** - * Sets required options. - * - * If these options are not passed to resolve() and no default has been set for - * them, an exception will be thrown. - * - * @param array $optionNames A list of option names. - * - * @return OptionsResolver The resolver instance. - * - * @throws OptionDefinitionException When trying to pass default values. + * {@inheritdoc} */ public function setRequired(array $optionNames) { @@ -164,17 +132,7 @@ class OptionsResolver } /** - * Sets allowed values for a list of options. - * - * @param array $allowedValues A list of option names as keys and arrays - * with values acceptable for that option as - * values. - * - * @return OptionsResolver The resolver instance. - * - * @throws InvalidOptionsException If an option has not been defined - * (see {@link isKnown()}) for which - * an allowed value is set. + * {@inheritdoc} */ public function setAllowedValues(array $allowedValues) { @@ -186,18 +144,7 @@ class OptionsResolver } /** - * Adds allowed values for a list of options. - * - * The values are merged with the allowed values defined previously. - * - * @param array $allowedValues A list of option names as keys and arrays - * with values acceptable for that option as - * values. - * - * @return OptionsResolver The resolver instance. - * - * @throws InvalidOptionsException If an option has not been defined for - * which an allowed value is set. + * {@inheritdoc} */ public function addAllowedValues(array $allowedValues) { @@ -209,13 +156,43 @@ class OptionsResolver } /** - * Returns whether an option is known. - * - * An option is known if it has been passed to either {@link setDefaults()}, - * {@link setRequired()} or {@link setOptional()} before. - * - * @param string $option The name of the option. - * @return Boolean Whether the option is known. + * {@inheritdoc} + */ + public function setAllowedTypes(array $allowedTypes) + { + $this->validateOptionsExistence($allowedTypes); + + $this->allowedTypes = array_replace($this->allowedTypes, $allowedTypes); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addAllowedTypes(array $allowedTypes) + { + $this->validateOptionsExistence($allowedTypes); + + $this->allowedTypes = array_merge_recursive($this->allowedTypes, $allowedTypes); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setFilters(array $filters) + { + $this->validateOptionsExistence($filters); + + $this->filters = array_replace($this->filters, $filters); + + return $this; + } + + /** + * {@inheritdoc} */ public function isKnown($option) { @@ -223,14 +200,7 @@ class OptionsResolver } /** - * Returns whether an option is required. - * - * An option is required if it has been passed to {@link setRequired()}, - * but not to {@link setDefaults()}. That is, the option has been declared - * as required and no default value has been set. - * - * @param string $option The name of the option. - * @return Boolean Whether the option is required. + * {@inheritdoc} */ public function isRequired($option) { @@ -238,18 +208,7 @@ class OptionsResolver } /** - * Returns the combination of the default and the passed options. - * - * @param array $options The custom option values. - * - * @return array A list of options and their values. - * - * @throws InvalidOptionsException If any of the passed options has not - * been defined or does not contain an - * allowed value. - * @throws MissingOptionsException If a required option is missing. - * @throws OptionDefinitionException If a cyclic dependency is detected - * between two lazy options. + * {@inheritdoc} */ public function resolve(array $options) { @@ -264,11 +223,16 @@ class OptionsResolver $combinedOptions->set($option, $value); } + // Apply filters + foreach ($this->filters as $option => $filter) { + $combinedOptions->overload($option, $filter); + } + // Resolve options $resolvedOptions = $combinedOptions->all(); - // Validate against allowed values $this->validateOptionValues($resolvedOptions); + $this->validateOptionTypes($resolvedOptions); return $resolvedOptions; } @@ -336,4 +300,44 @@ class OptionsResolver } } } + + /** + * Validates that the given options match the allowed types and + * throws an exception otherwise. + * + * @param array $options A list of options. + * + * @throws InvalidOptionsException If any of the types does not match the + * allowed types of the option. + */ + private function validateOptionTypes(array $options) + { + foreach ($this->allowedTypes as $option => $allowedTypes) { + $value = $options[$option]; + $allowedTypes = (array) $allowedTypes; + + foreach ($allowedTypes as $type) { + $isFunction = 'is_' . $type; + + if (function_exists($isFunction) && $isFunction($value)) { + continue 2; + } elseif ($value instanceof $type) { + continue 2; + } + } + + $printableValue = is_object($value) + ? get_class($value) + : (is_array($value) + ? 'Array' + : (string) $value); + + throw new InvalidOptionsException(sprintf( + 'The option "%s" with value "%s" is expected to be of type "%s"', + $option, + $printableValue, + implode('", "', $allowedTypes) + )); + } + } } diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolverInterface.php b/src/Symfony/Component/OptionsResolver/OptionsResolverInterface.php new file mode 100644 index 0000000000..fb2fa16918 --- /dev/null +++ b/src/Symfony/Component/OptionsResolver/OptionsResolverInterface.php @@ -0,0 +1,208 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\OptionsResolver; + +/** + * @author Bernhard Schussek + */ +interface OptionsResolverInterface +{ + /** + * Sets default option values. + * + * The options can either be values of any types or closures that + * evaluate the option value lazily. These closures must have one + * of the following signatures: + * + * + * function (Options $options) + * function (Options $options, $value) + * + * + * The second parameter passed to the closure is the previously + * set default value, in case you are overwriting an existing + * default value. + * + * The closures should return the lazily created option value. + * + * @param array $defaultValues A list of option names as keys and default + * values or closures as values. + * + * @return OptionsResolverInterface The resolver instance. + */ + function setDefaults(array $defaultValues); + + /** + * Replaces default option values. + * + * Old defaults are erased, which means that closures passed here cannot + * access the previous default value. This may be useful to improve + * performance if the previous default value is calculated by an expensive + * closure. + * + * @param array $defaultValues A list of option names as keys and default + * values or closures as values. + * + * @return OptionsResolverInterface The resolver instance. + */ + function replaceDefaults(array $defaultValues); + + /** + * Sets optional options. + * + * This method is identical to {@ĺink setDefaults()}, only that no default values + * are configured for the options. If these options are not passed to + * {@link resolve()}, they will be missing in the final options array. This can be + * helpful if you want to determine whether an option has been set or not. + * + * @param array $optionNames A list of option names. + * + * @return OptionsResolverInterface The resolver instance. + * + * @throws Exception\OptionDefinitionException When trying to pass default values. + */ + function setOptional(array $optionNames); + + /** + * Sets required options. + * + * If these options are not passed to {@link resolve()} and no default has been set for + * them, an exception will be thrown. + * + * @param array $optionNames A list of option names. + * + * @return OptionsResolverInterface The resolver instance. + * + * @throws Exception\OptionDefinitionException When trying to pass default values. + */ + function setRequired(array $optionNames); + + /** + * Sets allowed values for a list of options. + * + * @param array $allowedValues A list of option names as keys and arrays + * with values acceptable for that option as + * values. + * + * @return OptionsResolverInterface The resolver instance. + * + * @throws Exception\InvalidOptionsException If an option has not been defined for + * which an allowed value is set. + */ + function setAllowedValues(array $allowedValues); + + /** + * Adds allowed values for a list of options. + * + * The values are merged with the allowed values defined previously. + * + * @param array $allowedValues A list of option names as keys and arrays + * with values acceptable for that option as + * values. + * + * @return OptionsResolverInterface The resolver instance. + * + * @throws Exception\InvalidOptionsException If an option has not been defined + * (see {@link isKnown()}) for which + * an allowed value is set. + */ + function addAllowedValues(array $allowedValues); + + /** + * Sets allowed types for a list of options. + * + * @param array $allowedTypes A list of option names as keys and type + * names passed as string or array as values. + * + * @return OptionsResolverInterface The resolver instance. + * + * @throws Exception\InvalidOptionsException If an option has not been defined for + * which an allowed type is set. + */ + function setAllowedTypes(array $allowedTypes); + + /** + * Adds allowed types for a list of options. + * + * The types are merged with the allowed types defined previously. + * + * @param array $allowedTypes A list of option names as keys and type + * names passed as string or array as values. + * + * @return OptionsResolverInterface The resolver instance. + * + * @throws Exception\InvalidOptionsException If an option has not been defined for + * which an allowed type is set. + */ + function addAllowedTypes(array $allowedTypes); + + /** + * Sets filters that are applied on resolved options. + * + * The filters should be closures with the following signature: + * + * + * function (Options $options, $value) + * + * + * The second parameter passed to the closure is the value of + * the option. + * + * The closure should return the filtered value. + * + * @param array $filters An array of filter closures. + * + * @return OptionsResolverInterface The resolver instance. + */ + function setFilters(array $filters); + + /** + * Returns whether an option is known. + * + * An option is known if it has been passed to either {@link setDefaults()}, + * {@link setRequired()} or {@link setOptional()} before. + * + * @param string $option The name of the option. + * + * @return Boolean Whether the option is known. + */ + function isKnown($option); + + /** + * Returns whether an option is required. + * + * An option is required if it has been passed to {@link setRequired()}, + * but not to {@link setDefaults()}. That is, the option has been declared + * as required and no default value has been set. + * + * @param string $option The name of the option. + * + * @return Boolean Whether the option is required. + */ + function isRequired($option); + + /** + * Returns the combination of the default and the passed options. + * + * @param array $options The custom option values. + * + * @return array A list of options and their values. + * + * @throws Exception\InvalidOptionsException If any of the passed options has not + * been defined or does not contain an + * allowed value. + * @throws Exception\MissingOptionsException If a required option is missing. + * @throws Exception\OptionDefinitionException If a cyclic dependency is detected + * between two lazy options. + */ + function resolve(array $options); +} diff --git a/src/Symfony/Component/OptionsResolver/README.md b/src/Symfony/Component/OptionsResolver/README.md index c2280011e4..84a87787b5 100644 --- a/src/Symfony/Component/OptionsResolver/README.md +++ b/src/Symfony/Component/OptionsResolver/README.md @@ -22,12 +22,12 @@ possible, and may only be one of "male" and "female". public function __construct(array $options = array()) { $resolver = new OptionsResolver(); - $this->configure($resolver); + $this->setDefaultOptions($resolver); $this->options = $resolver->resolve($options); } - protected function configure(OptionsResolver $resolver) + protected function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setRequired(array( 'firstName', @@ -68,7 +68,7 @@ We can also override the default values of the optional options: 'age' => 30, )); -Options can be added or changed in subclasses by overriding the `configure` +Options can be added or changed in subclasses by overriding the `setDefaultOptions` method: use Symfony\Component\OptionsResolver\OptionsResolver; @@ -76,9 +76,9 @@ method: class Employee extends Person { - protected function configure(OptionsResolver $resolver) + protected function setDefaultOptions(OptionsResolverInterface $resolver) { - parent::configure($resolver); + parent::setDefaultOptions($resolver); $resolver->setRequired(array( 'birthDate', diff --git a/src/Symfony/Component/OptionsResolver/Tests/OptionResolverTest.php b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php similarity index 67% rename from src/Symfony/Component/OptionsResolver/Tests/OptionResolverTest.php rename to src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php index ef68c7f1e1..d112dd30f8 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/OptionResolverTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php @@ -238,13 +238,13 @@ class OptionsResolverTest extends \PHPUnit_Framework_TestCase 'two' => '2', )); - $this->resolver->addAllowedValues(array( - 'one' => array('1'), - 'two' => array('2'), + $this->resolver->setAllowedValues(array( + 'one' => '1', + 'two' => '2', )); $this->resolver->addAllowedValues(array( - 'one' => array('one'), - 'two' => array('two'), + 'one' => 'one', + 'two' => 'two', )); $options = array( @@ -276,6 +276,171 @@ class OptionsResolverTest extends \PHPUnit_Framework_TestCase )); } + public function testResolveSucceedsIfOptionTypeAllowed() + { + $this->resolver->setDefaults(array( + 'one' => '1', + )); + + $this->resolver->setAllowedTypes(array( + 'one' => 'string', + )); + + $options = array( + 'one' => 'one', + ); + + $this->assertEquals(array( + 'one' => 'one', + ), $this->resolver->resolve($options)); + } + + public function testResolveSucceedsIfOptionTypeAllowedPassArray() + { + $this->resolver->setDefaults(array( + 'one' => '1', + )); + + $this->resolver->setAllowedTypes(array( + 'one' => array('string', 'bool'), + )); + + $options = array( + 'one' => true, + ); + + $this->assertEquals(array( + 'one' => true, + ), $this->resolver->resolve($options)); + } + + public function testResolveSucceedsIfOptionTypeAllowedPassObject() + { + $this->resolver->setDefaults(array( + 'one' => '1', + )); + + $this->resolver->setAllowedTypes(array( + 'one' => 'object', + )); + + $object = new \stdClass(); + $options = array( + 'one' => $object, + ); + + $this->assertEquals(array( + 'one' => $object, + ), $this->resolver->resolve($options)); + } + + public function testResolveSucceedsIfOptionTypeAllowedPassClass() + { + $this->resolver->setDefaults(array( + 'one' => '1', + )); + + $this->resolver->setAllowedTypes(array( + 'one' => '\stdClass', + )); + + $object = new \stdClass(); + $options = array( + 'one' => $object, + ); + + $this->assertEquals(array( + 'one' => $object, + ), $this->resolver->resolve($options)); + } + + public function testResolveSucceedsIfOptionTypeAllowedAddTypes() + { + $this->resolver->setDefaults(array( + 'one' => '1', + 'two' => '2', + )); + + $this->resolver->setAllowedTypes(array( + 'one' => 'string', + 'two' => 'bool', + )); + $this->resolver->addAllowedTypes(array( + 'one' => 'float', + 'two' => 'integer', + )); + + $options = array( + 'one' => 1.23, + 'two' => false, + ); + + $this->assertEquals(array( + 'one' => 1.23, + 'two' => false, + ), $this->resolver->resolve($options)); + } + + /** + * @expectedException Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testResolveFailsIfOptionTypeNotAllowed() + { + $this->resolver->setDefaults(array( + 'one' => '1', + )); + + $this->resolver->setAllowedTypes(array( + 'one' => array('string', 'bool'), + )); + + $this->resolver->resolve(array( + 'one' => 1.23, + )); + } + + /** + * @expectedException Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testResolveFailsIfOptionTypeNotAllowedMultipleOptions() + { + $this->resolver->setDefaults(array( + 'one' => '1', + 'two' => '2', + )); + + $this->resolver->setAllowedTypes(array( + 'one' => 'string', + 'two' => 'bool', + )); + + $this->resolver->resolve(array( + 'one' => 'foo', + 'two' => 1.23, + )); + } + + /** + * @expectedException Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testResolveFailsIfOptionTypeNotAllowedAddTypes() + { + $this->resolver->setDefaults(array( + 'one' => '1', + )); + + $this->resolver->setAllowedTypes(array( + 'one' => 'string', + )); + $this->resolver->addAllowedTypes(array( + 'one' => 'bool', + )); + + $this->resolver->resolve(array( + 'one' => 1.23, + )); + } + /** * @expectedException Symfony\Component\OptionsResolver\Exception\OptionDefinitionException */ @@ -373,6 +538,36 @@ class OptionsResolverTest extends \PHPUnit_Framework_TestCase $this->assertFalse($this->resolver->isRequired('foo')); } + public function testFiltersTransformFinalOptions() + { + $this->resolver->setDefaults(array( + 'foo' => 'bar', + 'bam' => 'baz', + )); + $this->resolver->setFilters(array( + 'foo' => function (Options $options, $value) { + return $options['bam'] . '[' . $value . ']'; + }, + )); + + $expected = array( + 'foo' => 'baz[bar]', + 'bam' => 'baz', + ); + + $this->assertEquals($expected, $this->resolver->resolve(array())); + + $expected = array( + 'foo' => 'boo[custom]', + 'bam' => 'boo', + ); + + $this->assertEquals($expected, $this->resolver->resolve(array( + 'foo' => 'custom', + 'bam' => 'boo', + ))); + } + public function testResolveWithoutOptionSucceedsIfRequiredAndDefaultValue() { $this->resolver->setRequired(array(