From eb75ab1b743bcc8719d63120a7bc787df9b76842 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 20 Apr 2012 18:42:21 +0200 Subject: [PATCH 1/7] [Form] Fixed results of the FieldType+FormType merge. --- UPGRADE-2.1.md | 105 ++++++++-- .../views/Form/form_div_layout.html.twig | 194 ++++++++---------- .../views/Form/form_table_layout.html.twig | 24 +-- .../Twig/Tests/Extension/theme.html.twig | 6 +- .../Tests/Extension/theme_extends.html.twig | 6 +- .../Twig/Tests/Extension/theme_use.html.twig | 6 +- .../Resources/views/Form/attributes.html.php | 10 +- .../views/Form/checkbox_widget.html.php | 2 +- .../views/Form/choice_options.html.php | 12 +- .../views/Form/choice_widget.html.php | 21 +- .../Form/choice_widget_collapsed.html.php | 13 ++ .../Form/choice_widget_expanded.html.php | 6 + .../views/Form/choice_widget_options.html.php | 11 + .../views/Form/container_attributes.html.php | 3 +- .../Resources/views/Form/date_widget.html.php | 4 +- .../views/Form/datetime_widget.html.php | 4 +- .../views/Form/email_widget.html.php | 2 +- .../views/Form/field_widget.html.php | 2 +- .../Resources/views/Form/form_label.html.php | 2 +- .../Resources/views/Form/form_row.html.php | 2 +- .../Resources/views/Form/form_widget.html.php | 9 +- .../views/Form/form_widget_complex.html.php | 4 + .../views/Form/form_widget_primitive.html.php | 5 + .../views/Form/hidden_widget.html.php | 2 +- .../Resources/views/Form/input.html.php | 5 - .../views/Form/integer_widget.html.php | 2 +- .../views/Form/money_widget.html.php | 2 +- .../views/Form/number_widget.html.php | 2 +- .../views/Form/password_widget.html.php | 2 +- .../views/Form/percent_widget.html.php | 2 +- .../views/Form/radio_widget.html.php | 2 +- .../views/Form/search_widget.html.php | 2 +- .../views/Form/textarea_widget.html.php | 2 +- .../Resources/views/Form/time_widget.html.php | 4 +- .../Resources/views/Form/url_widget.html.php | 2 +- .../views/Form/widget_attributes.html.php | 9 + .../Form/widget_container_attributes.html.php | 2 + .../views/FormTable/form_errors.html.php | 46 ++--- .../views/FormTable/form_row.html.php | 2 +- .../views/FormTable/form_widget.html.php | 8 - .../FormTable/form_widget_complex.html.php | 4 + ...tml.php => form_widget_primitive.html.php} | 2 +- src/Symfony/Component/Form/CHANGELOG.md | 15 +- .../Form/Extension/Core/Type/CheckboxType.php | 11 +- .../Form/Extension/Core/Type/ChoiceType.php | 5 + .../Form/Extension/Core/Type/DateTimeType.php | 6 + .../Form/Extension/Core/Type/DateType.php | 9 +- .../Form/Extension/Core/Type/FileType.php | 10 + .../Form/Extension/Core/Type/FormType.php | 3 + .../Form/Extension/Core/Type/HiddenType.php | 1 + .../Form/Extension/Core/Type/IntegerType.php | 1 + .../Form/Extension/Core/Type/MoneyType.php | 1 + .../Form/Extension/Core/Type/NumberType.php | 1 + .../Form/Extension/Core/Type/PercentType.php | 1 + .../Form/Extension/Core/Type/TextType.php | 10 + .../Form/Extension/Core/Type/TimeType.php | 6 + .../Form/Tests/AbstractDivLayoutTest.php | 13 ++ .../Form/Tests/AbstractTableLayoutTest.php | 13 ++ .../Component/Form/Tests/FormFactoryTest.php | 8 +- 59 files changed, 396 insertions(+), 273 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_expanded.html.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_options.html.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_complex.html.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_primitive.html.php delete mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/input.html.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_container_attributes.html.php delete mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget.html.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_complex.html.php rename src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/{input.html.php => form_widget_primitive.html.php} (60%) diff --git a/UPGRADE-2.1.md b/UPGRADE-2.1.md index 29baddf4f6c15..e8f9ca869b950 100644 --- a/UPGRADE-2.1.md +++ b/UPGRADE-2.1.md @@ -102,7 +102,7 @@ ``` * The custom factories for the firewall configuration are now registered during the build method of bundles instead of being registered - by the end-user. This means that you will you need to remove the 'factories' + by the end-user. This means that you will you need to remove the 'factories' keys in your security configuration. * The Firewall listener is now registered after the Router listener. This @@ -313,29 +313,29 @@ return isset($options['widget']) && 'single_text' === $options['widget'] ? 'text' : 'choice'; } ``` - + * 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. - + Before: - + ``` public function getDefaultOptions(array $options) { $defaultOptions = array(); - + if ($options['multiple']) { $defaultOptions['empty_data'] = array(); } - + return $defaultOptions; } ``` - + After: - + ``` public function getDefaultOptions() { @@ -346,7 +346,7 @@ ); } ``` - + The second argument `$previousValue` does not have to be specified if not needed. @@ -366,29 +366,92 @@ (or any other of the BIND events). In case you used the CallbackValidator class, you should now pass the callback directly to `addEventListener`. - * simplified CSRF protection and removed the csrf type + * 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_primitive": + + 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_primitive') }} + {% 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 "primitive": + + Before: + + ``` + {% block form_errors %} + {% spaceless %} + ... form code ... + {% endspaceless %} + {% endblock form_errors %} - * deprecated FieldType and merged it into FormType + {% block field_errors %} + {% spaceless %} + ... field code ... + {% endspaceless %} + {% endblock field_errors %} + ``` + + After: + + ``` + {% block form_errors %} + {% spaceless %} + {% if primitive %} + ... 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. - * [BC BREAK] renamed "field_*" theme blocks to "form_*" and "field_widget" to - "input" - * 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". - + Before: - + public function guessMinLength($class, $property) { if (/* condition */) { return new ValueGuess($minLength, Guess::LOW_CONFIDENCE); } } - + After: - + public function guessPattern($class, $property) { if (/* condition */) { @@ -470,7 +533,7 @@ `validate` and its return value was dropped. `ConstraintValidator` still contains the deprecated `isValid` method and - forwards `validate` calls to `isValid` by default. This BC layer will be + forwards `validate` calls to `isValid` by default. This BC layer will be removed in Symfony 2.3. You are advised to rename your methods. You should also remove the return values, which have never been used by the framework. @@ -500,7 +563,7 @@ $this->context->addViolation($constraint->message, array( '{{ value }}' => $value, )); - + return; } } 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 46420a71221fd..8fe3d004fa5d2 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,17 +2,30 @@ {% block form_widget %} {% spaceless %} - {% if form.children|length > 0 %} -
- {{ block('form_rows') }} - {{ form_rest(form) }} -
+ {% if primitive %} + {{ block('form_widget_primitive') }} {% else %} - {{ block('input') }} + {{ block('form_widget_complex') }} {% endif %} {% endspaceless %} {% endblock form_widget %} +{% block form_widget_primitive %} +{% spaceless %} + {% set type = type|default('text') %} + +{% endspaceless %} +{% endblock form_widget_primitive %} + +{% block form_widget_complex %} +{% spaceless %} +
+ {{ block('form_rows') }} + {{ form_rest(form) }} +
+{% endspaceless %} +{% endblock form_widget_complex %} + {% block collection_widget %} {% spaceless %} {% if prototype is defined %} @@ -28,49 +41,61 @@ {% endspaceless %} {% endblock textarea_widget %} -{% block widget_choice_options %} +{% block choice_widget %} {% spaceless %} - {% for index, choice in options %} - {% if _form_is_choice_group(choice) %} - - {% for nested_choice in choice %} - - {% endfor %} - - {% else %} - - {% endif %} + {% if expanded %} + {{ block('choice_widget_expanded') }} + {% else %} + {{ block('choice_widget_collapsed') }} + {% endif %} +{% endspaceless %} +{% endblock choice_widget %} + +{% block choice_widget_expanded %} +{% spaceless %} +
+ {% for child in form %} + {{ form_widget(child) }} + {{ form_label(child) }} {% endfor %} +
{% endspaceless %} -{% endblock widget_choice_options %} +{% endblock choice_widget_expanded %} -{% block choice_widget %} +{% block choice_widget_collapsed %} {% spaceless %} - {% if expanded %} -
- {% for child in form %} - {{ form_widget(child) }} - {{ form_label(child) }} - {% endfor %} -
- {% else %} - {% endif %} {% endspaceless %} -{% endblock choice_widget %} +{% endblock choice_widget_collapsed %} + +{% block choice_widget_options %} +{% spaceless %} + {% for index, choice in options %} + {% if _form_is_choice_group(choice) %} + + {% for nested_choice in choice %} + + {% endfor %} + + {% else %} + + {% endif %} + {% endfor %} +{% endspaceless %} +{% endblock choice_widget_options %} {% block checkbox_widget %} {% spaceless %} @@ -87,7 +112,7 @@ {% block datetime_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% else %}
{{ form_errors(form.date) }} @@ -102,7 +127,7 @@ {% block date_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% else %}
{{ date_pattern|replace({ @@ -118,7 +143,7 @@ {% block time_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% 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 %} @@ -131,81 +156,77 @@ {% spaceless %} {# type="number" doesn't work with floats #} {% set type = type|default('text') %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% endspaceless %} {% endblock number_widget %} {% block integer_widget %} {% spaceless %} {% set type = type|default('number') %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% endspaceless %} {% endblock integer_widget %} {% block money_widget %} {% spaceless %} - {{ money_pattern|replace({ '{{ widget }}': block('input') })|raw }} + {{ money_pattern|replace({ '{{ widget }}': block('form_widget_primitive') })|raw }} {% endspaceless %} {% endblock money_widget %} {% block url_widget %} {% spaceless %} {% set type = type|default('url') %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% endspaceless %} {% endblock url_widget %} {% block search_widget %} {% spaceless %} {% set type = type|default('search') %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% endspaceless %} {% endblock search_widget %} {% block percent_widget %} {% spaceless %} {% set type = type|default('text') %} - {{ block('input') }} % + {{ block('form_widget_primitive') }} % {% endspaceless %} {% endblock percent_widget %} {% block password_widget %} {% spaceless %} {% set type = type|default('password') %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% endspaceless %} {% endblock password_widget %} {% block hidden_widget %} +{% spaceless %} {% set type = type|default('hidden') %} - {{ block('input') }} + {{ block('form_widget_primitive') }} +{% endspaceless %} {% endblock hidden_widget %} {% block email_widget %} {% spaceless %} {% set type = type|default('email') %} - {{ block('input') }} + {{ block('form_widget_primitive') }} {% endspaceless %} {% endblock email_widget %} {# Labels #} -{% block generic_label %} +{% block form_label %} {% spaceless %} + {% if primitive %} + {% set attr = attr|merge({'for': id}) %} + {% endif %} {% if required %} {% set attr = attr|merge({'class': attr.class|default('') ~ ' required'}) %} {% endif %} {{ label|trans({}, translation_domain) }} {% endspaceless %} -{% endblock %} - -{% block form_label %} -{% spaceless %} - {% if form.children|length == 0 %} - {% set attr = attr|merge({'for': id}) %} - {% endif %} - {{ block('generic_label') }} -{% endspaceless %} {% endblock form_label %} {# Rows #} @@ -220,7 +241,9 @@ {% spaceless %}
{{ form_label(form, label|default(null)) }} - {% if form.children|length == 0 %} + {# If the child is a form, the errors are rendered inside the container #} + {# see block form_rows #} + {% if primitive %} {{ form_errors(form) }} {% endif %} {{ form_widget(form) }} @@ -247,10 +270,8 @@ {% for error in errors %}
  • {{ error.messagePluralization is null - ? - error.messageTemplate|trans(error.messageParameters, 'validators') - : - error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators') + ? error.messageTemplate|trans(error.messageParameters, 'validators') + : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators') }}
  • {% endfor %} @@ -279,13 +300,6 @@ {% endspaceless %} {% endblock form_rows %} -{% block input %} -{% spaceless %} - {% set type = type|default('text') %} - -{% endspaceless %} -{% endblock input %} - {% block widget_attributes %} {% spaceless %} id="{{ id }}" name="{{ full_name }}"{% if read_only %} readonly="readonly"{% endif %}{% if disabled %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %} @@ -302,44 +316,12 @@ {# Deprecated in Symfony 2.1, to be removed in 2.3 #} -{% block field_widget %} -{% spaceless %} - {{ block('input') }} -{% endspaceless %} -{% endblock field_widget %} - -{% block field_label %} -{% spaceless %} - {{ block('form_label') }} -{% endspaceless %} -{% endblock field_label %} - -{% block field_row %} -{% spaceless %} - {{ block('form_row') }} -{% endspaceless %} -{% endblock field_row %} - -{% block field_enctype %} -{% spaceless %} - {{ block('form_enctype') }} -{% endspaceless %} -{% endblock field_enctype %} - -{% block field_errors %} -{% spaceless %} - {{ block('form_errors') }} -{% endspaceless %} -{% endblock field_errors %} - -{% block field_rest %} -{% spaceless %} - {{ block('form_rest') }} -{% endspaceless %} -{% endblock field_rest %} - -{% block field_rows %} -{% spaceless %} - {{ block('form_rows') }} -{% endspaceless %} -{% endblock field_rows %} \ No newline at end of file +{% block generic_label %}{{ block('form_label') }}{% endblock %} +{% block widget_choice_options %}{{ block('choice_widget_options') }}{% endblock %} +{% block field_widget %}{{ block('form_widget_primitive') }}{% endblock %} +{% block field_label %}{{ block('form_label') }}{% endblock %} +{% block field_row %}{{ block('form_row') }}{% endblock %} +{% block field_enctype %}{{ block('form_enctype') }}{% endblock %} +{% block field_errors %}{{ block('form_errors') }}{% endblock %} +{% block field_rest %}{{ block('form_rest') }}{% endblock %} +{% block field_rows %}{{ block('form_rows') }}{% endblock %} \ No newline at end of file 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 b053c59e6f7e1..69ef373fdda3e 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 form.children|length == 0 %} + {% if primitive %} {{ form_errors(form) }} {% endif %} {{ form_widget(form) }} @@ -18,7 +18,9 @@ {% block form_errors %} {% spaceless %} - {% if form.children|length > 0 %} + {% if primitive %} + {{ parent() }} + {% else %} {% if errors|length > 0 %} @@ -26,8 +28,6 @@ {% endif %} - {% else %} - {{ parent() }} {% endif %} {% endspaceless %} {% endblock form_errors %} @@ -42,15 +42,11 @@ {% endspaceless %} {% endblock hidden_row %} -{% block form_widget %} +{% block form_widget_complex %} {% spaceless %} - {% if form.children|length > 0 %} - - {{ block('form_rows') }} - {{ form_rest(form) }} -
    - {% else %} - {{ parent() }} - {% endif %} + + {{ block('form_rows') }} + {{ form_rest(form) }} +
    {% endspaceless %} -{% endblock form_widget %} +{% endblock form_widget_complex %} diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig b/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig index ee5b19e0737d8..517dd4549b54a 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 input %} +{% block form_widget_primitive %} {% spaceless %} {% set type = type|default('text') %} - + {% endspaceless %} -{% endblock input %} +{% endblock form_widget_primitive %} 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 f58e589498dae..c34955139c6fc 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 input %} +{% block form_widget_primitive %} {% spaceless %} {% set type = type|default('text') %} - + {% endspaceless %} -{% endblock input %} +{% endblock form_widget_primitive %} 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 9304e9dcfa94d..ef7025efcc117 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 input %} +{% block form_widget_primitive %} {% spaceless %} {% set type = type|default('text') %} - + {% endspaceless %} -{% endblock input %} +{% endblock form_widget_primitive %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/attributes.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/attributes.html.php index fe4afa01d2e61..12366d6e44655 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/attributes.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/attributes.html.php @@ -1,9 +1 @@ -id="escape($id) ?>" -name="escape($full_name) ?>" -readonly="readonly" -disabled="disabled" -required="required" -maxlength="escape($max_length) ?>" -pattern="escape($pattern) ?>" - $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?> - +renderBlock('widget_attributes') ?> \ No newline at end of file diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php index 921f4af25bbff..fff427db11119 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/checkbox_widget.html.php @@ -1,5 +1,5 @@ renderBlock('attributes') ?> + renderBlock('widget_attributes') ?> value="escape($value) ?>" checked="checked" /> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_options.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_options.html.php index 66c664fb1d620..298df7b3001c0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_options.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_options.html.php @@ -1,11 +1 @@ - $choice): ?> - isChoiceGroup($choice)): ?> - - - - - - - - - +renderBlock('choice_widget_options') ?> \ No newline at end of file diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php index e54bdb4df8423..99db4acfae15b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php @@ -1,22 +1,5 @@ -
    renderBlock('container_attributes') ?>> - - widget($child) ?> - label($child) ?> - -
    +renderBlock('choice_widget_expanded') ?> - +renderBlock('choice_widget_collapsed') ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php new file mode 100644 index 0000000000000..b0c601ea8f9a4 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php @@ -0,0 +1,13 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_expanded.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_expanded.html.php new file mode 100644 index 0000000000000..58de38d646988 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_expanded.html.php @@ -0,0 +1,6 @@ +
    renderBlock('widget_container_attributes') ?>> + + widget($child) ?> + label($child) ?> + +
    diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_options.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_options.html.php new file mode 100644 index 0000000000000..66c664fb1d620 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_options.html.php @@ -0,0 +1,11 @@ + $choice): ?> + isChoiceGroup($choice)): ?> + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php index a36cfbbdfc462..e132ed73c4c2a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/container_attributes.html.php @@ -1,2 +1 @@ -id="escape($id) ?>" - $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?> +renderBlock('widget_container_attributes') ?> \ No newline at end of file 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 bd2c2769af420..14ef80f00f1c4 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,7 +1,7 @@ - renderBlock('input'); ?> + renderBlock('form_widget_primitive'); ?> -
    renderBlock('container_attributes') ?>> +
    renderBlock('widget_container_attributes') ?>> widget($form['year']), $view['form']->widget($form['month']), diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php index f71bd64e377f3..fdb1258c14b92 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/datetime_widget.html.php @@ -1,7 +1,7 @@ - renderBlock('input'); ?> + renderBlock('form_widget_primitive'); ?> -
    renderBlock('container_attributes') ?>> +
    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 a00dda278e983..388259f2d09d3 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('input', array('type' => isset($type) ? $type : 'email')) ?> +renderBlock('form_widget_primitive', 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 f1ca2edadbfda..d47f413bf4e6b 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('input') ?> \ No newline at end of file +renderBlock('form_widget_primitive') ?> \ No newline at end of file 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 3ddc300fd4540..f46d91bf459c6 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 @@ -hasChildren()) { $attr['for'] = $id; } ?> + 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 02fb9ae9b635c..f837415297c54 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) ?> - hasChildren()): ?> + 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 1c9368693b49c..137a50eca5cc2 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,8 +1,5 @@ -hasChildren()): ?> -
    renderBlock('container_attributes') ?>> - renderBlock('form_rows') ?> - rest($form) ?> -
    + +renderBlock('form_widget_primitive')?> -renderBlock('input')?> +renderBlock('form_widget_complex')?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_complex.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_complex.html.php new file mode 100644 index 0000000000000..ee349d1bd7290 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_complex.html.php @@ -0,0 +1,4 @@ +
    renderBlock('widget_container_attributes') ?>> + renderBlock('form_rows') ?> + rest($form) ?> +
    \ No newline at end of file diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_primitive.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_primitive.html.php new file mode 100644 index 0000000000000..29649cfbd6065 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_primitive.html.php @@ -0,0 +1,5 @@ +value="escape($value) ?>" + renderBlock('widget_attributes') ?> +/> 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 50a42451aef26..e1354a64a0aff 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('input', array('type' => isset($type) ? $type : "hidden")) ?> +renderBlock('form_widget_primitive', array('type' => isset($type) ? $type : "hidden")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/input.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/input.html.php deleted file mode 100644 index 0c8648338639a..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/input.html.php +++ /dev/null @@ -1,5 +0,0 @@ -" - value="escape($value) ?>" - renderBlock('attributes') ?> -/> 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 1fc6ace34b4fb..6dee8dea13ae9 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('input', array('type' => isset($type) ? $type : "number")) ?> +renderBlock('form_widget_primitive', 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 a68ad5ddacb10..1dcf72d4637b8 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('input'), $money_pattern) ?> +renderBlock('form_widget_primitive'), $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 7e1a2776a7d49..7b5152d4680a8 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('input', array('type' => isset($type) ? $type : "text")) ?> +renderBlock('form_widget_primitive', 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 7aff242ef43cc..469bdd667d72a 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('input', array('type' => isset($type) ? $type : "password")) ?> +renderBlock('form_widget_primitive', 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 328321f21fcae..d67bb38246b8b 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('input', array('type' => isset($type) ? $type : "text")) ?> % +renderBlock('form_widget_primitive', array('type' => isset($type) ? $type : "text")) ?> % diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php index daa16dbc6298f..3ecad14ca2ec8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/radio_widget.html.php @@ -1,5 +1,5 @@ renderBlock('attributes') ?> + renderBlock('widget_attributes') ?> value="escape($value) ?>" checked="checked" /> 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 d8a773544e713..2678205f36fdd 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('input', array('type' => isset($type) ? $type : "search")) ?> +renderBlock('form_widget_primitive', array('type' => isset($type) ? $type : "search")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php index 11a786d69c487..a82744b8e0684 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/textarea_widget.html.php @@ -1 +1 @@ - + 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 2178974c74c4c..ade5582b6693e 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,7 +1,7 @@ - renderBlock('input'); ?> + renderBlock('form_widget_primitive'); ?> -
    renderBlock('container_attributes') ?>> +
    renderBlock('widget_container_attributes') ?>> renderBlock('input', array('type' => isset($type) ? $type : "url")) ?> +renderBlock('form_widget_primitive', array('type' => isset($type) ? $type : "url")) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php new file mode 100644 index 0000000000000..fe4afa01d2e61 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php @@ -0,0 +1,9 @@ +id="escape($id) ?>" +name="escape($full_name) ?>" +readonly="readonly" +disabled="disabled" +required="required" +maxlength="escape($max_length) ?>" +pattern="escape($pattern) ?>" + $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?> + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_container_attributes.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_container_attributes.html.php new file mode 100644 index 0000000000000..a36cfbbdfc462 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_container_attributes.html.php @@ -0,0 +1,2 @@ +id="escape($id) ?>" + $v) { printf('%s="%s" ', $view->escape($k), $view->escape($v)); } ?> 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 05d8c4aea89d3..b3e732ef96e72 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,26 @@ -hasChildren()): ?> + + +
      + +
    • getMessagePluralization()) { + echo $view['translator']->trans( + $error->getMessageTemplate(), + $error->getMessageParameters(), + 'validators' + ); + } else { + echo $view['translator']->transChoice( + $error->getMessageTemplate(), + $error->getMessagePluralization(), + $error->getMessageParameters(), + 'validators' + ); + }?>
    • + +
    + + 0): ?> @@ -26,26 +48,4 @@ - - -
      - -
    • getMessagePluralization()) { - echo $view['translator']->trans( - $error->getMessageTemplate(), - $error->getMessageParameters(), - 'validators' - ); - } else { - echo $view['translator']->transChoice( - $error->getMessageTemplate(), - $error->getMessagePluralization(), - $error->getMessageParameters(), - 'validators' - ); - }?>
    • - -
    - \ No newline at end of file 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 9262a1bae10b3..3e6d7ba05f422 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) ?> - hasChildren()): ?> + errors($form) ?> widget($form) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget.html.php deleted file mode 100644 index 171f1eb40c74e..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget.html.php +++ /dev/null @@ -1,8 +0,0 @@ -hasChildren()): ?> -renderBlock('container_attributes') ?>> - renderBlock('form_rows') ?> - rest($form) ?> -
    - -renderBlock('input')?> - diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_complex.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_complex.html.php new file mode 100644 index 0000000000000..9c90f15e58fc9 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_complex.html.php @@ -0,0 +1,4 @@ +renderBlock('widget_container_attributes') ?>> + renderBlock('form_rows') ?> + rest($form) ?> +
    diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/input.html.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_primitive.html.php similarity index 60% rename from src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/input.html.php rename to src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_primitive.html.php index 64f43ddf6eb1b..6506f9140eeab 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/input.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_primitive.html.php @@ -1,2 +1,2 @@ -renderBlock('attributes') ?> value="" rel="theme" /> +renderBlock('widget_attributes') ?> value="" rel="theme" /> diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index f6f32633e5f1d..c1849cb7b0d38 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -25,16 +25,12 @@ CHANGELOG * [BC BREAK] removed EntitiesToArrayTransformer and EntityToIdTransformer. The former has been replaced by CollectionToArrayTransformer in combination with EntityChoiceList, the latter is not required in the core anymore. - * [BC BREAK] renamed - * ArrayToBooleanChoicesTransformer to ChoicesToBooleanArrayTransformer * ScalarToBooleanChoicesTransformer to ChoiceToBooleanArrayTransformer * ArrayToChoicesTransformer to ChoicesToValuesTransformer * ScalarToChoiceTransformer to ChoiceToValueTransformer - - to be consistent with the naming in ChoiceListInterface. - + to be consistent with the naming in ChoiceListInterface. * [BC BREAK] removed FormUtil::toArrayKey() and FormUtil::toArrayKeys(). They were merged into ChoiceList and have no public equivalent anymore. * choice fields now throw a FormException if neither the "choices" nor the @@ -62,8 +58,13 @@ CHANGELOG by event subscribers * simplified CSRF protection and removed the csrf type * deprecated FieldType and merged it into FormType - * [BC BREAK] renamed "field_*" theme blocks to "form_*" and "field_widget" to - "input" + * [BC BREAK] renamed theme blocks + * "field_*" to "form_*" + * "field_widget" to "form_widget_primitive" + * "widget_choice_options" to "choice_widget_options" + * "generic_label" to "form_label" + * added theme blocks "form_widget_complex", "choice_widget_expanded" and + "choice_widget_collapsed" to make theming more modular * ValidatorTypeGuesser now guesses "collection" for array type constraint * added method `guessPattern` to FormTypeGuesserInterface to guess which pattern to use in the HTML5 attribute "pattern" * deprecated method `guessMinLength` in favor of `guessPattern` diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php b/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php index 8ab2c6843d0ae..cd48c2952ce73 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php @@ -46,11 +46,14 @@ public function buildView(FormView $view, FormInterface $form) */ public function getDefaultOptions() { + $emptyData = function (FormInterface $form, $clientData) { + return $clientData; + }; + return array( - 'value' => '1', - 'empty_data' => function (FormInterface $form, $clientData) { - return $clientData; - }, + 'value' => '1', + 'empty_data' => $emptyData, + 'primitive' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index 1a8ba2d1be6a2..09cacecb52994 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -165,6 +165,10 @@ public function getDefaultOptions() return $options['required'] ? null : ''; }; + $primitive = function (Options $options) { + return !$options['expanded']; + }; + return array( 'multiple' => false, 'expanded' => false, @@ -174,6 +178,7 @@ public function getDefaultOptions() 'empty_data' => $emptyData, 'empty_value' => $emptyValue, 'error_bubbling' => false, + 'primitive' => $primitive, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php index f428054edee74..cbd23ea2adc3e 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php @@ -21,6 +21,7 @@ use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\ArrayToPartsTransformer; +use Symfony\Component\Form\Options; class DateTimeType extends AbstractType { @@ -130,6 +131,10 @@ public function buildView(FormView $view, FormInterface $form) */ public function getDefaultOptions() { + $primitive = function (Options $options) { + return $options['widget'] === 'single_text'; + }; + return array( 'input' => 'datetime', 'data_timezone' => null, @@ -158,6 +163,7 @@ public function getDefaultOptions() // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, + 'primitive' => $primitive, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index c506714c7ffd3..a6f74c81c5daa 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -11,18 +11,18 @@ namespace Symfony\Component\Form\Extension\Core\Type; -use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; - use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormBuilder; use Symfony\Component\Form\Exception\CreationException; use Symfony\Component\Form\FormView; +use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; 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\Form\Options; class DateType extends AbstractType { @@ -163,6 +163,10 @@ public function buildViewBottomUp(FormView $view, FormInterface $form) */ public function getDefaultOptions() { + $primitive = function (Options $options) { + return $options['widget'] === 'single_text'; + }; + return array( 'years' => range(date('Y') - 5, date('Y') + 5), 'months' => range(1, 12), @@ -182,6 +186,7 @@ public function getDefaultOptions() // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, + 'primitive' => $primitive, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index 468c65a0f359a..ac44c5d8bd366 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -38,6 +38,16 @@ public function buildViewBottomUp(FormView $view, FormInterface $form) ; } + /** + * {@inheritdoc} + */ + public function getDefaultOptions() + { + return array( + 'primitive' => true, + ); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index ec5870acff7d3..29d5ed240cb56 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -61,6 +61,7 @@ public function buildForm(FormBuilder $builder, array $options) ->setAttribute('invalid_message_parameters', $options['invalid_message_parameters']) ->setAttribute('translation_domain', $options['translation_domain']) ->setAttribute('virtual', $options['virtual']) + ->setAttribute('primitive', $options['primitive']) ->setData($options['data']) ->setDataMapper(new PropertyPathMapper($options['data_class'])) ->addEventSubscriber(new ValidationListener()) @@ -125,6 +126,7 @@ public function buildView(FormView $view, FormInterface $form) ->set('label', $form->getAttribute('label')) ->set('multipart', false) ->set('attr', $form->getAttribute('attr')) + ->set('primitive', $form->getAttribute('primitive')) ->set('types', $types) ->set('translation_domain', $form->getAttribute('translation_domain')) ; @@ -201,6 +203,7 @@ public function getDefaultOptions() 'label' => null, 'attr' => array(), 'virtual' => false, + 'primitive' => false, 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'translation_domain' => 'messages', diff --git a/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php b/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php index 71066250624af..2d2c3e61d135c 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php @@ -25,6 +25,7 @@ public function getDefaultOptions() 'required' => false, // Pass errors to the parent 'error_bubbling' => true, + 'primitive' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php b/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php index 9beaed51029bf..286bc4dfbf6b1 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php @@ -41,6 +41,7 @@ public function getDefaultOptions() 'grouping' => false, // Integer cast rounds towards 0, so do the same when displaying fractions 'rounding_mode' => \NumberFormatter::ROUND_DOWN, + 'primitive' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php index 1f87f3a2a6872..cba4f8fe6f7d1 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php @@ -55,6 +55,7 @@ public function getDefaultOptions() 'grouping' => false, 'divisor' => 1, 'currency' => 'EUR', + 'primitive' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php b/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php index 21ea17046e760..cac3024990f0e 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php @@ -39,6 +39,7 @@ public function getDefaultOptions() 'precision' => null, 'grouping' => false, 'rounding_mode' => \NumberFormatter::ROUND_HALFUP, + 'primitive' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php b/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php index ea6550869a244..2ef7449186d0d 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php @@ -33,6 +33,7 @@ public function getDefaultOptions() return array( 'precision' => 0, 'type' => 'fractional', + 'primitive' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php index 28003119340d1..dd23e7b38ff1f 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php @@ -27,6 +27,16 @@ public function buildForm(FormBuilder $builder, array $options) ; } + /** + * {@inheritdoc} + */ + public function getDefaultOptions() + { + return array( + 'primitive' => true, + ); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index 546220d0ab318..7e5892d7d68c7 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -20,6 +20,7 @@ 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\Options; class TimeType extends AbstractType { @@ -136,6 +137,10 @@ public function buildView(FormView $view, FormInterface $form) */ public function getDefaultOptions() { + $primitive = function (Options $options) { + return $options['widget'] === 'single_text'; + }; + return array( 'hours' => range(0, 23), 'minutes' => range(0, 59), @@ -155,6 +160,7 @@ public function getDefaultOptions() // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, + 'primitive' => $primitive, ); } diff --git a/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php index 07813061886ba..19c9b60bc67ee 100644 --- a/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php @@ -277,6 +277,19 @@ public function testCollection() ); } + public function testEmptyCollection() + { + $form = $this->factory->createNamed('collection', 'name', array(), array( + 'type' => 'text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/div + [count(./div)=0] +' + ); + } + public function testCollectionRow() { $collection = $this->factory->createNamedBuilder( diff --git a/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php index f6edbce25a440..d786cdec012c1 100644 --- a/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php @@ -170,6 +170,19 @@ public function testCollection() ); } + public function testEmptyCollection() + { + $form = $this->factory->createNamed('collection', 'name', array(), array( + 'type' => 'text', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array(), +'/table + [count(./tr[./td/input])=0] +' + ); + } + public function testForm() { $view = $this->factory->createNamedBuilder('form', 'name') diff --git a/src/Symfony/Component/Form/Tests/FormFactoryTest.php b/src/Symfony/Component/Form/Tests/FormFactoryTest.php index 206fa5eccf396..a45395921c055 100644 --- a/src/Symfony/Component/Form/Tests/FormFactoryTest.php +++ b/src/Symfony/Component/Form/Tests/FormFactoryTest.php @@ -619,8 +619,8 @@ public function testUnknownOptions() '"attr", "by_reference", "data", "data_class", "disabled", ' . '"empty_data", "error_bubbling", "error_mapping", "invalid_message", ' . '"invalid_message_parameters", "label", "max_length", "pattern", ' . - '"property_path", "read_only", "required", "translation_domain", ' . - '"trim"' + '"primitive", "property_path", "read_only", "required", ' . + '"translation_domain", "trim"' ); $factory->createNamedBuilder($type, "text", "value", array("invalid" => "opt", "unknown" => "opt")); } @@ -636,8 +636,8 @@ public function testUnknownOption() '"by_reference", "data", "data_class", "disabled", "empty_data", ' . '"error_bubbling", "error_mapping", "invalid_message", ' . '"invalid_message_parameters", "label", "max_length", "pattern", ' . - '"property_path", "read_only", "required", "translation_domain", ' . - '"trim"' + '"primitive", "property_path", "read_only", "required", ' . + '"translation_domain", "trim"' ); $factory->createNamedBuilder($type, "text", "value", array("unknown" => "opt")); } From c623fcf4d417b214f9d3bb0276aafc328af09a68 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 20 Apr 2012 18:51:15 +0200 Subject: [PATCH 2/7] [Form] Fixed: CSRF protection did not run if token was missing --- .../EventListener/CsrfValidationListener.php | 4 +-- .../Csrf/Type/FormTypeCsrfExtensionTest.php | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php index dd74d87b2eaea..1c7a1edfaaa11 100644 --- a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php +++ b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php @@ -63,8 +63,8 @@ public function onBindClientData(FilterDataEvent $event) $form = $event->getForm(); $data = $event->getData(); - if ($form->isRoot() && $form->hasChildren() && isset($data[$this->fieldName])) { - if (!$this->csrfProvider->isCsrfTokenValid($this->intention, $data[$this->fieldName])) { + if ($form->isRoot() && $form->hasChildren()) { + 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/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php index 4424f81e14140..0d269d0267c62 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php @@ -171,6 +171,32 @@ public function testValidateTokenOnBindIfRootAndChildren($valid) $this->assertSame($valid, $form->isValid()); } + public function testFailIfRootAndChildrenAndTokenMissing() + { + $this->csrfProvider->expects($this->never()) + ->method('isCsrfTokenValid'); + + $form = $this->factory + ->createBuilder('form', null, array( + 'csrf_field_name' => 'csrf', + 'csrf_provider' => $this->csrfProvider, + 'intention' => '%INTENTION%' + )) + ->add($this->factory->createNamedBuilder('form', 'child')) + ->getForm(); + + $form->bind(array( + 'child' => 'foobar', + // token is missing + )); + + // Remove token from data + $this->assertSame(array('child' => 'foobar'), $form->getData()); + + // Validate accordingly + $this->assertFalse($form->isValid()); + } + public function testDontValidateTokenIfChildrenButNoRoot() { $this->csrfProvider->expects($this->never()) From 649752c947d17b46ecbede055c959a09aeb99693 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 20 Apr 2012 18:58:52 +0200 Subject: [PATCH 3/7] [Form] Fixed: CSRF token was not displayed on empty complex forms --- .../EventListener/CsrfValidationListener.php | 2 +- .../Csrf/Type/FormTypeCsrfExtension.php | 2 +- .../Form/Tests/AbstractDivLayoutTest.php | 1 + .../Form/Tests/AbstractTableLayoutTest.php | 3 +- .../Csrf/Type/FormTypeCsrfExtensionTest.php | 71 +++++++++---------- 5 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php index 1c7a1edfaaa11..7b05185878202 100644 --- a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php +++ b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php @@ -63,7 +63,7 @@ public function onBindClientData(FilterDataEvent $event) $form = $event->getForm(); $data = $event->getData(); - if ($form->isRoot() && $form->hasChildren()) { + if ($form->isRoot() && !$form->getAttribute('primitive')) { 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 8145e8e5755d6..9bff7cc12878b 100644 --- a/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php +++ b/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php @@ -64,7 +64,7 @@ public function buildForm(FormBuilder $builder, array $options) */ public function buildViewBottomUp(FormView $view, FormInterface $form) { - if (!$view->hasParent() && $view->hasChildren() && $form->hasAttribute('csrf_field_name')) { + if (!$view->hasParent() && !$form->getAttribute('primitive') && $form->hasAttribute('csrf_field_name')) { $name = $form->getAttribute('csrf_field_name'); $csrfProvider = $form->getAttribute('csrf_provider'); $intention = $form->getAttribute('csrf_intention'); diff --git a/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php index 19c9b60bc67ee..6f0675cba5804 100644 --- a/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php @@ -285,6 +285,7 @@ public function testEmptyCollection() $this->assertWidgetMatchesXpath($form->createView(), array(), '/div + [./input[@type="hidden"][@id="name__token"]] [count(./div)=0] ' ); diff --git a/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php index d786cdec012c1..9bf77d9c59ee4 100644 --- a/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php @@ -178,7 +178,8 @@ public function testEmptyCollection() $this->assertWidgetMatchesXpath($form->createView(), array(), '/table - [count(./tr[./td/input])=0] + [./tr[@style="display: none"][./td[@colspan="2"]/input[@type="hidden"][@id="name__token"]]] + [count(./tr[./td/input])=1] ' ); } 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 0d269d0267c62..bb03c601b4f22 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php @@ -56,43 +56,42 @@ protected function getExtensions() )); } - public function testCsrfProtectionByDefaultIfRootAndChildren() + public function testCsrfProtectionByDefaultIfRootAndNotPrimitive() { $view = $this->factory - ->createBuilder('form', null, array( + ->create('form', null, array( 'csrf_field_name' => 'csrf', + 'primitive' => false, )) - ->add($this->factory->createNamedBuilder('form', 'child')) - ->getForm() ->createView(); $this->assertTrue($view->hasChild('csrf')); } - public function testNoCsrfProtectionByDefaultIfChildrenButNotRoot() + public function testNoCsrfProtectionByDefaultIfNotPrimitiveButNotRoot() { $view = $this->factory ->createNamedBuilder('form', 'root') ->add($this->factory ->createNamedBuilder('form', 'form', null, array( 'csrf_field_name' => 'csrf', + 'primitive' => false, )) - ->add($this->factory->createNamedBuilder('form', 'child')) ) ->getForm() - ->get('form') - ->createView(); + ->createView() + ->getChild('form'); $this->assertFalse($view->hasChild('csrf')); } - public function testNoCsrfProtectionByDefaultIfRootButNoChildren() + public function testNoCsrfProtectionByDefaultIfRootButPrimitive() { $view = $this->factory - ->createBuilder('form', null, array( + ->create('form', null, array( 'csrf_field_name' => 'csrf', + 'primitive' => true, )) - ->getForm() ->createView(); $this->assertFalse($view->hasChild('csrf')); @@ -101,12 +100,11 @@ public function testNoCsrfProtectionByDefaultIfRootButNoChildren() public function testCsrfProtectionCanBeDisabled() { $view = $this->factory - ->createBuilder('form', null, array( + ->create('form', null, array( 'csrf_field_name' => 'csrf', 'csrf_protection' => false, + 'primitive' => false, )) - ->add($this->factory->createNamedBuilder('form', 'child')) - ->getForm() ->createView(); $this->assertFalse($view->hasChild('csrf')); @@ -120,13 +118,12 @@ public function testGenerateCsrfToken() ->will($this->returnValue('token')); $view = $this->factory - ->createBuilder('form', null, array( + ->create('form', null, array( 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, - 'intention' => '%INTENTION%' + 'intention' => '%INTENTION%', + 'primitive' => false, )) - ->add($this->factory->createNamedBuilder('form', 'child')) - ->getForm() ->createView(); $this->assertEquals('token', $view->getChild('csrf')->get('value')); @@ -143,7 +140,7 @@ public function provideBoolean() /** * @dataProvider provideBoolean */ - public function testValidateTokenOnBindIfRootAndChildren($valid) + public function testValidateTokenOnBindIfRootAndNotPrimitive($valid) { $this->csrfProvider->expects($this->once()) ->method('isCsrfTokenValid') @@ -151,13 +148,12 @@ public function testValidateTokenOnBindIfRootAndChildren($valid) ->will($this->returnValue($valid)); $form = $this->factory - ->createBuilder('form', null, array( + ->create('form', null, array( 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, - 'intention' => '%INTENTION%' - )) - ->add($this->factory->createNamedBuilder('form', 'child')) - ->getForm(); + 'intention' => '%INTENTION%', + 'primitive' => false, + )); $form->bind(array( 'child' => 'foobar', @@ -171,19 +167,18 @@ public function testValidateTokenOnBindIfRootAndChildren($valid) $this->assertSame($valid, $form->isValid()); } - public function testFailIfRootAndChildrenAndTokenMissing() + public function testFailIfRootAndNotPrimitiveAndTokenMissing() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); $form = $this->factory - ->createBuilder('form', null, array( + ->create('form', null, array( 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, - 'intention' => '%INTENTION%' - )) - ->add($this->factory->createNamedBuilder('form', 'child')) - ->getForm(); + 'intention' => '%INTENTION%', + 'primitive' => false, + )); $form->bind(array( 'child' => 'foobar', @@ -197,7 +192,7 @@ public function testFailIfRootAndChildrenAndTokenMissing() $this->assertFalse($form->isValid()); } - public function testDontValidateTokenIfChildrenButNoRoot() + public function testDontValidateTokenIfNotPrimitiveButNoRoot() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); @@ -208,9 +203,9 @@ public function testDontValidateTokenIfChildrenButNoRoot() ->createNamedBuilder('form', 'form', null, array( 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, - 'intention' => '%INTENTION%' + 'intention' => '%INTENTION%', + 'primitive' => false, )) - ->add($this->factory->createNamedBuilder('form', 'child')) ) ->getForm() ->get('form'); @@ -221,18 +216,18 @@ public function testDontValidateTokenIfChildrenButNoRoot() )); } - public function testDontValidateTokenIfRootButNoChildren() + public function testDontValidateTokenIfRootButPrimitive() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); $form = $this->factory - ->createBuilder('form', null, array( + ->create('form', null, array( 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, - 'intention' => '%INTENTION%' - )) - ->getForm(); + 'intention' => '%INTENTION%', + 'primitive' => true, + )); $form->bind(array( 'csrf' => 'token', From 68018a10dac1e019c62d2523be12129fa3c5d1d7 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 20 Apr 2012 19:39:34 +0200 Subject: [PATCH 4/7] [Form] Dropped useless test that is guaranteed by OptionsParser tests and that needs to be adapted very often --- .../Component/Form/Tests/FormFactoryTest.php | 35 +------------------ 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/FormFactoryTest.php b/src/Symfony/Component/Form/Tests/FormFactoryTest.php index a45395921c055..4b8eb3f3a9329 100644 --- a/src/Symfony/Component/Form/Tests/FormFactoryTest.php +++ b/src/Symfony/Component/Form/Tests/FormFactoryTest.php @@ -608,41 +608,8 @@ public function testCreateNamedBuilderFromParentBuilder() $this->assertEquals($parentBuilder, $builder->getParent()); } - public function testUnknownOptions() - { - $type = new \Symfony\Component\Form\Extension\Core\Type\TextType(); - - $factory = new FormFactory(array(new \Symfony\Component\Form\Extension\Core\CoreExtension())); - - $this->setExpectedException('Symfony\Component\Form\Exception\InvalidOptionException', - 'The options "invalid", "unknown" do not exist. Known options are: ' . - '"attr", "by_reference", "data", "data_class", "disabled", ' . - '"empty_data", "error_bubbling", "error_mapping", "invalid_message", ' . - '"invalid_message_parameters", "label", "max_length", "pattern", ' . - '"primitive", "property_path", "read_only", "required", ' . - '"translation_domain", "trim"' - ); - $factory->createNamedBuilder($type, "text", "value", array("invalid" => "opt", "unknown" => "opt")); - } - - public function testUnknownOption() - { - $type = new \Symfony\Component\Form\Extension\Core\Type\TextType(); - - $factory = new FormFactory(array(new \Symfony\Component\Form\Extension\Core\CoreExtension())); - - $this->setExpectedException('Symfony\Component\Form\Exception\InvalidOptionException', - 'The option "unknown" does not exist. Known options are: "attr", ' . - '"by_reference", "data", "data_class", "disabled", "empty_data", ' . - '"error_bubbling", "error_mapping", "invalid_message", ' . - '"invalid_message_parameters", "label", "max_length", "pattern", ' . - '"primitive", "property_path", "read_only", "required", ' . - '"translation_domain", "trim"' - ); - $factory->createNamedBuilder($type, "text", "value", array("unknown" => "opt")); - } - public function testFieldTypeCreatesDefaultValueForEmptyDataOption() + public function testFormTypeCreatesDefaultValueForEmptyDataOption() { $factory = new FormFactory(array(new \Symfony\Component\Form\Extension\Core\CoreExtension())); From 167e64f79992f6366108fde1548e2a2c9552d3c6 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 20 Apr 2012 19:40:14 +0200 Subject: [PATCH 5/7] [Form] Fixed: Field attributes are not rendered in the label anymore. Label attributes are now passed in "label_attr" --- .../views/Form/form_div_layout.html.twig | 6 ++--- .../Resources/views/Form/form_label.html.php | 6 ++--- src/Symfony/Component/Form/CHANGELOG.md | 2 ++ .../Form/Extension/Core/Type/FormType.php | 14 ++++++++--- .../Form/Tests/AbstractLayoutTest.php | 23 ++++++++++++++++--- 5 files changed, 39 insertions(+), 12 deletions(-) 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 8fe3d004fa5d2..46c162712012c 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 @@ -220,12 +220,12 @@ {% block form_label %} {% spaceless %} {% if primitive %} - {% set attr = attr|merge({'for': id}) %} + {% set label_attr = label_attr|merge({'for': id}) %} {% endif %} {% if required %} - {% set attr = attr|merge({'class': attr.class|default('') ~ ' required'}) %} + {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %} {% endif %} - {{ label|trans({}, translation_domain) }} + {{ label|trans({}, translation_domain) }} {% endspaceless %} {% endblock form_label %} 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 f46d91bf459c6..f185683491ec6 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/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index c1849cb7b0d38..56a8554d17da1 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -68,3 +68,5 @@ CHANGELOG * ValidatorTypeGuesser now guesses "collection" for array type constraint * added method `guessPattern` to FormTypeGuesserInterface to guess which pattern to use in the HTML5 attribute "pattern" * deprecated method `guessMinLength` in favor of `guessPattern` + * labels don't display field attributes anymore. Label attributes can be + passed in the "label_attr" option/variable \ No newline at end of file diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index 29d5ed240cb56..b5bf497e8782c 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -40,8 +40,13 @@ public function buildForm(FormBuilder $builder, array $options) } else { $options['property_path'] = new PropertyPath($options['property_path']); } + if (!is_array($options['attr'])) { - throw new FormException('The "attr" option must be "array".'); + 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 @@ -56,7 +61,8 @@ public function buildForm(FormBuilder $builder, array $options) ->setAttribute('max_length', $options['max_length']) ->setAttribute('pattern', $options['pattern']) ->setAttribute('label', $options['label'] ?: $this->humanize($builder->getName())) - ->setAttribute('attr', $options['attr'] ?: array()) + ->setAttribute('attr', $options['attr']) + ->setAttribute('label_attr', $options['label_attr']) ->setAttribute('invalid_message', $options['invalid_message']) ->setAttribute('invalid_message_parameters', $options['invalid_message_parameters']) ->setAttribute('translation_domain', $options['translation_domain']) @@ -126,6 +132,7 @@ public function buildView(FormView $view, FormInterface $form) ->set('label', $form->getAttribute('label')) ->set('multipart', false) ->set('attr', $form->getAttribute('attr')) + ->set('label_attr', $form->getAttribute('label_attr')) ->set('primitive', $form->getAttribute('primitive')) ->set('types', $types) ->set('translation_domain', $form->getAttribute('translation_domain')) @@ -185,7 +192,7 @@ public function getDefaultOptions() return ''; }; }; - + return array( 'data' => null, 'data_class' => $dataClass, @@ -202,6 +209,7 @@ public function getDefaultOptions() 'error_mapping' => array(), 'label' => null, 'attr' => array(), + 'label_attr' => array(), 'virtual' => false, 'primitive' => false, 'invalid_message' => 'This value is not valid.', diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index c75ba7c7a4ff3..7be8193cfe39d 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -155,7 +155,7 @@ public function testLabelOnForm() $this->assertMatchesXpath($html, '/label - [@class=" required"] + [@class="required"] [.="[trans]Name[/trans]"] ' ); @@ -204,7 +204,7 @@ public function testLabelWithCustomTextPassedAsOptionAndDirectly() ); } - public function testLabelWithCustomOptionsPassedDirectly() + public function testLabelDoesNotRenderFieldAttributes() { $form = $this->factory->createNamed('text', 'name'); $html = $this->renderLabel($form->createView(), null, array( @@ -215,6 +215,23 @@ public function testLabelWithCustomOptionsPassedDirectly() $this->assertMatchesXpath($html, '/label + [@for="name"] + [@class="required"] +' + ); + } + + public function testLabelWithCustomOptionsPassedDirectly() + { + $form = $this->factory->createNamed('text', 'name'); + $html = $this->renderLabel($form->createView(), null, array( + 'label_attr' => array( + 'class' => 'my&class' + ), + )); + + $this->assertMatchesXpath($html, +'/label [@for="name"] [@class="my&class required"] ' @@ -225,7 +242,7 @@ public function testLabelWithCustomTextAndCustomOptionsPassedDirectly() { $form = $this->factory->createNamed('text', 'name'); $html = $this->renderLabel($form->createView(), 'Custom label', array( - 'attr' => array( + 'label_attr' => array( 'class' => 'my&class' ), )); From d3bb4d085c9df4e977ce58aedc6ea9cf53f58600 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 27 Apr 2012 10:16:56 +0200 Subject: [PATCH 6/7] [Form] Renamed option 'primitive' to 'single_control' --- UPGRADE-2.1.md | 8 +-- .../views/Form/form_div_layout.html.twig | 50 ++++++++++--------- .../views/Form/form_table_layout.html.twig | 8 +-- .../Twig/Tests/Extension/theme.html.twig | 4 +- .../Tests/Extension/theme_extends.html.twig | 4 +- .../Twig/Tests/Extension/theme_use.html.twig | 4 +- .../Resources/views/Form/date_widget.html.php | 2 +- .../views/Form/datetime_widget.html.php | 2 +- .../views/Form/email_widget.html.php | 2 +- .../views/Form/field_widget.html.php | 2 +- .../Resources/views/Form/form_label.html.php | 2 +- .../Resources/views/Form/form_row.html.php | 2 +- .../Resources/views/Form/form_widget.html.php | 6 +-- ...html.php => form_widget_compound.html.php} | 0 ...hp => form_widget_single_control.html.php} | 0 .../views/Form/hidden_widget.html.php | 2 +- .../views/Form/integer_widget.html.php | 2 +- .../views/Form/money_widget.html.php | 2 +- .../views/Form/number_widget.html.php | 2 +- .../views/Form/password_widget.html.php | 2 +- .../views/Form/percent_widget.html.php | 2 +- .../views/Form/search_widget.html.php | 2 +- .../Resources/views/Form/time_widget.html.php | 2 +- .../Resources/views/Form/url_widget.html.php | 2 +- .../views/FormTable/form_errors.html.php | 2 +- .../views/FormTable/form_row.html.php | 2 +- ...html.php => form_widget_compound.html.php} | 0 ...hp => form_widget_single_control.html.php} | 0 src/Symfony/Component/Form/CHANGELOG.md | 4 +- .../Form/Extension/Core/Type/CheckboxType.php | 6 +-- .../Form/Extension/Core/Type/ChoiceType.php | 4 +- .../Form/Extension/Core/Type/DateTimeType.php | 4 +- .../Form/Extension/Core/Type/DateType.php | 4 +- .../Form/Extension/Core/Type/FileType.php | 2 +- .../Form/Extension/Core/Type/FormType.php | 6 +-- .../Form/Extension/Core/Type/HiddenType.php | 2 +- .../Form/Extension/Core/Type/IntegerType.php | 8 +-- .../Form/Extension/Core/Type/MoneyType.php | 10 ++-- .../Form/Extension/Core/Type/NumberType.php | 8 +-- .../Form/Extension/Core/Type/PercentType.php | 6 +-- .../Form/Extension/Core/Type/TextType.php | 2 +- .../Form/Extension/Core/Type/TimeType.php | 4 +- .../EventListener/CsrfValidationListener.php | 2 +- .../Csrf/Type/FormTypeCsrfExtension.php | 2 +- .../Csrf/Type/FormTypeCsrfExtensionTest.php | 32 ++++++------ 45 files changed, 113 insertions(+), 111 deletions(-) rename src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/{form_widget_complex.html.php => form_widget_compound.html.php} (100%) rename src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/{form_widget_primitive.html.php => form_widget_single_control.html.php} (100%) rename src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/{form_widget_complex.html.php => form_widget_compound.html.php} (100%) rename src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/{form_widget_primitive.html.php => form_widget_single_control.html.php} (100%) diff --git a/UPGRADE-2.1.md b/UPGRADE-2.1.md index e8f9ca869b950..f0b9d0046ccc8 100644 --- a/UPGRADE-2.1.md +++ b/UPGRADE-2.1.md @@ -370,7 +370,7 @@ themes. The "field_widget" and all references to it should be renamed to - "form_widget_primitive": + "form_widget_single_control": Before: @@ -389,7 +389,7 @@ {% block url_widget %} {% spaceless %} {% set type = type|default('url') %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% endspaceless %} {% endblock url_widget %} ``` @@ -397,7 +397,7 @@ 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 "primitive": + Boolean variable "single_control": Before: @@ -420,7 +420,7 @@ ``` {% block form_errors %} {% spaceless %} - {% if primitive %} + {% if single_control %} ... field code ... {% else %} ... form code ... 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 46c162712012c..468423b66d945 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,29 +2,29 @@ {% block form_widget %} {% spaceless %} - {% if primitive %} - {{ block('form_widget_primitive') }} + {% if single_control %} + {{ block('form_widget_single_control') }} {% else %} - {{ block('form_widget_complex') }} + {{ block('form_widget_compound') }} {% endif %} {% endspaceless %} {% endblock form_widget %} -{% block form_widget_primitive %} +{% block form_widget_single_control %} {% spaceless %} {% set type = type|default('text') %} {% endspaceless %} -{% endblock form_widget_primitive %} +{% endblock form_widget_single_control %} -{% block form_widget_complex %} +{% block form_widget_compound %} {% spaceless %}
    {{ block('form_rows') }} {{ form_rest(form) }}
    {% endspaceless %} -{% endblock form_widget_complex %} +{% endblock form_widget_compound %} {% block collection_widget %} {% spaceless %} @@ -112,7 +112,7 @@ {% block datetime_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% else %}
    {{ form_errors(form.date) }} @@ -127,7 +127,7 @@ {% block date_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% else %}
    {{ date_pattern|replace({ @@ -143,7 +143,7 @@ {% block time_widget %} {% spaceless %} {% if widget == 'single_text' %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% 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_primitive') }} + {{ block('form_widget_single_control') }} {% endspaceless %} {% endblock number_widget %} {% block integer_widget %} {% spaceless %} {% set type = type|default('number') %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% endspaceless %} {% endblock integer_widget %} {% block money_widget %} {% spaceless %} - {{ money_pattern|replace({ '{{ widget }}': block('form_widget_primitive') })|raw }} + {{ money_pattern|replace({ '{{ widget }}': block('form_widget_single_control') })|raw }} {% endspaceless %} {% endblock money_widget %} {% block url_widget %} {% spaceless %} {% set type = type|default('url') %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% endspaceless %} {% endblock url_widget %} {% block search_widget %} {% spaceless %} {% set type = type|default('search') %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% endspaceless %} {% endblock search_widget %} {% block percent_widget %} {% spaceless %} {% set type = type|default('text') %} - {{ block('form_widget_primitive') }} % + {{ block('form_widget_single_control') }} % {% endspaceless %} {% endblock percent_widget %} {% block password_widget %} {% spaceless %} {% set type = type|default('password') %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% endspaceless %} {% endblock password_widget %} {% block hidden_widget %} {% spaceless %} {% set type = type|default('hidden') %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% endspaceless %} {% endblock hidden_widget %} {% block email_widget %} {% spaceless %} {% set type = type|default('email') %} - {{ block('form_widget_primitive') }} + {{ block('form_widget_single_control') }} {% endspaceless %} {% endblock email_widget %} @@ -219,7 +219,7 @@ {% block form_label %} {% spaceless %} - {% if primitive %} + {% if single_control %} {% set label_attr = label_attr|merge({'for': id}) %} {% endif %} {% if required %} @@ -241,9 +241,11 @@ {% spaceless %}
    {{ form_label(form, label|default(null)) }} - {# If the child is a form, the errors are rendered inside the container #} - {# see block form_rows #} - {% if primitive %} + {# + If the child is a compound form, the errors are rendered inside + the container. See also block form_rows. + #} + {% if single_control %} {{ form_errors(form) }} {% endif %} {{ form_widget(form) }} @@ -318,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_primitive') }}{% endblock %} +{% block field_widget %}{{ block('form_widget_single_control') }}{% 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 69ef373fdda3e..b3a95582839b6 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 primitive %} + {% if single_control %} {{ form_errors(form) }} {% endif %} {{ form_widget(form) }} @@ -18,7 +18,7 @@ {% block form_errors %} {% spaceless %} - {% if primitive %} + {% if single_control %} {{ parent() }} {% else %} {% if errors|length > 0 %} @@ -42,11 +42,11 @@ {% endspaceless %} {% endblock hidden_row %} -{% block form_widget_complex %} +{% block form_widget_compound %} {% spaceless %} {{ block('form_rows') }} {{ form_rest(form) }}
    {% endspaceless %} -{% endblock form_widget_complex %} +{% endblock form_widget_compound %} diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig b/src/Symfony/Bridge/Twig/Tests/Extension/theme.html.twig index 517dd4549b54a..36f8636ad2e1b 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_primitive %} +{% block form_widget_single_control %} {% spaceless %} {% set type = type|default('text') %} {% endspaceless %} -{% endblock form_widget_primitive %} +{% endblock form_widget_single_control %} 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 c34955139c6fc..12b9da872dd32 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_primitive %} +{% block form_widget_single_control %} {% spaceless %} {% set type = type|default('text') %} {% endspaceless %} -{% endblock form_widget_primitive %} +{% endblock form_widget_single_control %} 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 ef7025efcc117..1b7f6b59cfd53 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_primitive %} +{% block form_widget_single_control %} {% spaceless %} {% set type = type|default('text') %} {% endspaceless %} -{% endblock form_widget_primitive %} +{% endblock form_widget_single_control %} 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 14ef80f00f1c4..338e8edfed078 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_primitive'); ?> + renderBlock('form_widget_single_control'); ?>
    renderBlock('widget_container_attributes') ?>> - renderBlock('form_widget_primitive'); ?> + renderBlock('form_widget_single_control'); ?>
    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 388259f2d09d3..80409c0a3079c 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_primitive', array('type' => isset($type) ? $type : 'email')) ?> +renderBlock('form_widget_single_control', 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 d47f413bf4e6b..bad67a85e279c 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_primitive') ?> \ No newline at end of file +renderBlock('form_widget_single_control') ?> \ No newline at end of file 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 f185683491ec6..ac6bf646ce6ad 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 f837415297c54..977a272257d9f 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 137a50eca5cc2..98d1a80be7068 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_primitive')?> + +renderBlock('form_widget_single_control')?> -renderBlock('form_widget_complex')?> +renderBlock('form_widget_compound')?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_complex.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_compound.html.php similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_complex.html.php rename to src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_compound.html.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_primitive.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_single_control.html.php similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_primitive.html.php rename to src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_widget_single_control.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 e1354a64a0aff..d7395a48573fe 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_primitive', array('type' => isset($type) ? $type : "hidden")) ?> +renderBlock('form_widget_single_control', 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 6dee8dea13ae9..dc2866fd20605 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_primitive', array('type' => isset($type) ? $type : "number")) ?> +renderBlock('form_widget_single_control', 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 1dcf72d4637b8..17279721c5dfb 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_primitive'), $money_pattern) ?> +renderBlock('form_widget_single_control'), $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 7b5152d4680a8..3d6fd62209321 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_primitive', array('type' => isset($type) ? $type : "text")) ?> +renderBlock('form_widget_single_control', 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 469bdd667d72a..716e46cf60162 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_primitive', array('type' => isset($type) ? $type : "password")) ?> +renderBlock('form_widget_single_control', 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 d67bb38246b8b..5446968bafffd 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_primitive', array('type' => isset($type) ? $type : "text")) ?> % +renderBlock('form_widget_single_control', 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 2678205f36fdd..ca3b00917fbf1 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_primitive', array('type' => isset($type) ? $type : "search")) ?> +renderBlock('form_widget_single_control', 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 ade5582b6693e..8d34459b56aac 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_primitive'); ?> + renderBlock('form_widget_single_control'); ?>
    renderBlock('widget_container_attributes') ?>> renderBlock('form_widget_primitive', array('type' => isset($type) ? $type : "url")) ?> +renderBlock('form_widget_single_control', 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 b3e732ef96e72..1a889760ca869 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 3e6d7ba05f422..5526a03fe9cc5 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/Resources/views/FormTable/form_widget_complex.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_compound.html.php similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_complex.html.php rename to src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_widget_compound.html.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_primitive.html.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_single_control.html.php similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_primitive.html.php rename to src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Parent/form_widget_single_control.html.php diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 56a8554d17da1..818b43e969bca 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -60,10 +60,10 @@ CHANGELOG * deprecated FieldType and merged it into FormType * [BC BREAK] renamed theme blocks * "field_*" to "form_*" - * "field_widget" to "form_widget_primitive" + * "field_widget" to "form_widget_single_control" * "widget_choice_options" to "choice_widget_options" * "generic_label" to "form_label" - * added theme blocks "form_widget_complex", "choice_widget_expanded" and + * added theme blocks "form_widget_compound", "choice_widget_expanded" and "choice_widget_collapsed" to make theming more modular * ValidatorTypeGuesser now guesses "collection" for array type constraint * added method `guessPattern` to FormTypeGuesserInterface to guess which pattern to use in the HTML5 attribute "pattern" diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php b/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php index cd48c2952ce73..b99b5892aeb0b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php @@ -51,9 +51,9 @@ public function getDefaultOptions() }; return array( - 'value' => '1', - 'empty_data' => $emptyData, - 'primitive' => true, + 'value' => '1', + 'empty_data' => $emptyData, + 'single_control' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index 09cacecb52994..3e21af5ad1800 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -165,7 +165,7 @@ public function getDefaultOptions() return $options['required'] ? null : ''; }; - $primitive = function (Options $options) { + $singleControl = function (Options $options) { return !$options['expanded']; }; @@ -178,7 +178,7 @@ public function getDefaultOptions() 'empty_data' => $emptyData, 'empty_value' => $emptyValue, 'error_bubbling' => false, - 'primitive' => $primitive, + 'single_control' => $singleControl, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php index cbd23ea2adc3e..2308059058b12 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php @@ -131,7 +131,7 @@ public function buildView(FormView $view, FormInterface $form) */ public function getDefaultOptions() { - $primitive = function (Options $options) { + $singleControl = function (Options $options) { return $options['widget'] === 'single_text'; }; @@ -163,7 +163,7 @@ public function getDefaultOptions() // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, - 'primitive' => $primitive, + 'single_control' => $singleControl, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index a6f74c81c5daa..38b23e436ab01 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -163,7 +163,7 @@ public function buildViewBottomUp(FormView $view, FormInterface $form) */ public function getDefaultOptions() { - $primitive = function (Options $options) { + $singleControl = function (Options $options) { return $options['widget'] === 'single_text'; }; @@ -186,7 +186,7 @@ public function getDefaultOptions() // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, - 'primitive' => $primitive, + 'single_control' => $singleControl, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index ac44c5d8bd366..d57176ec672b1 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -44,7 +44,7 @@ public function buildViewBottomUp(FormView $view, FormInterface $form) public function getDefaultOptions() { return array( - 'primitive' => true, + 'single_control' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index b5bf497e8782c..34aac4ab8c4c5 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -67,7 +67,7 @@ public function buildForm(FormBuilder $builder, array $options) ->setAttribute('invalid_message_parameters', $options['invalid_message_parameters']) ->setAttribute('translation_domain', $options['translation_domain']) ->setAttribute('virtual', $options['virtual']) - ->setAttribute('primitive', $options['primitive']) + ->setAttribute('single_control', $options['single_control']) ->setData($options['data']) ->setDataMapper(new PropertyPathMapper($options['data_class'])) ->addEventSubscriber(new ValidationListener()) @@ -133,7 +133,7 @@ public function buildView(FormView $view, FormInterface $form) ->set('multipart', false) ->set('attr', $form->getAttribute('attr')) ->set('label_attr', $form->getAttribute('label_attr')) - ->set('primitive', $form->getAttribute('primitive')) + ->set('single_control', $form->getAttribute('single_control')) ->set('types', $types) ->set('translation_domain', $form->getAttribute('translation_domain')) ; @@ -211,7 +211,7 @@ public function getDefaultOptions() 'attr' => array(), 'label_attr' => array(), 'virtual' => false, - 'primitive' => false, + 'single_control' => false, 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'translation_domain' => 'messages', diff --git a/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php b/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php index 2d2c3e61d135c..49562d9fd87ef 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php @@ -25,7 +25,7 @@ public function getDefaultOptions() 'required' => false, // Pass errors to the parent 'error_bubbling' => true, - 'primitive' => true, + 'single_control' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php b/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php index 286bc4dfbf6b1..293c01d3cd7cb 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/IntegerType.php @@ -37,11 +37,11 @@ public function getDefaultOptions() { return 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, - 'primitive' => true, + 'rounding_mode' => \NumberFormatter::ROUND_DOWN, + 'single_control' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php index cba4f8fe6f7d1..560cbe59b562d 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php @@ -51,11 +51,11 @@ public function buildView(FormView $view, FormInterface $form) public function getDefaultOptions() { return array( - 'precision' => 2, - 'grouping' => false, - 'divisor' => 1, - 'currency' => 'EUR', - 'primitive' => true, + 'precision' => 2, + 'grouping' => false, + 'divisor' => 1, + 'currency' => 'EUR', + 'single_control' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php b/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php index cac3024990f0e..993df32809561 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/NumberType.php @@ -36,10 +36,10 @@ public function getDefaultOptions() { return array( // default precision is locale specific (usually around 3) - 'precision' => null, - 'grouping' => false, - 'rounding_mode' => \NumberFormatter::ROUND_HALFUP, - 'primitive' => true, + 'precision' => null, + 'grouping' => false, + 'rounding_mode' => \NumberFormatter::ROUND_HALFUP, + 'single_control' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php b/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php index 2ef7449186d0d..0ee0af39e320d 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php @@ -31,9 +31,9 @@ public function buildForm(FormBuilder $builder, array $options) public function getDefaultOptions() { return array( - 'precision' => 0, - 'type' => 'fractional', - 'primitive' => true, + 'precision' => 0, + 'type' => 'fractional', + 'single_control' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php index dd23e7b38ff1f..f454160d3ec61 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php @@ -33,7 +33,7 @@ public function buildForm(FormBuilder $builder, array $options) public function getDefaultOptions() { return array( - 'primitive' => true, + 'single_control' => true, ); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index 7e5892d7d68c7..42cd7f42e536a 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -137,7 +137,7 @@ public function buildView(FormView $view, FormInterface $form) */ public function getDefaultOptions() { - $primitive = function (Options $options) { + $singleControl = function (Options $options) { return $options['widget'] === 'single_text'; }; @@ -160,7 +160,7 @@ public function getDefaultOptions() // representation is not \DateTime, but an array, we need to unset // this option. 'data_class' => null, - 'primitive' => $primitive, + 'single_control' => $singleControl, ); } diff --git a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php index 7b05185878202..da8a07d1af32c 100644 --- a/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php +++ b/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php @@ -63,7 +63,7 @@ public function onBindClientData(FilterDataEvent $event) $form = $event->getForm(); $data = $event->getData(); - if ($form->isRoot() && !$form->getAttribute('primitive')) { + if ($form->isRoot() && !$form->getAttribute('single_control')) { 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 9bff7cc12878b..c26324b41e2a1 100644 --- a/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php +++ b/src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php @@ -64,7 +64,7 @@ public function buildForm(FormBuilder $builder, array $options) */ public function buildViewBottomUp(FormView $view, FormInterface $form) { - if (!$view->hasParent() && !$form->getAttribute('primitive') && $form->hasAttribute('csrf_field_name')) { + 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'); 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 bb03c601b4f22..0fdea7d438e5b 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php @@ -56,26 +56,26 @@ protected function getExtensions() )); } - public function testCsrfProtectionByDefaultIfRootAndNotPrimitive() + public function testCsrfProtectionByDefaultIfRootAndNotSingleControl() { $view = $this->factory ->create('form', null, array( 'csrf_field_name' => 'csrf', - 'primitive' => false, + 'single_control' => false, )) ->createView(); $this->assertTrue($view->hasChild('csrf')); } - public function testNoCsrfProtectionByDefaultIfNotPrimitiveButNotRoot() + public function testNoCsrfProtectionByDefaultIfNotSingleControlButNotRoot() { $view = $this->factory ->createNamedBuilder('form', 'root') ->add($this->factory ->createNamedBuilder('form', 'form', null, array( 'csrf_field_name' => 'csrf', - 'primitive' => false, + 'single_control' => false, )) ) ->getForm() @@ -85,12 +85,12 @@ public function testNoCsrfProtectionByDefaultIfNotPrimitiveButNotRoot() $this->assertFalse($view->hasChild('csrf')); } - public function testNoCsrfProtectionByDefaultIfRootButPrimitive() + public function testNoCsrfProtectionByDefaultIfRootButSingleControl() { $view = $this->factory ->create('form', null, array( 'csrf_field_name' => 'csrf', - 'primitive' => true, + 'single_control' => true, )) ->createView(); @@ -103,7 +103,7 @@ public function testCsrfProtectionCanBeDisabled() ->create('form', null, array( 'csrf_field_name' => 'csrf', 'csrf_protection' => false, - 'primitive' => false, + 'single_control' => false, )) ->createView(); @@ -122,7 +122,7 @@ public function testGenerateCsrfToken() 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'primitive' => false, + 'single_control' => false, )) ->createView(); @@ -140,7 +140,7 @@ public function provideBoolean() /** * @dataProvider provideBoolean */ - public function testValidateTokenOnBindIfRootAndNotPrimitive($valid) + public function testValidateTokenOnBindIfRootAndNotSingleControl($valid) { $this->csrfProvider->expects($this->once()) ->method('isCsrfTokenValid') @@ -152,7 +152,7 @@ public function testValidateTokenOnBindIfRootAndNotPrimitive($valid) 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'primitive' => false, + 'single_control' => false, )); $form->bind(array( @@ -167,7 +167,7 @@ public function testValidateTokenOnBindIfRootAndNotPrimitive($valid) $this->assertSame($valid, $form->isValid()); } - public function testFailIfRootAndNotPrimitiveAndTokenMissing() + public function testFailIfRootAndNotSingleControlAndTokenMissing() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); @@ -177,7 +177,7 @@ public function testFailIfRootAndNotPrimitiveAndTokenMissing() 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'primitive' => false, + 'single_control' => false, )); $form->bind(array( @@ -192,7 +192,7 @@ public function testFailIfRootAndNotPrimitiveAndTokenMissing() $this->assertFalse($form->isValid()); } - public function testDontValidateTokenIfNotPrimitiveButNoRoot() + public function testDontValidateTokenIfNotSingleControlButNoRoot() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); @@ -204,7 +204,7 @@ public function testDontValidateTokenIfNotPrimitiveButNoRoot() 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'primitive' => false, + 'single_control' => false, )) ) ->getForm() @@ -216,7 +216,7 @@ public function testDontValidateTokenIfNotPrimitiveButNoRoot() )); } - public function testDontValidateTokenIfRootButPrimitive() + public function testDontValidateTokenIfRootButSingleControl() { $this->csrfProvider->expects($this->never()) ->method('isCsrfTokenValid'); @@ -226,7 +226,7 @@ public function testDontValidateTokenIfRootButPrimitive() 'csrf_field_name' => 'csrf', 'csrf_provider' => $this->csrfProvider, 'intention' => '%INTENTION%', - 'primitive' => true, + 'single_control' => true, )); $form->bind(array( From 246c8852c883fa7e1c3e801e8a05fa4ddddbc5d0 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 27 Apr 2012 10:24:06 +0200 Subject: [PATCH 7/7] [Form] Fixed: Default value of 'error_bubbling' is now determined by the 'single_control' option --- .../Form/Extension/Core/Type/FormType.php | 8 ++- src/Symfony/Component/Form/Form.php | 7 +-- .../Extension/Core/Type/FormTypeTest.php | 28 ++++++++++ src/Symfony/Component/Form/Tests/FormTest.php | 55 ------------------- 4 files changed, 37 insertions(+), 61 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index 34aac4ab8c4c5..0dea6d113c96c 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -193,6 +193,12 @@ public function getDefaultOptions() }; }; + // 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 array( 'data' => null, 'data_class' => $dataClass, @@ -205,7 +211,7 @@ public function getDefaultOptions() 'pattern' => null, 'property_path' => null, 'by_reference' => true, - 'error_bubbling' => false, + 'error_bubbling' => $errorBubbling, 'error_mapping' => array(), 'label' => null, 'attr' => array(), diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 5669e0ead4956..f75cd4b0a128e 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -225,10 +225,7 @@ public function __construct($name, EventDispatcherInterface $dispatcher, $this->validators = $validators; $this->required = (Boolean) $required; $this->disabled = (Boolean) $disabled; - // NULL is the default meaning: - // bubble up if the form has children (complex forms) - // don't bubble up if the form has no children (primitive fields) - $this->errorBubbling = null === $errorBubbling ? null : (Boolean) $errorBubbling; + $this->errorBubbling = (Boolean) $errorBubbling; $this->emptyData = $emptyData; $this->attributes = $attributes; @@ -665,7 +662,7 @@ public function addError(FormError $error) */ public function getErrorBubbling() { - return null === $this->errorBubbling ? $this->hasChildren() : $this->errorBubbling; + return $this->errorBubbling; } /** 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 8275c61455999..6df8130e383fd 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php @@ -568,4 +568,32 @@ public function testCreateViewDoNoMarkItAsRendered() $this->assertFalse($view->isRendered()); } + + public function testErrorBubblingIfNoSingleControl() + { + $form = $this->factory->create('form', null, array( + 'single_control' => false, + )); + + $this->assertTrue($form->getErrorBubbling()); + } + + public function testNoErrorBubblingIfSingleControl() + { + $form = $this->factory->create('form', null, array( + 'single_control' => true, + )); + + $this->assertFalse($form->getErrorBubbling()); + } + + public function testOverrideErrorBubbling() + { + $form = $this->factory->create('form', null, array( + 'single_control' => true, + 'error_bubbling' => true, + )); + + $this->assertTrue($form->getErrorBubbling()); + } } diff --git a/src/Symfony/Component/Form/Tests/FormTest.php b/src/Symfony/Component/Form/Tests/FormTest.php index 08ef363e4bcf4..b7b7cb0803db7 100644 --- a/src/Symfony/Component/Form/Tests/FormTest.php +++ b/src/Symfony/Component/Form/Tests/FormTest.php @@ -133,61 +133,6 @@ public function testDataIsInitializedEmpty() $this->assertSame('bar', $form->getClientData()); } - public function testErrorsBubbleUpIfEnabled() - { - $error = new FormError('Error!'); - $parent = $this->form; - $form = $this->getBuilder()->setErrorBubbling(true)->getForm(); - - $form->setParent($parent); - $form->addError($error); - - $this->assertEquals(array(), $form->getErrors()); - $this->assertEquals(array($error), $parent->getErrors()); - } - - public function testErrorsDontBubbleUpIfDisabled() - { - $error = new FormError('Error!'); - $parent = $this->form; - $form = $this->getBuilder()->setErrorBubbling(false)->getForm(); - - $form->setParent($parent); - $form->addError($error); - - $this->assertEquals(array($error), $form->getErrors()); - $this->assertEquals(array(), $parent->getErrors()); - } - - public function testErrorsBubbleUpIfNullAndChildren() - { - $error = new FormError('Error!'); - $parent = $this->form; - $form = $this->getBuilder() - ->setErrorBubbling(null) - ->add($this->getBuilder('child')) - ->getForm(); - - $form->setParent($parent); - $form->addError($error); - - $this->assertEquals(array(), $form->getErrors()); - $this->assertEquals(array($error), $parent->getErrors()); - } - - public function testErrorsDontBubbleUpIfNullAndNoChildren() - { - $error = new FormError('Error!'); - $parent = $this->form; - $form = $this->getBuilder()->setErrorBubbling(null)->getForm(); - - $form->setParent($parent); - $form->addError($error); - - $this->assertEquals(array($error), $form->getErrors()); - $this->assertEquals(array(), $parent->getErrors()); - } - public function testValidIfAllChildrenAreValid() { $this->form->add($this->getValidForm('firstName'));