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-02-14 03:11:40 +00: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
|
|
|
|
associated objects.
|
2012-01-17 09:53:31 +00:00
|
|
|
|
2012-02-11 11:44:56 +00: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
|
2012-02-14 03:11:40 +00:00
|
|
|
enable BC behavior by setting the `cascade_validation` form option to `true`
|
|
|
|
on the parent form.
|
2012-01-16 23:46:26 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
* Changed implementation of choice lists
|
2012-01-30 09:57:14 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
ArrayChoiceList was replaced. If you have custom classes that extend this
|
|
|
|
class, you must now extend SimpleChoiceList.
|
2012-01-30 10:10:25 +00:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
class MyChoiceList extends ArrayChoiceList
|
|
|
|
{
|
|
|
|
protected function load()
|
2012-01-30 10:10:25 +00:00
|
|
|
{
|
2012-02-14 03:11:40 +00:00
|
|
|
parent::load();
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
// load choices
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
$this->choices = $choices;
|
2012-01-30 10:10:25 +00:00
|
|
|
}
|
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
|
|
|
```
|
|
|
|
class MyChoiceList extends SimpleChoiceList
|
|
|
|
{
|
|
|
|
public function __construct()
|
2012-01-30 10:10:25 +00:00
|
|
|
{
|
2012-02-14 03:11:40 +00:00
|
|
|
// load choices
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
parent::__construct($choices);
|
2012-01-30 10:10:25 +00:00
|
|
|
}
|
2012-02-14 03:11:40 +00:00
|
|
|
}
|
|
|
|
```
|
2012-01-30 10:10:25 +00:00
|
|
|
|
2012-02-14 03:11:40 +00: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.
|
2012-01-30 10:10:25 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
class MyChoiceList extends LazyChoiceList
|
|
|
|
{
|
|
|
|
protected function loadChoiceList()
|
2012-01-30 10:10:25 +00:00
|
|
|
{
|
2012-02-14 03:11:40 +00:00
|
|
|
// load choices
|
2012-02-29 08:44:47 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
return new SimpleChoiceList($choices);
|
2012-01-30 10:10:25 +00:00
|
|
|
}
|
2012-02-14 03:11:40 +00:00
|
|
|
}
|
|
|
|
```
|
2012-01-30 09:57:14 +00:00
|
|
|
|
|
|
|
PaddedChoiceList, MonthChoiceList and TimezoneChoiceList were removed.
|
2012-02-14 03:11:40 +00:00
|
|
|
Their functionality was merged into DateType, TimeType and TimezoneType.
|
2012-01-30 09:57:14 +00:00
|
|
|
|
2012-02-14 03:11:40 +00: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
|
2012-01-30 09:57:14 +00:00
|
|
|
replacement exists.
|
|
|
|
|
2012-04-10 14:32:55 +01:00
|
|
|
* The strategy for generating the `id` and `name` HTML attributes for
|
|
|
|
checkboxes and radio buttons in a choice field has changed.
|
2012-02-02 11:36:28 +00:00
|
|
|
|
2012-01-23 17:58:56 +00:00
|
|
|
Instead of appending the choice value, a generated integer is now appended
|
2012-04-10 14:32:55 +01:00
|
|
|
by default. Take care if your JavaScript relies on that.
|
2012-02-14 03:11:40 +00:00
|
|
|
|
|
|
|
* In the choice field type's template, the structure of the `choices` variable
|
|
|
|
has changed.
|
2012-01-24 00:23:01 +00:00
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
The `choices` variable now contains ChoiceView objects with two getters,
|
2012-05-08 13:56:34 +01:00
|
|
|
`getValue()` and `getLabel()`, to access the choice data.
|
2012-01-24 00:23:01 +00:00
|
|
|
|
|
|
|
Before:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
{% for choice, label in choices %}
|
|
|
|
<option value="{{ choice }}"{% if _form_is_choice_selected(form, choice) %} selected="selected"{% endif %}>
|
|
|
|
{{ label }}
|
|
|
|
</option>
|
|
|
|
{% endfor %}
|
|
|
|
```
|
2012-01-24 00:23:01 +00:00
|
|
|
|
|
|
|
After:
|
|
|
|
|
2012-02-14 03:11:40 +00:00
|
|
|
```
|
|
|
|
{% for choice in choices %}
|
|
|
|
<option value="{{ choice.value }}"{% if _form_is_choice_selected(form, choice) %} selected="selected"{% endif %}>
|
|
|
|
{{ choice.label }}
|
|
|
|
</option>
|
|
|
|
{% endfor %}
|
|
|
|
```
|
2012-01-28 12:37:13 +00:00
|
|
|
|
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
|
|
|
|
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-04-11 17:24:00 +01:00
|
|
|
* The `read_only` field attribute now renders as `readonly="readonly"`, use
|
|
|
|
`disabled` instead for `disabled="disabled"`.
|
|
|
|
|
|
|
|
* Form and field names must now start with a letter, digit or underscore
|
|
|
|
and only contain letters, digits, underscores, hyphens and colons
|
|
|
|
|
|
|
|
* `EntitiesToArrayTransformer` and `EntityToIdTransformer` have been removed.
|
|
|
|
The former has been replaced by `CollectionToArrayTransformer` in combination
|
|
|
|
with `EntityChoiceList`, the latter is not required in the core anymore.
|
|
|
|
|
|
|
|
* The following transformers have been renamed:
|
|
|
|
|
|
|
|
* `ArrayToBooleanChoicesTransformer` to `ChoicesToBooleanArrayTransformer`
|
|
|
|
* `ScalarToBooleanChoicesTransformer` to `ChoiceToBooleanArrayTransformer`
|
|
|
|
* `ArrayToChoicesTransformer` to `ChoicesToValuesTransformer`
|
|
|
|
* `ScalarToChoiceTransformer` to `ChoiceToValueTransformer`
|
|
|
|
|
|
|
|
to be consistent with the naming in `ChoiceListInterface`.
|
|
|
|
|
|
|
|
* `FormUtil::toArrayKey()` and `FormUtil::toArrayKeys()` have been removed.
|
|
|
|
They were merged into ChoiceList and have no public equivalent anymore.
|
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
* The options passed to the `getParent()` method of form types no longer
|
|
|
|
contain default options. They only contain the options passed by the user.
|
|
|
|
|
|
|
|
You should check if options exist before attempting to read their value.
|
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```
|
|
|
|
public function getParent(array $options)
|
|
|
|
{
|
|
|
|
return 'single_text' === $options['widget'] ? 'text' : 'choice';
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```
|
|
|
|
public function getParent(array $options)
|
|
|
|
{
|
|
|
|
return isset($options['widget']) && 'single_text' === $options['widget'] ? 'text' : 'choice';
|
|
|
|
}
|
|
|
|
```
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
* The methods `getDefaultOptions()` and `getAllowedOptionValues()` of form
|
|
|
|
types no longer receive an option array.
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
You can specify options that depend on other options using closures instead.
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
Before:
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
```
|
|
|
|
public function getDefaultOptions(array $options)
|
|
|
|
{
|
|
|
|
$defaultOptions = array();
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
if ($options['multiple']) {
|
|
|
|
$defaultOptions['empty_data'] = array();
|
|
|
|
}
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
return $defaultOptions;
|
|
|
|
}
|
|
|
|
```
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
After:
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
```
|
|
|
|
public function getDefaultOptions()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
'empty_data' => function (Options $options, $previousValue) {
|
|
|
|
return $options['multiple'] ? array() : $previousValue;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
```
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-17 16:19:12 +01:00
|
|
|
The second argument `$previousValue` does not have to be specified if not
|
|
|
|
needed.
|
|
|
|
|
|
|
|
* The `add()`, `remove()`, `setParent()`, `bind()` and `setData()` methods in
|
|
|
|
the Form class now throw an exception if the form is already bound.
|
|
|
|
|
|
|
|
If you used these methods on bound forms, you should consider moving your
|
|
|
|
logic to an event listener that observes one of the following events:
|
|
|
|
`FormEvents::PRE_BIND`, `FormEvents::BIND_CLIENT_DATA` or
|
|
|
|
`FormEvents::BIND_NORM_DATA`.
|
|
|
|
|
|
|
|
* 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`.
|
|
|
|
|
2012-04-20 17:42:21 +01:00
|
|
|
* Since FormType and FieldType were merged, you need to adapt your form
|
|
|
|
themes.
|
|
|
|
|
|
|
|
The "field_widget" and all references to it should be renamed to
|
2012-04-27 09:16:56 +01:00
|
|
|
"form_widget_single_control":
|
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-04-27 09:16:56 +01:00
|
|
|
{{ block('form_widget_single_control') }}
|
2012-04-20 17:42:21 +01:00
|
|
|
{% endspaceless %}
|
|
|
|
{% endblock url_widget %}
|
|
|
|
```
|
|
|
|
|
|
|
|
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
|
2012-04-27 09:16:56 +01:00
|
|
|
Boolean variable "single_control":
|
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-04-27 09:16:56 +01:00
|
|
|
{% if single_control %}
|
2012-04-20 17:42:21 +01:00
|
|
|
... field code ...
|
|
|
|
{% else %}
|
|
|
|
... form code ...
|
|
|
|
{% endif %}
|
|
|
|
{% endspaceless %}
|
|
|
|
{% endblock form_errors %}
|
|
|
|
```
|
|
|
|
|
|
|
|
Furthermore, the block "generic_label" was merged into "form_label". You
|
|
|
|
should now override "form_label" in order to customize labels.
|
|
|
|
|
|
|
|
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-04-23 14:55:54 +01:00
|
|
|
* 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".
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-23 14:55:54 +01:00
|
|
|
Before:
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-23 14:55:54 +01:00
|
|
|
public function guessMinLength($class, $property)
|
|
|
|
{
|
|
|
|
if (/* condition */) {
|
|
|
|
return new ValueGuess($minLength, Guess::LOW_CONFIDENCE);
|
|
|
|
}
|
|
|
|
}
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-23 14:55:54 +01:00
|
|
|
After:
|
2012-04-20 17:42:21 +01:00
|
|
|
|
2012-04-23 14:55:54 +01:00
|
|
|
public function guessPattern($class, $property)
|
|
|
|
{
|
|
|
|
if (/* condition */) {
|
|
|
|
return new ValueGuess('.{' . $minLength . ',}', Guess::LOW_CONFIDENCE);
|
|
|
|
}
|
|
|
|
}
|
2012-04-13 15:06:32 +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-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-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.
|