This PR was squashed before being merged into the 2.7 branch (closes#22627).
Discussion
----------
[Intl] Update ICU data to 59.1
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
The [GMT timezone has been split from the UTC](http://site.icu-project.org/download/59) timezone [in CLDR](http://cldr.unicode.org/index/downloads/cldr-31) (which ICU is based on).
For example, the code blow:
* before ICU 59.1 would return "GMT" in all cases
* with ICU 59.1 it returns "UTC" for the first three ('z', 'zz', 'zzz')
and "Coordinated Universal Time" for the last two ('zzzz', 'zzzzz').
```php
foreach (['z', 'zz', 'zzz', 'zzzz', 'zzzzz'] as $pattern) {
$formatter = new \IntlDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT, new \DateTimeZone('UTC'), IntlDateFormatter::GREGORIAN, $pattern);
var_dump($formatter->format(new \DateTime('@0')));
}
```
Similarly Form's `DateTimeToLocalizedStringTransformer` is also affected:
```php
$transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, \IntlDateFormatter::FULL);
var_dump($transformer->transform(new \DateTime('2010-02-03 04:05:06 UTC')));
// ICU 58.2: '03.02.2010, 04:05:06 GMT'
// ICU 59.1: '03.02.2010, 04:05:06 Koordinierte Weltzeit'
```
Refer to added and modified test cases for more changes. I split this PR in two commits for easier review. First commit updates ICU data (generated files), the second updates code and test cases to be compatible with updated data.
Commits
-------
5d3d1b25e0 [Intl][Form] Update tests, TimeZoneTransformer, and DateTimeToLocalizedStringTransformer for the GMT and UTC split in ICU
00acb37205 [Intl] Update ICU data to 59.1
The [GMT timezone has been split from the UTC](http://site.icu-project.org/download/59) timezone [in CLDR](http://cldr.unicode.org/index/downloads/cldr-31) (which ICU is based on).
For example, the code blow:
* before ICU 59.1 would return "GMT" in all cases
* with ICU 59.1 it returns "UTC" for the first three ('z', 'zz', 'zzz')
and "Coordinated Universal Time" for the last two ('zzzz', 'zzzzz').
```php
foreach (['z', 'zz', 'zzz', 'zzzz', 'zzzzz'] as $pattern) {
$formatter = new \IntlDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT, new \DateTimeZone('UTC'), IntlDateFormatter::GREGORIAN, $pattern);
var_dump($formatter->format(new \DateTime('@0')));
}
```
Similarly Form's `DateTimeToLocalizedStringTransformer` is also affected:
```php
$transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, \IntlDateFormatter::FULL);
var_dump($transformer->transform(new \DateTime('2010-02-03 04:05:06 UTC')));
// ICU 58.2: '03.02.2010, 04:05:06 GMT'
// ICU 59.1: '03.02.2010, 04:05:06 Koordinierte Weltzeit'
```
Refer to added and modified test cases for more changes. I split this PR in two commits for easier review. First commit updates ICU data (generated files), the second updates code and test cases to be compatible with updated data.
This PR was merged into the 2.7 branch.
Discussion
----------
fix some more risky tests
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR |
Continuation of #22066 fixing the tests for the following components:
* Config
* Form
* HttpFoundation
* Security
Commits
-------
fffcd247b2 fix some risky tests
This PR was squashed before being merged into the 2.7 branch (closes#22232).
Discussion
----------
CS: Remove invisible chars
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | n/a
| Fixed tickets | n/a
| License | MIT
| Doc PR | n/a
I found out that we have 2 non-visible in regular IDE chars in codebase.
One is just inside a comment, it could be safely removed.
But second is inside a real code, I have replaced it with `pack`, so one won't accidentally replace non-breaking space with regular space.
Commits
-------
0f623f4 CS: Remove invisible chars
This PR was merged into the 2.7 branch.
Discussion
----------
[Form] Improve the exceptions when trying to get the data in a PRE_SET_DATA listener and the data has not already been set
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #22103
| License | MIT
| Doc PR | -
Commits
-------
ef39b704cc [Form] Improve the exceptions when trying to get the data in a PRE_SET_DATA listener and the data has not already been set
This PR was merged into the 2.7 branch.
Discussion
----------
[Form] Fixed typo in a test after #21877
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | ~
| License | MIT
| Doc PR | ~
Reviewing the diff on GitHub, I realized I've missed some typos in a new test of #21877. Sorry!
Commits
-------
b21a0978de [Form] Fixed typo in a test after #21877
This PR was squashed before being merged into the 2.7 branch (closes#21267).
Discussion
----------
[Form] Fix ChoiceType to ensure submitted data is not nested unnecessarily
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
Fixed ChoiceType to protect against some problem caused by treating of array.
Let's say we have the choice-form like:
```php
$form = $factory->create(ChoiceType, null, [
'choices' => [
'A',
'B',
'C',
],
'expanded' => true,
'multiple' => true,
]);
```
Then, submit data like this:
```php
$form->submit([
[], // unnecessality nested
]);
```
(Yes, I agree in most cases these situation doesn't happen, but can be)
Then, we get `array_flip(): Can only flip STRING and INTEGER values!` error at [here](6babdb3296/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php (L114)).
Even if form is not `multiple`, annoying `Array to string conversion` error occurs in [here](6babdb3296/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php (L144)) (via [ChoicesToValuesTransformer](5129c4cf7e/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToValuesTransformer.php (L74))).
(As far as I know, non-multiple and non-expanded form has no problem, thanks to [ChoiceToValueTransformer](6babdb3296/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php (L43)))
To resolve these problems, I just added a simple-validation listener to choice type.
Commits
-------
64d7a82d28 [Form] Fix ChoiceType to ensure submitted data is not nested unnecessarily
This PR was merged into the 2.7 branch.
Discussion
----------
[Form] Fixed DateType format option for single text widget
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | ~
| License | MIT
| Doc PR | ~
It's currently not possible to use a custom format with `DateType` when not using one of the three values day, month or year (i.e in my case "MM/yyyy").
The formatter handles it, it looks like this option check is wrong, this PR fixes it.
Commits
-------
9e0d531d36 [Form] Fixed DateType format option
By default, the `DateType` as well as the `DateTimeType` set the choices
being available for the year to a range starting five years in the past.
After some time, this will make tests fail when the year of the fixed
date being used as the initial data is before the first year being part
of the choices.
This PR was merged into the 2.7 branch.
Discussion
----------
Fix @return statements to use $this or static when relevant
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #20290
| License | MIT
| Doc PR | n/a
see #20290
Commits
-------
3c0693d fixed @return when returning this or static
This PR was merged into the 2.7 branch.
Discussion
----------
Avoid warning in PHP 7.2 because of non-countable data
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
Recently, the "[Counting of non-countable objects][1]" RFC was merged in PHP 7.2-dev. This means `count()` now causes a warning when passing anything that's not countable (e.g. `null` or `''`).
As PHP does not lazily execute conditions, `FormUtil::isEmtpy($data) || 0 === count($data)` will cause *both* conditions to be executed. This means `count($data)` errors when `$data` is empty.
Splitting it up in 2 statements avoids the warning being triggered in PHP 7.2.
See https://travis-ci.org/symfony-cmf/content-bundle/jobs/181815895 for a failing test caused by this bug.
[1]: https://wiki.php.net/rfc/counting_non_countables
Commits
-------
94253e8 Only count on arrays or countables to avoid warnings in PHP 7.2
This PR was merged into the 2.7 branch.
Discussion
----------
[Form] fix group sequence based validation
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #20929
| License | MIT
| Doc PR |
Commits
-------
fb91f74 [Form] fix group sequence based validation
This PR was squashed before being merged into the 2.7 branch (closes#20418).
Discussion
----------
[Form][DX] FileType "multiple" fixes
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | https://github.com/symfony/symfony/issues/12547
| License | MIT
| Doc PR | -
# (1st) Derive "data_class" option from passed "multiple" option
Information
-------------
Following this tutorial ["How to Upload Files"][1] but storing many `brochures` instead of one, i.e.:
```php
// src/AppBundle/Entity/Product.php
class Product
{
/**
* @var string[]
*
* @ORM\Column(type="array")
*/
private $brochures;
//...
}
```
```php
//src/AppBundle/Form/ProductType.php
$builder->add('brochures', FileType::class, array(
'label' => 'Brochures (PDF files)',
'multiple' => true,
));
```
The Problem
--------------
I found a pain point here when the form is loaded again after save some brochures (Exception):
> The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) array. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) array to an instance of Symfony\Component\HttpFoundation\File\File.
The message is very clear, but counter-intuitive in this case, because the form field (`FileType`) was configured with `multiple = true`, so IMHO it shouldn't expect a `File` instance but an array of them at all events.
The PR's effect
---------------
**Before:**
```php
$form = $this->createFormBuilder($product)
->add('brochures', FileType::class, [
'multiple' => true,
'data_class' => null, // <---- mandatory
])
->getForm();
```
**After:**
```php
$form = $this->createFormBuilder($product)
->add('brochures', FileType::class, [
'multiple' => true,
])
->getForm();
```
# (2nd) Return empty `array()` at submit no file
Information
-------------
Based on the same information before, but adding some constraints:
```php
// src/AppBundle/Entity/Product.php
use Symfony\Component\Validator\Constraints as Assert;
class Product
{
/**
* @var string[]
*
* @ORM\Column(type="array")
*
* @Assert\Count(min="1") // or @Assert\NotBlank()
* @Assert\All({
* @Assert\File(mimeTypes = {"application/pdf", "application/x-pdf"})
* })
*
*/
private $brochures;
}
```
This should require at least one file to be stored.
The Problem
--------------
But, when no file is uploaded at submit the form, it's valid completely. The submitted data for this field was `array(null)` so the constraints pass without any problem:
* `@Assert\Count(min="1")` pass! because contains at least one element (No matter what)
* `@Assert\NotBlank()` it could pass! because no `false` and no `empty()`
* `@Assert\File()` pass! because the element is `null`
Apart from that really we expecting an empty array instead.
The PR's effect
----------------
**Before:**
```php
// src/AppBundle/Entity/Product.php
use Symfony\Component\Validator\Constraints as Assert;
class Product
{
/**
* @var string[]
*
* @ORM\Column(type="array")
*
* @Assert\All({
* @Assert\NotBlank,
* @Assert\File(mimeTypes = {"application/pdf", "application/x-pdf"})
* })
*
*/
private $brochures;
}
```
**After:**
```php
// src/AppBundle/Entity/Product.php
use Symfony\Component\Validator\Constraints as Assert;
class Product
{
/**
* @var string[]
*
* @ORM\Column(type="array")
*
* @Assert\Count(min="1") // or @Assert\NotBlank
* @Assert\All({
* @Assert\File(mimeTypes = {"application/pdf", "application/x-pdf"})
* })
*
*/
private $brochures;
}
```
[1]: http://symfony.com/doc/current/controller/upload_file.html
Commits
-------
36b7ba6 [Form][DX] FileType "multiple" fixes
This PR was merged into the 2.7 branch.
Discussion
----------
[Form] fixed "empty_value" option deprecation
| Q | A
| ------------- | ---
| Branch? | 2.x only
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | https://github.com/symfony/symfony/pull/15945#r86547326
| License | MIT
| Doc PR | ~
I didn't make any profiling but a resolver instance is passed to `configureOptions()` creating locale variables including those exceptions for each field using one of the patched form types, so I guess the memory usage can grow really fast.
Commits
-------
7e84907 [Form] fixed "empty_value" option deprecation
This PR was squashed before being merged into the 2.7 branch (closes#20307).
Discussion
----------
[Form] Fix Date\TimeType marked as invalid on request with single_text and zero seconds
| Q | A |
| --- | --- |
| Branch? | 2.7 |
| Bug fix? | yes |
| New feature? | no |
| BC breaks? | no |
| Deprecations? | no |
| Tests pass? | yes |
| Fixed tickets | 20304 |
| License | MIT |
| Doc PR | |
Fix: When using a form with an Time type with option 'widget' => 'single_text', and 0 is selected in the seconds, we obtain an TransformationFailedException "Unable to reverse value for property path "[time]": Data missing". Check ticket #20304
Commits
-------
bcb03e0 [Form] Fix Date\TimeType marked as invalid on request with single_text and zero seconds
This PR was merged into the 2.7 branch.
Discussion
----------
[Form] Fixed show float values as choice value in ChoiceType
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #13817
| License | MIT
| Doc PR | -
There is a closed [issue][1] related to this before Symfony 2.7 (when choice value still was the key from the `array`). This issue already happened in 2.7+ but now inside Symfony core.
Information
-----------
[This method][3] checks whether the given choices can be cast to strings without generating duplicates (3ab8189080 in #16705):
```php
private function castableToString(array $choices, array &$cache = array())
{
foreach ($choices as $choice) {
if (is_array($choice)) {
if (!$this->castableToString($choice, $cache)) {
return false;
}
continue;
} elseif (!is_scalar($choice)) {
return false;
} elseif (isset($cache[$choice])) { // <---- red breakpoint
return false;
}
$cache[$choice] = true; // <---- red breakpoint
}
return true;
}
```
So it should to keep [scalar values (integer, float, string or boolean)][2] as choice values always (unless have duplicates values).
The Problem
-----------
But in this situation it doesn't happen:
```php
$form = $this->createFormBuilder()
->add('foo', ChoiceType::class, [
'choices' => [
'Min' => 0.5,
'Mid' => 1.0,
'Max' => 1.5,
]
])
->getForm();
```
**Output:**
```html
<select id="form_foo" name="form[foo]">
<option value="0">Min</option>
<option value="1">Mid</option>
<option value="2">Max</option>
</select>
```
[**Why?**][5]
If the key of the array is a float number, it's interpreted as integer automatically:
```php
// ...
$cache[$choice] = true;
// when $choice = 0.5: $cache = [0 => true]
// when $choice = 1.0: $cache = [0 => true, 1 => true]
```
Then, when `$choice = 1.5` [this sentence][4] `isset($cache[1.5])` returns `true` because really checks `isset($cache[1])` and this key already exists, so `castableToString()` returns `false` (detected as duplicate) and the choices values are generated incrementing integers as values.
The PR's Effect
-------------
**Before:**
```html
<select id="form_foo" name="form[foo]">
<option value="0">Min</option>
<option value="1">Mid</option>
<option value="2">Max</option>
</select>
```
**After:**
```html
<select id="form_foo" name="form[foo]">
<option value="0.5">Min</option>
<option value="1">Mid</option>
<option value="1.5">Max</option>
</select>
```
[1]: https://github.com/symfony/symfony/issues/13817
[2]: http://php.net/manual/en/function.is-scalar.php
[3]: https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php#L228
[4]: https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php#L239
[5]: https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php#L243
Commits
-------
3564228 [Form] Fix show float values as choices values in ChoiceType
This PR was squashed before being merged into the 2.7 branch (closes#19373).
Discussion
----------
[Form] Skip CSRF validation on form when POST max size is exceeded
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #19140
| License | MIT
| Doc PR | N/A
In #19140 the CSRF validation listener was not aware that the POST max size had exceeded, and was adding a form error message that wasn't relevant to the actual error.
This introduces the `ServerParams` utility class into the `CsrfValidationListener` and checks that the POST max size has not been exceeded. If it has then it won't bother trying to validate the CSRF token.
My main concern with this change is that it opens up an attack vector around tokens, but I've encapsulated the request size validation in a single method in `ServerParams` now so that the request handlers are using the same logic.
Commits
-------
289531f [Form] Skip CSRF validation on form when POST max size is exceeded
This PR was merged into the 2.7 branch.
Discussion
----------
removed dots at the end of @param and @return
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | n/a
| License | MIT
| Doc PR | n/a
For phpdocs, we only add dots for sentences like description, but not for @param and @return for instance. This PR fixes this issue.
This should probably be added to PHP-CS-Fixer as well (/cc @phansys @keradus).
Commits
-------
554303e removed dots at the end of @param and @return
This PR was merged into the 2.7 branch.
Discussion
----------
[Form] Consider a violation even if the form is not submitted
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | yes (only for the behavior)
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #11493
| License | MIT
| Doc PR |
Hey!
I'm currently implementing an API using the form component in order to validate the payload sent (in conjonction with the FOSRestBundle). Unfortunatelly, we dig into an issue about the PATCH request which don't map some of our validation rules to the form. Basically, the violations are lost in the middle of the process.
### Use case
We have an entity with the following fields "type", "image" & "video". The field "type"can be either "default", "image" or "video" and then accordingly we use the appropriate field (none for the "default" type, video for the "video" type and image for the "image" type. Then, in our form, we change the validation groups according to our entity type in order to make the "image" field mandatory if the type is "image" and the same for the video field if the type is "video".
### Current behavior
The current behavior (since 2.5) seems to not propages a violation to a form if this form is not submitted but in our use case, changing the field "type" via a PATCH request triggers some new validation which should be reported to end user (inform that a field (video or image) is missing in the PATCH request).
### Expected behavior
The current behavior was introduced in #10567 but IMO, this update is a bug as suggested by @webmozart in https://github.com/symfony/symfony/issues/11493#issuecomment-59549054 Instead, the form component should still map validation errors to the form even if the field was not submitted. If the initial data is not valid, then your initial data was buggy from the beginning but the form should not accept it and instead of silently ignoring the errors, end users should be informed and fix it.
WDYT?
Commits
-------
c483a0f [Form] Consider a violation even if the form is not submitted
This PR was merged into the 2.7 branch.
Discussion
----------
FormBuilderInterface: fix getForm() return type.
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
FormBuilderInterface->getForm() should depend on abstractions and
not implementations as a return type.
Commits
-------
3fa081c FormBuilderInterface: fix getForm() return type.
This PR was merged into the 2.7 branch.
Discussion
----------
add docblock type elements to support newly added IteratorAggregate::getIterator PhpStorm support
| Q | A
| ------------- | ---
| Branch | 2.7
| Bug fix | no
| New feature | no
| BC breaks | no
| Deprecations | no
| Tests pass | yes
| License | MIT
In additional to #16965 PhpStorm supports `IteratorAggregate::getIterator` now. see https://blog.jetbrains.com/phpstorm/2016/06/phpstorm-2016-2-eap-162-844/
example
```
$collection = new \Symfony\Component\Routing\RouteCollection();
foreach ($collection as $route) {
$route->getHost();
}
```
Commits
-------
ede3556 add docblock type elements to support newly added IteratorAggregate::getIterator PhpStorm support