This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/UPGRADE-2.1.md

1479 lines
40 KiB
Markdown
Raw Normal View History

UPGRADE FROM 2.0 to 2.1
2011-10-08 17:29:31 +01:00
=======================
### General
* The merging strategy for `assets_base_urls` and `base_urls` has changed.
2011-10-08 17:29:31 +01:00
Unlike most configuration blocks, successive values for `assets_base_urls`
will overwrite each other instead of being merged. This behavior was chosen
because developers will typically define base URL's for each environment.
Given that most projects tend to inherit configurations (e.g.
`config_test.yml` imports `config_dev.yml`) and/or share a common base
configuration (i.e. `config.yml`), merging could yield a set of base URL's
for multiple environments.
2011-10-08 17:29:31 +01:00
* The priorities for the built-in listeners have changed.
2012-08-22 18:38:06 +01:00
```
2.0 2.1
security.firewall kernel.request 64 8
locale listener kernel.request 0 16
router listener early_request 255 n/a
request 0 32
```
2012-04-19 10:14:55 +01:00
### Doctrine
2012-06-16 17:50:09 +01:00
* The DoctrineBundle is moved from the Symfony repository to the Doctrine repository.
2012-04-19 10:14:55 +01:00
Therefore you should change the namespace of this bundle in your AppKernel.php:
Before: `new Symfony\Bundle\DoctrineBundle\DoctrineBundle()`
2012-04-19 10:14:55 +01:00
After: `new Doctrine\Bundle\DoctrineBundle\DoctrineBundle()`
### HttpFoundation
2012-02-23 04:10:06 +00:00
* Locale management was moved from the Session class to the Request class.
##### Configuring the default locale
2012-01-17 09:53:31 +00:00
Before:
2014-09-26 11:51:50 +01:00
```yaml
framework:
session:
default_locale: fr
```
2012-01-17 09:53:31 +00:00
After:
2014-09-26 11:51:50 +01:00
```yaml
framework:
default_locale: fr
```
##### Retrieving the locale from a Twig template
Before: `{{ app.request.session.locale }}` or `{{ app.session.locale }}`
2012-02-02 11:36:28 +00:00
2012-01-17 09:53:31 +00:00
After: `{{ app.request.locale }}`
##### Retrieving the locale from a PHP template
Before: `$view['session']->getLocale()`
2012-02-02 11:36:28 +00:00
2012-01-17 09:53:31 +00:00
After: `$view['request']->getLocale()`
##### Retrieving the locale from PHP code
Before: `$session->getLocale()`
2012-02-02 11:36:28 +00:00
2012-01-17 09:53:31 +00:00
After: `$request->getLocale()`
##### Simulate old behavior
You can simulate that the locale for the user is still stored in the session by
2014-09-26 11:51:50 +01:00
registering a listener that looks like the following if the parameter which
handles the locale value in the request is `_locale`:
2014-09-26 11:51:50 +01:00
```php
namespace XXX;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleListener implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct($defaultLocale = 'en')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $locale);
} else {
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
}
static public function getSubscribedEvents()
{
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
);
}
}
```
* The methods `getPathInfo()`, `getBaseUrl()` and `getBasePath()` of
a `Request` now all return a raw value (vs a urldecoded value before). Any call
to one of these methods must be checked and wrapped in a `rawurldecode()` if
needed.
### Security
* `Symfony\Component\Security\Core\User\UserInterface::equals()` has moved to
`Symfony\Component\Security\Core\User\EquatableInterface::isEqualTo()`.
You must rename the `equals()` method in your implementation of the `User`
class to `isEqualTo()` and implement `EquatableInterface`. Apart from that,
no other changes are required.
Alternatively, you may use the default implementation provided by
`AbstractToken::hasUserChanged()` if you have no need of custom comparison
logic. In this case, do not implement `EquatableInterface` and remove your
comparison method.
2012-01-17 09:53:31 +00:00
Before:
2014-09-26 11:51:50 +01:00
```php
class User implements UserInterface
{
// ...
public function equals(UserInterface $user) { /* ... */ }
// ...
}
2012-07-09 13:19:00 +01:00
```
2012-01-17 09:53:31 +00:00
After:
2014-09-26 11:51:50 +01:00
```php
class User implements UserInterface, EquatableInterface
{
// ...
public function isEqualTo(UserInterface $user) { /* ... */ }
// ...
}
```
2012-07-09 13:19:00 +01:00
* The custom factories for the firewall configuration are now
registered during the build method of bundles instead of being registered
2012-09-04 10:35:57 +01:00
by the end-user. This means that you will need to remove the 'factories'
keys in your security configuration.
Before:
2014-09-26 11:51:50 +01:00
```yaml
security:
factories:
- "%kernel.root_dir%/../src/Acme/DemoBundle/Resources/config/security_factories.yml"
```
2014-09-26 11:51:50 +01:00
```yaml
# src/Acme/DemoBundle/Resources/config/security_factories.yml
services:
security.authentication.factory.custom:
class: Acme\DemoBundle\DependencyInjection\Security\Factory\CustomFactory
tags:
- { name: security.listener.factory }
```
After:
2014-09-26 11:51:50 +01:00
```php
namespace Acme\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Acme\DemoBundle\DependencyInjection\Security\Factory\CustomFactory;
class AcmeDemoBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$extension = $container->getExtension('security');
$extension->addSecurityListenerFactory(new CustomFactory());
}
}
```
* The Firewall listener is now registered after the Router listener. This
means that specific Firewall URLs (like /login_check and /logout) must now
2012-08-22 18:38:06 +01:00
have proper routes defined in your routing configuration. Also, if you have
a custom 404 error page, make sure that you do not use any security related
features such as `is_granted` on it.
* The user provider configuration has been refactored. The configuration
for the chain provider and the memory provider has been changed:
Before:
2014-09-26 11:51:50 +01:00
```yaml
security:
providers:
my_chain_provider:
providers: [my_memory_provider, my_doctrine_provider]
my_memory_provider:
users:
toto: { password: foobar, roles: [ROLE_USER] }
foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] }
```
After:
2014-09-26 11:51:50 +01:00
```yaml
security:
providers:
my_chain_provider:
chain:
providers: [my_memory_provider, my_doctrine_provider]
my_memory_provider:
memory:
users:
toto: { password: foobar, roles: [ROLE_USER] }
foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] }
```
* `MutableAclInterface::setParentAcl` now accepts `null`, review any
implementations of this interface to reflect this change.
* The `UserPassword` constraint has moved from the Security Bundle to the Security Component:
Before:
2014-09-26 11:51:50 +01:00
```php
use Symfony\Bundle\SecurityBundle\Validator\Constraint\UserPassword;
use Symfony\Bundle\SecurityBundle\Validator\Constraint as SecurityAssert;
```
2012-08-22 18:38:06 +01:00
After:
2012-08-22 18:38:06 +01:00
2014-09-26 11:51:50 +01:00
```php
use Symfony\Component\Security\Core\Validator\Constraint\UserPassword;
use Symfony\Component\Security\Core\Validator\Constraint as SecurityAssert;
```
### Form
2012-01-17 09:53:31 +00:00
2012-05-25 08:13:02 +01:00
#### BC Breaks in Form Types and Options
2012-01-17 09:53:31 +00:00
2012-05-25 08:13:02 +01:00
* A third argument `$options` was added to the methods `buildView()` and
`buildViewBottomUp()` in `FormTypeInterface` and `FormTypeExtensionInterface`.
Furthermore, `buildViewBottomUp()` was renamed to `finishView()`. At last,
all methods in these types now receive instances of `FormBuilderInterface`
where they received instances of `FormBuilder` before. You need to change the
method signatures in your form types and extensions as shown below.
2012-05-25 08:13:02 +01:00
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
use Symfony\Component\Form\FormBuilder;
2012-01-30 10:10:25 +00:00
2012-05-25 08:13:02 +01:00
public function buildForm(FormBuilder $builder, array $options)
```
After:
2012-01-30 10:10:25 +00:00
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
use Symfony\Component\Form\FormBuilderInterface;
2012-05-25 08:13:02 +01:00
public function buildForm(FormBuilderInterface $builder, array $options)
```
* The method `createBuilder` was removed from `FormTypeInterface` for performance
reasons. It is now not possible anymore to use custom implementations of
`FormBuilderInterface` for specific form types.
If you are in such a situation, you can implement a custom `ResolvedFormTypeInterface`
where you create your own `FormBuilderInterface` implementation. You also need to
register a custom `ResolvedFormTypeFactoryInterface` implementation under the service
name "form.resolved_type_factory" in order to replace the default implementation.
* If you previously inherited from `FieldType`, you should now inherit from
`FormType`. You should also set the option `compound` to `false` if your field
is not supposed to contain child fields.
`FieldType` was deprecated and will be removed in Symfony 2.3.
Before:
2014-09-26 11:51:50 +01:00
```php
public function getParent(array $options)
{
return 'field';
}
```
After:
2014-09-26 11:51:50 +01:00
```php
public function getParent()
{
return 'form';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'compound' => false,
));
}
```
The changed signature of `getParent()` is explained in the next step.
The new method `setDefaultOptions` is described in the section "Deprecations".
2012-05-25 08:13:02 +01:00
* No options are passed to `getParent()` of `FormTypeInterface` anymore. If
you previously dynamically inherited from `FormType` or `FieldType`, you can now
dynamically set the "compound" option instead.
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
public function getParent(array $options)
{
return $options['expanded'] ? 'form' : 'field';
}
```
2012-01-30 10:10:25 +00:00
After:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\Options;
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
2012-05-25 08:13:02 +01:00
$compound = function (Options $options) {
return $options['expanded'];
};
2012-05-25 08:13:02 +01:00
$resolver->setDefaults(array(
'compound' => $compound,
));
}
public function getParent()
{
return 'form';
}
```
2012-01-30 10:10:25 +00:00
2012-05-25 08:13:02 +01:00
The new method `setDefaultOptions` is described in the section "Deprecations".
* The "data_class" option now *must* be set if a form maps to an object. If
you leave it empty, the form will expect an array, an instance of \ArrayAccess
or a scalar value and fail with a corresponding exception.
Likewise, if a form maps to an array or an instance of \ArrayAccess, the option
*must* be left null now.
Form mapped to an instance of `Person`:
2012-01-30 10:10:25 +00:00
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
2012-05-25 08:13:02 +01:00
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\Demo\Person',
));
}
```
2012-05-25 08:13:02 +01:00
* The mapping of property paths to arrays has changed.
2012-05-25 08:13:02 +01:00
Previously, a property path "street" mapped to both a field `$street` of
a class (or its accessors `getStreet()` and `setStreet()`) and an index
`['street']` of an array or an object implementing `\ArrayAccess`.
2012-02-02 11:36:28 +00:00
2012-05-25 08:13:02 +01:00
Now, the property path "street" only maps to a class field (or accessors),
while the property path "[street]" only maps to indices.
2012-05-25 08:13:02 +01:00
If you defined property paths manually in the "property_path" option, you
should revise them and adjust them if necessary.
2012-01-24 00:23:01 +00:00
2012-05-25 08:13:02 +01:00
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$builder->add('name', 'text', array(
'property_path' => 'address.street',
));
```
After (if the address object is an array):
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$builder->add('name', 'text', array(
'property_path' => 'address[street]',
));
```
If address is an object in this case, the code given in "Before"
works without changes.
* Form and field names must now start with a letter, digit or underscore
and only contain letters, digits, underscores, hyphens and colons.
* In the collection type's template, the default name of the prototype field
has changed from `$$name$$` to `__name__`.
You can now customize the name of the prototype field by changin the
"prototype_name" option. You are advised to prepend and append two
underscores wherever you specify a value for the field's "prototype_name"
option.
2014-09-26 11:51:50 +01:00
```php
2012-10-25 09:13:34 +01:00
$builder->add('tags', 'collection', array('prototype_name' => '__proto__'));
// results in the name "__proto__" in the template
```
2012-05-25 08:13:02 +01:00
* The "read_only" option now renders as `readonly="readonly"`, use
"disabled" instead for `disabled="disabled"`.
2012-05-25 08:13:02 +01:00
* Child forms are no longer automatically validated. That means that you must
explicitly set the `Valid` constraint in your model if you want to validate
objects modified by child forms.
2012-05-25 08:13:02 +01:00
If you don't want to set the `Valid` constraint, or if there is no reference
from the data of the parent form to the data of the child form, you can
enable BC behavior by setting the "cascade_validation" option to `true`
on the parent form.
2012-05-25 08:13:02 +01:00
#### BC Breaks in Themes and HTML
2012-05-25 08:13:02 +01:00
* FormType and FieldType were merged and require you to adapt your form
themes.
2012-05-25 08:13:02 +01:00
The block `field_widget` and all references to it should be renamed to
`form_widget_simple`:
Before:
2014-09-26 11:51:50 +01:00
```jinja
{% block url_widget %}
{% spaceless %}
{% set type = type|default('url') %}
{{ block('field_widget') }}
{% endspaceless %}
{% endblock url_widget %}
```
After:
2014-09-26 11:51:50 +01:00
```jinja
{% block url_widget %}
{% spaceless %}
{% set type = type|default('url') %}
{{ block('form_widget_simple') }}
{% endspaceless %}
{% endblock url_widget %}
```
2012-05-25 08:13:02 +01:00
All other `field_*` blocks and references to them should be renamed to
`form_*`. If you previously defined both a `field_*` and a `form_*`
block, you can merge them into a single `form_*` block and check the new
Boolean variable `compound` instead:
Before:
2014-09-26 11:51:50 +01:00
```jinja
{% block form_errors %}
{% spaceless %}
... form code ...
{% endspaceless %}
{% endblock form_errors %}
merged branch bschussek/issue3878 (PR #3923) Commits ------- 6e4ed9e [Form] Fixed regression: bind(null) was not converted to an empty string anymore fcb2227 [Form] Deprecated FieldType, which has been merged into FormType bfa7ef2 [Form] Removed obsolete exceptions 2a49449 [Form] Simplified CSRF mechanism and removed "csrf" type Discussion ---------- [Form] Merged FieldType into FormType Bug fix: no Feature addition: no Backwards compatibility break: yes Symfony2 tests pass: yes Fixes the following tickets: #3878 Todo: update the documentation on theming ![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=issue3878) This PR is a preparatory PR for #3879. See also #3878. --------------------------------------------------------------------------- by juliendidier at 2012-04-13T14:25:19Z What's the benefit ? --------------------------------------------------------------------------- by henrikbjorn at 2012-04-13T14:26:40Z why `input_widget` ? and not just `widget` --------------------------------------------------------------------------- by Burgov at 2012-04-13T14:27:49Z @juliendidier dynamic inheritance is now obsolete which fixes some other issues --------------------------------------------------------------------------- by stloyd at 2012-04-13T14:37:26Z What about __not__ breaking API so *badly* and leaving `FieldType` which will be simple like (with marking as deprecated): ```php <?php class FieldType extends AbstractType { public function getParent(array $options) { return 'form'; } public function getName() { return 'field'; } } --------------------------------------------------------------------------- by bschussek at 2012-04-13T14:43:41Z @stloyd That's a very good idea. --------------------------------------------------------------------------- by mvrhov at 2012-04-13T17:41:21Z IMHO what @stloyd proposed sounds like a good idea, but removing FieldType class, if #3903 will come into life might ensure that more forms will broke and people will check them thoroughly. --------------------------------------------------------------------------- by r1pp3rj4ck at 2012-04-13T18:46:08Z @bschussek looks great, but I'm concerned about how quickly will the third-party bundles adapt to this BC break. I hope really quick, because if they don't the whole stuff will be useless :S of course it's not your problem to solve. --------------------------------------------------------------------------- by stof at 2012-04-13T18:50:32Z @r1pp3rj4ck there is already another BC break requiring to update custom types for Symfony master. So third party bundles already have to do some work. --------------------------------------------------------------------------- by r1pp3rj4ck at 2012-04-13T18:59:37Z @stof which one? I've looked into @bschussek 's RFC about these [foo].bar stuff, but it's not yet implemented. Are you refering to this or another one I've missed? --------------------------------------------------------------------------- by stof at 2012-04-13T19:04:06Z @r1pp3rj4ck the change regarding default options --------------------------------------------------------------------------- by r1pp3rj4ck at 2012-04-13T19:06:10Z @stof oh, I forgot that one. Weird thing is that I've already changed my default options today and still forgetting these stuff :D --------------------------------------------------------------------------- by bschussek at 2012-04-14T08:58:29Z I restored and deprecated FieldType now. I'd appreciate further reviews. --------------------------------------------------------------------------- by stloyd at 2012-04-14T09:02:32Z Maybe we should try to avoid this BC in templates ? What do you think about similar move like with `FieldType` ? (hold old, but inside just render new) --------------------------------------------------------------------------- by bschussek at 2012-04-14T09:07:22Z @stloyd You mean for those cases where people explicitely render the block "field_*"? We can do that. --------------------------------------------------------------------------- by stloyd at 2012-04-14T09:09:45Z @bschussek Yes I mean this case =) Sorry for not being explicit, I need some coffee I think =) --------------------------------------------------------------------------- by bschussek at 2012-04-17T14:45:35Z I added the field_* blocks again for BC. Could someone please review again? Otherwise this can be merged. --------------------------------------------------------------------------- by Burgov at 2012-04-17T15:11:16Z @bschussek I'm not sure what has changed to cause this, but if I try out your branch on our forms, if I leave the value of an input empty, eventually the reverseTransform method receives a null value, rather than a '' (empty string) value, as on the current symfony master. DateTimeToLocalizedStringTransformer, for example, will throw an Exception if the value is not a string ```php if (!is_string($value)) { throw new UnexpectedTypeException($value, 'string'); } ``` Other than that, all forms render just the same as they do on symfony master --------------------------------------------------------------------------- by bschussek at 2012-04-17T15:30:29Z @Burgov Fixed.
2012-04-18 11:50:00 +01:00
{% block field_errors %}
{% spaceless %}
... field code ...
{% endspaceless %}
{% endblock field_errors %}
```
After:
2014-09-26 11:51:50 +01:00
```jinja
{% block form_errors %}
{% spaceless %}
{% if compound %}
... form code ...
{% else %}
... field code ...
{% endif %}
{% endspaceless %}
{% endblock form_errors %}
```
2012-05-25 08:13:02 +01:00
Furthermore, the block `generic_label` was merged into `form_label`. You
should now override `form_label` in order to customize labels.
2012-05-25 08:13:02 +01:00
Last but not least, the block `widget_choice_options` was renamed to
`choice_widget_options` to be consistent with the rest of the default
theme.
merged branch bschussek/issue3878 (PR #3923) Commits ------- 6e4ed9e [Form] Fixed regression: bind(null) was not converted to an empty string anymore fcb2227 [Form] Deprecated FieldType, which has been merged into FormType bfa7ef2 [Form] Removed obsolete exceptions 2a49449 [Form] Simplified CSRF mechanism and removed "csrf" type Discussion ---------- [Form] Merged FieldType into FormType Bug fix: no Feature addition: no Backwards compatibility break: yes Symfony2 tests pass: yes Fixes the following tickets: #3878 Todo: update the documentation on theming ![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=issue3878) This PR is a preparatory PR for #3879. See also #3878. --------------------------------------------------------------------------- by juliendidier at 2012-04-13T14:25:19Z What's the benefit ? --------------------------------------------------------------------------- by henrikbjorn at 2012-04-13T14:26:40Z why `input_widget` ? and not just `widget` --------------------------------------------------------------------------- by Burgov at 2012-04-13T14:27:49Z @juliendidier dynamic inheritance is now obsolete which fixes some other issues --------------------------------------------------------------------------- by stloyd at 2012-04-13T14:37:26Z What about __not__ breaking API so *badly* and leaving `FieldType` which will be simple like (with marking as deprecated): ```php <?php class FieldType extends AbstractType { public function getParent(array $options) { return 'form'; } public function getName() { return 'field'; } } --------------------------------------------------------------------------- by bschussek at 2012-04-13T14:43:41Z @stloyd That's a very good idea. --------------------------------------------------------------------------- by mvrhov at 2012-04-13T17:41:21Z IMHO what @stloyd proposed sounds like a good idea, but removing FieldType class, if #3903 will come into life might ensure that more forms will broke and people will check them thoroughly. --------------------------------------------------------------------------- by r1pp3rj4ck at 2012-04-13T18:46:08Z @bschussek looks great, but I'm concerned about how quickly will the third-party bundles adapt to this BC break. I hope really quick, because if they don't the whole stuff will be useless :S of course it's not your problem to solve. --------------------------------------------------------------------------- by stof at 2012-04-13T18:50:32Z @r1pp3rj4ck there is already another BC break requiring to update custom types for Symfony master. So third party bundles already have to do some work. --------------------------------------------------------------------------- by r1pp3rj4ck at 2012-04-13T18:59:37Z @stof which one? I've looked into @bschussek 's RFC about these [foo].bar stuff, but it's not yet implemented. Are you refering to this or another one I've missed? --------------------------------------------------------------------------- by stof at 2012-04-13T19:04:06Z @r1pp3rj4ck the change regarding default options --------------------------------------------------------------------------- by r1pp3rj4ck at 2012-04-13T19:06:10Z @stof oh, I forgot that one. Weird thing is that I've already changed my default options today and still forgetting these stuff :D --------------------------------------------------------------------------- by bschussek at 2012-04-14T08:58:29Z I restored and deprecated FieldType now. I'd appreciate further reviews. --------------------------------------------------------------------------- by stloyd at 2012-04-14T09:02:32Z Maybe we should try to avoid this BC in templates ? What do you think about similar move like with `FieldType` ? (hold old, but inside just render new) --------------------------------------------------------------------------- by bschussek at 2012-04-14T09:07:22Z @stloyd You mean for those cases where people explicitely render the block "field_*"? We can do that. --------------------------------------------------------------------------- by stloyd at 2012-04-14T09:09:45Z @bschussek Yes I mean this case =) Sorry for not being explicit, I need some coffee I think =) --------------------------------------------------------------------------- by bschussek at 2012-04-17T14:45:35Z I added the field_* blocks again for BC. Could someone please review again? Otherwise this can be merged. --------------------------------------------------------------------------- by Burgov at 2012-04-17T15:11:16Z @bschussek I'm not sure what has changed to cause this, but if I try out your branch on our forms, if I leave the value of an input empty, eventually the reverseTransform method receives a null value, rather than a '' (empty string) value, as on the current symfony master. DateTimeToLocalizedStringTransformer, for example, will throw an Exception if the value is not a string ```php if (!is_string($value)) { throw new UnexpectedTypeException($value, 'string'); } ``` Other than that, all forms render just the same as they do on symfony master --------------------------------------------------------------------------- by bschussek at 2012-04-17T15:30:29Z @Burgov Fixed.
2012-04-18 11:50:00 +01:00
2012-05-25 08:13:02 +01:00
* The strategy for generating the `id` and `name` HTML attributes for
checkboxes and radio buttons in a choice field has changed.
2012-05-25 08:13:02 +01:00
Instead of appending the choice value, a generated integer is now appended
by default. Take care if your JavaScript relies on that. If you want to
read the actual choice value, read the `value` attribute instead.
* In the choice field type's template, the `_form_is_choice_selected` method
used to identify a selected choice has been replaced with the `selectedchoice`
2014-09-26 11:51:50 +01:00
filter. Similarly, the `_form_is_choice_group` method used to check if a
choice is grouped has been removed and can be checked with the `iterable`
test.
Before:
2014-09-26 11:51:50 +01:00
```jinja
2012-05-25 08:13:02 +01:00
{% for choice, label in choices %}
{% if _form_is_choice_group(label) %}
<optgroup label="{{ choice|trans }}">
{% for nestedChoice, nestedLabel in label %}
... options tags ...
{% endfor %}
</optgroup>
{% else %}
<option value="{{ choice }}"{% if _form_is_choice_selected(form, choice) %} selected="selected"{% endif %}>
{{ label }}
</option>
{% endif %}
2012-05-25 08:13:02 +01:00
{% endfor %}
```
After:
2014-09-26 11:51:50 +01:00
```jinja
{% for label, choice in choices %}
{% if choice is iterable %}
<optgroup label="{{ label|trans({}, translation_domain) }}">
{% for nestedChoice, nestedLabel in choice %}
... options tags ...
{% endfor %}
</optgroup>
{% else %}
<option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>
{{ label }}
</option>
{% endif %}
2012-05-25 08:13:02 +01:00
{% endfor %}
```
* Creation of default labels has been moved to the view layer. You will need
to incorporate this logic into any custom `form_label` templates to
accommodate those cases when the `label` option has not been explicitly
set.
2014-09-26 11:51:50 +01:00
```jinja
{% block form_label %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
{# ... #}
{% endblock %}
````
* Custom styling of individual rows of a collection form has been removed for
performance reasons. Instead, all rows now have the same block name, where
2012-10-16 10:22:54 +01:00
the word "entry" replaces the previous occurrence of the row index.
Before:
2014-09-26 11:51:50 +01:00
```jinja
{% block _author_tags_0_label %}
{# ... #}
{% endblock %}
{% block _author_tags_1_label %}
{# ... #}
{% endblock %}
```
After:
2014-09-26 11:51:50 +01:00
```jinja
{% block _author_tags_entry_label %}
{# ... #}
{% endblock %}
```
* The method `renderBlock()` of the helper for the PHP Templating component was
renamed to `block()`. Its first argument is now expected to be a `FormView`
instance.
Before:
2014-09-26 11:51:50 +01:00
```php
<?php echo $view['form']->renderBlock('widget_attributes') ?>
```
After:
2014-09-26 11:51:50 +01:00
```php
<?php echo $view['form']->block($form, 'widget_attributes') ?>
```
2012-05-25 08:13:02 +01:00
#### Other BC Breaks
2012-05-20 16:16:03 +01:00
2012-05-25 08:13:02 +01:00
* The order of the first two arguments of the methods `createNamed` and
`createNamedBuilder` in `FormFactoryInterface` was reversed to be
consistent with the rest of the component. You should scan your code
for occurrences of these methods and reverse the parameters.
2012-05-20 16:16:03 +01:00
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$form = $factory->createNamed('text', 'firstName');
2012-05-20 16:16:03 +01:00
```
2012-05-25 08:13:02 +01:00
After:
2012-05-20 16:16:03 +01:00
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$form = $factory->createNamed('firstName', 'text');
2012-05-20 16:16:03 +01:00
```
2012-05-25 08:13:02 +01:00
* The implementation of `ChoiceList` was changed heavily. As a result,
`ArrayChoiceList` was replaced. If you have custom classes that extend
this class, you must now extend `SimpleChoiceList` and pass choices
to the parent constructor.
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
class MyChoiceList extends ArrayChoiceList
{
protected function load()
{
parent::load();
// load choices
$this->choices = $choices;
}
}
```
After:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
class MyChoiceList extends SimpleChoiceList
{
public function __construct()
{
// load choices
2012-05-25 08:13:02 +01:00
parent::__construct($choices);
}
}
```
2012-05-25 08:13:02 +01:00
If you need to load the choices lazily -- that is, as soon as they are
accessed for the first time -- you can extend `LazyChoiceList` instead
and load the choices by overriding `loadChoiceList()`.
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
class MyChoiceList extends LazyChoiceList
{
protected function loadChoiceList()
{
// load choices
return new SimpleChoiceList($choices);
}
}
```
2012-05-25 08:13:02 +01:00
`PaddedChoiceList`, `MonthChoiceList` and `TimezoneChoiceList` were removed.
Their functionality was merged into `DateType`, `TimeType` and `TimezoneType`.
2012-05-25 08:13:02 +01:00
`EntityChoiceList` was adapted. The methods `getEntities()`,
`getEntitiesByKeys()`, `getIdentifier()` and `getIdentifierValues()` were
removed or made private. Instead of the first two, you can now use
`getChoices()` and `getChoicesByValues()`. For the latter two, no
replacement exists.
* HTML attributes are now passed in the `label_attr` variable for the `form_label` function.
Before:
2014-09-26 11:51:50 +01:00
```jinja
{{ form_label(form.name, 'Your Name', { 'attr': {'class': 'foo'} }) }}
```
After:
2014-09-26 11:51:50 +01:00
```jinja
{{ form_label(form.name, 'Your Name', { 'label_attr': {'class': 'foo'} }) }}
```
2012-05-25 08:13:02 +01:00
* `EntitiesToArrayTransformer` and `EntityToIdTransformer` were removed.
The former was replaced by `CollectionToArrayTransformer` in combination
with `EntityChoiceList`, the latter is not required in the core anymore.
2012-05-25 08:13:02 +01:00
* The following transformers were renamed:
2012-05-25 08:13:02 +01:00
* `ArrayToBooleanChoicesTransformer` to `ChoicesToBooleanArrayTransformer`
* `ScalarToBooleanChoicesTransformer` to `ChoiceToBooleanArrayTransformer`
* `ArrayToChoicesTransformer` to `ChoicesToValuesTransformer`
* `ScalarToChoiceTransformer` to `ChoiceToValueTransformer`
2012-05-25 08:13:02 +01:00
to be consistent with the naming in `ChoiceListInterface`.
2012-05-25 08:13:02 +01:00
* `FormUtil::toArrayKey()` and `FormUtil::toArrayKeys()` were removed.
They were merged into ChoiceList and have no public equivalent anymore.
2012-05-25 08:13:02 +01:00
* The `add()`, `remove()`, `setParent()`, `bind()` and `setData()` methods in
the Form class now throw an exception if the form is already bound.
2012-05-25 08:13:02 +01:00
If you used these methods on bound forms, you should consider moving your
logic to an event listener that observes `FormEvents::PRE_BIND` or
`FormEvents::BIND`.
#### Deprecations
* The following methods of `FormTypeInterface` and `FormTypeExtensionInterface`
are deprecated and will be removed in Symfony 2.3:
* `getDefaultOptions`
* `getAllowedOptionValues`
You should use the newly added `setDefaultOptions` instead, which gives you
access to the OptionsResolverInterface instance and with that a lot more power.
Before:
2014-09-26 11:51:50 +01:00
```php
public function getDefaultOptions(array $options)
{
return array(
'gender' => 'male',
);
}
public function getAllowedOptionValues(array $options)
{
return array(
'gender' => array('male', 'female'),
);
}
```
After:
2014-09-26 11:51:50 +01:00
```php
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'gender' => 'male',
));
$resolver->setAllowedValues(array(
'gender' => array('male', 'female'),
));
}
```
You can specify options that depend on other options using closures.
Before:
2014-09-26 11:51:50 +01:00
```php
public function getDefaultOptions(array $options)
{
$defaultOptions = array();
if ($options['multiple']) {
$defaultOptions['empty_data'] = array();
}
return $defaultOptions;
}
```
After:
2014-09-26 11:51:50 +01:00
```php
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'empty_data' => function (Options $options, $value) {
return $options['multiple'] ? array() : $value;
}
));
}
```
The second argument `$value` contains the current default value and
does not have to be specified if not needed.
2012-05-25 08:13:02 +01:00
* The following methods in `FormBuilder` were deprecated and have a new
equivalent:
* `prependClientTransformer`: `addViewTransformer`, with `true` as second argument
2012-06-01 06:59:14 +01:00
* `appendClientTransformer`: `addViewTransformer`
* `getClientTransformers`: `getViewTransformers`
* `resetClientTransformers`: `resetViewTransformers`
2012-06-01 06:59:14 +01:00
* `prependNormTransformer`: `addModelTransformer`
* `appendNormTransformer`: `addModelTransformer`, with `true` as second argument
* `getNormTransformers`: `getModelTransformers`
* `resetNormTransformers`: `resetModelTransformers`
2012-05-25 08:13:02 +01:00
The deprecated methods will be removed in Symfony 2.3. You are advised to
update your application.
Before:
2014-09-26 11:51:50 +01:00
```php
$builder->appendClientTransformer(new MyTransformer());
```
After:
2014-09-26 11:51:50 +01:00
```php
$builder->addViewTransformer(new MyTransformer());
```
* The following events were deprecated and have a new equivalent:
* `FormEvents::SET_DATA`: `FormEvents::PRE_SET_DATA`
* `FormEvents::BIND_CLIENT_DATA`: `FormEvents::PRE_BIND`
* `FormEvents::BIND_NORM_DATA`: `FormEvents::BIND`
The deprecated events will be removed in Symfony 2.3.
Furthermore, the event classes `DataEvent` and `FilterDataEvent` were
deprecated and replaced by the generic `FormEvent`. You are advised to
code your listeners against the new event now. The deprecated events will
be removed in Symfony 2.3.
Before:
2014-09-26 11:51:50 +01:00
```php
$builder->addListener(FormEvents::BIND_CLIENT_DATA, function (FilterDataEvent $event) {
// ...
});
```
After:
2014-09-26 11:51:50 +01:00
```php
$builder->addListener(FormEvents::PRE_BIND, function (FormEvent $event) {
// ...
});
```
2012-05-25 08:13:02 +01:00
* The interface `FormValidatorInterface` was deprecated and will be removed
in Symfony 2.3.
If you implemented custom validators using this interface, you can
substitute them by event listeners listening to the `FormEvents::POST_BIND`
(or any other of the `*BIND` events). In case you used the CallbackValidator
class, you should now pass the callback directly to `addEventListener`.
* The method `guessMinLength()` of `FormTypeGuesserInterface` was deprecated
and will be removed in Symfony 2.3. You should use the new method
`guessPattern()` instead which may return any regular expression that
is inserted in the HTML5 attribute `pattern`.
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
public function guessMinLength($class, $property)
{
if (/* condition */) {
return new ValueGuess($minLength, Guess::LOW_CONFIDENCE);
}
}
2012-05-25 13:14:30 +01:00
```
2012-05-25 08:13:02 +01:00
After:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
public function guessPattern($class, $property)
{
if (/* condition */) {
return new ValueGuess('.{'.$minLength.',}', Guess::LOW_CONFIDENCE);
2012-05-25 08:13:02 +01:00
}
}
2012-05-25 13:14:30 +01:00
```
2012-05-25 08:13:02 +01:00
* Setting the option "property_path" to `false` was deprecated and will be unsupported
as of Symfony 2.3.
You should use the new option "mapped" instead in order to set that you don't want
a field to be mapped to its parent's data.
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$builder->add('termsAccepted', 'checkbox', array(
'property_path' => false,
));
```
After:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$builder->add('termsAccepted', 'checkbox', array(
'mapped' => false,
));
```
2012-05-25 08:13:02 +01:00
* The following methods in `Form` were deprecated and will be removed in
Symfony 2.3:
2012-05-25 08:13:02 +01:00
* `getTypes`
* `getErrorBubbling`
* `getNormTransformers`
* `getClientTransformers`
* `getAttribute`
* `hasAttribute`
* `getClientData`
* `getChildren`
* `hasChildren`
* `bindRequest`
2012-05-25 08:13:02 +01:00
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$form->getErrorBubbling()
```
After:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$form->getConfig()->getErrorBubbling();
```
The method `getClientData` has a new equivalent that is named `getViewData`.
You can access all other methods on the `FormConfigInterface` object instead.
Instead of `getChildren` and `hasChildren`, you should now use `all` and
`count`.
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
if ($form->hasChildren()) {
```
After:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
if (count($form) > 0) {
```
Instead of `bindRequest`, you should now simply call `bind`:
Before:
2014-09-26 11:51:50 +01:00
```php
$form->bindRequest($request);
```
After:
2014-09-26 11:51:50 +01:00
```php
$form->bind($request);
```
2012-05-25 08:13:02 +01:00
* The option "validation_constraint" was deprecated and will be removed
in Symfony 2.3. You should use the option "constraints" instead,
where you can pass one or more constraints for a form.
Before:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$builder->add('name', 'text', array(
'validation_constraint' => new NotBlank(),
));
```
After:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$builder->add('name', 'text', array(
'constraints' => new NotBlank(),
));
```
Unlike previously, you can also pass a list of constraints now:
2014-09-26 11:51:50 +01:00
```php
2012-05-25 08:13:02 +01:00
$builder->add('name', 'text', array(
'constraints' => array(
new NotBlank(),
new MinLength(3),
),
));
```
Be aware that constraints will now only be validated if they belong
to the validated group! So if you validate a form in group "Custom"
and previously did:
2014-09-26 11:51:50 +01:00
```php
$builder->add('name', 'text', array(
'validation_constraint' => new NotBlank(),
));
```
Then you need to add the constraint to the group "Custom" now:
2014-09-26 11:51:50 +01:00
```php
$builder->add('name', 'text', array(
'constraints' => new NotBlank(array('groups' => 'Custom')),
));
```
* The options "data_timezone" and "user_timezone" in `DateType`,
`DateTimeType` and `TimeType` were deprecated and will be removed in
Symfony 2.3. They were renamed to "model_timezone" and "view_timezone".
Before:
2014-09-26 11:51:50 +01:00
```php
$builder->add('scheduledFor', 'date', array(
'data_timezone' => 'UTC',
'user_timezone' => 'America/New_York',
));
```
After:
2014-09-26 11:51:50 +01:00
```php
$builder->add('scheduledFor', 'date', array(
'model_timezone' => 'UTC',
'view_timezone' => 'America/New_York',
));
```
* The methods `addType`, `hasType` and `getType` in `FormFactory` are deprecated
and will be removed in Symfony 2.3. You should use the methods with the same
name on the `FormRegistry` instead.
Before:
2014-09-26 11:51:50 +01:00
```php
$this->get('form.factory')->addType(new MyFormType());
```
After:
2014-09-26 11:51:50 +01:00
```php
$registry = $this->get('form.registry');
$registry->addType($registry->resolveType(new MyFormType()));
```
* The following methods in class `FormView` were deprecated and will be
removed in Symfony 2.3:
* `set`
* `has`
* `get`
* `all`
* `getVars`
* `addChild`
* `getChild`
* `getChildren`
* `removeChild`
* `hasChild`
* `hasChildren`
* `getParent`
* `hasParent`
* `setParent`
You should access the public properties `vars`, `children` and `parent`
instead.
Before:
2014-09-26 11:51:50 +01:00
```php
$view->set('help', 'A text longer than six characters');
$view->set('error_class', 'max_length_error');
```
After:
2014-09-26 11:51:50 +01:00
```php
$view->vars = array_replace($view->vars, array(
2014-10-22 19:27:13 +01:00
'help' => 'A text longer than six characters',
'error_class' => 'max_length_error',
));
```
Before:
2014-09-26 11:51:50 +01:00
```php
echo $view->get('error_class');
```
After:
2014-09-26 11:51:50 +01:00
```php
echo $view->vars['error_class'];
```
Before:
2014-09-26 11:51:50 +01:00
```php
if ($view->hasChildren()) { ...
```
After:
2014-09-26 11:51:50 +01:00
```php
if (count($view->children)) { ...
```
### Validator
* The methods `setMessage()`, `getMessageTemplate()` and
2012-07-18 05:53:58 +01:00
`getMessageParameters()` in the `ConstraintValidator` class were deprecated and will
be removed in Symfony 2.3.
If you have implemented custom validators, you should use the
`addViolation()` method on the `ExecutionContext` object instead.
Before:
2014-09-26 11:51:50 +01:00
```php
public function isValid($value, Constraint $constraint)
{
// ...
if (!$valid) {
$this->setMessage($constraint->message, array(
'{{ value }}' => $value,
));
return false;
}
}
```
After:
2014-09-26 11:51:50 +01:00
```php
public function isValid($value, Constraint $constraint)
{
// ...
if (!$valid) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $value,
));
return false;
merged branch bschussek/issue2615 (PR #3228) Commits ------- 2e4ebe4 [Validator] Renamed methods addViolationAtRelativePath() and getAbsolutePropertyPath() in ExecutionContext 9153f0e [Validator] Deprecated ConstraintValidator methods setMessage(), getMessageTemplate() and getMessageParameters() 0417282 [Validator] Fixed typos a30a679 [Validator] Made ExecutionContext immutable and introduced new class GlobalExecutionContext fe85bbd [Validator] Simplified ExecutionContext::addViolation(), added ExecutionContext::addViolationAt() f77fd41 [Form] Fixed typos 1fc615c Fixed string access by curly brace to bracket a103c28 [Validator] The Collection constraint adds "missing" and "extra" errors to the individual fields now f904a9e [Validator] Fixed: GraphWalker does not add constraint violation if error message is empty 1dd302c [Validator] Fixed ConstraintViolationList::__toString() to not include dots in the output if the root is empty 1678a3d [Validator] Fixed: Validator::validateValue() propagates empty validation root instead of the provided value Discussion ---------- [Validator] Improved "missing" and "extra" errors of Collection constraint Bug fix: yes Feature addition: no Backwards compatibility break: no Symfony2 tests pass: yes Fixes the following tickets: #2615 Todo: - ![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=issue2615) Instead of a single violation Array: The fields "foo", "bar" are missing various violations are now generated. Array[foo]: This field is missing Array[bar]: This field is missing Apart from that, the PR contains various minor fixes to the Validator. --------------------------------------------------------------------------- by bschussek at 2012-02-02T09:14:52Z @fabpot Ready for merge.
2012-02-02 09:16:32 +00:00
}
}
```
* The method `setPropertyPath()` in the ExecutionContext class
was removed.
You should use the `addViolationAtSubPath()` method on the
`ExecutionContext` object instead.
Before:
2014-09-26 11:51:50 +01:00
```php
public function isPropertyValid(ExecutionContext $context)
{
// ...
$propertyPath = $context->getPropertyPath().'.property';
$context->setPropertyPath($propertyPath);
$context->addViolation('Error Message', array(), null);
}
```
After:
2014-09-26 11:51:50 +01:00
```php
public function isPropertyValid(ExecutionContext $context)
{
// ...
$context->addViolationAtSubPath('property', 'Error Message', array(), null);
}
```
* The method `isValid` of `ConstraintValidatorInterface` was renamed to
`validate` and its return value was dropped.
2012-02-11 11:44:56 +00:00
`ConstraintValidator` still contains the deprecated `isValid` method and
forwards `validate` calls to `isValid` by default. This BC layer will be
removed in Symfony 2.3. You are advised to rename your methods. You should
also remove the return values, which have never been used by the framework.
2012-02-11 11:44:56 +00:00
Before:
2014-09-26 11:51:50 +01:00
```php
public function isValid($value, Constraint $constraint)
{
// ...
if (!$valid) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $value,
));
return false;
}
}
```
2012-02-11 11:44:56 +00:00
After:
2014-09-26 11:51:50 +01:00
```php
public function validate($value, Constraint $constraint)
{
// ...
if (!$valid) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $value,
));
return;
}
}
```
2012-07-23 17:12:06 +01:00
* Core translation messages changed. A dot is added at the end of each message.
Overwritten core translations need to be fixed.
2012-04-13 15:02:15 +01:00
* Collections (arrays or instances of `\Traversable`) in properties
annotated with `Valid` are not traversed recursively by default anymore.
This means that if a collection contains an entry which is again a
collection, the inner collection won't be traversed anymore as it
happened before. You can set the BC behavior by setting the new property
`deep` of `Valid` to `true`.
Before:
2014-09-26 11:51:50 +01:00
```php
/** @Assert\Valid */
private $recursiveCollection;
```
After:
2014-09-26 11:51:50 +01:00
```php
/** @Assert\Valid(deep = true) */
private $recursiveCollection;
```
* The `Size`, `Min` and `Max` constraints were deprecated and will be removed in
Symfony 2.3. You should use the new constraint `Range` instead.
Before:
2014-09-26 11:51:50 +01:00
```php
/** @Assert\Size(min = 2, max = 16) */
private $numberOfCpus;
```
After:
2014-09-26 11:51:50 +01:00
```php
/** @Assert\Range(min = 2, max = 16) */
private $numberOfCpus;
```
Before:
2014-09-26 11:51:50 +01:00
```php
/** @Assert\Min(2) */
private $numberOfCpus;
```
After:
2014-09-26 11:51:50 +01:00
```php
/** @Assert\Range(min = 2) */
private $numberOfCpus;
```
* The `MinLength` and `MaxLength` constraints were deprecated and will be
removed in Symfony 2.3. You should use the new constraint `Length` instead.
Before:
2014-09-26 11:51:50 +01:00
```php
/** @Assert\MinLength(8) */
private $password;
```
After:
2014-09-26 11:51:50 +01:00
```php
/** @Assert\Length(min = 8) */
private $password;
```
* The classes `ValidatorContext` and `ValidatorFactory` were deprecated and
will be removed in Symfony 2.3. You should use the new entry point
`Validation` instead.
Before:
2014-09-26 11:51:50 +01:00
```php
$validator = ValidatorFactory::buildDefault(array('path/to/mapping.xml'))
->getValidator();
```
After:
2014-09-26 11:51:50 +01:00
```php
$validator = Validation::createValidatorBuilder()
->addXmlMapping('path/to/mapping.xml')
->getValidator();
```
### Session
2012-11-19 16:25:14 +00:00
* The namespace of the Session class changed from `Symfony\Component\HttpFoundation\Session`
to `Symfony\Component\HttpFoundation\Session\Session`.
* Using `get` to retrieve flash messages now returns an array.
##### Retrieving the flash messages from a Twig template
Before:
2014-09-26 11:51:50 +01:00
```jinja
2012-03-23 17:01:12 +00:00
{% if app.session.hasFlash('notice') %}
<div class="flash-notice">
2012-03-23 17:01:12 +00:00
{{ app.session.getFlash('notice') }}
</div>
{% endif %}
```
After:
2014-09-26 11:51:50 +01:00
```jinja
2012-02-11 06:41:34 +00:00
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="flash-notice">
2012-02-11 06:41:34 +00:00
{{ flashMessage }}
</div>
2012-02-11 06:41:34 +00:00
{% endfor %}
```
2012-03-23 17:01:12 +00:00
You can process all flash messages in a single loop with:
2014-09-26 11:51:50 +01:00
```jinja
2012-02-11 06:41:34 +00:00
{% for type, flashMessages in app.session.flashbag.all() %}
2012-03-25 22:27:20 +01:00
{% for flashMessage in flashMessages %}
2012-02-11 06:41:34 +00:00
<div class="flash-{{ type }}">
{{ flashMessage }}
</div>
{% endfor %}
2012-02-25 15:44:52 +00:00
{% endfor %}
```
2012-03-06 19:41:09 +00:00
* Session handler drivers should implement `\SessionHandlerInterface` or extend from
2012-03-23 07:16:11 +00:00
`Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeHandlerInterface` base class and renamed
2012-03-06 19:41:09 +00:00
to `Handler\FooSessionHandler`. E.g. `PdoSessionStorage` becomes `Handler\PdoSessionHandler`.
2012-03-06 19:41:09 +00:00
* Refactor code using `$session->*flash*()` methods to use `$session->getFlashBag()->*()`.
### Serializer
2012-05-06 11:34:55 +01:00
* The key names created by the `GetSetMethodNormalizer` have changed from
2012-06-22 12:22:20 +01:00
all lowercased to camelCased (e.g. `mypropertyvalue` to `myPropertyValue`).
* The `item` element is now converted to an array when deserializing XML.
2014-09-26 11:51:50 +01:00
```xml
<?xml version="1.0"?>
<response>
<item><title><![CDATA[title1]]></title></item><item><title><![CDATA[title2]]></title></item>
</response>
```
Before:
Array()
After:
Array(
[item] => Array(
[0] => Array(
[title] => title1
)
[1] => Array(
[title] => title2
)
)
)
### Routing
* The UrlMatcher urldecodes the route parameters only once, they were
decoded twice before. Note that the `urldecode()` calls have been changed for a
single `rawurldecode()` in order to support `+` for input paths.
* Two new parameters have been added to the DIC: `router.request_context.host`
and `router.request_context.scheme`. You can customize them for your
functional tests or for generating urls with the right host and scheme
when your are in the cli context.
### FrameworkBundle
* session options: lifetime, path, domain, secure, httponly were deprecated.
Prefixed versions should now be used instead: cookie_lifetime, cookie_path, cookie_domain, cookie_secure, cookie_httponly
Before:
2014-09-26 11:51:50 +01:00
```yaml
framework:
session:
lifetime: 3600
path: \
domain: example.com
secure: true
httponly: true
```
After:
2014-09-26 11:51:50 +01:00
```yaml
framework:
session:
cookie_lifetime: 3600
cookie_path: \
cookie_domain: example.com
cookie_secure: true
cookie_httponly: true
```
2012-03-06 19:41:09 +00:00
Added `handler_id`, defaults to `session.handler.native_file`.
2014-09-26 11:51:50 +01:00
```yaml
2012-03-06 19:41:09 +00:00
framework:
session:
storage_id: session.storage.native
handler_id: session.handler.native_file
```
To use mock session storage use the following. `handler_id` is irrelevant in this context.
2014-09-26 11:51:50 +01:00
```yaml
2012-03-06 19:41:09 +00:00
framework:
session:
storage_id: session.storage.mock_file
```
### WebProfilerBundle
* You must clear old profiles after upgrading to 2.1. If you are using a
database then you will need to remove the table.