Skip to content

Commit 791e583

Browse files
committed
feature #14403 [Form] deprecate read_only option (Tobion)
This PR was squashed before being merged into the 2.8 branch (closes #14403). Discussion ---------- [Form] deprecate read_only option | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #10658 | License | MIT | Doc PR | symfony/symfony-docs#3782 Replaces #10676 with a slightly different implementation. - fixes BC break when 'read_only' => true option and at the same time custom attributes are used by using a normalizer - adds deprecation notice - keeps legacy tests Commits ------- 53330e1 [Form] deprecate read_only option
2 parents 65d4ae0 + 53330e1 commit 791e583

File tree

9 files changed

+92
-25
lines changed

9 files changed

+92
-25
lines changed

src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,6 @@
314314

315315
{%- block widget_attributes -%}
316316
id="{{ id }}" name="{{ full_name }}"
317-
{%- if read_only %} readonly="readonly"{% endif -%}
318317
{%- if disabled %} disabled="disabled"{% endif -%}
319318
{%- if required %} required="required"{% endif -%}
320319
{%- for attrname, attrvalue in attr -%}

src/Symfony/Bridge/Twig/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"symfony/phpunit-bridge": "~2.7|~3.0.0",
2424
"symfony/asset": "~2.7|~3.0.0",
2525
"symfony/finder": "~2.3|~3.0.0",
26-
"symfony/form": "~2.7|~3.0.0",
26+
"symfony/form": "~2.8|~3.0.0",
2727
"symfony/http-kernel": "~2.3|~3.0.0",
2828
"symfony/intl": "~2.3|~3.0.0",
2929
"symfony/routing": "~2.2|~3.0.0",
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
id="<?php echo $view->escape($id) ?>" name="<?php echo $view->escape($full_name) ?>" <?php if ($read_only): ?>readonly="readonly" <?php endif ?>
2-
<?php if ($disabled): ?>disabled="disabled" <?php endif ?>
3-
<?php if ($required): ?>required="required" <?php endif ?>
1+
id="<?php echo $view->escape($id) ?>" name="<?php echo $view->escape($full_name) ?>"<?php if ($disabled): ?> disabled="disabled"<?php endif ?>
2+
<?php if ($required): ?> required="required"<?php endif ?>
43
<?php foreach ($attr as $k => $v): ?>
54
<?php if (in_array($k, array('placeholder', 'title'), true)): ?>
6-
<?php printf('%s="%s" ', $view->escape($k), $view->escape($view['translator']->trans($v, array(), $translation_domain))) ?>
5+
<?php printf(' %s="%s"', $view->escape($k), $view->escape($view['translator']->trans($v, array(), $translation_domain))) ?>
76
<?php elseif ($v === true): ?>
8-
<?php printf('%s="%s" ', $view->escape($k), $view->escape($k)) ?>
7+
<?php printf(' %s="%s"', $view->escape($k), $view->escape($k)) ?>
98
<?php elseif ($v !== false): ?>
10-
<?php printf('%s="%s" ', $view->escape($k), $view->escape($v)) ?>
9+
<?php printf(' %s="%s"', $view->escape($k), $view->escape($v)) ?>
1110
<?php endif ?>
1211
<?php endforeach ?>

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"symfony/finder": "~2.0,>=2.0.5|~3.0.0",
4242
"symfony/intl": "~2.3|~3.0.0",
4343
"symfony/security": "~2.6|~3.0.0",
44-
"symfony/form": "~2.7|~3.0.0",
44+
"symfony/form": "~2.8|~3.0.0",
4545
"symfony/class-loader": "~2.1|~3.0.0",
4646
"symfony/expression-language": "~2.6|~3.0.0",
4747
"symfony/process": "~2.0,>=2.0.5|~3.0.0",

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
2.8.0
5+
-----
6+
7+
* deprecated option "read_only" in favor of "attr['readonly']"
8+
49
2.7.0
510
-----
611

src/Symfony/Component/Form/Extension/Core/Type/FormType.php

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,20 @@ public function buildView(FormView $view, FormInterface $form, array $options)
7171
parent::buildView($view, $form, $options);
7272

7373
$name = $form->getName();
74-
$readOnly = $options['read_only'];
7574

7675
if ($view->parent) {
7776
if ('' === $name) {
7877
throw new LogicException('Form node with empty name can be used only as root form node.');
7978
}
8079

8180
// Complex fields are read-only if they themselves or their parents are.
82-
if (!$readOnly) {
83-
$readOnly = $view->parent->vars['read_only'];
81+
if (!isset($view->vars['attr']['readonly']) && isset($view->parent->vars['attr']['readonly']) && false !== $view->parent->vars['attr']['readonly']) {
82+
$view->vars['attr']['readonly'] = true;
8483
}
8584
}
8685

8786
$view->vars = array_replace($view->vars, array(
88-
'read_only' => $readOnly,
87+
'read_only' => isset($view->vars['attr']['readonly']) && false !== $view->vars['attr']['readonly'], // deprecated
8988
'errors' => $form->getErrors(),
9089
'valid' => $form->isSubmitted() ? $form->isValid() : true,
9190
'value' => $form->getViewData(),
@@ -185,12 +184,31 @@ public function configureOptions(OptionsResolver $resolver)
185184
return $attributes;
186185
};
187186

187+
// BC for "read_only" option
188+
$attrNormalizer = function (Options $options, array $attr) {
189+
if (!isset($attr['readonly']) && $options['read_only']) {
190+
$attr['readonly'] = true;
191+
}
192+
193+
return $attr;
194+
};
195+
196+
$readOnlyNormalizer = function (Options $options, $readOnly) {
197+
if (null !== $readOnly) {
198+
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);
199+
200+
return $readOnly;
201+
}
202+
203+
return false;
204+
};
205+
188206
$resolver->setDefaults(array(
189207
'data_class' => $dataClass,
190208
'empty_data' => $emptyData,
191209
'trim' => true,
192210
'required' => true,
193-
'read_only' => false,
211+
'read_only' => null, // deprecated
194212
'max_length' => null,
195213
'pattern' => null,
196214
'property_path' => null,
@@ -209,6 +227,9 @@ public function configureOptions(OptionsResolver $resolver)
209227
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
210228
));
211229

230+
$resolver->setNormalizer('attr', $attrNormalizer);
231+
$resolver->setNormalizer('read_only', $readOnlyNormalizer);
232+
212233
$resolver->setAllowedTypes('label_attr', 'array');
213234
}
214235

src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,7 +1342,10 @@ public function testHidden()
13421342
);
13431343
}
13441344

