Skip to content

[Form] deprecate read_only option #14403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,6 @@

{%- block widget_attributes -%}
id="{{ id }}" name="{{ full_name }}"
{%- if read_only %} readonly="readonly"{% endif -%}
{%- if disabled %} disabled="disabled"{% endif -%}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnapoli Could you please try to reverse the change on this line to confirm it fixes it ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry I don't think I'll have time to test, but I believe the test that was changed in this pull request could be used to check? (i.e. revert the test and see if it fails/passes)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{%- if required %} required="required"{% endif -%}
{%- for attrname, attrvalue in attr -%}
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bridge/Twig/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
id="<?php echo $view->escape($id) ?>" name="<?php echo $view->escape($full_name) ?>" <?php if ($read_only): ?>readonly="readonly" <?php endif ?>
<?php if ($disabled): ?>disabled="disabled" <?php endif ?>
<?php if ($required): ?>required="required" <?php endif ?>
id="<?php echo $view->escape($id) ?>" name="<?php echo $view->escape($full_name) ?>"<?php if ($disabled): ?> disabled="disabled"<?php endif ?>
<?php if ($required): ?> required="required"<?php endif ?>
<?php foreach ($attr as $k => $v): ?>
<?php if (in_array($k, array('placeholder', 'title'), true)): ?>
<?php printf('%s="%s" ', $view->escape($k), $view->escape($view['translator']->trans($v, array(), $translation_domain))) ?>
<?php printf(' %s="%s"', $view->escape($k), $view->escape($view['translator']->trans($v, array(), $translation_domain))) ?>
<?php elseif ($v === true): ?>
<?php printf('%s="%s" ', $view->escape($k), $view->escape($k)) ?>
<?php printf(' %s="%s"', $view->escape($k), $view->escape($k)) ?>
<?php elseif ($v !== false): ?>
<?php printf('%s="%s" ', $view->escape($k), $view->escape($v)) ?>
<?php printf(' %s="%s"', $view->escape($k), $view->escape($v)) ?>
<?php endif ?>
<?php endforeach ?>
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/FrameworkBundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

2.8.0
-----

* deprecated option "read_only" in favor of "attr['readonly']"

2.7.0
-----

Expand Down
31 changes: 26 additions & 5 deletions src/Symfony/Component/Form/Extension/Core/Type/FormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,20 @@ 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) {
throw new LogicException('Form node with empty name can be used only as root form node.');
}

// 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;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnapoli Ok so to avoid the BC break, we just need to add a line here with:

$view->vars['read_only'] = true; // BC`

Wrong this has to be done in the form theme.

}

$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(),
Expand Down Expand Up @@ -185,12 +184,31 @@ 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.8 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, // deprecated
'max_length' => null,
'pattern' => null,
'property_path' => null,
Expand All @@ -209,6 +227,9 @@ 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');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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('<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);
$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);
}

public function testWidgetAttributeNameRepeatedIfTrue()
Expand Down
10 changes: 6 additions & 4 deletions src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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('<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);
$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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand, this doesn't preserve BC here? The test was changed to support the new way (through attributes), but the old way is not tested anymore.

This created a BC break for us when migrating from 2.7 to 2.8. We have to switch from the read_only variable to the attr key.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnapoli what exactly is breaking except the position in the string ? One would just expect to get the attribute here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before (2.7) passing read_only as a variable was working, after (2.8) it isn't. We had to put readonly in the attr array instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the change we had to do:

 {% block _form_category_name_widget %}
-    {% set read_only = true %}
     {% set attr = {
         'data-target-show': '.choose-categories',
+        'readonly': true,
     } %}
     {{ block('form_widget_simple') }}
{% endblock %}

}

public function testWidgetAttributeNameRepeatedIfTrue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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))
Expand All @@ -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')
Expand All @@ -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)));
Expand Down
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