Issue 1:
Originally I wanted to display radio buttons without the possibility of changing them.

I tried using the read_only attribute on my field type first:

$builder->add('onCall', 'choice', array(
'choices' => array(0 => 'no', 1 => 'yes'),
'expanded' => true,
'read_only' => true
));

As expected the readonly attribute gets added to the input:

<input id="timekeeping_entry_day_onCall_0" type="radio" value="0" required="required" readonly="readonly" name="timekeeping_entry_day[onCall]">

But in the end this does not have any effect since - as we all know by now - readonly is not supported for radio buttons:

http://www.w3.org/TR/WD-forms-970402#readonly

READONLY applies to INPUT elements of type TEXT or PASSWORD and to the TEXTAREA element.

So allowing the read_only option on an expanded choice does not seem to make sense anyway, correct?

The desired effect on the element should be to disable it. But setting disabled on the field type will ignore validation after form submit if the radio buttons have been enabled again by a javascript on client side.

So it looks like the only way to do it is to set the HTML attribute disabled on the field type.

This way it can be enabled again by the client and the submitted value would not be ignored.

My attempt for this:

$builder->add('onCall', 'choice', array(
'choices' => array(0 => 'no', 1 => 'yes'),
'expanded' => true,
'attr' => array('disabled' => 'disabled')
));

Unfortunately the HTML result does not apply the disabled attribute to the input but to the div around it:

<div id="timekeeping_entry_day_onCall" disabled="disabled">
<input id="timekeeping_entry_day_onCall_0" type="radio" value="0" required="required" name="timekeeping_entry_day[onCall]">
<label class="required" for="timekeeping_entry_day_onCall_0">no</label>
<input id="timekeeping_entry_day_onCall_1" type="radio" value="1" required="required" name="timekeeping_entry_day[onCall]">
<label class="required" for="timekeeping_entry_day_onCall_1">yes</label>
</div>

I'm not using the Bootstrap theme.

Setting the attr seems to be the issue:

#8269 by @sargath

#8051 by @AdamQuadmon

The div uses the widget_container_attributes block:

https://github.com/symfony/symfony/blob/2.7/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig#L46

While the input uses a widget_attributes block:

https://github.com/symfony/symfony/blob/2.7/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig#L93

Are the attr passed to the wrong block?

Original issue I started:

sonata-project/SonataAdminBundle#2842

Possibly related:

#12946

Issue 2:
Q
A

Bug report?
no

Feature request?
no

BC Break report?
no

RFC?
yes

Symfony version
2.8.0 - 3.2.2

In my application, I have several authentication mechanisms and each one has it's own UserProvider. The security.yml looks like this:

security:
providers:
chain_provider:
chain:
providers: [provider1, provider2]
provider1: ...
provider2: ...

firewalls:
main:
guard:
authenticators:
- authenticator1
- authenticator2
entry_point: authenticator1

Now, as far as I understand, ChainUserProvider::loadUserByUsername lets each chained provider try to load a user with the provided credentials until one user is found or all providers have tried unsuccessfully. I.e. provider1 will eventually try to load a user with the credentials provided by authenticator2. If user1's credentials for authenticator1 are the same as user2's credentials for authenticator2, user2 would be logged in as user1 due to the order of the chained user providers. I think this should be prevented.

My idea to work around that problem was to tie providers to authenticators, so that a provider would only accept credentials from it's corresponding authenticator(s). If loadUserByUsername would not only have one parameter for the username, but a second one for the calling authenticator, I could've implemented that check in this method.

Makes sense? Is there a already a better way to tie the both of them? Or am I missing another concept here?