1345-
public function testReadOnly()
1345+
/**
1346+
* @group legacy
1347+
*/
1348+
public function testLegacyReadOnly()
13461349
{
13471350
$form = $this->factory->createNamed('name', 'text', null, array(
13481351
'read_only' => true,
@@ -1907,14 +1910,13 @@ public function testWidgetAttributes()
19071910
$form = $this->factory->createNamed('text', 'text', 'value', array(
19081911
'required' => true,
19091912
'disabled' => true,
1910-
'read_only' => true,
1911-
'attr' => array('maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'),
1913+
'attr' => array('readonly' => true, 'maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'),
19121914
));
19131915

19141916
$html = $this->renderWidget($form->createView());
19151917

19161918
// compare plain HTML to check the whitespace
1917-
$this->assertSame('<input type="text" id="text" name="text" readonly="readonly" disabled="disabled" required="required" maxlength="10" pattern="\d+" class="foobar form-control" data-foo="bar" value="value" />', $html);
1919+
$this->assertSame('<input type="text" id="text" name="text" disabled="disabled" required="required" readonly="readonly" maxlength="10" pattern="\d+" class="foobar form-control" data-foo="bar" value="value" />', $html);
19181920
}
19191921

19201922
public function testWidgetAttributeNameRepeatedIfTrue()

src/Symfony/Component/Form/Tests/AbstractLayoutTest.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,10 @@ public function testHidden()
15121512
);
15131513
}
15141514

