This PR was squashed before being merged into the 5.x branch.
Discussion
----------
[RateLimiter] Adding SlidingWindow algorithm
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | yes
| Deprecations? |
| Tickets |
| License | MIT
| Doc PR | Should be added
This is a draft PR to make sure we like the idea. I'll keep working on adding tests.
Commits
-------
c6d3b70315 [RateLimiter] Adding SlidingWindow algorithm
This PR was merged into the 5.x branch.
Discussion
----------
Deeprecate lock service
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | no
| Deprecations? | yes
| Tickets | #38458
| License | MIT
| Doc PR | TODO
This PR deprecate the `lock`, `LockInterface` service ass discussed in #38458
Commits
-------
40ea90ef6b Deeprecate lock service
This PR was merged into the 3.4 branch.
Discussion
----------
[HttpFoundation] Fix Range Requests
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | #38295
| License | MIT
| Doc PR |
This PR fixes some deviations from [RFC 7233](https://tools.ietf.org/html/rfc7233) for handling range requests, mentioned in #38295.
- overlapping ranges are now satisfiable (e.g. when requested range end is larger than the file size)
- range units other than `bytes` will get ignored
- range requests for methods other than `GET` will be ignored
I did not manage yet to implement the support for multiple ranges, but also don't know, if that's needed here.
Commits
-------
681804ba1a [HttpFoundation] Fix Range Requests
* 5.1:
[Contracts] add branch-aliases for dev-main
[Cache] Make Redis initializers static
[Messenger] Fixed typos in Connection
[CI] Fixed build on AppVeyor
Fix tests typo
[Lock] Reset Key lifetime time before we acquire it
[CI] Silence errors when remove file/dir on test tearDown()
Fix tests
Remove content-type check on toArray methods
* 4.4:
[Contracts] add branch-aliases for dev-main
[Cache] Make Redis initializers static
Fix tests typo
[Lock] Reset Key lifetime time before we acquire it
[CI] Silence errors when remove file/dir on test tearDown()
This PR was squashed before being merged into the 5.x branch.
Discussion
----------
Fix minor issue when sharing windows between Limiters
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
If I start using my custom Limiter, then change back to `FixedWindowLimiter`, then my cache might contain a value that `FixedWindowLimiter` does not support.
This PR makes sure that we handle such switch.
Commits
-------
e9ac9712d8 Fix minor issue when sharing windows between Limiters
This PR was squashed before being merged into the 5.x branch.
Discussion
----------
[Messenger][Redis] Adding support for lazy connect
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | Fix#38558
| License | MIT
| Doc PR | Should be added
With inspiration from the CacheComponent. This PR makes it possible to make the connection to Redis only when you first use it.
Commits
-------
1d7c8013e6 [Messenger][Redis] Adding support for lazy connect
This PR was merged into the 4.4 branch.
Discussion
----------
[Lock] Reset Key lifetime time before we acquire it
| Q | A
| ------------- | ---
| Branch? | 5.1 (maybe lower, I'll check)
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38541
| License | MIT
| Doc PR | n/a
Im out on somewhat deep water now. I am pretty sure we should reset the Key lifetime every time we acquire it. Without it it will me tricky to re-use a lock. (As pointed out by #38541)
@jderusse can you confirm.
Commits
-------
55ad70225a [Lock] Reset Key lifetime time before we acquire it
This PR was merged into the 4.4 branch.
Discussion
----------
Fix tests typo
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
While working on PSR 16 cache tests, I found this small glitch in the mocked `isHit` method
Commits
-------
047ce05f6b Fix tests typo
This PR was squashed before being merged into the 5.x branch.
Discussion
----------
[FrameworkBundle] Bugfixes in buildDir in the CacheClear command
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38547
| License | MIT
| Doc PR | n/a
Making sure one can clear cache with and without a buildDir
Commits
-------
2cad6bbbc7 [FrameworkBundle] Bugfixes in buildDir in the CacheClear command
This PR was merged into the 3.4 branch.
Discussion
----------
Remove "version" from composer.json files, use "branch-version" instead
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Waiting for confirmation from @Seldaek or @naderman
Commits
-------
f9ed6940fd Remove "version" from composer.json files, use "branch-version" instead
* 5.1:
[DI] fix dumping env vars
[HttpClient] skip executing the multi handle when it's freed already
[HttpClient] fix using freed curl resource at destruct time
[HttpClient] shutdown verbose output from curl at destruction
fix warning for preloading TranslatorTrait class
[Typography] Remove unneeded description comments
* 4.4:
[DI] fix dumping env vars
[HttpClient] skip executing the multi handle when it's freed already
[HttpClient] fix using freed curl resource at destruct time
[HttpClient] shutdown verbose output from curl at destruction
fix warning for preloading TranslatorTrait class
[Typography] Remove unneeded description comments
This PR was merged into the 5.x branch.
Discussion
----------
[HttpClient] simplify retry mechanism around RetryStrategyInterface
| Q | A
| ------------- | ---
| Branch? | 5.2
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Replaces #38466
I feel like the mechanism behind RetryableHttpClient is too bloated for no pragmatic reasons.
I propose to merge RetryDeciderInterface and RetryBackoffInterface into one single RetryStrategyInterface.
Having two separate interfaces supports no real-world use case. The only implementations we provide are trivial, and they can be reused by extending the provided GenericRetryStrategy implementation if one really doesn't want to duplicate that.
The methods are also simplified by accepting an AsyncContext as argument. This makes the signatures shorter and allows accessing the "info" of the request (allowing to decide based on the IP of the host, etc).
/cc @jderusse
Commits
-------
544c3e8678 [HttpClient] simplify retry mechanism around RetryStrategyInterface
This PR was merged into the 5.x branch.
Discussion
----------
[Security] Making login link signature_properties option required
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | yes (for a 5.2 feature)
| New feature? | no
| Deprecations? | no
| Tickets | none
| License | MIT
| Doc PR | not needed
Hi!
My intention was always to force the user to set this option. Before this PR, you can simply leave this option off completely without a validation error. Thanks to Wouter for finding it.
Also: made some punctuation & capitalization consistent on info messages.
Cheers!
Commits
-------
f7bb954979 Making login link signature_properties option required
This PR was merged into the 5.x branch.
Discussion
----------
[Serializer] Enabled mapping configuration via attributes
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | N/A
| License | MIT
| Doc PR | TODO
Let's use attributes for the serializer mapping configuration!
```php
class MyEntity
{
#[Groups(['list', 'detail])]
#[SerializedName('some-property')]
public $someProperty;
#[Ignore]
public string $secret;
}
```
Commits
-------
cfb9986203 [Serializer] Enabled mapping configuration via attributes.
This PR was merged into the 5.x branch.
Discussion
----------
[Form] fix ViolationMapper was always generating a localized label for each FormType
| Q | A
| ------------- | ---
| Branch? | 5.x (fix new behavior from 5.2)
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | /
Follow-up of #38435, with branch changed
**Explanation of the issue**
In Symfony 5.2, the `{{ label }}` placeholder can be used in constraint messages (-> introduced in commit 0d9f44235c)
However, the way it was coded is introducing a small side effect: now, every time there is validation error, `ViolationMapper` will ask the Form Type its `label`, and if not `false`, it will try to translate it.
**Why it is important/why it causes a BC break**
Since by default `AbstractType` does not have any `label`, it also introduces a minor BC break.
I will explain it with an example: in a project I work on, we check we don't have any missing translation. Sometimes we have violation errors bound to form ; then current code will get Form `label`, which in `null` in form type classes (which is quite usual I believe), so it will generate one, and pass that one to translator. And we see a lot on erroneous missing translations.
**Proposed fix**
This fix moves all this logic into a `if`, so `ViolationMapper` call the translator component only if `{{ label }}` placeholder is used in constraint error message.
On top of fixing BC, it has the benefit of lowering the performance cost for every violation when the feature is not used.
I added a test, as I believe the behavior should be guaranteed from now on.
Commits
-------
aee5571a71 [Form] fix ViolationMapper was always generating a localized label for each FormType
This PR was merged into the 5.x branch.
Discussion
----------
[Mailer] Fix mailjet image embedding
Filename is not enough to embed the image through cid, ContentID field
has to be set with the cid identifier used in the HTMLPart
| Q | A
| ------------- | ---
| Branch? | 5.1 <!-- see below -->
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | none <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | not needed <!-- required for new features -->
<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.
Additionally (see https://symfony.com/releases):
- Always add tests and ensure they pass.
- Never break backward compatibility (see https://symfony.com/bc).
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too.)
- Features and deprecations must be submitted against branch 5.x.
-->
Hello!
While switching from `Mandrill` to `Mailjet` I noticed that embedding images was not working properly, the `Content-ID` mime is not set properly without setting the `ContentID` key. With this change things will work as described in the [symfony documentation](https://symfony.com/doc/current/mailer.html#embedding-images)
[Mailjet reference](https://dev.mailjet.com/email/guides/send-api-v31/#send-with-attached-files)
Commits
-------
7ab772eeea [Mailer] Fix mailjet image embedding
* 5.1:
Disable the PhpUnit bridge when testing it
[PropertyInfo] Support for the mixed type.
Don't unset the inflate resource on close as it might still be needed
[HttpClient] Fix CurlHttpClient memory leak
[Form] Add Bosnian (bs) validators translation
[Form] Add missing Serbian (latn & cyrl) validators translation
[Cache] skip igbinary < 3.1.6
[Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3
[Form] [Validator] added pt_BR translations
Estonian update
Fix no collection in extract default value
[PhpUnitBridge] fix running parallel tests with phpunit 9
[VarDumper] fix truncating big arrays
* 4.4:
Disable the PhpUnit bridge when testing it
[PropertyInfo] Support for the mixed type.
Don't unset the inflate resource on close as it might still be needed
[HttpClient] Fix CurlHttpClient memory leak
[Form] Add Bosnian (bs) validators translation
[Form] Add missing Serbian (latn & cyrl) validators translation
[Cache] skip igbinary < 3.1.6
[Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3
[Form] [Validator] added pt_BR translations
Estonian update
[PhpUnitBridge] fix running parallel tests with phpunit 9
[VarDumper] fix truncating big arrays
* 3.4:
Disable the PhpUnit bridge when testing it
[PropertyInfo] Support for the mixed type.
[Form] Add Bosnian (bs) validators translation
[Form] Add missing Serbian (latn & cyrl) validators translation
[Form] [Validator] added pt_BR translations
Estonian update
[PhpUnitBridge] fix running parallel tests with phpunit 9
[VarDumper] fix truncating big arrays
This PR was squashed before being merged into the 5.x branch.
Discussion
----------
[Validator] Upgraded constraints to enable named arguments and attributes
| Q | A
| ------------- | ---
| Branch? | 5.2
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | #38096
| License | MIT
| Doc PR | TODO with symfony/symfony-docs#14305
This PR enables all remaining atomic (!= composite) constraints to be used as attributes.
The only exception is `UniqueEntity` from Doctrine bridge because we don't have a Doctrine ORM release yet that supports PHP 8. So I could migrate that one as well, but I cannot really test it.
Commits
-------
fb99eb2052 [Validator] Upgraded constraints to enable named arguments and attributes
This PR was merged into the 5.x branch.
Discussion
----------
[Security][Login Link] Allow null and DateTime objects to be used as signatureProperties
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Returning `DateTime` objects seems like a common use-case to automatically expire all login links when one is used or to only allow the login link to be used once.
**Before**
```php
class User
{
private ?\DateTime $lastAuthenticatedAt = null;
// ...
public function getLastAuthenticatedAtString(): string
{
return null === $this->lastAuthenticatedAt ? '' : $this->lastAuthenticatedAt->format('c');
}
}
```
```yaml
security:
firewalls:
main:
login_link:
# ...
signature_properties: ['lastAuthenticatedAtString']
````
**After**
```php
class User
{
private ?\DateTime $lastAuthenticatedAt = null;
// ...
public function getLastAuthenticatedAt(): ?\DateTime
{
return $this->lastAuthenticatedAt;
}
}
```
```yaml
security:
firewalls:
main:
login_link:
# ...
signature_properties: ['lastAuthenticatedAt']
````
---
The disadvantage of this patch is that there needs to be some boundary as to which objects we want to support casting to a scalar, but I'm convinced that `DateTime` objects will commonly be used as signature properties.
cc @weaverryan
Commits
-------
0f947b2e84 Allow null and DateTime objects to be used as signatureProperties
This PR was merged into the 5.x branch.
Discussion
----------
[Security] Add error message when using LoginLinkHandler outside a firewall
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Add a more friendly error message when autowiring `LoginLinkHanderInterface` in a route outside the firewall. Current error was `Call to a member function getName() on null`.
Commits
-------
f807b5fc15 Add error message when using LoginLinkHandler outside a firewall
Small mistake in the rate limiter configuration, instead of unsetting the `storage_service` option the never existing `storage` option was unset, resulting into an application error when trying to use a Limiter in your application.
Uncaught PHP Exception: The option "storage_service" does not exist. Defined options are: "id", "interval", "limit", "rate", "strategy"."
Returning DateTime objects seems like a common use-case to automatically expire
all login links when one is used or to only allow the login link to be used
once.
This PR was merged into the 5.x branch.
Discussion
----------
[Notifier] Introduce NullMessage and remove transport setter in MessageInterface
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | - <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | - <!-- required for new features -->
Follow-up PR of https://github.com/symfony/symfony/pull/36479
Commits
-------
5701e89960 Introduce NullMessage and remove transport setter in MessageInterface
This PR was merged into the 5.x branch.
Discussion
----------
[lock] Mark Key unserializable whith PgsqlStore
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | /
Marks key unserializable #38395 with the new PgsqlStore #38346
Commits
-------
eb934e9015 Mark Key unserializable whith PgsqlStore
This PR was merged into the 5.x branch.
Discussion
----------
[SecurityBundle] Make user lazy loading working without user provider
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | Fix#38429 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
Make user lazy loading in security working again without user provider.
Commits
-------
df9e8486f5 Make user lazy loading working without user provider
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38352
| License | MIT
| Doc PR |
As stated on #38352 [ldap_control_paged_result](https://www.php.net/manual/en/function.ldap-control-paged-result.php) and [ldap_control_paged_result_response](https://www.php.net/manual/en/function.ldap-control-paged-result-response.php) have been deprecated since PHP 7.4 and will be removed on PHP 8.0.
With this fix, Query uses serverctrls to handle LDAP results pagination.
Since `serverctrls` where introduced in PHP 7.3 and they are the only way to circumvent the usage of `ldap_control_paged_result`, I've added a new Query class implementation which uses `serverctrls` to control pagination.
To do so I've also had to update the LDAP Adapter in order to use the new class if PHP version 7.3 or greater are found
Commits
-------
d332b30526 [Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3
This PR was merged into the 5.x branch.
Discussion
----------
[HttpClient] Add jitter to RetryBackoff
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | TODO
From the idea https://twitter.com/mtdowling/status/1313205613158043648 this PR adds a new `jitter` parameter to the ExponentialBackOff implementation.
jitter is a percentage (float between 0 and 1) of randomness to apply to the computed delay.
ie. if the initial delay is 1000ms, and jitter=0.2, the finale delay will be an number between 800 and 1200 (1000 +/- 20%)
Commits
-------
ace731437e Add jitter to RetryBackof
This PR was squashed before being merged into the 3.4 branch.
Discussion
----------
[Form] [Validator] added pt_BR translations
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | --
| License | MIT
| Doc PR | --
Added missing pt_BR translations to Form and Validator components.
Commits
-------
4bede2824c [Form] [Validator] added pt_BR translations
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[Mime] Fix serialization of RawMessage
| Q | A
| ------------- | ---
| Branch? | 4.4 <!-- see below -->
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | Fix#38430, Related #33394 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | - <!-- required for new features -->
The serialization of RawMessage is currently broken if using a generator for message like done by `Symfony\Component\Mailer\SentMessage` see 5f1c3a7972/src/Symfony/Component/Mailer/SentMessage.php (L45)
This patch converts the message to a string so further serialization can be done.
This patch probably also solves #33394.
<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.
Additionally (see https://symfony.com/releases):
- Always add tests and ensure they pass.
- Never break backward compatibility (see https://symfony.com/bc).
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too.)
- Features and deprecations must be submitted against branch 5.x.
-->
Commits
-------
fd99eb26d8 [Mime] Fix serialization of RawMessage
This PR was merged into the 5.2-dev branch.
Discussion
----------
[DoctrineBridge] fix and replace namespace to Uid
| Q | A
| ------------- | ---
| Branch? | master <!-- see below -->
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | https://github.com/symfony/symfony/pull/37678#discussion_r499709057 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | ... <!-- required for new features -->
This post should also be corrected: https://symfony.com/blog/new-in-symfony-5-2-doctrine-types-for-uuid-and-ulid cc @javiereguiluz
Commits
-------
28d1169714 [DoctrineBridge] fix and replace namespace to Uid
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Validator] Migrate File and Image constraints to attributes
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | #38096
| License | MIT
| Doc PR | TODO with symfony/symfony-docs#14305
I have migrated a lot of the constraints already and am preparing a big PR with them at the moment. I decided to pull this part out because it might raise some discussion.
This PR enables the `File` and `Image` constraints to be used as attributes. Especially the constructor signature of the `Image` constraint has grown pretty large this way. This by itself should be a big problem, if we don't expect the constructor to be called with ordered parameters by userland code. But it shows that the constraints have grown a bit too large. We might want to consider to split it.
Commits
-------
d8c186938e [Validator] Migrate File and Image constraints to attributes.
This PR was merged into the 5.2-dev branch.
Discussion
----------
[HttpClient] minor fixes in RetryableHttpClient
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Commits
-------
495562836a [HttpClient] minor fixes in RetryableHttpClient
This PR was merged into the 3.4 branch.
Discussion
----------
Fix type annotation in ExpressionLanguage\Token
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
The expected argument `$type` should be a string - the strict comparison would always fail with the current annotated types (`array|int`).
See the constructor + constants for reference:
7db7dcc431/src/Symfony/Component/ExpressionLanguage/Token.php (L33)7db7dcc431/src/Symfony/Component/ExpressionLanguage/Token.php (L25-L30)
Commits
-------
bfde15b728 Fix type annotation
* 5.1:
Added Stopwatch example to the README
Bump Symfony version to 5.1.8
Update VERSION for 5.1.7
Update CHANGELOG for 5.1.7
Bump Symfony version to 4.4.16
Update VERSION for 4.4.15
Update CHANGELOG for 4.4.15
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Validator] Use comparison constraints as attributes
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | yes
| Tickets | #38096
| License | MIT
| Doc PR | TODO, let's add it to symfony/symfony-docs#14305
This PR enables all child classes of `AbstractComparison` to be used as attributes.
Some of those constraints used a trait called `NumberConstraintTrait` for a shared implementation. After my changes, that trait did not fit well anymore, so I've added a new `ZeroComparisonConstraintTrait` as a replacement. Although I don't expect `NumberConstraintTrait` to provide much value outside of the Symfony codebase, I think we cannot safely change it because it was not labelled as `@internal`. This is basically why I went for the deprecation.
Commits
-------
b5bdf8288f [Validator] Use comparison constraints as attributes.
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[HttpFoundation] Expired cookies string representation consistency & tests
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| License | MIT
These changes add consistent behavior when converting expired cookies back and forth from string representation into `Symfony\Component\HttpFoundation\Cookie` instances in `Cookie::fromString`:
- When `Max-Age` is zero and `expires` is in the past, the `expires` date is kept as is (previous behavior: `expires` is overwritten with current timestamp because it is reset to current timestamp + `Max-Age`)
- When `Max-Age` is zero and `expires` is in the future, expires is reset to current timestamp, as `Max-Age` is the preferred "source of truth" (same as previous behavior)
- Add tests for how the Cookie class handles `Max-Age` in a cookie string and how `expires` and `Max-Age` interact
- Extract helper function `expiresTimestamp` so converting to a unix timestamp can be reused in `Cookie::fromString`
This is more a new feature than a bug fix in my mind, therefore I would include it in 5.1+.
Commits
-------
4f5d5eceb0 [HttpFoundation] Expired cookies string representation consistency & tests
This PR was merged into the 5.2-dev branch.
Discussion
----------
[lock] Prevent user serializing the key when store does not support it.
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | /
Some store relies on connection with the running process. ie. kernel relaease flock/semaphore, or zookeeper neeeds a connection to the database.
When the users tries to serialize the key to send it to another process, they are not aware that they lose the lock.
This PR throws an exception in that situation.
Commits
-------
1ec0630262 Prevent user serializing the key
This PR was merged into the 5.2-dev branch.
Discussion
----------
Remove array return type from Request::toArray()
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38400
| License | MIT
| Doc PR | -
Laravel already extends Symfony's `Request` class and defines it's own `toArray` method. https://github.com/symfony/symfony/pull/38224 added a new `toArray` method to this class with a different signature to the one that is in Laravel, causing fatal errors (https://github.com/laravel/framework/issues/34660). I think the best course of action here is to remove the return type for now, and only add it in Symfony 6. This will allow Symfony 6.0 and Laravel 11 to synchronize adding the return type.
Older versions of Laravel can't just change their signature to add an array return type to them, because that would be a breaking change for Laravel users extending Laravel's request class. I'm thinking, in particular, API packages and the like, or just straight up application code.
Commits
-------
8b291a49a6 Remove array return type from Request::toArray()
This PR was merged into the 5.1 branch.
Discussion
----------
Handle consecutive supports() calls in the RememberMeAuthenticator
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38206
| License | MIT
| Doc PR | -
If I read the issue correctly, the problem is not so much that `autoLogin()` is called in supports, but that it is called multiple times in the same request (in lazy firewalls). This is fixed by this issue.
@qurben or @fancyweb do you have an application with this error, and can you please test the patch in this PR? Please let me know if this actually fixed the issue. (if you can't, I'll create a small demo app to test this one)
Commits
-------
e0d1867b54 Handle consecutive supports() calls in the RememberMeAuthenticator
This PR was merged into the 5.2-dev branch.
Discussion
----------
[HttpClient] Minor fix of type and message in ExponentialBackOff
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Make the type consistent and fix an error message
Commits
-------
6149a0c04b [HttpClient] Minor fix of type and message in ExponentialBackOff
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Console] Remove "php" invokation from help messages.
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| License | MIT
Discusstion started here:
https://github.com/symfony/symfony/pull/38349
I was a bit puzzled to find that the help for the list and help commands suggests that you call the console application by prefixing it with `php myconsoleapp`.
As suggested in the PR above I am removing the `php ` prefix from the help.
I am providing a script with a shebang like the first example suggested in the following link:
https://symfony.com/doc/current/components/console.html
Eventually I want to distribute my console app as docker image so there is no need for php installed or the users even knowing is written in php.
The script name is easy to override by just setting a different value to `$_SERVER['PHP_SELF']` but this php prefix is hardcoded into the help strings for the the two default commands available.
Slightly related to #38347 as I am trying to improve the console help output.
Commits
-------
e036c30e7a [Console] Remove "php" invokation from help messages.
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Form] Implement Twig helpers to get field variables
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/14308
Designing Symfony Forms has always been difficult, especially for developers not comfortable with Symfony or Twig. The reason behind this difficulty is that the current `form_*` helper functions, while providing a way to quickly render a form, are hiding the generated HTML behind a notation specific to Symfony.
HTML standards introduced many new attributes since the Form component was created, from new constraints to how should inputs be displayed, treated by screen readers, etc.
I propose to introduce a series of new Twig functions to help create more flexible forms without the hurdle of having to use `form_*` functions. I called these methods `field_*` because they aim at rendering only the tiny bits of strings necessary to map forms to the Symfony backend.
The functions introduced are:
* `field_name` returns the name of the given field
* `field_value` returns the current value of the given field
* `field_label` returns the label of the given field, translated if possible
* `field_help` returns the help of the given field, translated if possible
* `field_errors` returns an iterator of strings for each of the errors of the given field
* `field_choices` returns an iterator of choices (the structure depending on whether the field uses or doesn't use optgroup) with translated labels if possible as keys and values as values
A quick example of usage of these functions could be the following:
``` twig
<input
name="{{ field_name(form.username) }}"
value="{{ field_value(form.username) }}"
placeholder="{{ field_label(form.username) }}"
class="form-control"
/>
<select name="{{ field_name(form.country) }}" class="form-control">
<option value="">{{ field_label(form.country) }}</option>
{% for label, value in field_choices(form.country) %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
</select>
<select name="{{ field_name(form.stockStatus) }}" class="form-control">
<option value="">{{ field_label(form.stockStatus) }}</option>
{% for groupLabel, groupChoices in field_choices(form.stockStatus) %}
<optgroup label="{{ groupLabel }}">
{% for label, value in groupChoices %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
{% for error in field_errors(form.country) %}
<div class="text-danger mb-2">
{{ error }}
</div>
{% endfor %}
```
There are several advantages to using these functions instead of their `form_*` equivalents:
* they are much easier to use for developers not knowing Symfony: they rely on native HTML with bits of logic inside, instead of relying on specific tools needing to be configured to display proper HTML
* they allow for better integration with CSS frameworks or Javascript libraries as adding a new HTML attribute is trivial (no need to look at the documentation)
* they are easier to use in contexts where one would like to customize the rendering of a input in details: having the label as placeholder, displaying a select empty field, ...
The `form_*` functions are still usable of course, but I'd argue this technique is actually easier to read and understand.
Commits
-------
3941d70928 [Form] Implement Twig helpers to get field variables
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[Lock] Fix StoreFactory to accept same DSN syntax as AbstractAdapter
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#35350
| License | MIT
| Doc PR |
Updates `Symfony\Component\Lock\Store\StoreFactory` to accept same DSN syntax as `Symfony\Component\Cache\Adapter\AbstractAdapter` which is used to create Redis class instance.
Commits
-------
4ebbe3d86b [Lock] Fix StoreFactory to accept same DSN syntax as AbstractAdapter
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[Security] Magic login link authentication
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | none
| License | MIT
| Doc PR | TODO
Hi!
This adds a Slack-style "magic link" login authenticator to the new login system: (A) enter your email into a form, (B) receive an email with a link in it (C) click that link and you are authenticated!
For most users, implementing this would require:
A) Create a [controller](https://github.com/weaverryan/symfony-magic-login-link-example/blob/master/src/Controller/MagicLinkLoginController.php) with the "enter your email" form and a route for the "check" functionality (similar to `form_login`)
B) Activate in `security.yaml`:
```yml
security:
enable_authenticator_manager: true
# ...
firewalls:
# ...
main:
# ...
login_link:
check_route: 'magic_link_verify'
# this is an important and powerful option
# An array of properties on your User that are used to sign the link.
# If any of these change, all existing links will become invalid
# tl;dr If you want the modification of ANY field to invalidate ALL existing magic links immediately,
# then you can add it to this list. You could even add a "lastLoginLinkSentAt" to invalid
# all existing login links when a new one is sent.
signature_properties: [id, password, email]
# optional - by default, links can be reused but have a 10 minute lifetime
#max_uses: 3
#used_link_cache: cache.app
```
Done! This will generate a URL that looks something like this:
> https://127.0.0.1:9033/login/verify?user=weaverryan@gmail.com&expires=1601342578&hash=YzE1ZDJlYjM3YTMyMjgwZDdkYzg2ZjFlMjZhN2E5ZWRmMzk3NjAxNjRjYThiMjMzNmIxYzAzYzQ4NmQ2Zjk4NA%3D%3D
We would implement a Maker command this config + login/controller. The implementation is done via a "signed URL" and an optional cache pool to "expire" links. The hash of the signed URL can contain any user fields you want, which give you a powerful mechanism to invalidate magic tokens on user data changes. See `signature_properties` above.
#### Security notes:
There is a LOT of variability about how secure these need to be:
* A) Many/most implementation only allow links to be used ONE time. That is *possible* with this implementation, but is not the *default*. You CAN add a `max_uses` config which stores the expired links in a cache so they cannot be re-used. However, to make this work, you need to do more work by adding some "page" between the link the users clicks and *actually* using the login link. Why? Because unless you do this, email clients may follow the link to "preview" it and will "consume" the link.
* B) Many implementations will invalidate all other login links for a user when a new one is created. We do *not* do that, but that IS possible (and we could even generate the code for it) by adding a `lastLoginLinkSentAt` field to `User` and including this in `signature_properties`.
* C) We *do* invalidate all links if the user's email address is changed (assuming the `email` is included in `signature_properties`, which it should be). You can also invalidate on password change or whatever you want.
* D) Some implementations add a "state" so that you can only use the link on the same device that created it. That is, in many cases, quite annoying. We do not currently support that, but we could in the future (and the user could add it themselves).
Thanks!
#### TODOS:
* [x] A) more tests: functional (?) traits
* [ ] B) documentation
* [ ] C) MakerBundle PR
* [ ] D) Make sure we have what we need to allow that "in between" page
* [ ] E) Create a new cache pool instead of relying on cache.app?
Commits
-------
a8afe109d8 [Security] Magic login link authentication
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[HttpFoundation] Add Request::toArray() for JSON content
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | ni
| New feature? | yes
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
The past few months I've been working more and more with javascript and APIs. I've written controllers that parse json from the request body. I've found myself copying code between projects so I looked at the possibility to add this code to the `Request` class itself.
### Usage
```http
POST /add-user
Content-Type: application/json
{"name": "Tobias", "email": "tobias.nyholm@gmail.com"}
```
```php
use Symfony\Component\HttpFoundation\Exception\JsonException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
class MyController
// ...
public function addUser(Request $request): JsonResponse
{
try {
$data = $request->toArray();
} catch (JsonException $e) {
return new JsonResponse(['message'=>'Request does not contain valid json'], 415);
}
$command = new AddUser($data['email'] ?? '', $data['name'] ?? '');
try {
$this->commandBus->dispatch($command);
} catch (ValidationFailedException $e) {
return new JsonResponse(['message' => 'Unexpected JSON body'], 400);
}
return new JsonResponse(['message' => 'User successfully added']);
}
}
```
----------
I've searched but I have not found that this has been proposed before.. With is strange.. ¯\\_(ツ)_/¯
Commits
-------
83c1a2666d [HttpFoundation] Add Request::toArray() for JSON content
This PR was merged into the 5.2-dev branch.
Discussion
----------
[PropertyInfo] Fix failure over array<string,mixed> PhpDoc type
| Q | A
| ------------- | ---
| Branch? | master (issue introduced in master)
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | /
**Background**
Since a few days ago ([this commit](80e5a7fbd8)), PropertyInfo 5.2 component supports array PhpDoc types, such as `array<string,string>`.
While testing SF 5.2 over my project, it was failing over:
```php
class SomeDoctrineEntityProxy implements \Doctrine\ORM\Proxy\Proxy
{
/**
* @var array<string, mixed> default values of properties to be lazy loaded, with keys being the property names
*
* @see \Doctrine\Common\Proxy\Proxy::__getLazyProperties
*/
public static $lazyPropertiesDefaults = array();
}
```
Upon investigation, it appears `array<string,mixed>` is causing the issue: `mixed` type is not handled.
**Expected behavior**
PropertyInfo component should not guess anything for `mixed` type (return `NULL`), but it should not throw any exception.
**Comment about my fix**
I added a test case (`arrayOfMixed`) you can use to reproduce the issue.
Since array PhpDoc types were not tested at all, I also added a test case over `array<string,string>`.
Commits
-------
590177ff8e [PropertyInfo] Fix failure over array<string,mixed> PhpDoc type
This PR was merged into the 5.2-dev branch.
Discussion
----------
[HttpClient] Fix exception triggered with AsyncResponse
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | https://github.com/symfony/symfony/pull/38289#issuecomment-702573975
| License | MIT
| Doc PR | /
When a request is replayed with the AsyncResponse and the 2nd request failed, users get an exception even when they pass `$throw=false`.
In fact, there are 2 exceptions:
1. Cannot get the content of the response twice: buffering is disabled.
73ca97c97a/src/Symfony/Component/HttpClient/Response/CommonResponseTrait.php (L51-L68)
Because CommonResponseTrait::$content is null and `self::stream` yield only the LastChunk. The content is stays null
2. HTTP/2 429 returned for "https://httpbin.org/status/429"
73ca97c97a/src/Symfony/Component/HttpClient/Response/AsyncResponse.php (L209-L225)
Because on the second request passthru is null, it didn't disable the the exception thrown on destruct for the wrapped response.
This
Commits
-------
3aedb51dd8 [HttpClient] Fix exception triggered with AsyncResponse
* 5.1:
[5.1] Ignore more deprecations for Mockery mocks
[PhpUnitBridge] Fix Deprecation file when it comes from the TestsListener
disallow FrameworkBundle 4.4+
propagate validation groups to subforms
[Form] [Validator] Add failing testcase to demonstrate group sequence issue
This PR was merged into the 5.1 branch.
Discussion
----------
[PhpUnitBridge] Fix Deprecation file when it comes from the TestsListener
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
https://github.com/symfony/symfony/pull/38031 caused an unwanted regression: if the frame `class` matches `SymfonyTestsListenerFor` it used to always return, now it continues so the `originClass` and `originMethod` properties are set. Therefore, the deprecation is considered as coming from the test listener. It ends up in the "legacy" group and muted because the test listeners contains the word "Legacy" in their namespaces.
Example test:
```php
<?php
namespace App\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\DependencyInjection\ExtractingEventDispatcher;
final class FooTest extends TestCase
{
public function test(): void
{
// ExtractingEventDispatcher is @internal
new class extends ExtractingEventDispatcher {};
$this->assertTrue(true);
}
}
```
On 4.4:
```
Other deprecation notices (1)
1x: The "Symfony\Component\EventDispatcher\DependencyInjection\ExtractingEventDispatcher" class is considered internal. It may change without further notice. You should not use it from "Symfony\Component\EventDispatcher\DependencyInjection\ExtractingEventDispatcher@anonymous".
```
On 5.1:
```
Legacy deprecation notices (1)
```
Commits
-------
1ba06a0f86 [PhpUnitBridge] Fix Deprecation file when it comes from the TestsListener
* 4.4:
disallow FrameworkBundle 4.4+
propagate validation groups to subforms
[Form] [Validator] Add failing testcase to demonstrate group sequence issue
* 3.4:
disallow FrameworkBundle 4.4+
propagate validation groups to subforms
[Form] [Validator] Add failing testcase to demonstrate group sequence issue
This PR was merged into the 3.4 branch.
Discussion
----------
[Form] propagate validation groups to subforms
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38300
| License | MIT
| Doc PR |
Commits
-------
04f5698e29 propagate validation groups to subforms
e2c7c3373d [Form] [Validator] Add failing testcase to demonstrate group sequence issue
* 5.1:
[HttpClient] fix using proxies with NativeHttpClient
[4.4] Ignore more deprecations for Mockery mocks
[Routing] fix using !important and defaults/reqs in inline route definitions
[ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes
[HttpClient] Fix using https with proxies
[TwigBundle] Only remove kernel exception listener if twig is used
[DI] Fix changelog
Remove CHANGELOG files for 4.x
Adjust expired range check
Fix redis connection error message
[DI] fix dumping non-shared lazy services
* 4.4:
[HttpClient] fix using proxies with NativeHttpClient
[4.4] Ignore more deprecations for Mockery mocks
[Routing] fix using !important and defaults/reqs in inline route definitions
[ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes
[HttpClient] Fix using https with proxies
[TwigBundle] Only remove kernel exception listener if twig is used
Adjust expired range check
Fix redis connection error message
This PR was merged into the 4.4 branch.
Discussion
----------
[HttpClient] fix using proxies with NativeHttpClient
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
As spotted by @stof in https://github.com/symfony/symfony/pull/38368#issuecomment-702272737, we cannot use local DNS resolution with HTTP proxies.
Commits
-------
28f301bf03 [HttpClient] fix using proxies with NativeHttpClient
This PR was merged into the 4.4 branch.
Discussion
----------
[Routing] fix using !important and defaults/reqs in inline route definitions
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#33224
| License | MIT
| Doc PR | -
Commits
-------
826db225b7 [Routing] fix using !important and defaults/reqs in inline route definitions
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[RateLimiter] Fix cache storage (use namespaced pool + remove \Serializable)
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38365, fix#38338
| License | MIT
| Doc PR | -
Commits
-------
251c202874 Use a dedicated cache.rate_limiter cache pool
5dc562a318 Use __sleep/__wakeup instead of Serializable
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Messenger] Added ErrorDetailsStamp
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | yes
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #32311
| License | MIT
| Doc PR | No doc changes are needed
#SymfonyHackday
This PR is part of the work started in #32341. That PR has a workaround for showing exceptions added to a previous retry. This PR stores error messages in a separate stamp, so they're more easily accessed.
I also added the exceptionClass as a separate string (independant of FlattenException), so that information is always available, even if the trace is not (due to FlattenException not being available).
Duplicated exceptions (compared to the last one) are not stored separately.
**Questions:**
- Should we limit the total amount of exceptions (remove the oldest when adding a new one)?
- Yes, but in a new PR
- The current implementation adds this stamp in the Worker instead of the listeners to prevent duplicate code (due to the immutability of the envelope in the event). Is this the proper way to do this?
- No, create a new listener and a way to add stamps to the envelope inside the event.
- When adding details of a `HandlerFailedException`, should we add a stamp per wrapped `Throwable`? There can be multiple errors wrapped by a single `HandlerFailedException`.
- Yes, but in a later PR
**Todo:**
- [x] only add new information if it differs from the previous exception
- [x] add deprecations
- [x] fall back to old stamp data if no new stamp is available
- [x] rebase and retarget to master
- [x] update CHANGELOG.md
- [x] check for docs PR
**BC Breaks:**
When this PR is merged, RedeliveryStamps will no longer be populated with exception data. Any implementations that use `RedeliveryStamp::getExceptionMessage()` or `RedeliveryStamp::getFlattenedException()` will receive an empty string or `null` respectively for stamps added after this update. They should rely on `ErrorDetailsStamp` instead.
**New stuff:**
- New stamp `ErrorDetailsStamp`.
- New event subscriber `AddErrorDetailsStampListener`.
- New method `AbstractWorkerMessageEvent::addStamps`.
Commits
-------
cd27b863f9 [Messenger] Added FailedMessageErrorDetailsStamp
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[Messenger] dispatch event when a message is retried
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| License | MIT
Hello,
i'm working on a bundle which helps to monitor messenger queues (add some stats for queues/transports + ability to manage failed messages from the browser)
https://github.com/SymfonyCasts/messenger-monitor-bundle/
and we're missing some hooks in the messaging system:
1. a way to know when a message has been retried (fixed by dispatching a new `WorkerMessageRetriedEvent` in `SendFailedMessageForRetryListener::onMessageFailed()`)
2. a way to update the enveloppe in worker message events (fixed by adding `AbstractWorkerMessageEvent::setEnvelope()`)
if needed i can provide some precise use cases.
thanks.
Commits
-------
55bddcb721 [Messenger] dispatch event when a message is retried
This PR was merged into the 5.2-dev branch.
Discussion
----------
[HttpClient] provide response body to the RetryDecider
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | yes but for not-yet released 5.2 feature
| Tickets | /
| License | MIT
| Doc PR | TODO
Some servers, like AWS, does not always return standard HTTP code. The strategy needs to parse the body to take a decision.
example:
```
400
x-amzn-requestid: XXXXX
content-type: application/x-amz-json-1.1
content-length: 58
date: Thu, 24 Sep 2020 11:17:35 GMT
connection: close
{"__type":"ThrottlingException","message":"Rate exceeded"}
````
This PR update the `RetryDeciderInterface` interface to let the decider notifying the Client when it need the body to take a decision. in that case, the Client, fetch te client, and call again the decider with the full body.
usage
```php
class Decider implements RetryDeciderInterface {
public function shouldRetry(string $requestMethod, string $requestUrl, array $requestOptions, int $responseCode, array $responseHeaders, ?string $responseContent, \Throwable $throwable = null): ?bool
{
if (null !== $throwable) {
return true;
}
if (in_array($responseCode, [423, 425, 429, 500, 502, 503, 504, 507, 510])) {
return true;
}
if (
$responseCode !== 400
|| $headers['content-type'][0] ?? null !== 'application/x-amz-json-1.1'
|| (int) $headers['content-length'][0] ?? '0' > 1024
) {
return false;
}
if (null === $responseContent) {
return null; // null mean no decision taken and need to be called again with the body
}
$data = json_decode($responseContent, true);
return $data['__type'] ?? '' === 'ThrottlingException';
}
}
```
Commits
-------
321be5884d [HttpClient] provide response body to the RetryDecider
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[TwigBundle] Only remove kernel exception listener if twig is used
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | https://github.com/contao/contao/issues/1527
| License | MIT
| Doc PR |
In a setup using the template engine but not twig as the template engine no exceptions are logged. This is caused by the twig-bundle which removes the `exception_listener` service. For my understanding this should only happen if twig is used as template engine. This PR fixes the logic that only for the case where twig is enabled as template engine the http kernel exception listener is removed. Otherwise the twig exception listener got removed now.
Disclaimer: I'm not too deep into the details, so maybe I oversee something why it's implemented the way it is.
Commits
-------
7c34f6e866 [TwigBundle] Only remove kernel exception listener if twig is used
This PR was merged into the 3.4 branch.
Discussion
----------
[BrowserKit] Cookie expiration at current timestamp
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| License | MIT
In `Symfony\Component\BrowserKit\Cookie` a cookie is expired if the `expires` timestamp is in the past. I would like to change it to also be expired if the `expires` timestamp equals the current exact timestamp. This would still be in line with [RFC 6265](https://tools.ietf.org/html/rfc6265#section-4.1.2.1), as it states `The Expires attribute indicates the maximum lifetime of the cookie, represented as the date and time at which the cookie expires`.
Reason for this change: Cookies usually both have `expires` and `Max-Age` set, and Symfony sets `Max-Age` to zero if a cookie is expired (in `Symfony\Component\HttpFoundation\Cookie`). When converting cookies between string and object representations, `Max-Age` is the preferred source of truth for the expiration, but `Max-Age` set to zero is converted to an `expires` timestamp at this exact second, currently making the cookie not expired in `Symfony\Component\BrowserKit\Cookie`, even though it should be.
I noticed this discrepancy in my tests when checking if a cookie no longer existed after deleting it, yet it was still there, because `Cookie` thought it would only expire after the `expires` timestamp had passed. I am also thinking of raising an issue for `Symfony\Component\HttpFoundation\Cookie`, as importing and exporting an expired cookie (via strings) changes the `expired` value. I thought this change was a simpler one for now, and should have no negative/unexpected impact.
Commits
-------
9d187c0d1a Adjust expired range check
This PR was merged into the 5.1 branch.
Discussion
----------
[DI] fix dumping non-shared lazy services
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38327
| License | MIT
| Doc PR | -
It took me a while to get this correct, but here we are.
Commits
-------
e33a0b0f94 [DI] fix dumping non-shared lazy services
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Security][RateLimiter] Added request rate limiter to prevent breadth-first attacks
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
This allows limiting on different elements of a request. The normal `CompoundLimiter` requires the same key for all its limiters.
This request limiter is useful to e.g. prevent breadth-first attacks, by allowing to enforce a limit on both IP and IP+username. It can also be useful for applications using some sort of API request limiting (or e.g. file upload limiting).
The default login throttling limiter will allow `max_attempts` (default: 5) attempts per minute for `username + IP` and `5 * max_attempts` for `IP`. Customizing this will require creating a new service that extends `AbstractRequestRateLimiter` and implementing `getLimiters(Request $request): LimiterInterface[]`.
Commits
-------
5d03afea99 Added request rate limiters and improved login throttling
This PR was squashed before being merged into the 5.2-dev branch (closes#38351).
Discussion
----------
[Console] clone stream on multiline questions so EOT doesn't close input
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | N/A
| License | MIT
| Doc PR | N/A
This fixes a bug in the multiline question feature that was introduced in #37683.
Today, @epitre commented on https://github.com/symfony/symfony/pull/37683#issuecomment-700666826:
> If I ask a question AFTER using the multiline option in a previous question, then it seems that the ctrl+d is kind of saved, and the command gets aborted.
I'm honestly not sure how I missed this while working on #37683, since I was testing it with multiple questions, but I think it might have resulted from some of the back-and-forth and the lack of ability to effectively test the EOT character from a unit test.
The solution was to _clone_ the input stream resource and use the clone to read the multiline input and capture the EOT byte. In this way, the primary input stream is not closed by the EOT.
This is similar to @epitre's solution in https://github.com/symfony/symfony/pull/38345, but I'm using the `uri` and `mode` from `stream_get_meta_data()` to create the new stream, and if the existing stream has any data and is seekable and writable (like the streams used in the tests), I add the data to the clone and seek to the same offset.
I've ensured that this solution works on a question that is in the middle of a series of other questions, and I've tested in on *nix and Windows. I've also improved the tests for multiline questions. While I'm unable to test (with a unit test) that an EOT character effectively stops reading from STDIN while continuing to the next question and prompt, I feel confident that the tests here provide sufficient coverage.
Commits
-------
ec688a361e [Console] clone stream on multiline questions so EOT doesn't close input
This allows limiting on different elements of a request. This is usefull to
e.g. prevent breadth-first attacks, by allowing to enforce a limit on both IP
and IP+username.
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Validator] Constraints as php 8 Attributes
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | #38096
| License | MIT
| Doc PR | TODO
This is my attempt to teach the validator to load constraints from PHP attributes. Like we've done it for the `Route` attribute, I've hooked into the existing `AnnotationLoader`, so we can again mix and match annotations and attributes.
### Named Arguments
An attribute declaration is basically a constructor call. This is why, in order to effectively use a constraint as attribute, we need to equip it with a constructor that works nicely with named arguments. This way, IDEs like PhpStorm can provide auto-completion and guide a developer when declaring a constraint without the need for additional plugins. Right now, PhpStorm supports neither attributes nor named arguments, but I expect those features to be implemented relatively soon.
To showcase this, I have migrated the `Range` and `Choice` constraints. The example presented in #38096 works with this PR.
```php
#[Assert\Choice(
choices: ['fiction', 'non-fiction'],
message: 'Choose a valid genre.',
)]
private $genre;
```
A nice side effect is that we get a more decent constructor call in php 8 in situations where we directly instantiate constraints, for instance when attaching constraints to a form field via the form builder.
```php
$builder->add('genre, TextType::class, [
'constraints' => [new Assert\Choice(
choices: ['fiction', 'non-fiction'],
message: 'Choose a valid genre.',
)],
]);
```
The downside is that all those constructors generate the need for some boilerplate code that was previously abstracted away by the `Constraint` class.
The alternative to named arguments would be leaving the constructors as they are. That would basically mean that when declaring a constraint we would have to emulate the array that Doctrine annotations would crate. We would lose IDE support and the declarations would be uglier, but it would work.
```php
#[Assert\Choice([
'choices' => ['fiction', 'non-fiction'],
'message' => 'Choose a valid genre.',
])]
private $genre;
```
### Nested Attributes
PHP does not support nesting attributes (yet?). This is why I could not recreate composite annotations like `All` and `Collection`. I think it's okay if they're not included in the first iteration of attribute constraints and we can work on a solution in a later PR. Possible options:
* A later PHP 8.x release might give us nested attributes.
* We could find a way to flatten those constraints so we can recreate them without nesting.
* We could come up with a convention for a structure that lets us emulate nested attributes in userland.
### Repeatable attributes
In order to attach two instances of the same attribute class to an element, we explicitly have to allow repetition via the flag `Attribute::IS_REPEATABLE`. While we could argue if it really makes sense to do this for certain constraints (like `NotNull` for instance), there are others (like `Callback`) where having two instances with different configurations could make sense. On the other hand, the validator certainly won't break if we repeat any of the constraints and all other ways to configure constraints allow repetition. This is why I decided to allow repetition for all constraints I've marked as attributes in this PR and propose to continue with that practice for all other constraints.
### Migration Path
This PR only migrates a handful of constraints. My plan is to discuss the general idea with this PR first and use it as a blueprint to migrate the individual constraints afterwards. Right now, the migration path would look like this:
* Attach the `#[Attribute]` attribute.
* Recreate all options of the constraint as constructor arguments.
* Add test cases for constructor calls with named arguments to the test class of the constraint's validator.
Commits
-------
d1cb2d6354 [Validator] Constraints as php 8 Attributes.
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Notifier] Add Dsn test case
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | - <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | - <!-- required for new features -->
<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.
Additionally (see https://symfony.com/releases):
- Always add tests and ensure they pass.
- Never break backward compatibility (see https://symfony.com/bc).
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too.)
- Features and deprecations must be submitted against branch master.
-->
Commits
-------
6a0510d859 Add Dsn test case
* 4.4:
Revert "bug #38063 [FrameworkBundle] generate preload.php in src/ to make opcache.preload predictable (nicolas-grekas)"
[PhpUnitBridge] Fix class_alias() for PHPUnit\Framework\Error\Error
This PR was merged into the 4.4 branch.
Discussion
----------
[PhpUnitBridge] Fixed class_alias() for PHPUnit\Framework\Error\Error
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | n/a
| License | MIT
| Doc PR | n/a
PHPUnit 6.x removed the PHPUnit_Framework_* classes in favor of PHP namespaces, but one error class did not map the same as the others: `PHPUnit_Framework_Error`.
Instead of mapping to `PHPUnit\Framework\Error` in the same way that `PHPUnit_Framework_Error_Warning` mapped to `PHPUnit\Framework\Error\Warning`, this base class was replaced with `PHPUnit\Framework\Error\Error`, so we cannot map it using simple string replacement like its descendants.
Commits
-------
8e607b58df [PhpUnitBridge] Fix class_alias() for PHPUnit\Framework\Error\Error
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Contracts] add TranslatableInterface
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | #38319
| License | MIT
| Doc PR | -
An alternative to #38328:
- `TranslatableInterface` is added to symfony/contracts;
- `Translatable`, still in the component, implements it (and is not final as it makes no sense for a value-object)
- the `t()` function is kept in the component - it doesn't fit in the contracts IMHO;
- `Translatable::trans()` is not static anymore;
- the domain is nullable instead of defaulting to "messages";
- the `t()` function moved in the `Symfony\Component\Translation` namespace (for reference, the `s()` function from String is also namespaced.);
- the Twig extension is made strictly polymorphic: if you pass a Translatable, you cannot pass arguments/domain/count.
Commits
-------
9224f7ac5b [Contracts] add TranslatableInterface
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[Validator] Add Ulid constraint and validator
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | Fix#38152
| License | MIT
ULID constraint and validator as mentioned in ticket #38103
I checked for it ulid specifications https://github.com/ulid/spec
Commits
-------
e36fd559da [Validator] Add Ulid constraint and validator
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Uid] make UUIDv6 always return truly random nodes to prevent leaking the MAC of the host
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
As explained in http://gh.peabody.io/uuidv6/, the wording of the UUIDv1 spec suggests that using the MAC of the host is preferred to compute the "node" field of UUIDs. This is what the uuid extension does, and the reason why the 12 last chars of the UUIDv1 it generates are stable. But this is a privacy leak. There are stories in the wild about how knowing the MAC has been abused in the past.
UUIDv6 prefers putting a secure random number there.
So here is the PR to do so.
Commits
-------
b9c61ca86c [Uid] make UUIDv6 always return truly random nodes to prevent leaking the MAC of the host
PHPUnit 6.x removed the PHPUnit_Framework_* classes in favor of PHP namespaces, but one error class did not map the same as the others: `PHPUnit_Framework_Error`.
Instead of mapping to `PHPUnit\Framework\Error` in the same way that `PHPUnit_Framework_Error_Warning` mapped to `PHPUnit\Framework\Error\Warning`, this base class was replaced with `PHPUnit\Framework\Error\Error`.
* 5.1:
[Filesystem] fix for PHP 8
[Cache] fix DBAL v3 compat
Bump Symfony version to 5.1.7
Update VERSION for 5.1.6
Update CHANGELOG for 5.1.6
Bump Symfony version to 4.4.15
Update VERSION for 4.4.14
Update CHANGELOG for 4.4.14
Bump Symfony version to 3.4.46
Update VERSION for 3.4.45
Update CONTRIBUTORS for 3.4.45
Update CHANGELOG for 3.4.45
* 4.4:
[Filesystem] fix for PHP 8
[Cache] fix DBAL v3 compat
Bump Symfony version to 4.4.15
Update VERSION for 4.4.14
Update CHANGELOG for 4.4.14
Bump Symfony version to 3.4.46
Update VERSION for 3.4.45
Update CONTRIBUTORS for 3.4.45
Update CHANGELOG for 3.4.45
* 5.1:
[ErrorHandler] Return false directly and remove unused variable
[OptionsResolver] Assert that the error type is valid in deprecations test
[OptionsResolver] Fix deprecation message access
[HttpClient] Allow bearer token with colon
[Form] Fix custom formats deprecation with HTML5 widgets
[Translator] Optional Intl dependency
[Contracts][Translation] Optional Intl dependency
[ErrorHandler] Escape JSON encoded log context
update missing translations arabic
[Yaml] simplify the test
fix test by letting mock throw the actual expected exception
* 4.4:
[ErrorHandler] Return false directly and remove unused variable
[OptionsResolver] Assert that the error type is valid in deprecations test
[HttpClient] Allow bearer token with colon
[Form] Fix custom formats deprecation with HTML5 widgets
[Translator] Optional Intl dependency
[Contracts][Translation] Optional Intl dependency
[ErrorHandler] Escape JSON encoded log context
update missing translations arabic
[Yaml] simplify the test
fix test by letting mock throw the actual expected exception
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[lock] Provides default implementation when store does not supports the behavior
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | yes
| Tickets | /
| License | MIT
| Doc PR | /
All stores does not provide the same behaviors. Some are blocking, some allows shared Locks, ...
Issue is: When people use `lock` to use a behavior that is not supported by the store, they get an `UnsuportedException`, but they don't have any way to know if the store supports or not the behavior they want to use.
ie: when using the FrameworkBundle
```yaml
framework:
lock: '%env(LOCK_DSN)%'
```
User (or bundle) can't use safely `$lock->acquire(true)` or `$lock->acquireRead()`.
Given it's very easy to provide an fallback implementation to those behavior, this PR
- use fallback implementation when store does not support the behavior
- deprecate the RetryTillSaveStore (not needed anymore)
Commits
-------
575b391b9b [lock] Provides default implementation when store does not supports the behavior
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Notifier] Add Sendinblue notifier.
| Q | A
| ------------- | ---
| Branch? | master <!-- see below -->
| Bug fix? | no
| New feature? | yes <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | no <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | todo <!-- required for new features -->
Add Sendinblue SMS notifier bridge.
Commits
-------
e7300a8580 Add Sendinblue notifier.
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Messenger] Fix misleading comment about time-limit
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | n/a
| License | MIT
| Doc PR | n/a
The current explanation of the time-limit option of the `messenger:consume` command is misleading as it lets you think that this is an enforced hard limit.
For instance, you may think that a command started with `--time-limit=10` will stop once 10 seconds are elapsed, no matter what.
Actually, two things happen:
- Once 10 seconds have elapsed, then the worker won't receive and handle any other message
- The worker will keep running until the currently handled message is fully handled so it can last way longer than 10 seconds, then it will stop.
I'm not sure this is behavior is actually a bug or not, but the current documentation does not describe the current behavior
Commits
-------
21176646e9 [Messenger] Fix misleading comment about time-limit
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Translation] Allow Translatable objects to be used as strings
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Allow Translatable objects to be used as strings.
Commits
-------
0ba206420e [Translation] Allow Translatable objects to be used as strings
This PR was merged into the 5.2-dev branch.
Discussion
----------
[DomCrawler] Add checkbox assertions for functional tests
| Q | A
| ------------- | ---
| Branch? | master for features
| Bug fix? | no
| New feature? | yes <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets |
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
Add new assertions for checkboxes, to use in functional tests.
Example:
```php
public function testAssertCheckboxChecked()
{
$this->visit('/edit-form');
$this->client->submitForm('Save', [
'activateMembership' => 'on',
]);
self::assertResponseIsSuccessful();
// Check that the field is checked after the form was submitted
self::assertCheckboxChecked('activateMembership');
}
```
This wasn't possible to achieve with the existing `self::assertInputValueSame()` assertion.
Commits
-------
f26758e1c0 [DomCrawler] Add `assertCheckboxChecked()`
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[Validator] Add invalid datetime message in Range validator
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
When the validated value is invalid (it isn't a number nor a datetime), but `min` or `max` option indicate that the `Range` constraint is being used to validate a datetime, the displayed message will be `This value should be a valid datetime` instead of `This value should be a valid number`. This PR replaces #35998.
Commits
-------
c77730699e [Validator] Add invalid datetime message in Range validator
This PR was merged into the 5.2-dev branch.
Discussion
----------
[HttpKernel] Auto-register kernel as an extension
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Symfony already supports having the kernel as an extension. This is evident by the fact that the [`config:dump-reference` and `debug:config`](https://github.com/symfony/symfony/pull/36186) commands check whether the kernel implements the `ExtensionInterface`. Nonetheless, it's still required to register the kernel manually as an extension.
With this PR the kernel will be automatically registered as an extension if it implements the `ExtensionInterface`. This is the same logic as when the kernel implements the `CompilerPassInterface`.
Commits
-------
9c34980869 Auto-register kernel as an extension
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[Mailer] Added Sendinblue bridge
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| License | MIT
| Doc PR | [https://github.com/symfony/symfony-docs/pull/14272](https://github.com/symfony/symfony-docs/pull/14272)
| Recipe | [https://github.com/symfony/recipes/pull/822](https://github.com/symfony/recipes/pull/822)
<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.
Additionally (see https://symfony.com/releases):
- Always add tests and ensure they pass.
- Never break backward compatibility (see https://symfony.com/bc).
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too.)
- Features and deprecations must be submitted against branch master.
-->
N.B. I had a little help from [Pierre TONDEREAU](https://github.com/ptondereau) for the API.
Commits
-------
836a20350b [Mailer] Added Sendinblue bridge
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Form] Added "html5" option to both MoneyType and PercentType
| Q | A
| ------------- | ---
| Branch? | master for features
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | TBD
Hello,
In the same way that [NumberType](https://symfony.com/doc/current/reference/forms/types/number.html) offers a `html5` option to render a `number` input instead of a `text` input, this PR adds the same option to both `MoneyType` and `PercentType`. Number inputs offer a better UI, especially on mobile (specific keyboard), and they accept extra HTML attributes, such as `max=100`, which are quite useful.
The challenge is that `number` inputs need a "raw" value, nor formatted nor localized.
Format is described here https://www.w3.org/TR/html51/sec-forms.html#date-time-and-number-formats (non-normative, but tested on a few browsers). It matches number formatting for `en` locale (which is great, since it is the one provided by Symfony Intl polyflil), without grouping.
Implementation was done in a manner similar to `NumberType` for `MoneyType`.
`PercentType` required to modify `PercentToLocalizedStringTransformer` too.
As a bonus, `PercentType` had no tests at all, I added a few.
I wanted to get some feedback on the idea first, remaining steps:
- update `CHANGELOG.md`
- update the doc
Commits
-------
f7312a48ea [Form] Added "html5" option to both MoneyType and PercentType
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[HttpClient] Allow bearer token with colon
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | n/a
| License | MIT
| Doc PR | n/a
The JetBrains Hub (YouTrack API) creates tokens with a `perm:` prefix. This doesn't work right now, because HttpClient doesn't allow a colon in the bearer token.
As far as I can see, there is no reason to disallow the use of the semicolon in the bearer token, so this PR fixes it.
Example of a token: `perm:c3RlcGhhbg==.NTUtMw==.NiZw16agafhsQAShTvclhb78hyJh2H`
Commits
-------
82ed1ec20a [HttpClient] Allow bearer token with colon
This PR was merged into the 4.4 branch.
Discussion
----------
[Form] Fix custom formats deprecation with HTML5 widgets
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | https://github.com/symfony/symfony/issues/37698
| License | MIT
| Doc PR | -
1. The options resolver only show the deprecations for user defined (overidden) options.
2. The default value of the `html5` option is enough to pass the logical condition of the callback.
That means that only setting the `format` option (like in the reproducer) does not trigger the deprecation while it should. I think we need a feature in the options resolver component to handle those kind of cases 🤷♂️
Meanwhile, we can fix the issue by "deprecating" all the concerned options of the logical condition of the callback.
Commits
-------
d28182f99b [Form] Fix custom formats deprecation with HTML5 widgets
This PR was merged into the 5.2-dev branch.
Discussion
----------
Always require SQL comment hint
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
The `GuidType` does not always return true, because it is mapped to the native uuid type if available. But `AbstractBinaryUidType` and `AbstractUidType` are not mapped like that, so they always requires the comment hint to avoid issues when diffing the schema (the DB introspection would detect a `GuidType` and so a change would be needed).
Commits
-------
33e78b43a4 Always require SQL comment hint
This PR was merged into the 4.4 branch.
Discussion
----------
[Contracts][Translation] Optional Intl dependency
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
same as #38283, and should help streamlining #38230
Commits
-------
d65d39da14 [Contracts][Translation] Optional Intl dependency
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[Translator] Optional Intl dependency
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38279
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.
Additionally (see https://symfony.com/releases):
- Always add tests and ensure they pass.
- Never break backward compatibility (see https://symfony.com/bc).
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too.)
- Features and deprecations must be submitted against branch master.
-->
i decided to cast $locale at construct, given its property is documented to be string
Commits
-------
a2eb263457 [Translator] Optional Intl dependency
This PR was merged into the 4.4 branch.
Discussion
----------
[ErrorHandler] Escape JSON encoded log context
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | eno <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
Fixes https://github.com/symfony/symfony/issues/35569#issuecomment-581317792
Fixes https://github.com/symfony/symfony/issues/35569#issuecomment-696767559
The initial issue remains though (the webprofiler showing the logs tab in the exception panel), i'll try to give it another look sometime, but this is a quick win nevertheless.
cc @yceruto
Commits
-------
5572a68ed7 [ErrorHandler] Escape JSON encoded log context
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Config] Adding the "info" to a missing option error messages
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | None
| License | MIT
| Doc PR | Not needed
New error:
<img width="1063" alt="Screen Shot 2020-09-13 at 10 51 32 AM" src="https://user-images.githubusercontent.com/121003/93021186-6329ff00-f5af-11ea-83c6-98581b12ef75.png">
I used the missing `class` just as an example. I hit this while building a new feature in Symfony. It occurred to me that if, for example, you activate some feature in config and that feature has a required sub-key, why not print the `info()` for that sub key to make it discoverable?
Commits
-------
3780f122c7 adding the description to a missing option
This PR was merged into the 5.2-dev branch.
Discussion
----------
Return AbstractUid as string
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
Should return AbstractUidType as string.
Commits
-------
1a9d76a869 Return AbstractUid as string
This PR was merged into the 5.2-dev branch.
Discussion
----------
replace expectExceptionMessageRegExp() with expectExceptionMessageMat…
…ches()
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
Commits
-------
593a94c932 replace expectExceptionMessageRegExp() with expectExceptionMessageMatches()
* 5.1: (25 commits)
stop using the deprecated at() PHPUnit matcher
fix lowest allowed version of the HTTP client contracts
fix lowest allowed version for the PHPUnit bridge
fix merge
fix merge
drop logger mock in favor of using the BufferingLogger
catch ValueError thrown on PHP 8
[Yaml Parser] Fix edge cases when parsing multiple documents
fix parsing comments not prefixed by a space
[Translator] Make sure a null locale is handled properly
deal with errors being thrown on PHP 8
loadRoutes shoud receive RoutingPhpFileLoader
[Cache] Allow cache tags to be objects implementing __toString()
[HttpKernel] Do not override max_redirects option in HttpClientKernel
Log notice when no entry point is configured
remove superfluous cast
[HttpClient] Support for CURLOPT_LOCALPORT.
Upgrade PHPUnit to 8.5 (php 7.2) and 9.3 (php >= 7.3).
Fixed exception message formatting
[FrameworkBundle] Fix error in xsd which prevent to register more than one metadata
...
This PR was merged into the 5.1 branch.
Discussion
----------
[Validator] stop using the deprecated at() PHPUnit matcher
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
Commits
-------
0d0f92b7c6 stop using the deprecated at() PHPUnit matcher
This PR was merged into the 5.1 branch.
Discussion
----------
[HttpClient] fix lowest allowed version of the HTTP client contracts
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
fixes `deps=low` builds for the HttpClient component by making sure that the installed version of the HTTP client contracts package contains the changes from #37831
Commits
-------
edca581889 fix lowest allowed version of the HTTP client contracts
* 4.4:
fix merge
drop logger mock in favor of using the BufferingLogger
catch ValueError thrown on PHP 8
[Yaml Parser] Fix edge cases when parsing multiple documents
fix parsing comments not prefixed by a space
[Translator] Make sure a null locale is handled properly
deal with errors being thrown on PHP 8
[Cache] Allow cache tags to be objects implementing __toString()
[HttpKernel] Do not override max_redirects option in HttpClientKernel
remove superfluous cast
[HttpClient] Support for CURLOPT_LOCALPORT.
Upgrade PHPUnit to 8.5 (php 7.2) and 9.3 (php >= 7.3).
Fixed exception message formatting
[FrameworkBundle] Fix error in xsd which prevent to register more than one metadata
[Console] work around disabled putenv()
[PhpUnitBridge] Fix error with ReflectionClass
[HttpClient][HttpClientTrait] don't calculate alternatives if option is auth_ntlm
Change 'cache_key' to AbstractRendererEngine::CACHE_KEY_VAR
Upgrade PHPUnit to 8.5 (php 7.2) and 9.3 (php >= 7.3).
* 3.4:
drop logger mock in favor of using the BufferingLogger
[Yaml Parser] Fix edge cases when parsing multiple documents
fix parsing comments not prefixed by a space
This PR was merged into the 4.4 branch.
Discussion
----------
[Validator] catch ValueError thrown on PHP 8
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
see php/php-src@95f4ee38bb
Commits
-------
fb0d7beaaf catch ValueError thrown on PHP 8
This PR was merged into the 3.4 branch.
Discussion
----------
[Yaml Parser] Fix edge cases when parsing multiple documents
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
I identified some edge cases when parsing multiple YAML documents with the same parser instance, because the totalNumberOfLines was not reset and so any subsequent parsing considered the number of lines of the first document.
Consider this document:
```yaml
a:
b: |
row
row2
c: d
```
Normally, `a.b` would be parsed as `row\nrow2\n`. But if the parser parsed a shorter document before, the `\n` after row2 was missing, as the parser considered it as the end of the file (that's why the `c: d` at the end is important).
So this fix resets the `totalNumberOfLines` in the YAML parser to `null` so that any subsequent parsing will initialize the value for the new document and does not use the file length of the first parsed document.
I stumbled upon this because of a flickering unit test that was using the translation component. Sometimes the translated string contained a trailing `\n` and sometimes not. In the end it was based on this bug, as the translation files were not loaded in the same order every time (not really sure why. It's somehow related to the cache state, but even with a warm cache it was not totally deterministic).
Commits
-------
012ee4fa59 [Yaml Parser] Fix edge cases when parsing multiple documents
This PR was merged into the 3.4 branch.
Discussion
----------
[Yaml] fix parsing comments not prefixed by a space
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38223
| License | MIT
| Doc PR |
Commits
-------
35b223aaa4 fix parsing comments not prefixed by a space
This PR was merged into the 5.2-dev branch.
Discussion
----------
[MonologBridge] Use composition instead of inheritance in monolog bridge
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| Deprecations? | yes <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets |
| License | MIT
| Doc PR |
In order to allow better customization in monolog activation strategy, this PR introduce composition instead of inheritance for these 2 classes :
- HttpCodeActivationStrategy
- NotFoundActivationStrategy
Commits
-------
0fb14394ca Use composition instead of inheritance in HttpCodeActivationStrategy
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[Translator] Make sure a null locale is handled properly
| Q | A
| ------------- | ---
| Branch? | 4.4<!-- see below -->
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | Fix#38124 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | - <!-- required for new features -->
<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.
Additionally (see https://symfony.com/releases):
- Always add tests and ensure they pass.
- Never break backward compatibility (see https://symfony.com/bc).
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too.)
- Features and deprecations must be submitted against branch master.
-->
Commits
-------
080ea5a0f7 [Translator] Make sure a null locale is handled properly
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[Cache] Allow cache tags to be objects implementing __toString()
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | maybe
| New feature? | maybe
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
`\Symfony\Contracts\Cache\CacheInterface::get(string $key, …)` implicitly converts objects with `__toString` while `CacheItem::tag()` will throw an exception. That’s a bit of a sharp edge.
Commits
-------
c2c03e050f [Cache] Allow cache tags to be objects implementing __toString()
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[HttpKernel] Do not override max_redirects option in HttpClientKernel
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38207
| License | MIT
| Doc PR | -
As [proposed](https://github.com/symfony/symfony/issues/38207#issuecomment-693382336) by @nicolas-grekas this pull request removes the `max_redirects` setting in the `\Symfony\Component\HttpKernel\HttpClientKernel::handle` method.
It solves the issue that requests made by the `\Symfony\Component\HttpClient\CachingHttpClient` wouldn't follow redirects as described in the linked issue.
Commits
-------
981a11beed [HttpKernel] Do not override max_redirects option in HttpClientKernel
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[HttpClient] Added RetryHttpClient
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | TODO
This PR adds a new HttpClient decorator to automatically retry failed requests.
When calling API, A very small % of requests are expected to timeout due to transient network issues. Some providers like AWS recommends retrying these requests and use a lower connection timeout so that the clients can fail fast and retry.
I used the almost the same configuration as Messenger
```yaml
framework:
http_client:
default_options:
retry_failed:
enabled: true // default false
decider_service: null
backoff_service: null
http_codes: [423, 425, 429, 500, 502, 503, 504, 507, 510]
max_retries: 3
delay: 1000
multiplier: 2
max_delay: 0
response_header: true
scoped_clients:
github:
scope: 'https://api\.github\.com'
retry_failed:
max_delay: 2000
```
Commits
-------
712ac5999d [HttpClient] Added RetryHttpClient
This PR was merged into the 4.4 branch.
Discussion
----------
[HttpClient] Support for CURLOPT_LOCALPORT
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | https://github.com/symfony/symfony/issues/38081#issuecomment-688166943
| License | MIT
| Doc PR | N/A
Commits
-------
45fa6b8f24 [HttpClient] Support for CURLOPT_LOCALPORT.
This PR was merged into the 4.4 branch.
Discussion
----------
Upgrade PHPUnit to 8.5 (php 7.2) and 9.3 (php >= 7.3)
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | #37564
| License | MIT
| Doc PR | N/A
This is #38103 on the 4.4 branch.
Commits
-------
73647e5ffe Upgrade PHPUnit to 8.5 (php 7.2) and 9.3 (php >= 7.3).
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Amqp] Add amqps support
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | Fix#37002
| License | MIT
| Doc PR | symfony/symfony-docs#... TODO <!-- required for new features -->
### Cases
_Case 1 (simple):_
I want to set up my app with a locally installed amqp broker supporting SSL. No auth is needed, no vhost, only SSL certificate file located at /etc/ssl/cafile.
'amqps://'
_Case 2 (complex):_
I use a special port, special file locations for SSL. I pass it through php.ini or configuration.
### Questions
1) Actually AmqpTransportFactory use `supports` function to see if 'amqp://' is contained in dsn string and accept cacert argument to use SSL
How are we supposed to cover AMQPS's case in your opinion?
cacert argument is settable through php.ini and code.
### Observations
I think this PR should aim at:
- Having correct defaults ssl values in case of 'amqps://' eg : case 1
- Being able to pass cacert file path and verify argument. eg : case 2
- Test: but test what?
#### EDIT
As discuted with @nicolas-grekas, we should check that cacert is existing in php.ini or is passed in configuration and throw an exception to give a nice feedback about what's wrong. Php amqp lib isn't actually precise about why it fails when you forget it.
### Steps
- [x] Ensure AMQPS can be used out of the box without DSN.
- [x] If not, try to modify vendor directly to fix it.
- [x] Modify vendor to make AMQPS works with DSN.
- [x] Check cacert to throw a better exception.
- [x] Add test related to last point.
- [ ] Pass CI
Commits
-------
99fc3f3b89 [Amqp] Add amqps support
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[RFC] Introduce a RateLimiter component
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | Refs #37444
| License | MIT
| Doc PR | tbd
Based on the discussions in #37444, I decided to write a general purpose RateLimiter component. This implementation uses the token bucket algorithm, inspired by the [Go's time/rate](3af7569d3a/rate/rate.go) library and the [PHP `bandwidth-throttle/token-bucket` package](https://github.com/bandwidth-throttle/token-bucket) (which is [unmaintained for years](https://github.com/bandwidth-throttle/token-bucket/issues/19)).
### Usage
The component has two main methods:
* `Limiter::reserve(int $tokens, int $maxTime)`, allocates `$tokens` and returns a `Reservation` containing the wait time. Use this method if your process wants to wait before consuming the token.
* `Limiter::consume(int $tokens)`, checks if `$tokens` are available now and discards the reservation if that's not the case. Use this method if you want to skip when there are not enough tokens at this moment.
The component uses the Lock component to make sure it can be used in parallel processes.
Example:
```php
<?php
namespace App\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\RateLimiter\LimiterFactory;
class LimitListener
{
private $limiterFactory;
public function __construct(LimiterFactory $apiLimiterFactory)
{
$this->limiterFactory = $apiLimiterFactory;
}
public function __invoke(RequestEvent $event)
{
$ip = $event->getRequest()->getClientIp();
$limiter = $this->limiterFactory->createLimiter(preg_replace('/[^a-zA-Z0-9]/', '-', $ip));
if (!$limiter->consume()) {
$event->setResponse(new Response('Too many requests', 429));
}
}
}
```
### Usefullness of the component
I think a generic rate limiter is usefull in quite some places:
* Add a login throttling feature in Symfony
* <s>Rate limiting outgoing API calls (e.g. HttpClient), to prevent hitting upstream API limits.</s> See #37471 (and https://blog.heroku.com/rate-throttle-api-client )
* Allowing users to easily implement API rate limits in their own Symfony-based APIs.
### State of the art
There are some rate limiting packages in PHP, but I think there is no precendent for this component:
* [`graham-campbell/throttle`](https://github.com/GrahamCampbell/Laravel-Throttle) is heavily relying on Laravel. It is however very popular, proofing there is a need for such feature
* [`nikolaposa/rate-limit`](https://github.com/nikolaposa/rate-limit) does not implement reservation of tokens and as such less feature complete. Also its architecture combines the rate limiter and storage, making it harder to implement different storages.
### Todo
If it is agreed that this component can bring something to Symfony, it needs some more love:
* [x] Add more tests
* [x] Integrate with the FrameworkBundle
* [x] Add sliding window implementation
* [x] Add integration with the Security component
* <s>Maybe add more storage implementations? I didn't want to duplicate storage functionalities already existing in the Lock and Cache component, thus I for now focused mostly on integrating the Cache adapters. But maybe a special Doctrine adapter makes sense?</s>
Commits
-------
67417a693e [RFC] Introduce a RateLimiter component
This PR was merged into the 5.2-dev branch.
Discussion
----------
Make RetryTillSaveStore implements the SharedLockStoreInterface
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | /
The `RetryTillSaveStore` decorates a non blocking store (ie. `RedisStore`) to make it blockable.
The issue is: if the decorate store manage SharedLock, the Decorator does not implements this interface. It's currently not possible to get both `blocking` and `sharable` store.
Commits
-------
a0321e66c9 Make RetryTillSaveStore implements the SharedLockStoreInterface
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Form] Add new way of mapping data using callback functions
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | yes
| Tickets | Fix#37597 (partially)
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/14241
Replaces https://github.com/symfony/symfony/pull/37614
## What this solves
Objects and Forms have different mechanisms for structuring data. When you build an object model with a lot of business logic it's valuable to use these mechanisms to better collect the data and the behavior that goes with it. Doing so leads to variant schemas; that is, the object model schema and the form schema don't match up.
You still need to transfer data between the two schemas, and this data transfer becomes a complexity in its own right. If the objects know about the form structure, changes in one tend to ripple to the other.
Currently, the Data Mapper layer separates the objects from the form, transfering data between the two and also isolating them from each other. That's fine, but at present the default data mapper has a limitation: _it's very tied to one property path_ (see [`PropertyPathMapper`](https://github.com/symfony/symfony/blob/5.1/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php)).
That said, you'll have to write your own data mapper in the following situations:
* When the property path differs for reading and writing
* When several form fields are mapped to a single method
* When you need to read data based on the model's state
* When the mapping of the model depends on the submitted form data
* ...
Also, when we create a new data mapper, we usually forget about checking the status of the given data and forms. Whether the data is empty or not; throw an exception if the given data is not an object/array and whether the form field is submitted/synchronized/disabled or not. Not doing that could lead to unwanted behavior.
## What this proposes
Create a new way to write and read values to/from an object/array using callback functions. This feature would be tied to each form field and would also mean a new way of mapping data, but a very convenient one, in which it won't be necessary to define a new data mapper and take into account all what it would imply when you only need to map one field in a different manner or perhaps in only one direction (writing or reading the value).
This PR adds two new options for each form type: `getter` and `setter`, allowed to be `null` or `callable`:
```php
$builder->add('name', TextType::class, [
'getter' => function (Person $person, FormInterface $form): string {
return $person->firstName().' '.$person->lastName();
},
'setter' => function (Person &$person, ?string $name, FormInterface $form): void {
$person->rename($name);
},
]);
```
This would give us the same possibilities as data mappers, but within the form field scope, where:
* `$person` is the view data, basically the underlying data to the form.
* `$form` is the current child form that is being mapped.
* `$name` is the submitted data that belongs to that field.
These two callbacks will be executed following the same rules as for property paths before read and write any value (e.i. early return if empty data, skip mapping if the form field is not mapped or it's disabled, etc).
## What this also proposes
I based the implementation on solving this problem first:
> https://github.com/symfony/symfony/pull/37614#issuecomment-662957865
> [...] the property_path option defines the rules on how it's accessed. From there, the actual way it is accessed (direct property access, accessors, reflection, whatever) are hidden from view. All that matters is the property path (which is deduced from the name if not explicitly set). [...]
So splitting the default data mapper `PropertyPathMapper` into two artifacts: "[DataMapper](https://github.com/yceruto/symfony/blob/data_accessor/src/Symfony/Component/Form/Extension/Core/DataMapper/DataMapper.php)" and "[DataAccessor](https://github.com/yceruto/symfony/blob/data_accessor/src/Symfony/Component/Form/DataAccessorInterface.php)" would allow us adding multiple data accessors along the way (the code that varies in this case) without having to reinvent the wheel over and over again (the data mapper code).
You can also think about a new `ReflectionAccessor` for instance? or use this `CallbackAccessor` to map your form partially from an external API? yes, you could do it :)
Here is a view of the proposed changes:
![data_accessor](https://user-images.githubusercontent.com/2028198/91452859-16bf8f00-e84d-11ea-8564-d497c2f73730.png)
Where "DataMapper" will take care of common checks, iterates the given child forms, manages the form data and all what is needed for mapping a standard form, whereas "DataAccessor" will take care of how to read and write values to/from the underlying object or array.
## BC
The `PropertyPathMapper` is being deprecated in favor of `DataMapper` class, which uses the `PropertyPathAccessor` by default.
Although `DataMapper` is now the default for each compound form, the behavior must remains the same (tests prove it). So that if `getter` or `setter` option is null (they're by default) the `CallbackAccessor` will falls back to `PropertyPathAccessor` either for reading or writing values.
---
Sorry for the long description, but I think that sometimes it is necessary for too complex issues and big changes. Besides, now you know a little more about what these changes is about.
/cc @xabbuh as creator of [rich-model-forms-bundle](https://github.com/sensiolabs-de/rich-model-forms-bundle) and @alcaeus as you had worked on this issue.
WDYT?
Commits
-------
878effaf47 add new way of mapping data using callback functions
This PR was merged into the 4.4 branch.
Discussion
----------
[Console] work around disabled putenv()
If this is set to true, then putenv functions simply won't be run in this script, making this function usable on servers, where putenv is disabled
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | yes <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
Commits
-------
d3f909bff3 [Console] work around disabled putenv()
This PR was merged into the 5.1 branch.
Discussion
----------
[Notifier] Fix errors parsing in FirebaseTransport
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | /
I noticed that, when parsing the response, this transport use `getHeader()` like a `string[]` instead of `string[][]`.
I did not test it and I'm not sure about this fix: could you have a look @Jeroeny ?
Commits
-------
2818e2cd43 Fix errors parsing in FirebaseTransport
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[HttpClient][HttpClientTrait] don't calculate alternatives if option is auth_ntlm
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | no
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
If option is `auth_ntlm` an exception is thrown, `$alternatives` then is not used.
Commits
-------
ab1a96c999 [HttpClient][HttpClientTrait] don't calculate alternatives if option is auth_ntlm
The purpose of this change is to find all usages of AbstractRendererEngine::CACHE_KEY_VAR. Currently, if you search for AbstractRendererEngine::CACHE_KEY_VAR you will see only access to it, i.e. (`$view->vars[AbstractRendererEngine::CACHE_KEY_VAR]`), but you can't find it in write level. With this pull request you can see where is was used for write.
* 5.1:
Internal classes are not legacy.
[HttpFoundation] Skip the cookie_max_age fixture on PHP 8.
add choice_translation_domain tests to prevent further regressions
Update validators.tr.xlf
* 4.4:
Internal classes are not legacy.
[HttpFoundation] Skip the cookie_max_age fixture on PHP 8.
add choice_translation_domain tests to prevent further regressions
Update validators.tr.xlf
* 3.4:
[HttpFoundation] Skip the cookie_max_age fixture on PHP 8.
add choice_translation_domain tests to prevent further regressions
Update validators.tr.xlf
This PR was merged into the 3.4 branch.
Discussion
----------
[DoctrineBridge] add choice_translation_domain tests to prevent further regressions
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | Fix #https://github.com/symfony/symfony/pull/37521#issuecomment-678247192
| License | MIT
| Doc PR |
Commits
-------
7775b3707b add choice_translation_domain tests to prevent further regressions
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Messenger] - Add option to confirm message delivery in Amqp connection
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Hello! My first PR here.
Sometimes we need to be sure that messages are delivered to Amqp. To make it work we need to wait for the confirmation from the Amqp server. So let's wait for it confirmation if confirmation timeout is defined. Default behaviour are not modified - waiting for confirmation will impact performance of sending message.
Commits
-------
5682d76b2a Messenger - Add option to confirm message delivery in Amqp connection
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Cache] add integration with Messenger to allow computing cached values in a worker
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
~~This PR needs and for now embeds #30334. See 2nd commit.~~
Using the new `CacheInterface` enables probabilistic early expiration by default. This means that from time to time, items are elected as early-expired while they are still fresh ([see Wikipedia](https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration) for details).
This PR adds a new `early_expiration_message_bus` option when configuring cache pools. When this option is set, cache pools are configured to send those early-expired items on a Messenger bus, then serve the current value immediately, while the updated value is computed in a worker in the background.
`CacheInterface::get($key, $callback)` accepts any callable, but sending any callable on a bus is not possible (e.g. a `Closure` cannot be serialized). To bypass this constraint, this feature works only with callables in the form `[$service, 'publicMethod']`, where `$service` is any public or [reversible service](https://github.com/symfony/symfony/pull/30334).
This constraint is a serious one: this $service must compute a value when knowing only its key. This means keys should embed enough information for this to happen. I think that's not that hard - and we may find ways to provide additional context in the future.
At least the goal is worth it: in theory, this strategy allows achieving a 100% hit ratio even when invalidation-by-expiration is used.
There are two things one needs to do to enable this behavior:
1. bind a message bus to a cache pool:
```yaml
framework:
cache:
pools:
test.cache:
early_expiration_message_bus: messenger.default_bus
```
2. route EarlyExpirationMessage to a transport:
```yaml
framework:
messenger:
routing:
'Symfony\Component\Cache\Messenger\EarlyExpirationMessage': amqp
```
Commits
-------
6c0911f58c [Cache] add integration with Messenger to allow computing cached values in a worker
This PR was squashed before being merged into the 5.2-dev branch.
Discussion
----------
[SecurityBundle] Comma separated ips for security.access_control
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/14219
There is currently no way to use env vars to configure `security.access_control` ips with multiple values. Ability to use comma separated ips make it able.
Commits
-------
0412e91060 [SecurityBundle] Comma separated ips for security.access_control
* 5.1:
fix merge
[Cache] fix previous PR
add mising sr (latn & cyrl) translations
[Cache] fix ProxyAdapter not persisting items with infinite expiration
[HttpClient] fail properly when the server replies with HTTP/0.9
Fix CS
[Cache] Limit cache version character range
[Mailer] Fixed Mailgun API bridge JsonException when API response is not applicaton/json
[String] improve fix
fix tests
[DI] dump OS-indepent paths in the compiled container
[DI] dump OS-indepent paths in the preload file
Run postgres setup trigger in transaction
allow consumers to mock all methods
* 4.4:
add mising sr (latn & cyrl) translations
[Cache] fix ProxyAdapter not persisting items with infinite expiration
[HttpClient] fail properly when the server replies with HTTP/0.9
Fix CS
[Cache] Limit cache version character range
[DI] dump OS-indepent paths in the compiled container
allow consumers to mock all methods
This PR was merged into the 4.4 branch.
Discussion
----------
[HttpClient] fail properly when the server replies with HTTP/0.9
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | Fix#37923
| License | MIT
| Doc PR | -
Commits
-------
96759af1da [HttpClient] fail properly when the server replies with HTTP/0.9
This PR was merged into the 5.2-dev branch.
Discussion
----------
Move form error normalizer to the Serializer component
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | n/a<!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | n/a
Commits
-------
c053db5553 Move form error normalizer to the Serializer component
This PR was merged into the 5.1 branch.
Discussion
----------
[DI] dump OS-indepent paths in the preload file
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38123
| License | MIT
| Doc PR | -
This allows generating the file on Windows and running it on Linux (Docker).
Commits
-------
e8feba5c36 [DI] dump OS-indepent paths in the preload file
This PR was merged into the 4.4 branch.
Discussion
----------
[DI] dump OS-indepent paths in the compiled container
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38123
| License | MIT
| Doc PR | -
This allows compiling on Windows and running on Linux (Docker).
Commits
-------
4dcf9e7d13 [DI] dump OS-indepent paths in the compiled container
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Messenger] Added factory methods to DelayStamp for better DX
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR | not necessary imho
I often find myself delaying messages for a few minutes or so and I always have to remember the `DelayStamp` uses milliseconds. I guess these simple factories could improve DX quite a bit :)
Commits
-------
fdc8da0aaa [Messenger] Added factory methods to DelayStamp for better DX
This PR was merged into the 5.2-dev branch.
Discussion
----------
[Lock] Fix wrong interface for MongoDbStore
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | /
The MongoDbStore is not a `BlockingStore` because does not "really" implements the method `waitAndSave`.
This PR changes the interface of `MongoDbStore` and remove the dummy implementation of `waitAndSave`.
Commits
-------
4c2d32ce11 Fix wrong interface for MongoDbStore
This PR was merged into the 5.1 branch.
Discussion
----------
[Mailer] Fixed Mailgun API bridge JsonException when API response is not applicaton/json
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix#38146
| License | MIT
| Doc PR | -
Handles gracefully cases in which the Mailgun API does not return JSON responses.
Commits
-------
ce8f7e5c02 [Mailer] Fixed Mailgun API bridge JsonException when API response is not applicaton/json
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[Cache] Limit cache version character range
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | n.A.
| License | MIT
| Doc PR |
Follow up for https://github.com/symfony/symfony/pull/38108
With current HEAD in 4.4, this will fail eventually: `simple-phpunit --repeat 1000 --stop-on-failure --filter "testGetMultiple$" src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTextModeTest.php`
After this PR it will no longer fail
@nicolas-grekas
Commits
-------
15c21db856 [Cache] Limit cache version character range
This PR was merged into the 5.1 branch.
Discussion
----------
[String] improve fix
| Q | A
| ------------- | ---
| Branch? | 5.1
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Improves https://github.com/symfony/symfony/pull/38128
(let's wait for the CI before merging)
Commits
-------
db4b1df062 [String] improve fix
This PR was merged into the 5.1 branch.
Discussion
----------
[Messenger] Run postgres setup trigger in transaction
| Q | A
| ------------- | ---
| Branch? | 5.1 <!-- see below -->
| Bug fix? | yes
| New feature? | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets | Fix#37179 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License | MIT
| Doc PR | n/a <!-- required for new features -->
This PR fix `messenger:setup-transports` command when using with ` doctrine/doctrine-bundle` version >= 2.1
Commits
-------
7ed93b4dc0 Run postgres setup trigger in transaction
This PR was merged into the 5.2-dev branch.
Discussion
----------
[AmazonSqsMessenger] Added the count message awareness on the transport
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | /
| License | MIT
| Doc PR | /
Added the possibility of have message count awareness of the receiver on the transport.
Commits
-------
96b63b83bf [AmazonSqsMessenger] Added the count message awareness on the transport