2012-04-11 11:44:45 +01:00
|
|
|
UPGRADE FROM 2.0 to 2.1
|
2011-10-08 17:29:31 +01:00
|
|
|
=======================
|
|
|
|
|
2011-12-24 10:36:18 +00:00
|
|
|
### General
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
* The merging strategy for `assets_base_urls` and `base_urls` has changed.
|
2011-10-08 17:29:31 +01:00
|
|
|
|
2012-02-14 03:11:40 +00: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
|
|
|
|
2012-04-19 10:14:55 +01:00
|
|
|
### Doctrine
|
|
|
|
|
|
|
|
The DoctrineBundle is moved from the Symfony repository to the Doctrine repository.
|
|
|
|
Therefore you should change the namespace of this bundle in your AppKernel.php:
|
|
|
|
|
|
|
|
Before: `new Symfony\Bundle\DoctrineBundle\DoctrineBundle()`
|
|
|
|
After: `new Doctrine\Bundle\DoctrineBundle\DoctrineBundle()`
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
### HttpFoundation
|
2011-12-24 10:36:18 +00:00
|
|
|
|
2012-02-23 04:10:06 +00:00
|
|
|
* Locale management was moved from the Session class to the Request class.
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
##### Configuring the default locale
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-01-17 09:53:31 +00:00
|
|
|
Before:
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
framework:
|
|
|
|
session:
|
|
|
|
default_locale: fr
|
|
|
|
```
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-01-17 09:53:31 +00:00
|
|
|
After:
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
framework:
|
|
|
|
default_locale: fr
|
|
|
|
```
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-04-11 15:01:47 +01:00
|
|
|
* 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.
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
##### Retrieving the locale from a Twig template
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-02-02 11:07:02 +00:00
|
|
|
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 }}`
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
##### Retrieving the locale from a PHP template
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-02-02 11:07:02 +00:00
|
|
|
Before: `$view['session']->getLocale()`
|
2012-02-02 11:36:28 +00:00
|
|
|
|
2012-01-17 09:53:31 +00:00
|
|
|
After: `$view['request']->getLocale()`
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
##### Retrieving the locale from PHP code
|
2011-10-05 10:09:51 +01:00
|
|
|
|
2012-02-02 11:07:02 +00:00
|
|
|
Before: `$session->getLocale()`
|
2012-02-02 11:36:28 +00:00
|
|
|
|
2012-01-17 09:53:31 +00:00
|
|
|
After: `$request->getLocale()`
|
2012-01-12 18:15:35 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
### Security
|
2012-01-12 18:15:35 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
* `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:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
class User implements UserInterface
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
public function equals(UserInterface $user) { /* ... */ }
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
```
|
2012-01-17 09:53:31 +00:00
|
|
|
|
|
|
|
After:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
class User implements UserInterface, EquatableInterface
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
public function isEqualTo(UserInterface $user) { /* ... */ }
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
```
|
2012-04-11 15:01:47 +01:00
|
|
|
* The custom factories for the firewall configuration are now
|
|
|
|
registered during the build method of bundles instead of being registered
|
2012-04-20 17:42:21 +01:00
|
|
|
by the end-user. This means that you will you need to remove the 'factories'
|
2012-04-11 15:01:47 +01:00
|
|
|
keys in your security configuration.
|
|
|
|
|
|
|
|
* The Firewall listener is now registered after the Router listener. This
|
|
|
|
means that specific Firewall URLs (like /login_check and /logout) must now
|
|
|
|
have proper routes defined in your routing configuration.
|
|
|
|
|
|
|
|
* The user provider configuration has been refactored. The configuration
|
|
|
|
for the chain provider and the memory provider has been changed:
|
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
``` 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:
|
|
|
|
|
|
|
|
``` 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] }
|
|
|
|
```
|
2012-02-14 03:11:40 +00:00
|
|
|
|
2012-04-11 17:24:00 +01:00
|
|
|
* `MutableAclInterface::setParentAcl` now accepts `null`, review any
|
|
|
|
implementations of this interface to reflect this change.
|
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
### 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`
|
|
|
|
and `FormViewInterface` where they received instances of `FormBuilder` and
|
|
|
|
`FormView` before. You need to change the method signatures in your
|
|
|
|
form types and extensions as shown below.
|
2012-01-16 23:46:26 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
Before:
|
2012-01-30 09:57:14 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
```
|
|
|
|
use Symfony\Component\Form\FormBuilder;
|
|
|
|
use Symfony\Component\Form\FormView;
|
2012-01-30 10:10:25 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
public function buildForm(FormBuilder $builder, array $options)
|
|
|
|
public function buildView(FormView $view, FormInterface $form)
|
|
|
|
public function buildViewBottomUp(FormView $view, FormInterface $form)
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
2012-01-30 10:10:25 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
use Symfony\Component\Form\FormBuilderInterface;
|
|
|
|
use Symfony\Component\Form\FormViewInterface;
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
|
|
public function buildView(FormViewInterface $view, FormInterface $form, array $options)
|
|
|
|
public function finishView(FormViewInterface $view, FormInterface $form, array $options)
|
|
|
|
```
|
2012-02-29 08:44:47 +00:00
|
|
|
|
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:
|
|
|
|
|
|
|
|
```
|
|
|
|
public function getParent(array $options)
|
|
|
|
{
|
|
|
|
return $options['expanded'] ? 'form' : 'field';
|
2012-02-14 03:11:40 +00:00
|
|
|
}
|
|
|
|
```
|
2012-01-30 10:10:25 +00:00
|
|
|
|
|
|
|
After:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
|
|
|
use Symfony\Component\OptionsResolver\Options;
|
|
|
|
|
|
|
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
2012-02-14 03:11:40 +00:00
|
|
|
{
|
2012-05-25 08:13:02 +01:00
|
|
|
$compound = function (Options $options) {
|
|
|
|
return $options['expanded'];
|
|
|
|
};
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
$resolver->setDefaults(array(
|
|
|
|
'compound' => $compound,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getParent()
|
|
|
|
{
|
|
|
|
return 'form';
|
2012-02-14 03:11:40 +00:00
|
|
|
}
|
|
|
|
```
|
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
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
|
|
|
{
|
|
|
|
$resolver->setDefaults(array(
|
|
|
|
'data_class' => 'Acme\Demo\Person',
|
|
|
|
));
|
2012-02-14 03:11:40 +00:00
|
|
|
}
|
|
|
|
```
|
2012-01-30 09:57:14 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
The new method `setDefaultOptions` is described in the section "Deprecations".
|
2012-01-30 09:57:14 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
* The mapping of property paths to arrays has changed.
|
2012-01-30 09:57:14 +00:00
|
|
|
|
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-02-14 03:11:40 +00:00
|
|
|
|
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:
|
|
|
|
|
|
|
|
```
|
|
|
|
$builder->add('name', 'text', array(
|
|
|
|
'property_path' => 'address.street',
|
|
|
|
));
|
|
|
|
```
|
|
|
|
|
|
|
|
After (if the address object is an array):
|
|
|
|
|
|
|
|
```
|
|
|
|
$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.
|
|
|
|
|
|
|
|
* The methods in class `FormView` were renamed to match the naming used in
|
|
|
|
`Form` and `FormBuilder`. The following list shows the old names on the
|
|
|
|
left and the new names on the right:
|
|
|
|
|
|
|
|
* `set`: `setVar`
|
|
|
|
* `has`: `hasVar`
|
|
|
|
* `get`: `getVar`
|
|
|
|
* `all`: `getVars`
|
|
|
|
* `addChild`: `add`
|
|
|
|
* `getChild`: `get`
|
|
|
|
* `getChildren`: `all`
|
|
|
|
* `removeChild`: `remove`
|
|
|
|
* `hasChild`: `has`
|
|
|
|
|
|
|
|
The new method `addVars` was added to make the definition of multiple
|
|
|
|
variables at once more convenient.
|
|
|
|
|
|
|
|
The method `hasChildren` was deprecated. You should use `count` instead.
|
2012-01-24 00:23:01 +00:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
$view->set('help', 'A text longer than six characters');
|
|
|
|
$view->set('error_class', 'max_length_error');
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-01-24 00:23:01 +00:00
|
|
|
|
|
|
|
After:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
$view->addVars(array(
|
|
|
|
'help' => 'A text longer than six characters',
|
|
|
|
'error_class' => 'max_length_error',
|
|
|
|
));
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-01-28 12:37:13 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
* Form and field names must now start with a letter, digit or underscore
|
|
|
|
and only contain letters, digits, underscores, hyphens and colons.
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
* In the collection type's template, the default name of the prototype field
|
|
|
|
has changed from `$$name$$` to `__name__`.
|
2012-01-28 12:37:13 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
For custom names, dollar signs are no longer prepended and appended. You are
|
|
|
|
advised to prepend and append two underscores wherever you specify a value
|
2012-05-25 08:13:02 +01:00
|
|
|
for the field's "prototype_name" option.
|
2012-01-28 12:37:13 +00:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
$builder->add('tags', 'collection', array('prototype' => 'proto'));
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
// results in the name "$$proto$$" in the template
|
|
|
|
```
|
2012-01-28 12:37:13 +00:00
|
|
|
|
|
|
|
After:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
$builder->add('tags', 'collection', array('prototype' => '__proto__'));
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
// results in the name "__proto__" in the template
|
|
|
|
```
|
2012-02-01 12:53:45 +00:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
* The "read_only" option now renders as `readonly="readonly"`, use
|
|
|
|
"disabled" instead for `disabled="disabled"`.
|
2012-04-11 17:24:00 +01:00
|
|
|
|
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-04-17 16:19:12 +01:00
|
|
|
|
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-04-17 16:19:12 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
#### BC Breaks in Themes and HTML
|
2012-04-17 16:19:12 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
* FormType and FieldType were merged and require you to adapt your form
|
2012-04-20 17:42:21 +01:00
|
|
|
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`:
|
2012-04-20 17:42:21 +01:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
|
|
|
{% block url_widget %}
|
|
|
|
{% spaceless %}
|
|
|
|
{% set type = type|default('url') %}
|
|
|
|
{{ block('field_widget') }}
|
|
|
|
{% endspaceless %}
|
|
|
|
{% endblock url_widget %}
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
{% block url_widget %}
|
|
|
|
{% spaceless %}
|
|
|
|
{% set type = type|default('url') %}
|
2012-05-24 14:01:02 +01:00
|
|
|
{{ block('form_widget_simple') }}
|
2012-04-20 17:42:21 +01:00
|
|
|
{% 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:
|
2012-04-20 17:42:21 +01:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
|
|
|
{% 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
|
|
|
|
2012-04-20 17:42:21 +01:00
|
|
|
{% block field_errors %}
|
|
|
|
{% spaceless %}
|
|
|
|
... field code ...
|
|
|
|
{% endspaceless %}
|
|
|
|
{% endblock field_errors %}
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
{% block form_errors %}
|
|
|
|
{% spaceless %}
|
2012-05-24 14:01:02 +01:00
|
|
|
{% if compound %}
|
2012-04-20 17:42:21 +01:00
|
|
|
... form code ...
|
2012-05-24 14:01:02 +01:00
|
|
|
{% else %}
|
|
|
|
... field code ...
|
2012-04-20 17:42:21 +01:00
|
|
|
{% 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-04-20 17:42:21 +01:00
|
|
|
|
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
|
2012-04-20 17:42:21 +01:00
|
|
|
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-04-20 17:42:21 +01:00
|
|
|
|
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.
|
2012-04-13 15:06:32 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
* In the choice field type's template, the structure of the `choices` variable
|
|
|
|
has changed.
|
2012-05-18 10:20:03 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
The `choices` variable now contains `ChoiceView` objects with two getters,
|
|
|
|
`getValue()` and `getLabel()`, to access the choice data.
|
2012-05-18 10:20:03 +01:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
{% for choice, label in choices %}
|
|
|
|
<option value="{{ choice }}"{% if _form_is_choice_selected(form, choice) %} selected="selected"{% endif %}>
|
|
|
|
{{ label }}
|
|
|
|
</option>
|
|
|
|
{% endfor %}
|
2012-05-18 10:20:03 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
{% for choice in choices %}
|
|
|
|
<option value="{{ choice.value }}"{% if _form_is_choice_selected(form, choice) %} selected="selected"{% endif %}>
|
|
|
|
{{ choice.label }}
|
|
|
|
</option>
|
|
|
|
{% endfor %}
|
2012-05-18 10:20:03 +01:00
|
|
|
```
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
```
|
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
|
|
|
|
|
|
|
```
|
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.
|
2012-05-24 13:24:28 +01:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
class MyChoiceList extends ArrayChoiceList
|
|
|
|
{
|
|
|
|
protected function load()
|
|
|
|
{
|
|
|
|
parent::load();
|
|
|
|
|
|
|
|
// load choices
|
|
|
|
|
|
|
|
$this->choices = $choices;
|
|
|
|
}
|
|
|
|
}
|
2012-05-24 13:24:28 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
class MyChoiceList extends SimpleChoiceList
|
|
|
|
{
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
// load choices
|
2012-05-21 08:27:45 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
parent::__construct($choices);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
2012-05-24 13:24:28 +01:00
|
|
|
|
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()`.
|
2012-05-21 08:27:45 +01:00
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
class MyChoiceList extends LazyChoiceList
|
|
|
|
{
|
|
|
|
protected function loadChoiceList()
|
|
|
|
{
|
|
|
|
// load choices
|
|
|
|
|
|
|
|
return new SimpleChoiceList($choices);
|
|
|
|
}
|
|
|
|
}
|
2012-05-21 08:27:45 +01:00
|
|
|
```
|
|
|
|
|
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-21 08:27:45 +01:00
|
|
|
|
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.
|
2012-05-21 08:27:45 +01:00
|
|
|
|
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-21 16:13:00 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
* The following transformers were renamed:
|
2012-05-21 16:13:00 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
* `ArrayToBooleanChoicesTransformer` to `ChoicesToBooleanArrayTransformer`
|
|
|
|
* `ScalarToBooleanChoicesTransformer` to `ChoiceToBooleanArrayTransformer`
|
|
|
|
* `ArrayToChoicesTransformer` to `ChoicesToValuesTransformer`
|
|
|
|
* `ScalarToChoiceTransformer` to `ChoiceToValueTransformer`
|
2012-05-21 16:13:00 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
to be consistent with the naming in `ChoiceListInterface`.
|
2012-05-21 16:13:00 +01:00
|
|
|
|
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-21 16:13:00 +01:00
|
|
|
|
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-22 10:22:27 +01:00
|
|
|
|
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
|
2012-05-22 10:22:27 +01:00
|
|
|
|
2012-05-23 16:29:07 +01:00
|
|
|
* 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
|
2012-05-23 18:49:55 +01:00
|
|
|
access to the OptionsResolverInterface instance and with that a lot more power.
|
2012-05-23 16:29:07 +01:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
|
|
|
public function getDefaultOptions(array $options)
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
'gender' => 'male',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getAllowedOptionValues(array $options)
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
'gender' => array('male', 'female'),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
2012-05-23 18:49:55 +01:00
|
|
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
2012-05-23 16:29:07 +01:00
|
|
|
{
|
|
|
|
$resolver->setDefaults(array(
|
|
|
|
'gender' => 'male',
|
|
|
|
));
|
|
|
|
|
|
|
|
$resolver->setAllowedValues(array(
|
|
|
|
'gender' => array('male', 'female'),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
You can specify options that depend on other options using closures.
|
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
|
|
|
public function getDefaultOptions(array $options)
|
|
|
|
{
|
|
|
|
$defaultOptions = array();
|
|
|
|
|
|
|
|
if ($options['multiple']) {
|
|
|
|
$defaultOptions['empty_data'] = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $defaultOptions;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
2012-05-23 18:49:55 +01:00
|
|
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
2012-05-23 16:29:07 +01:00
|
|
|
{
|
|
|
|
$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:
|
2012-05-23 18:34:41 +01:00
|
|
|
|
2012-06-09 13:22:15 +01:00
|
|
|
* `prependClientTransformer`: `addViewTransformer`, with `true` as second argument
|
2012-06-01 06:59:14 +01:00
|
|
|
* `appendClientTransformer`: `addViewTransformer`
|
2012-05-23 19:21:34 +01:00
|
|
|
* `getClientTransformers`: `getViewTransformers`
|
|
|
|
* `resetClientTransformers`: `resetViewTransformers`
|
2012-06-01 06:59:14 +01:00
|
|
|
* `prependNormTransformer`: `addModelTransformer`
|
2012-06-09 13:22:15 +01:00
|
|
|
* `appendNormTransformer`: `addModelTransformer`, with `true` as second argument
|
2012-05-23 19:21:34 +01:00
|
|
|
* `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.
|
2012-05-23 19:21:34 +01:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
2012-06-09 13:22:15 +01:00
|
|
|
$builder->appendClientTransformer(new MyTransformer());
|
2012-05-23 19:21:34 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
$builder->addViewTransformer(new MyTransformer());
|
|
|
|
```
|
2012-05-23 17:47:14 +01:00
|
|
|
|
2012-05-23 19:58:42 +01:00
|
|
|
* 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:
|
|
|
|
|
|
|
|
```
|
|
|
|
$builder->addListener(FormEvents::BIND_CLIENT_DATA, function (FilterDataEvent $event) {
|
|
|
|
// ...
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
$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:
|
|
|
|
|
2012-05-25 13:14:30 +01:00
|
|
|
```
|
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:
|
|
|
|
|
2012-05-25 13:14:30 +01:00
|
|
|
```
|
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 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.
|
2012-05-23 20:50:13 +01:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
$builder->add('termsAccepted', 'checkbox', array(
|
|
|
|
'property_path' => false,
|
|
|
|
));
|
2012-05-23 20:50:13 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
$builder->add('termsAccepted', 'checkbox', array(
|
|
|
|
'mapped' => false,
|
|
|
|
));
|
2012-05-23 20:50:13 +01:00
|
|
|
```
|
|
|
|
|
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-24 13:24:28 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
* `getTypes`
|
|
|
|
* `getErrorBubbling`
|
|
|
|
* `getNormTransformers`
|
|
|
|
* `getClientTransformers`
|
|
|
|
* `getAttribute`
|
|
|
|
* `hasAttribute`
|
|
|
|
* `getClientData`
|
|
|
|
* `getChildren`
|
|
|
|
* `hasChildren`
|
2012-05-24 13:24:28 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
Before:
|
2012-05-25 07:32:54 +01:00
|
|
|
|
2012-05-25 08:13:02 +01:00
|
|
|
```
|
|
|
|
$form->getErrorBubbling()
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
$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`.
|
2012-05-24 13:24:28 +01:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
if ($form->hasChildren()) {
|
2012-05-24 13:24:28 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
2012-05-25 08:13:02 +01:00
|
|
|
if (count($form) > 0) {
|
|
|
|
```
|
|
|
|
|
|
|
|
* 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:
|
|
|
|
|
|
|
|
```
|
|
|
|
$builder->add('name', 'text', array(
|
|
|
|
'validation_constraint' => new NotBlank(),
|
|
|
|
));
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
$builder->add('name', 'text', array(
|
|
|
|
'constraints' => new NotBlank(),
|
|
|
|
));
|
|
|
|
```
|
|
|
|
|
|
|
|
Unlike previously, you can also pass a list of constraints now:
|
|
|
|
|
|
|
|
```
|
|
|
|
$builder->add('name', 'text', array(
|
|
|
|
'constraints' => array(
|
|
|
|
new NotBlank(),
|
|
|
|
new MinLength(3),
|
|
|
|
),
|
|
|
|
));
|
2012-05-24 13:24:28 +01:00
|
|
|
```
|
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
### Validator
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
* The methods `setMessage()`, `getMessageTemplate()` and
|
2012-04-17 16:19:12 +01:00
|
|
|
`getMessageParameters()` in the Constraint class were deprecated and will
|
|
|
|
be removed in Symfony 2.3.
|
2012-02-01 12:53:45 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
If you have implemented custom validators, you should use the
|
|
|
|
`addViolation()` method on the `ExecutionContext` object instead.
|
2012-02-01 12:53:45 +00:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
public function isValid($value, Constraint $constraint)
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
if (!$valid) {
|
|
|
|
$this->setMessage($constraint->message, array(
|
|
|
|
'{{ value }}' => $value,
|
|
|
|
));
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
return false;
|
2012-02-01 12:53:45 +00:00
|
|
|
}
|
2012-02-14 03:11:40 +00:00
|
|
|
}
|
|
|
|
```
|
2012-02-01 12:53:45 +00:00
|
|
|
|
|
|
|
After:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
public function isValid($value, Constraint $constraint)
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
if (!$valid) {
|
|
|
|
$this->context->addViolation($constraint->message, array(
|
|
|
|
'{{ value }}' => $value,
|
|
|
|
));
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
return false;
|
2012-02-02 09:16:32 +00:00
|
|
|
}
|
2012-02-14 03:11:40 +00:00
|
|
|
}
|
|
|
|
```
|
2012-04-11 11:44:45 +01:00
|
|
|
|
|
|
|
* The method `setPropertyPath()` in the ExecutionContext class
|
|
|
|
was removed.
|
|
|
|
|
|
|
|
You should use the `addViolationAtSubPath()` method on the
|
|
|
|
`ExecutionContext` object instead.
|
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
|
|
|
public function isPropertyValid(ExecutionContext $context)
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
$propertyPath = $context->getPropertyPath() . '.property';
|
|
|
|
$context->setPropertyPath($propertyPath);
|
|
|
|
$context->addViolation('Error Message', array(), null);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
public function isPropertyValid(ExecutionContext $context)
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
$context->addViolationAtSubPath('property', 'Error Message', array(), null);
|
|
|
|
|
|
|
|
}
|
|
|
|
```
|
2012-02-07 09:51:21 +00:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
* The method `isValid` of `ConstraintValidatorInterface` was renamed to
|
|
|
|
`validate` and its return value was dropped.
|
2012-02-11 11:44:56 +00:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
`ConstraintValidator` still contains the deprecated `isValid` method and
|
2012-04-20 17:42:21 +01:00
|
|
|
forwards `validate` calls to `isValid` by default. This BC layer will be
|
2012-04-17 16:19:12 +01:00
|
|
|
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:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-04-17 16:19:12 +01:00
|
|
|
public function isValid($value, Constraint $constraint)
|
2012-02-14 03:11:40 +00:00
|
|
|
{
|
2012-04-17 16:19:12 +01:00
|
|
|
// ...
|
|
|
|
if (!$valid) {
|
|
|
|
$this->context->addViolation($constraint->message, array(
|
|
|
|
'{{ value }}' => $value,
|
|
|
|
));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2012-02-14 03:11:40 +00:00
|
|
|
}
|
|
|
|
```
|
2012-02-11 11:44:56 +00:00
|
|
|
|
|
|
|
After:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-04-17 16:19:12 +01:00
|
|
|
public function validate($value, Constraint $constraint)
|
2012-02-14 03:11:40 +00:00
|
|
|
{
|
2012-04-17 16:19:12 +01:00
|
|
|
// ...
|
|
|
|
if (!$valid) {
|
|
|
|
$this->context->addViolation($constraint->message, array(
|
|
|
|
'{{ value }}' => $value,
|
|
|
|
));
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
return;
|
2012-04-05 09:16:23 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
2012-04-13 15:42:01 +01:00
|
|
|
|
2012-04-13 15:02:15 +01:00
|
|
|
* Core translation messages are changed. Dot is added at the end of each message.
|
2012-04-18 10:57:20 +01:00
|
|
|
Overwritten core translations should be fixed if any. More info here.
|
2012-04-13 15:02:15 +01:00
|
|
|
|
2012-05-18 11:22:33 +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:
|
|
|
|
|
|
|
|
```
|
|
|
|
/** @Assert\Valid */
|
|
|
|
private $recursiveCollection;
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
/** @Assert\Valid(deep = true) */
|
|
|
|
private $recursiveCollection;
|
|
|
|
```
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
### Session
|
2011-12-24 10:36:18 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
* Flash messages now return an array based on their type. The old method is
|
|
|
|
still available but is now deprecated.
|
2011-12-24 10:36:18 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
##### Retrieving the flash messages from a Twig template
|
2011-12-24 10:36:18 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
Before:
|
2011-12-24 10:36:18 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-03-23 17:01:12 +00:00
|
|
|
{% if app.session.hasFlash('notice') %}
|
2012-02-14 03:11:40 +00:00
|
|
|
<div class="flash-notice">
|
2012-03-23 17:01:12 +00:00
|
|
|
{{ app.session.getFlash('notice') }}
|
2012-02-14 03:11:40 +00:00
|
|
|
</div>
|
|
|
|
{% endif %}
|
|
|
|
```
|
|
|
|
After:
|
2011-12-24 10:36:18 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
2012-02-11 06:41:34 +00:00
|
|
|
{% for flashMessage in app.session.flashbag.get('notice') %}
|
2012-02-14 03:11:40 +00:00
|
|
|
<div class="flash-notice">
|
2012-02-11 06:41:34 +00:00
|
|
|
{{ flashMessage }}
|
2012-02-14 03:11:40 +00:00
|
|
|
</div>
|
2012-02-11 06:41:34 +00:00
|
|
|
{% endfor %}
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
|
2012-03-23 17:01:12 +00:00
|
|
|
You can process all flash messages in a single loop with:
|
2012-02-14 03:11:40 +00:00
|
|
|
|
|
|
|
```
|
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-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
|
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`.
|
2011-12-24 10:36:18 +00:00
|
|
|
|
2012-03-06 19:41:09 +00:00
|
|
|
* Refactor code using `$session->*flash*()` methods to use `$session->getFlashBag()->*()`.
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-04-11 15:01:47 +01:00
|
|
|
### Serializer
|
|
|
|
|
2012-05-06 11:34:55 +01:00
|
|
|
* The key names created by the `GetSetMethodNormalizer` have changed from
|
2012-04-11 15:01:47 +01:00
|
|
|
from all lowercased to camelCased (e.g. `mypropertyvalue` to `myPropertyValue`).
|
|
|
|
|
|
|
|
* The `item` element is now converted to an array when deserializing XML.
|
|
|
|
|
|
|
|
``` 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
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2012-04-11 17:24:00 +01:00
|
|
|
### 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.
|
|
|
|
|
2012-06-09 11:40:37 +01:00
|
|
|
### BrowserKit
|
|
|
|
|
|
|
|
#### BC Breaks
|
|
|
|
|
|
|
|
* The Symfony\Component\HttpKernel\Client::request() method
|
|
|
|
now returns a Symfony\Component\BrowserKit\Response instance
|
|
|
|
(instead of a Symfony\Component\HttpFoundation\Response instance)
|
|
|
|
|
2012-02-29 08:44:47 +00:00
|
|
|
### 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:
|
|
|
|
|
|
|
|
```
|
|
|
|
framework:
|
|
|
|
session:
|
|
|
|
lifetime: 3600
|
|
|
|
path: \
|
|
|
|
domain: example.com
|
|
|
|
secure: true
|
|
|
|
httponly: true
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
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`.
|
|
|
|
|
|
|
|
```
|
|
|
|
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.
|
|
|
|
|
|
|
|
```
|
|
|
|
framework:
|
|
|
|
session:
|
|
|
|
storage_id: session.storage.mock_file
|
|
|
|
```
|
2012-04-13 15:42:01 +01:00
|
|
|
|
2012-04-11 15:01:47 +01:00
|
|
|
### 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.
|