Improved PropertyAccess Error Messages
Great error messages are essential to avoid frustration when using any piece of software. In Symfony 4.4 we improved the error messages generated by PropertyAccess when trying to find a writable property.
For example, when you already defined the adder/remover methods but their
signature was wrong (e.g. addFoo()
/removeFoo()
), this was the error displayed:
1 2
Neither the property "foo" nor one of the methods "addFoo()/removeFoo()",
"setFoo()", "foo()", "__set()" or "__call()" exist and have public access.
The error message is now much more clear:
1
The method "removeFoo()" requires at least "1" parameter, "0" found.
This is just one example, but we improved lots of other error messages in this component.
Support *:only-of-type
CSS selectors
The CssSelector component, which is used indirectly in functional tests to
select items based on CSS selectors, supported the :only-of-type
pseudo-class
when specifying an HTML element (e.g. p:only-of-type
selects a child only if
it's the only paragraph inside an element).
In Symfony 4.4 we also added support for *:only-of-type
(or just :only-of-type
)
which selects single child elements. If an element has 2 <p>
and 1 <a>
as children, only the <a>
is selected, but if it has 1 <p>
and 1 <a>
,
both are selected because they are the only ones of their types.
Use properties as Range values
The Range constraint validates that a given number or DateTime
object is
between some minimum and maximum. In Symfony 4.4, thanks to the new maxPropertyPath
and minPropertyPath
options, you can use the values stored in some properties
as the values of those minimum/maximum:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Entity/Event.php
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Event
{
/**
* @Assert\Range(
* minPropertyPath = "startsAt",
* maxPropertyPath = "endsAt"
* )
*/
private $registrationDate;
private $startsAt;
private $endsAt;
// ...
}
Allow to sort translation messages
The translation:update command helps you extract the translatable contents
from Twig templates and PHP controllers. In Symfony 4.4, we added a new --sort
option to sort the list of messages alphabetically (asc
or desc
):
1
$ php bin/console translation:update --force --sort=asc fr
Consider empty strings not valid
Should an empty string be considered valid or invalid in the Length constraint?
The answer is not as obvious as it may seem at first sight. In Symfony 4.4, we
tried to improve and simplify this behavior with a new allowEmptyString
option.
In Symfony 4.4, the new option is true
by default, to keep compatibility
with the existing behavior. However, it's deprecated to not define a value for
this option explicitly, so you'll see several deprecation logs related to this.
We had to deprecate not setting it so we could change its default value to
false
in Symfony 5.0.
Added .gitattributes
to remove tests
The special .gitattributes file allows to define attributes to different
paths (directories or files) in the Git project (e.g. to change end-of-line
characters or define how diff
should be calculated).
One of those attributes is export-ignore
, which makes the file or directory
to be excluded when generating the Git archives. These archives are used when
installing dependencies with composer update --prefer-dist
(installing them
with composer update --prefer-source
doesn't exclude anything).
Given that Symfony components include a ton of test files, and given that most
people don't need tests in production, some people from the community suggested
to remove all test files with export-ignore
. These discussions started in
2014 and have been a recurring demand since then. In Symfony 4.4, we finally
decided to add these .gitattributes
files.
The result is that when installing dependencies with --prefer-dist
, you'll
no longer get Symfony tests, which can save up to 50% of installation size
(several megabytes per installation). This will help you make much smaller
packages when deploying with Docker or on serverless.
I really like the change from
Consider empty strings not valid
but I would really like to see such an option also for other Constraints like Range, Type or Choice (just out of my head I know I have overwritten them, there might be more). If you e.g. get data from a csv file everything is at least an empty string and not null so validating this data is hard if an empty string is not allowed in a constraint.I don't get the the point of
allowEmptyString
option, we have always used the NotBlank Constraint to disallow empty values. Also why only on the Length Constraint? If we add such option it could make sense on other constraints too.@Michele Sangalli:
@Length(min=1)
was confusing because it allowed an empty string (''
). The targeted default behavior in 5.0 is to reject empty strings as the min char requirement is not satisfied. TheallowEmptyString
option is only here for BC purpose.@Maxime Steinhausser I understood that already, I also read the discussion on github but imho it makes no sense to put only that option on that constraint to disallow the empty string value (
''
). That option could logically fit on (almost any) other constraints as well. I can get why you are saying that the old behavior it's confusing due to the fact that's written as@Length(min=1)
but is actually coherent on how the whole symfony form constraints is working now. I don't see the actual value of this change, it's not in order to follow some standard, won't increase performance and won't create more polished codebases, it's only forcing devs to perform some (minor?) refactoring for no valid reason while updating symfony version. Despite the@NotBlank(allowNull=true)
change makes a lot of sense, I think that at some point the reasoning is derailed and has led to the conclusion of making also this unnecessary change (wrong by some point of view).My 2 cents.
It's not:
Actually I missed the part where you state this, it was not the point but ok, good to know.
I still think it's not a logical thing and I hope I managed to highlight why. It won't change my life but, as a developer that use Symfony on daily basis, it would have been irresponsible for me not to point out a possibile mistake, however you guys know what your're doing and I trust this is a change for the better.