1515-
public function testReadOnly()
1515+
/**
1516+
* @group legacy
1517+
*/
1518+
public function testLegacyReadOnly()
15161519
{
15171520
$form = $this->factory->createNamed('name', 'text', null, array(
15181521
'read_only' => true,
@@ -2119,14 +2122,13 @@ public function testWidgetAttributes()
21192122
$form = $this->factory->createNamed('text', 'text', 'value', array(
21202123
'required' => true,
21212124
'disabled' => true,
2122-
'read_only' => true,
2123-
'attr' => array('maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'),
2125+
'attr' => array('readonly' => true, 'maxlength' => 10, 'pattern' => '\d+', 'class' => 'foobar', 'data-foo' => 'bar'),
21242126
));
21252127

21262128
$html = $this->renderWidget($form->createView());
21272129

21282130
// compare plain HTML to check the whitespace
2129-
$this->assertSame('<input type="text" id="text" name="text" readonly="readonly" disabled="disabled" required="required" maxlength="10" pattern="\d+" class="foobar" data-foo="bar" value="value" />', $html);
2131+
$this->assertSame('<input type="text" id="text" name="text" disabled="disabled" required="required" readonly="readonly" maxlength="10" pattern="\d+" class="foobar" data-foo="bar" value="value" />', $html);
21302132
}
21312133

21322134
public function testWidgetAttributeNameRepeatedIfTrue()

src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,10 @@ public function testSubmittedDataIsNotTrimmedBeforeTransformingIfNoTrimming()
9999
$this->assertEquals('reverse[ a ]', $form->getData());
100100
}
101101

102-
public function testNonReadOnlyFormWithReadOnlyParentIsReadOnly()
102+
/**
103+
* @group legacy
104+
*/
105+
public function testLegacyNonReadOnlyFormWithReadOnlyParentIsReadOnly()
103106
{
104107
$view = $this->factory->createNamedBuilder('parent', 'form', null, array('read_only' => true))
105108
->add('child', 'form')
@@ -109,7 +112,20 @@ public function testNonReadOnlyFormWithReadOnlyParentIsReadOnly()
109112
$this->assertTrue($view['child']->vars['read_only']);
110113
}
111114

112-
public function testReadOnlyFormWithNonReadOnlyParentIsReadOnly()
115+
public function testNonReadOnlyFormWithReadOnlyParentIsReadOnly()
116+
{
117+
$view = $this->factory->createNamedBuilder('parent', 'form', null, array('attr' => array('readonly' => true)))
118+
->add('child', 'form')
119+
->getForm()
120+
->createView();
121+
122+
$this->assertTrue($view['child']->vars['attr']['readonly']);
123+
}
124+
125+
/**
126+
* @group legacy
127+
*/
128+
public function testLegacyReadOnlyFormWithNonReadOnlyParentIsReadOnly()
113129
{
114130
$view = $this->factory->createNamedBuilder('parent', 'form')
115131
->add('child', 'form', array('read_only' => true))
@@ -119,7 +135,20 @@ public function testReadOnlyFormWithNonReadOnlyParentIsReadOnly()
119135
$this->assertTrue($view['child']->vars['read_only']);
120136
}
121137

122-
public function testNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly()
138+
public function testReadOnlyFormWithNonReadOnlyParentIsReadOnly()
139+
{
140+
$view = $this->factory->createNamedBuilder('parent', 'form')
141+
->add('child', 'form', array('attr' => array('readonly' => true)))
142+
->getForm()
143+
->createView();
144+
145+
$this->assertTrue($view['child']->vars['attr']['readonly']);
146+
}
147+
148+
/**
149+
* @group legacy
150+
*/
151+
public function testLegacyNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly()
123152
{
124153
$view = $this->factory->createNamedBuilder('parent', 'form')
125154
->add('child', 'form')
@@ -129,6 +158,16 @@ public function testNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly()
129158
$this->assertFalse($view['child']->vars['read_only']);
130159
}
131160

161+
public function testNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly()
162+
{
163+
$view = $this->factory->createNamedBuilder('parent', 'form')
164+
->add('child', 'form')
165+
->getForm()
166+
->createView();
167+
168+
$this->assertArrayNotHasKey('readonly', $view['child']->vars['attr']);
169+
}
170+
132171
public function testPassMaxLengthToView()
133172
{
134173
$form = $this->factory->create('form', null, array('attr' => array('maxlength' => 10)));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy