-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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
[Form] choices_as_value not working properly with associative arrays #14377
Comments
Possibly related to #14350 but not sure. |
If you submit this form I assume the, the correct value, e.g. |
@Tobion indeed, the model data is not impacted. Sorry for that, I was just in trouble with the new render. ;) Thanks! 👍 |
I guess for people that rely on the values in javascript for example, it's still problematic. |
@Tobion it's possible, didn't think about that. Do you want me to reopen this issue? |
I reopen it. This not work with array fields on model. According to this And the following security roles type: class SecurityRolesType extends AbstractType
{
protected $pool;
protected $authorizationChecker;
public function __construct(Pool $pool, AuthorizationCheckerInterface $authorizationChecker)
{
$this->pool = $pool;
$this->authorizationChecker = $authorizationChecker;
}
public function configureOptions(OptionsResolver $resolver)
{
$roles = [];
// Define the Sonata roles by group
$adminGroups = $this->pool->getAdminGroups();
foreach ($adminGroups as $adminGroup) {
foreach ($adminGroup['items'] as $adminItem) {
try {
$admin = $this->pool->getInstance($adminItem['admin']);
} catch (\Exception $e) {
continue;
}
$isMaster = $admin->isGranted('MASTER');
$securityHandler = $admin->getSecurityHandler();
$baseRole = $securityHandler->getBaseRole($admin);
$subRoles = [];
foreach ($admin->getSecurityInformation() as $role => $permissions) {
$completeRole = sprintf($baseRole, $role);
if ($isMaster) {
$subRoles[$role] = $completeRole;
}
}
$roles['SONATA ' . $admin->getLabel()] = $subRoles;
}
}
// Define the Symfony roles
$subRoles = [];
foreach ($this->pool->getContainer()->getParameter('security.role_hierarchy.roles') as $name => $rolesHierarchy) {
if ($this->authorizationChecker->isGranted($name)) {
$subRoles[$name] = $name;
foreach ($rolesHierarchy as $role) {
if (!isset($subRoles[$role])) {
$subRoles[$role] = $role;
}
}
}
}
$roles['SYMFONY'] = $subRoles;
$resolver->setDefaults([
'choices' => function (Options $options, $parentChoices) use ($roles) {
return empty($parentChoices) ? $roles : [];
},
'choices_as_values' => true, // TODO: Remove it on SF 3.0, default value.
'expanded' => false,
'multiple' => true,
'required' => false,
'data_class' => null
]);
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'app_security_roles';
}
} This will give numeric again value but we also affect the data model as it's an array. |
@webmozart can we have your opinion about this? Thanks. |
This not works with complex encapsulated forms, like this twig form override: {% trans_default_domain 'front' %}
<legend>{{ form.vars.label | trans | ucfirst }}</legend>
{% for choiceFormView in form.type %}
<div class="form-group {% if form[choiceFormView.vars.value].vars.errors | length %}has-error{% endif %}"
{% if not form[choiceFormView.vars.value].vars.errors | length %}style="margin-bottom: 35px"{% endif %}>
<div class="input-group">
<span class="input-group-addon">
{{ form_widget(choiceFormView) }}
<label for="{{ choiceFormView.vars.id }}">
{{ choiceFormView.vars.label }}
</label>
</span>
{{ form_widget(form[choiceFormView.vars.value]) }}
{% if form[choiceFormView.vars.value].vars.label %}
<span class="input-group-addon">
{{ form[choiceFormView.vars.value].vars.label | trans }}
</span>
{% endif %}
</div>
{{ form_errors(form[choiceFormView.vars.value]) }}
</div>
{% endfor %}
{{ form_rest(form) }}
I think it's BC break because if not, I shouldn't have to change my code to get it working, isn't it? |
I think it's a BC break too, many of my choice type don't work anymore since this update. |
I just noticed this also thanks to a commenter on the blog post announcing this feature. |
Any new for this issue? Would be great to solve it before 2.7 stable release. ping @webmozart @fabpot |
@soullivaneuh if you want to access the model data, you should use the |
Same question here: http://symfony.help/viewtopic.php?f=8&t=43 @stof I'm not sure if this issue (described by Soullivaneuh at the very beginning) is considered as a bug in your last post. When there's no option to prevent the values get lost, I would consider it to be one. (In my case, I need the values for JavaScript handling and I don't see a practical workaround at the moment) |
Still an issue with 2.7 released. If it's not a BC at the model end, it's still a BC for everything else. Most of the cases, I've got some kind of ID-to-entity-map in the choice fields and I find it hard to read/debug/code if the array just runs with a zero based integer index. In addition the handling isn't consistent, when you're putting an integer based array into the form as it's then keeping the given keys. 😞 |
@webmozart thoughts? Sounds like there may be a BC break, and some people are having issues with the upgrade. |
Hi guys! A few things:
// Before:
$builder->add('status', 'choice', array(
'choices' => array(
'published' => 'Published',
'unpublished' => 'Unpublished',
'draft' => 'Draft',
),
'mapped' => false
));
// After:
$builder->add('status', 'choice', array(
'choices' => array(
'Published' => 'published',
'Unpublished' => 'unpublished',
'Draft' => 'draft',
),
'choices_as_values' => true,
'choice_value' => function ($choice) {
return $choice;
},
)); For me, these both render identical HTML markup. Please let me know what you guys are seeing so we can help make sure others don't hit issues :). Thanks! |
Yes, not changing the form type at all doesn't introduce any BC as the rendered markup doesn't change. That's due to the fact that What troubles me: Why do I need to configure a boolean and a closure the get the simplest results you'd expect? That doesn't feel very Symfony like. In addition the blogpost by @webmozart states the
Using this results in an exception:
Using your approach with only one argument works flawlessly. I must admit that I'm working with a more complex test case based using the
No clue why, but this works. It changes the choices' values and the form children are simply 0-based. At least with my form element using |
Another observation:
Without the |
Case of Replace
Just replaced, Can you please explain a little bit more? |
Any update on this? @webmozart @fabpot This is somehow a major showstopper for our product release. Especially with #14607 unresolved. |
Default behavior can produce strange bugs, when choice list changes between form get and form post [
...
'choices' => [
'Moscow' => 123,
'St. Peterburg' => 124
]
...
] If on form post cities order will be changed like [
...
'choices' => [
'St. Peterburg' => 124,
'Moscow' => 123
]
...
] User can user can very surprised and frustrated, because he is select Moscow, but factically will be selected St. Peterburg. But QA never known about it, if user do not write to support. Default behavior never produce undetectable potential bugs. If it is not, then it is very bad. |
…averryan) This PR was merged into the 2.7 branch. Discussion ---------- Documenting how to keep option value BC - see #14377 | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #14377 (kinda) | License | MIT | Doc PR | symfony/symfony-docs#5179 Hi guys! I'm still making sense of the form changes, but it seems that this before and after isn't totally honest - your option values will change, unless your add this extra option. @webmozart look correct to you? Thanks! Commits ------- deb9db8 Documenting how to keep option value BC - see #14377
* 2.7: Fix test name fixed CS Allow new lines in Messages translated with transchoice() (replacement for #14867) [Form] Swap new ChoiceView constructor arguments to ease migrating from the deprecated one [2.3] Fix tests on Windows [Yaml] remove partial deprecation annotation Silence invasive deprecation warnings, opt-in for warnings Documenting how to keep option value BC - see #14377 Conflicts: src/Symfony/Bridge/Doctrine/composer.json src/Symfony/Bridge/Twig/composer.json
This ticket isn't solved by documentation, IMO. |
I think this belongs here, so here is a reproducible test case : https://gist.github.com/anonymous/8d8dd618a7185c24d203 |
This PR was merged into the 2.8 branch. Discussion ---------- Upgrade information for the choice_value option | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Relates to #14825 and #14377. The behaviour was changed with #16681 so a not in the upgrade information makes sense to me. Commits ------- 28675c9 Reflected the change of the choice_value option in the Upgrade information
I agree with @craigh and feel this is a big BC break. I've been running my head into a wall for a day debugging this, and find the proposed "fix" ridiculous (even though it does indeed seem to work)... // important if you rely on your option value attribute (e.g. for JavaScript)
// this will keep the same functionality as before
'choice_value' => function ($choice) {
return $choice;
}, From my experience, this doesn't just affect the view layer. I was unable to set the default "data" value of my choice forms to anything other than a "string" and have the option set as checked. |
@MichaelMackus your proposal does not always work. It depends what |
@stof not sure what you mean by that, I guess I just find it confusing that this worked in SF ~2.6 but seems broken in >2.7. For example, if I have: (Symfony >2.7) [
'choices' => array_combine(array('Object 1', 'Object 2', 'Object 3'), array(ValueObject1, ValueObject2, ValueObject3)),
'choices_as_values' => true,
] Without setting I'm not sure if this is a separate issue, but seems related from my research. Curiously, the option stays checked upon form submission, and the correct ValueObject choice gets returned from |
@MichaelMackus This should definitely work. Could you please open a new ticket with a reproducible test case? |
By the way, if you pass options that can be cast to strings without generating duplicates, those strings should also be printed in the "value" attributes in the HTML. If that doesn't work for you, please also open a ticket. Thanks! |
@webmozart thanks I've submitted the issue #17939 |
By following the upgrade to 2.7 documentation, I'm changing
choice
options.With the given form:
We get this output:
If I try to reverse choices and use
choices_as_value
option:I got this:
As you can see, my associated array keys are simply ignored and replaced by numeric values.
The text was updated successfully, but these errors were encountered: