From 72846802ddc25a680b91300eedbeffcd422bf00a Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sat, 18 Apr 2015 23:42:40 +0200 Subject: [PATCH 1/5] [Form] deprecate read_only option --- .../Form/Extension/Core/Type/FormType.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index 19c94967ab219..dfafff70bb1da 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -185,12 +185,22 @@ public function configureOptions(OptionsResolver $resolver) return $attributes; }; + $readOnlyNormalizer = function (Options $options, $readOnly) { + if (null !== $readOnly) { + trigger_error('The form option "read_only" is deprecated since version 2.7 and will be removed in 3.0. Use "attr[\'readonly\']" instead.', E_USER_DEPRECATED); + + return $readOnly; + } + + return false; + }; + $resolver->setDefaults(array( 'data_class' => $dataClass, 'empty_data' => $emptyData, 'trim' => true, 'required' => true, - 'read_only' => false, + 'read_only' => null, 'max_length' => null, 'pattern' => null, 'property_path' => null, @@ -209,6 +219,8 @@ public function configureOptions(OptionsResolver $resolver) 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', )); + $resolver->setNormalizer('read_only', $readOnlyNormalizer); + $resolver->setAllowedTypes('label_attr', 'array'); } From 052168f27d5f7dcb3b2a46575dd244f7ce51d26d Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sun, 19 Apr 2015 02:03:41 +0200 Subject: [PATCH 2/5] [Form] use attr[readonly] instead of read_only option --- .../views/Form/form_div_layout.html.twig | 1 - .../views/Form/widget_attributes.html.php | 12 ++++++------ .../Form/Extension/Core/Type/FormType.php | 19 ++++++++++++++----- 3 files changed, 20 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 de54d49c30456..8ab60af3f447b 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 @@ -314,7 +314,6 @@ {%- block widget_attributes -%} id="{{ id }}" name="{{ full_name }}" - {%- if read_only %} readonly="readonly"{% endif -%} {%- if disabled %} disabled="disabled"{% endif -%} {%- if required %} required="required"{% endif -%} {%- for attrname, attrvalue in attr -%} 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 index 118e764c8555a..cd9aac8654fd0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php @@ -1,12 +1,12 @@ -id="escape($id) ?>" name="escape($full_name) ?>" readonly="readonly" -disabled="disabled" -required="required" +id="escape($id) ?>" name="escape($full_name) ?>" + disabled="disabled" + required="required" $v): ?> -escape($k), $view->escape($view['translator']->trans($v, array(), $translation_domain))) ?> +escape($k), $view->escape($view['translator']->trans($v, array(), $translation_domain))) ?> -escape($k), $view->escape($k)) ?> +escape($k), $view->escape($k)) ?> -escape($k), $view->escape($v)) ?> +escape($k), $view->escape($v)) ?> diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index dfafff70bb1da..d6e7e42fd6234 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -71,7 +71,6 @@ public function buildView(FormView $view, FormInterface $form, array $options) parent::buildView($view, $form, $options); $name = $form->getName(); - $readOnly = $options['read_only']; if ($view->parent) { if ('' === $name) { @@ -79,13 +78,13 @@ public function buildView(FormView $view, FormInterface $form, array $options) } // Complex fields are read-only if they themselves or their parents are. - if (!$readOnly) { - $readOnly = $view->parent->vars['read_only']; + if (!isset($view->vars['attr']['readonly']) && isset($view->parent->vars['attr']['readonly']) && false !== $view->parent->vars['attr']['readonly'])) { + $view->vars['attr']['readonly'] = true; } } $view->vars = array_replace($view->vars, array( - 'read_only' => $readOnly, + 'read_only' => isset($view->vars['attr']['readonly']) && false !== $view->vars['attr']['readonly'], // deprecated 'errors' => $form->getErrors(), 'valid' => $form->isSubmitted() ? $form->isValid() : true, 'value' => $form->getViewData(), @@ -185,6 +184,15 @@ public function configureOptions(OptionsResolver $resolver) return $attributes; }; + // BC for "read_only" option + $attrNormalizer = function (Options $options, array $attr) { + if (!isset($attr['readonly']) && $options['read_only']) { + $attr['readonly'] = true; + } + + return $attr; + }; + $readOnlyNormalizer = function (Options $options, $readOnly) { if (null !== $readOnly) { trigger_error('The form option "read_only" is deprecated since version 2.7 and will be removed in 3.0. Use "attr[\'readonly\']" instead.', E_USER_DEPRECATED); @@ -200,7 +208,7 @@ public function configureOptions(OptionsResolver $resolver) 'empty_data' => $emptyData, 'trim' => true, 'required' => true, - 'read_only' => null, + 'read_only' => null, // deprecated 'max_length' => null, 'pattern' => null, 'property_path' => null, @@ -219,6 +227,7 @@ public function configureOptions(OptionsResolver $resolver) 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', )); + $resolver->setNormalizer('attr', $attrNormalizer); $resolver->setNormalizer('read_only', $readOnlyNormalizer); $resolver->setAllowedTypes('label_attr', 'array'); From 83db940e3d2fcd1526de137cdd2cca14da4ff072 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sun, 19 Apr 2015 02:37:04 +0200 Subject: [PATCH 3/5] [Form] adjust tests for deprecated read_only option --- .../Form/Extension/Core/Type/FormType.php | 2 +- .../Tests/AbstractBootstrap3LayoutTest.php | 10 +++-- .../Form/Tests/AbstractLayoutTest.php | 10 +++-- .../Extension/Core/Type/FormTypeTest.php | 45 +++++++++++++++++-- 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index d6e7e42fd6234..74f63cb89bfde 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -78,7 +78,7 @@ public function buildView(FormView $view, FormInterface $form, array $options) } // Complex fields are read-only if they themselves or their parents are. - if (!isset($view->vars['attr']['readonly']) && isset($view->parent->vars['attr']['readonly']) && false !== $view->parent->vars['attr']['readonly'])) { + if (!isset($view->vars['attr']['readonly']) && isset($view->parent->vars['attr']['readonly']) && false !== $view->parent->vars['attr']['readonly']) { $view->vars['attr']['readonly'] = true; } } diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php index 41c52748704d9..41cb515c60865 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php @@ -1342,7 +1342,10 @@ public function testHidden() ); } - public function testReadOnly() + /** + * @group legacy + */ + public function testLegacyReadOnly() { $form = $this->factory->createNamed('name', 'text', null, array( 'read_only' => true, @@ -1907,14 +1910,13 @@ public function testWidgetAttributes() $form = $this->factory->createNamed('text', 'text', 'value', array( 'required' => true, 'disabled' => true, - 'read_only' => true, - 'attr' => array('maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'), + 'attr' => array('readonly' => true, 'maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'), )); $html = $this->renderWidget($form->createView()); // compare plain HTML to check the whitespace - $this->assertSame('', $html); + $this->assertSame('', $html); } public function testWidgetAttributeNameRepeatedIfTrue() diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php index 76365a552c7b5..4e3622902c1e5 100644 --- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php @@ -1512,7 +1512,10 @@ public function testHidden() ); } - public function testReadOnly() + /** + * @group legacy + */ + public function testLegacyReadOnly() { $form = $this->factory->createNamed('name', 'text', null, array( 'read_only' => true, @@ -2119,14 +2122,13 @@ public function testWidgetAttributes() $form = $this->factory->createNamed('text', 'text', 'value', array( 'required' => true, 'disabled' => true, - 'read_only' => true, - 'attr' => array('maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'), + 'attr' => array('readonly' => true, 'maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'), )); $html = $this->renderWidget($form->createView()); // compare plain HTML to check the whitespace - $this->assertSame('', $html); + $this->assertSame('', $html); } public function testWidgetAttributeNameRepeatedIfTrue() 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 2b4b255b0daab..0ebb554a6ac84 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php @@ -99,7 +99,10 @@ public function testSubmittedDataIsNotTrimmedBeforeTransformingIfNoTrimming() $this->assertEquals('reverse[ a ]', $form->getData()); } - public function testNonReadOnlyFormWithReadOnlyParentIsReadOnly() + /** + * @group legacy + */ + public function testLegacyNonReadOnlyFormWithReadOnlyParentIsReadOnly() { $view = $this->factory->createNamedBuilder('parent', 'form', null, array('read_only' => true)) ->add('child', 'form') @@ -109,7 +112,20 @@ public function testNonReadOnlyFormWithReadOnlyParentIsReadOnly() $this->assertTrue($view['child']->vars['read_only']); } - public function testReadOnlyFormWithNonReadOnlyParentIsReadOnly() + public function testNonReadOnlyFormWithReadOnlyParentIsReadOnly() + { + $view = $this->factory->createNamedBuilder('parent', 'form', null, array('attr' => array('readonly' => true))) + ->add('child', 'form') + ->getForm() + ->createView(); + + $this->assertTrue($view['child']->vars['attr']['readonly']); + } + + /** + * @group legacy + */ + public function testLegacyReadOnlyFormWithNonReadOnlyParentIsReadOnly() { $view = $this->factory->createNamedBuilder('parent', 'form') ->add('child', 'form', array('read_only' => true)) @@ -119,7 +135,20 @@ public function testReadOnlyFormWithNonReadOnlyParentIsReadOnly() $this->assertTrue($view['child']->vars['read_only']); } - public function testNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly() + public function testReadOnlyFormWithNonReadOnlyParentIsReadOnly() + { + $view = $this->factory->createNamedBuilder('parent', 'form') + ->add('child', 'form', array('attr' => array('readonly' => true))) + ->getForm() + ->createView(); + + $this->assertTrue($view['child']->vars['attr']['readonly']); + } + + /** + * @group legacy + */ + public function testLegacyNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly() { $view = $this->factory->createNamedBuilder('parent', 'form') ->add('child', 'form') @@ -129,6 +158,16 @@ public function testNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly() $this->assertFalse($view['child']->vars['read_only']); } + public function testNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly() + { + $view = $this->factory->createNamedBuilder('parent', 'form') + ->add('child', 'form') + ->getForm() + ->createView(); + + $this->assertArrayNotHasKey('readonly', $view['child']->vars['attr']); + } + public function testPassMaxLengthToView() { $form = $this->factory->create('form', null, array('attr' => array('maxlength' => 10))); From 40f44402a4c233514e6086e3c2dec85326cfb280 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sun, 19 Apr 2015 02:53:55 +0200 Subject: [PATCH 4/5] add changelog for deprecated read_only --- .../Resources/views/Form/widget_attributes.html.php | 3 +-- src/Symfony/Component/Form/CHANGELOG.md | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) 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 index cd9aac8654fd0..ac5a481d0b55e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/widget_attributes.html.php @@ -1,5 +1,4 @@ -id="escape($id) ?>" name="escape($full_name) ?>" - disabled="disabled" +id="escape($id) ?>" name="escape($full_name) ?>" disabled="disabled" required="required" $v): ?> diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index b1387bb2e6396..a4c8aa1912b5f 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.8.0 +----- + + * deprecated option "read_only" in favor of "attr['readonly']" + 2.7.0 ----- From f0dfd2faaba4eb7848d3e1b8a7add7da302d8cae Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Mon, 20 Apr 2015 14:02:11 +0200 Subject: [PATCH 5/5] [Form] implement feedback --- src/Symfony/Bridge/Twig/composer.json | 2 +- src/Symfony/Bundle/FrameworkBundle/composer.json | 2 +- src/Symfony/Component/Form/Extension/Core/Type/FormType.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 864fb1a480362..0af4e61229405 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -23,7 +23,7 @@ "symfony/phpunit-bridge": "~2.7|~3.0.0", "symfony/asset": "~2.7|~3.0.0", "symfony/finder": "~2.3|~3.0.0", - "symfony/form": "~2.7|~3.0.0", + "symfony/form": "~2.8|~3.0.0", "symfony/http-kernel": "~2.3|~3.0.0", "symfony/intl": "~2.3|~3.0.0", "symfony/routing": "~2.2|~3.0.0", diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 88d9379e7bef1..e1e245f488cd0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -41,7 +41,7 @@ "symfony/finder": "~2.0,>=2.0.5|~3.0.0", "symfony/intl": "~2.3|~3.0.0", "symfony/security": "~2.6|~3.0.0", - "symfony/form": "~2.7|~3.0.0", + "symfony/form": "~2.8|~3.0.0", "symfony/class-loader": "~2.1|~3.0.0", "symfony/expression-language": "~2.6|~3.0.0", "symfony/process": "~2.0,>=2.0.5|~3.0.0", diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index 74f63cb89bfde..cbd69a9aec56c 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -195,7 +195,7 @@ public function configureOptions(OptionsResolver $resolver) $readOnlyNormalizer = function (Options $options, $readOnly) { if (null !== $readOnly) { - trigger_error('The form option "read_only" is deprecated since version 2.7 and will be removed in 3.0. Use "attr[\'readonly\']" instead.', E_USER_DEPRECATED); + trigger_error('The form option "read_only" is deprecated since version 2.8 and will be removed in 3.0. Use "attr[\'readonly\']" instead.', E_USER_DEPRECATED); return $readOnly; }