Commits
-------
8dc78bd [Form] Fixed YODA issues
600cec7 [Form] Added missing entries to CHANGELOG and UPGRADE
b154f7c [Form] Fixed docblock and unneeded use statement
399af27 [Form] Implemented checks to assert that values and indices generated in choice lists match their requirements
5f6f75c [Form] Fixed outstanding issues mentioned in the PR
7c70976 [Form] Fixed text in UPGRADE file
c26b47a [Form] Made query parameter name generated by ORMQueryBuilderLoader unique
18f92cd [Form] Fixed double choice fixing
f533ef0 [Form] Added ChoiceView class for passing choice-related data to the view
d72900e [Form] Incorporated changes suggested in PR comments
28d2f6d Removed duplicated lines from UPGRADE file
e1fc5a5 [Form] Restricted form names to specific characters to (1) fix generation of HTML IDs and to (2) avoid problems with property paths.
87b16e7 [Form] Greatly improved ChoiceListInterface and all of its implementations
Discussion
----------
[Form] Improved ChoiceList implementation and made form naming more restrictive
Bug fix: yes
Feature addition: yes
Backwards compatibility break: **yes**
Symfony2 tests pass: yes
Fixes the following tickets: #2869, #3021, #1919, #3153
Todo: adapt documentation
![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=issue1919)
The changes in this PR are primarily motivated by the fact that invalid form/field names lead to various problems.
1. When a name contains any characters that are not permitted in HTML "id" attributes, these are invalid
2. When a name contains periods ("."), form validation is broken, because they confuse the property path resolution
3. Since choices in expanded choice fields are directly translated to field names, choices applying to either 1. or 2. lead to problems. But choices should be unrestricted.
4. Unless a choice field is not expanded and does not allow multiple selection, it is not possible to use empty strings as choices, which might be desirable in some occasions.
The solution to these problems is to
* Restrict form names to disallow unpermitted characters (solves 1. and 2.)
* Generate integer indices to be stored in the HTML "id" and "name" attributes and map them to the choices (solves 3.). Can be reverted to the old behaviour by setting the option "index_generation" to ChoiceList::COPY_CHOICE
* Generate integer values to be stored in the HTML "value" attribute and map them to the choices (solves 4.). Can be reverted to the old behaviour by setting the option "value_generation" to ChoiceList::COPY_CHOICE
Apart from these fixes, it is now possible to write more flexible choice lists. One of these is `ObjectChoiceList`, which allows to use objects as choices and is bundled in the core. `EntityChoiceList` has been made an extension of this class.
$form = $this->createFormBuilder()
->add('object', 'choice', array(
'choice_list' => new ObjectChoiceList(
array($obj1, $obj2, $obj3, $obj4),
// property path determining the choice label (optional)
'name',
// preferred choices (optional)
array($obj2, $obj3),
// property path for object grouping (optional)
'category',
// property path for value generation (optional)
'id',
// property path for index generation (optional)
'id'
)
))
->getForm()
;
---------------------------------------------------------------------------
by kriswallsmith at 2012-01-19T18:09:09Z
Rather than passing `choices` and a `choice_labels` arrays to the view would it make sense to introduce a `ChoiceView` class and pass one array of objects?
---------------------------------------------------------------------------
by stof at 2012-01-22T15:32:36Z
@bschussek can you update your PR according to the feedback (and rebase it as it conflicts according to github) ?
---------------------------------------------------------------------------
by bschussek at 2012-01-24T00:15:42Z
@kriswallsmith fixed
Fixed all outstanding issues. Would be glad if someone could review again, otherwise this PR is ready to merge.
---------------------------------------------------------------------------
by fabpot at 2012-01-25T15:17:59Z
Is it ready to be merged?
---------------------------------------------------------------------------
by Tobion at 2012-01-25T15:35:50Z
Yes I think so. He said it's ready to be merged when reviewed.
---------------------------------------------------------------------------
by bschussek at 2012-01-26T02:30:36Z
Yes.
---------------------------------------------------------------------------
by bschussek at 2012-01-28T12:39:00Z
Fixed outstanding issues. Ready for merge.
Commits
-------
753c067 [FrameworkBundle] added $view['form']->csrfToken() helper
e1aced8 [Twig] added {{ csrf_token() }} helper
Discussion
----------
[Twig] [FrameworkBundle] added CSRF token helper
I've added a templating helper and Twig function for generating a CSRF token without the overhead of creating a form.
```html+jinja
<form action="{{ path('user_delete', { 'id': user.id }) }}" method="post">
<input type="hidden" name="_method" value="delete">
<input type="hidden" name="_token" value="{{ csrf_token('delete_user_' ~ user.id) }}">
<button type="submit">delete</button>
</form>
```
```php
<?php
class UserController extends Controller
{
public function delete(User $user, Request $request)
{
$csrfProvider = $this->get('form.csrf_provider');
if (!$csrfProvider->isCsrfTokenValid('delete_user_'.$user->getId(), $request->request->get('_token')) {
throw new RuntimeException('CSRF attack detected.');
}
// etc...
}
}
```
The test that is failing on Travis appears to be unrelated, but I may be wrong?
```
1) Symfony\Bundle\SecurityBundle\Tests\Functional\LocalizedRoutesAsPathTest::testLoginLogoutProcedure with data set #1 ('de')
RuntimeException: OUTPUT:
Catchable fatal error: Argument 3 passed to Symfony\Bundle\FrameworkBundle\Controller\TraceableControllerResolver::__construct() must be an instance of Symfony\Component\HttpKernel\Debug\Stopwatch, instance of Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser given, called in /tmp/2.1.0-DEV/StandardFormLogin/cache/securitybundletest/appSecuritybundletestDebugProjectContainer.php on line 94 and defined in /home/vagrant/builds/kriswallsmith/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/TraceableControllerResolver.php on line 37
```
---------------------------------------------------------------------------
by pablodip at 2012-01-10T14:18:45Z
As you don't need forms to use the csrf provider, how about putting its service without the form prefix? It could even make sense to put the CsrfProvider as a component since you can use it standalone and in more cases than only forms. It would be a small component though.
---------------------------------------------------------------------------
by Tobion at 2012-01-10T17:54:14Z
I think it would be more clear to generate the token in the controller. Doing so in the template will spread the CSRF intention across template and controller. So I don't think this extension is necessary.
---------------------------------------------------------------------------
by kriswallsmith at 2012-01-10T17:58:14Z
@pablodip I'm open to the idea of a Csrf component. This would be a good place for some nonce classes as well.
@Tobion I disagree. One use case is for a list of users, each with a delete form. Iterating over the users in the controller and generating a token for each, just to iterate over them again in the view is a waste and adds complexity.
---------------------------------------------------------------------------
by Tobion at 2012-01-10T18:05:14Z
I see. But I don't understand why the intention needs to be different for each user to delete. Usually the intention is the same for each form type. I thought this is enough.
---------------------------------------------------------------------------
by kriswallsmith at 2012-01-10T18:06:13Z
Yes, a static intention would suffice.
---------------------------------------------------------------------------
by Tobion at 2012-01-10T18:07:08Z
Then your use case is not valid anymore.
---------------------------------------------------------------------------
by Tobion at 2012-01-10T18:12:25Z
I would suggest to make a cookbook article out of it about how to create a simple form without the form component.
And include such things as validating the result using the validator component and checking the CSRF.
---------------------------------------------------------------------------
by kriswallsmith at 2012-01-10T21:32:50Z
This helper makes it easier to use CSRF protection without a form and we should make it as easy as possible. Spreading the intention across controller and template is not concerning to me. Either way, a cookbook entry is a great idea.
---------------------------------------------------------------------------
by Tobion at 2012-01-10T21:47:12Z
Well, it's just one line more without this helper. So I disagree it makes it really easier when you know how to use the CsrfProvider which is a pre-condition anyway since you must still validate its correctness by hand.
---------------------------------------------------------------------------
by kriswallsmith at 2012-01-13T13:24:15Z
Another use case is when rendering a page with a bunch of simple buttons with different intentions: delete user, delete comment, follow, unfollow... Creating all of these in the controller just leads to spaghetti.
---------------------------------------------------------------------------
by jwage at 2012-01-17T21:55:53Z
👍 lots of use cases for something like this @OpenSky
* 2.0:
Updated Serbian translation.
fixed CS
[Locale][Testing] Fixed breaking tests if 'intl' extension is not installed (#3139)
[Bridge] [Twig] fixed typo in a comment of the Twig FormExtension extension.
Commits
-------
85c0087 [TwigBridge] Made the locale configurable for the trans and transchoice tags
3ea31a0 [TwigBridge] Made the locale configurable for the trans and transchoice filters
Discussion
----------
Trans locale
This allows setting the locale when translating in a Twig template. This was already allowed in the Translator and in the PHP templates
If some of the nested views are rendered individually they should not be rendered again when calling form_rest.
A typical would be when some nested file views are rendered, form_rest should not render them again.
It is still possible to render a label once the widget has been rendered. This is for checkboxes and radios
where the widget is typically rendered before the label.