From dcda2c44ab7cc5c9ecccb5b333dabb9faef5a4b9 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 29 Nov 2024 09:36:44 +0100 Subject: [PATCH 01/28] Update CHANGELOG for 5.4.49 --- CHANGELOG-5.4.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG-5.4.md b/CHANGELOG-5.4.md index 23768a799ed86..8929969db1276 100644 --- a/CHANGELOG-5.4.md +++ b/CHANGELOG-5.4.md @@ -7,6 +7,10 @@ in 5.4 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.4.0...v5.4.1 +* 5.4.49 (2024-11-29) + + * bug #59023 [HttpClient] Fix streaming and redirecting with NoPrivateNetworkHttpClient (nicolas-grekas) + * 5.4.48 (2024-11-27) * bug #59013 [HttpClient] Fix checking for private IPs before connecting (nicolas-grekas) From 23f75d33d284dd755d502b4f5cfbfe9f1398ceb4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 29 Nov 2024 09:36:48 +0100 Subject: [PATCH 02/28] Update VERSION for 5.4.49 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index a6a70bfb3cb4d..10a65d1393f36 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -78,12 +78,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ private static $freshCache = []; - public const VERSION = '5.4.49-DEV'; + public const VERSION = '5.4.49'; public const VERSION_ID = 50449; public const MAJOR_VERSION = 5; public const MINOR_VERSION = 4; public const RELEASE_VERSION = 49; - public const EXTRA_VERSION = 'DEV'; + public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '11/2024'; public const END_OF_LIFE = '02/2029'; From 273fa3fffcabe6d740b67966be8289f078afe0a0 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 29 Nov 2024 09:45:53 +0100 Subject: [PATCH 03/28] Bump Symfony version to 7.2.1 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index f37b506b2202c..65162adf1996f 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,12 +73,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ private static array $freshCache = []; - public const VERSION = '7.2.0'; - public const VERSION_ID = 70200; + public const VERSION = '7.2.1-DEV'; + public const VERSION_ID = 70201; public const MAJOR_VERSION = 7; public const MINOR_VERSION = 2; - public const RELEASE_VERSION = 0; - public const EXTRA_VERSION = ''; + public const RELEASE_VERSION = 1; + public const EXTRA_VERSION = 'DEV'; public const END_OF_MAINTENANCE = '07/2025'; public const END_OF_LIFE = '07/2025'; From ac4ca4616bf0dd18eb35d1b79b3a11a947d694e6 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 2 Dec 2024 07:48:00 +0100 Subject: [PATCH 04/28] fix Twig 3.17 compatibility --- .../Node/SearchAndRenderBlockNodeTest.php | 88 +++++++++++-------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php index 5c2bacf19d5f8..47ec58acb36cb 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php @@ -22,6 +22,7 @@ use Twig\Node\Expression\ConditionalExpression; use Twig\Node\Expression\ConstantExpression; use Twig\Node\Expression\NameExpression; +use Twig\Node\Expression\Ternary\ConditionalTernary; use Twig\Node\Expression\Variable\ContextVariable; use Twig\Node\Node; use Twig\Node\Nodes; @@ -308,32 +309,32 @@ public function testCompileLabelWithLabelAndAttributes() public function testCompileLabelWithLabelThatEvaluatesToNull() { + if (class_exists(ConditionalTernary::class)) { + $conditional = new ConditionalTernary( + // if + new ConstantExpression(true, 0), + // then + new ConstantExpression(null, 0), + // else + new ConstantExpression(null, 0), + 0 + ); + } else { + $conditional = new ConditionalExpression( + // if + new ConstantExpression(true, 0), + // then + new ConstantExpression(null, 0), + // else + new ConstantExpression(null, 0), + 0 + ); + } + if (class_exists(Nodes::class)) { - $arguments = new Nodes([ - new ContextVariable('form', 0), - new ConditionalExpression( - // if - new ConstantExpression(true, 0), - // then - new ConstantExpression(null, 0), - // else - new ConstantExpression(null, 0), - 0 - ), - ]); + $arguments = new Nodes([new ContextVariable('form', 0), $conditional]); } else { - $arguments = new Node([ - new NameExpression('form', 0), - new ConditionalExpression( - // if - new ConstantExpression(true, 0), - // then - new ConstantExpression(null, 0), - // else - new ConstantExpression(null, 0), - 0 - ), - ]); + $arguments = new Node([new NameExpression('form', 0), $conditional]); } if (class_exists(FirstClassTwigCallableReady::class)) { @@ -359,18 +360,32 @@ public function testCompileLabelWithLabelThatEvaluatesToNull() public function testCompileLabelWithLabelThatEvaluatesToNullAndAttributes() { + if (class_exists(ConditionalTernary::class)) { + $conditional = new ConditionalTernary( + // if + new ConstantExpression(true, 0), + // then + new ConstantExpression(null, 0), + // else + new ConstantExpression(null, 0), + 0 + ); + } else { + $conditional = new ConditionalExpression( + // if + new ConstantExpression(true, 0), + // then + new ConstantExpression(null, 0), + // else + new ConstantExpression(null, 0), + 0 + ); + } + if (class_exists(Nodes::class)) { $arguments = new Nodes([ new ContextVariable('form', 0), - new ConditionalExpression( - // if - new ConstantExpression(true, 0), - // then - new ConstantExpression(null, 0), - // else - new ConstantExpression(null, 0), - 0 - ), + $conditional, new ArrayExpression([ new ConstantExpression('foo', 0), new ConstantExpression('bar', 0), @@ -381,12 +396,7 @@ public function testCompileLabelWithLabelThatEvaluatesToNullAndAttributes() } else { $arguments = new Node([ new NameExpression('form', 0), - new ConditionalExpression( - new ConstantExpression(true, 0), - new ConstantExpression(null, 0), - new ConstantExpression(null, 0), - 0 - ), + $conditional, new ArrayExpression([ new ConstantExpression('foo', 0), new ConstantExpression('bar', 0), From 1a38acac242991a789c170ce28cfe74d0e28e9af Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 2 Dec 2024 10:05:27 +0100 Subject: [PATCH 05/28] generate conflict-free variable names --- .../TranslationDefaultDomainNodeVisitor.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php index 9a0ecc9d97781..3b8196fae410e 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php @@ -21,7 +21,8 @@ use Twig\Node\Expression\ConstantExpression; use Twig\Node\Expression\FilterExpression; use Twig\Node\Expression\NameExpression; -use Twig\Node\Expression\Variable\LocalVariable; +use Twig\Node\Expression\Variable\AssignContextVariable; +use Twig\Node\Expression\Variable\ContextVariable; use Twig\Node\ModuleNode; use Twig\Node\Node; use Twig\Node\Nodes; @@ -34,7 +35,6 @@ final class TranslationDefaultDomainNodeVisitor implements NodeVisitorInterface { private Scope $scope; - private int $nestingLevel = 0; public function __construct() { @@ -48,22 +48,25 @@ public function enterNode(Node $node, Environment $env): Node } if ($node instanceof TransDefaultDomainNode) { - ++$this->nestingLevel; - if ($node->getNode('expr') instanceof ConstantExpression) { $this->scope->set('domain', $node->getNode('expr')); return $node; } + if (null === $templateName = $node->getTemplateName()) { + throw new \LogicException('Cannot traverse a node without a template name.'); + } + + $var = '__internal_trans_default_domain'.hash('xxh128', $templateName); + if (class_exists(Nodes::class)) { - $name = new LocalVariable(null, $node->getTemplateLine()); - $this->scope->set('domain', $name); + $name = new AssignContextVariable($var, $node->getTemplateLine()); + $this->scope->set('domain', new ContextVariable($var, $node->getTemplateLine())); return new SetNode(false, new Nodes([$name]), new Nodes([$node->getNode('expr')]), $node->getTemplateLine()); } - $var = '__internal_trans_default_domain_'.$this->nestingLevel; $name = new AssignNameExpression($var, $node->getTemplateLine()); $this->scope->set('domain', new NameExpression($var, $node->getTemplateLine())); @@ -105,8 +108,6 @@ public function enterNode(Node $node, Environment $env): Node public function leaveNode(Node $node, Environment $env): ?Node { if ($node instanceof TransDefaultDomainNode) { - --$this->nestingLevel; - return null; } From 886d4eddfebcfdb067132c117bd5a08b00d38486 Mon Sep 17 00:00:00 2001 From: Maxime Pinot Date: Mon, 2 Dec 2024 12:09:41 +0100 Subject: [PATCH 06/28] [Mime] Fix wrong PHPDoc in `FormDataPart` constructor --- src/Symfony/Component/Mime/Part/Multipart/FormDataPart.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Mime/Part/Multipart/FormDataPart.php b/src/Symfony/Component/Mime/Part/Multipart/FormDataPart.php index 904c86d6b3cfd..0db5dfa0abe44 100644 --- a/src/Symfony/Component/Mime/Part/Multipart/FormDataPart.php +++ b/src/Symfony/Component/Mime/Part/Multipart/FormDataPart.php @@ -26,7 +26,7 @@ final class FormDataPart extends AbstractMultipartPart private array $fields = []; /** - * @param array $fields + * @param array $fields */ public function __construct(array $fields = []) { From 55a46e75a4fb55b768bc291ff1aa00e47664e7c0 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 2 Dec 2024 15:13:07 +0100 Subject: [PATCH 07/28] evaluate access flags for properties with asymmetric visibility --- .../Extractor/ReflectionExtractor.php | 8 +++- .../Extractor/ReflectionExtractorTest.php | 45 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 8e00e6473a4e8..89239a53f3505 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -581,8 +581,12 @@ private function isAllowedProperty(string $class, string $property, bool $writeA return false; } - if (\PHP_VERSION_ID >= 80400 && ($reflectionProperty->isProtectedSet() || $reflectionProperty->isPrivateSet())) { - return false; + if (\PHP_VERSION_ID >= 80400 && $reflectionProperty->isProtectedSet()) { + return (bool) ($this->propertyReflectionFlags & \ReflectionProperty::IS_PROTECTED); + } + + if (\PHP_VERSION_ID >= 80400 && $reflectionProperty->isPrivateSet()) { + return (bool) ($this->propertyReflectionFlags & \ReflectionProperty::IS_PRIVATE); } if (\PHP_VERSION_ID >= 80400 &&$reflectionProperty->isVirtual() && !$reflectionProperty->hasHook(\PropertyHookType::Set)) { diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index a6315103a2266..45565096d9963 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -672,6 +672,51 @@ public function testAsymmetricVisibility() $this->assertFalse($this->extractor->isWritable(AsymmetricVisibility::class, 'protectedPrivate')); } + /** + * @requires PHP 8.4 + */ + public function testAsymmetricVisibilityAllowPublicOnly() + { + $extractor = new ReflectionExtractor(null, null, null, true, ReflectionExtractor::ALLOW_PUBLIC); + + $this->assertTrue($extractor->isReadable(AsymmetricVisibility::class, 'publicPrivate')); + $this->assertTrue($extractor->isReadable(AsymmetricVisibility::class, 'publicProtected')); + $this->assertFalse($extractor->isReadable(AsymmetricVisibility::class, 'protectedPrivate')); + $this->assertFalse($extractor->isWritable(AsymmetricVisibility::class, 'publicPrivate')); + $this->assertFalse($extractor->isWritable(AsymmetricVisibility::class, 'publicProtected')); + $this->assertFalse($extractor->isWritable(AsymmetricVisibility::class, 'protectedPrivate')); + } + + /** + * @requires PHP 8.4 + */ + public function testAsymmetricVisibilityAllowProtectedOnly() + { + $extractor = new ReflectionExtractor(null, null, null, true, ReflectionExtractor::ALLOW_PROTECTED); + + $this->assertFalse($extractor->isReadable(AsymmetricVisibility::class, 'publicPrivate')); + $this->assertFalse($extractor->isReadable(AsymmetricVisibility::class, 'publicProtected')); + $this->assertTrue($extractor->isReadable(AsymmetricVisibility::class, 'protectedPrivate')); + $this->assertFalse($extractor->isWritable(AsymmetricVisibility::class, 'publicPrivate')); + $this->assertTrue($extractor->isWritable(AsymmetricVisibility::class, 'publicProtected')); + $this->assertFalse($extractor->isWritable(AsymmetricVisibility::class, 'protectedPrivate')); + } + + /** + * @requires PHP 8.4 + */ + public function testAsymmetricVisibilityAllowPrivateOnly() + { + $extractor = new ReflectionExtractor(null, null, null, true, ReflectionExtractor::ALLOW_PRIVATE); + + $this->assertFalse($extractor->isReadable(AsymmetricVisibility::class, 'publicPrivate')); + $this->assertFalse($extractor->isReadable(AsymmetricVisibility::class, 'publicProtected')); + $this->assertFalse($extractor->isReadable(AsymmetricVisibility::class, 'protectedPrivate')); + $this->assertTrue($extractor->isWritable(AsymmetricVisibility::class, 'publicPrivate')); + $this->assertFalse($extractor->isWritable(AsymmetricVisibility::class, 'publicProtected')); + $this->assertTrue($extractor->isWritable(AsymmetricVisibility::class, 'protectedPrivate')); + } + /** * @requires PHP 8.4 */ From bfdf5d92312f42db46ac8ceb21b129ea25e53045 Mon Sep 17 00:00:00 2001 From: Kurt Thiemann Date: Mon, 2 Dec 2024 12:18:11 +0100 Subject: [PATCH 08/28] [HttpClient] Always set CURLOPT_CUSTOMREQUEST to the correct HTTP method in CurlHttpClient --- .../Component/HttpClient/CurlHttpClient.php | 3 +-- .../HttpClient/Tests/HttpClientTestCase.php | 22 +++++++++++++++++++ .../Component/HttpClient/composer.json | 2 +- .../HttpClient/Test/Fixtures/web/index.php | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 7d996200527eb..3e15bef74cc9e 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -197,13 +197,12 @@ public function request(string $method, string $url, array $options = []): Respo $curlopts[\CURLOPT_RESOLVE] = $resolve; } + $curlopts[\CURLOPT_CUSTOMREQUEST] = $method; if ('POST' === $method) { // Use CURLOPT_POST to have browser-like POST-to-GET redirects for 301, 302 and 303 $curlopts[\CURLOPT_POST] = true; } elseif ('HEAD' === $method) { $curlopts[\CURLOPT_NOBODY] = true; - } else { - $curlopts[\CURLOPT_CUSTOMREQUEST] = $method; } if ('\\' !== \DIRECTORY_SEPARATOR && $options['timeout'] < 1) { diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php index a0e57bf2c5ff4..f572908c1535d 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php @@ -651,4 +651,26 @@ public function testDefaultContentType() $this->assertSame(['abc' => 'def', 'content-type' => 'application/json', 'REQUEST_METHOD' => 'POST'], $response->toArray()); } + + public function testHeadRequestWithClosureBody() + { + $p = TestHttpServer::start(8067); + + try { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('HEAD', 'http://localhost:8057/head', [ + 'body' => fn () => '', + ]); + $headers = $response->getHeaders(); + } finally { + $p->stop(); + } + + $this->assertArrayHasKey('x-request-vars', $headers); + + $vars = json_decode($headers['x-request-vars'][0], true); + $this->assertIsArray($vars); + $this->assertSame('HEAD', $vars['REQUEST_METHOD']); + } } diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index 23437d5363f28..9c9ee14a4a3ff 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -25,7 +25,7 @@ "php": ">=8.1", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "~3.4.3|^3.5.1", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", "symfony/service-contracts": "^2.5|^3" }, "require-dev": { diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index a75001785ae2d..59033d55a0350 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -42,6 +42,7 @@ exit; case '/head': + header('X-Request-Vars: '.json_encode($vars, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)); header('Content-Length: '.strlen($json), true); break; From 8a4e809e308d09b3c50140cbaad537bc47ac4b87 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 4 Dec 2024 11:03:46 +0100 Subject: [PATCH 09/28] [FrameworkBundle] Make uri_signer lazy and improve error when kernel.secret is empty --- .../DependencyInjection/FrameworkExtension.php | 9 ++++++++- .../Bundle/FrameworkBundle/Resources/config/services.php | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 26cae1f306c8f..8e19697f79532 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -310,10 +310,17 @@ public function load(array $configs, ContainerBuilder $container): void } } + $emptySecretHint = '"framework.secret" option'; if (isset($config['secret'])) { $container->setParameter('kernel.secret', $config['secret']); + $usedEnvs = []; + $container->resolveEnvPlaceholders($config['secret'], null, $usedEnvs); + + if ($usedEnvs) { + $emptySecretHint = \sprintf('"%s" env var%s', implode('", "', $usedEnvs), 1 === \count($usedEnvs) ? '' : 's'); + } } - $container->parameterCannotBeEmpty('kernel.secret', 'A non-empty value for the parameter "kernel.secret" is required. Did you forget to configure the "framework.secret" option?'); + $container->parameterCannotBeEmpty('kernel.secret', 'A non-empty value for the parameter "kernel.secret" is required. Did you forget to configure the '.$emptySecretHint.'?'); $container->setParameter('kernel.http_method_override', $config['http_method_override']); $container->setParameter('kernel.trust_x_sendfile_type_header', $config['trust_x_sendfile_type_header']); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php index 53856f356d056..6abe1b6d8f1a2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php @@ -157,6 +157,7 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : [] ->args([ new Parameter('kernel.secret'), ]) + ->lazy() ->alias(UriSigner::class, 'uri_signer') ->set('config_cache_factory', ResourceCheckerConfigCacheFactory::class) From 38f8ec2d08f4c73186c45483cb14c5787108f7f8 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Tue, 3 Dec 2024 10:06:44 +0100 Subject: [PATCH 10/28] Fix change log to mentioned thrown exception --- src/Symfony/Component/Security/Http/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Http/CHANGELOG.md b/src/Symfony/Component/Security/Http/CHANGELOG.md index a8e710597a989..de3dec5120bb3 100644 --- a/src/Symfony/Component/Security/Http/CHANGELOG.md +++ b/src/Symfony/Component/Security/Http/CHANGELOG.md @@ -6,7 +6,7 @@ CHANGELOG * Add `#[IsCsrfTokenValid]` attribute * Add CAS 2.0 access token handler - * Make empty username or empty password on form login attempts return Bad Request (400) + * Make empty username or empty password on form login attempts throw `BadCredentialsException` 7.0 --- From 15d56bb070669d73f165f7c39c176e368126f529 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Wed, 4 Dec 2024 15:37:29 +0100 Subject: [PATCH 11/28] Add an experimental CI job for PHP 8.5 --- .github/workflows/unit-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index e5defe2a989f9..8849fd3a94c58 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -33,6 +33,7 @@ jobs: mode: low-deps - php: '8.3' - php: '8.4' + - php: '8.5' #mode: experimental fail-fast: false From 26504c90a298a53d08682ab148a66f6539341be7 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 20 Nov 2024 11:50:15 +0100 Subject: [PATCH 12/28] add test covering associated entities referenced by their primary key --- .../Tests/Fixtures/AssociatedEntityDto.php | 17 +++++++++ .../Constraints/UniqueEntityValidatorTest.php | 35 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociatedEntityDto.php diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociatedEntityDto.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociatedEntityDto.php new file mode 100644 index 0000000000000..d6f82f8214846 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociatedEntityDto.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures; + +class AssociatedEntityDto +{ + public $singleId; +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index f554acb70d0fb..9f0341bdc7794 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -21,6 +21,7 @@ use Doctrine\Persistence\ObjectManager; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Bridge\Doctrine\Tests\DoctrineTestHelper; +use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociatedEntityDto; use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2; use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity; @@ -609,6 +610,40 @@ public function testAssociatedEntityWithNull() $this->assertNoViolation(); } + public function testAssociatedEntityReferencedByPrimaryKey() + { + $this->registry = $this->createRegistryMock($this->em); + $this->registry->expects($this->any()) + ->method('getManagerForClass') + ->willReturn($this->em); + $this->validator = $this->createValidator(); + $this->validator->initialize($this->context); + + $entity = new SingleIntIdEntity(1, 'foo'); + $associated = new AssociationEntity(); + $associated->single = $entity; + + $this->em->persist($entity); + $this->em->persist($associated); + $this->em->flush(); + + $dto = new AssociatedEntityDto(); + $dto->singleId = 1; + + $this->validator->validate($dto, new UniqueEntity( + fields: ['singleId' => 'single'], + entityClass: AssociationEntity::class, + )); + + $this->buildViolation('This value is already used.') + ->atPath('property.path.single') + ->setParameter('{{ value }}', 1) + ->setInvalidValue(1) + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) + ->setCause([$associated]) + ->assertRaised(); + } + public function testValidateUniquenessWithArrayValue() { $repository = $this->createRepositoryMock(SingleIntIdEntity::class); From d6375862fbdbd13bd6a5cc620e020fad9fb96bd7 Mon Sep 17 00:00:00 2001 From: AUDUL <97884272+AUDUL@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:22:09 +0100 Subject: [PATCH 13/28] Update SendgridSmtpTransport.php Fix region null check --- .../Mailer/Bridge/Sendgrid/Transport/SendgridSmtpTransport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridSmtpTransport.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridSmtpTransport.php index d939359ff8bc0..c7b67685dab9f 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridSmtpTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridSmtpTransport.php @@ -22,7 +22,7 @@ class SendgridSmtpTransport extends EsmtpTransport { public function __construct(#[\SensitiveParameter] string $key, ?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null, private ?string $region = null) { - parent::__construct('null' !== $region ? \sprintf('smtp.%s.sendgrid.net', $region) : 'smtp.sendgrid.net', 465, true, $dispatcher, $logger); + parent::__construct(null !== $region ? \sprintf('smtp.%s.sendgrid.net', $region) : 'smtp.sendgrid.net', 465, true, $dispatcher, $logger); $this->setUsername('apikey'); $this->setPassword($key); From 91cd48227ba61bb36d92f9933e69170342f75567 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Wed, 4 Dec 2024 16:33:28 +0100 Subject: [PATCH 14/28] [ErrorHandler] Fix error message with PHP 8.5 --- .../ErrorHandler/Tests/phpt/fatal_with_nested_handlers.phpt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/ErrorHandler/Tests/phpt/fatal_with_nested_handlers.phpt b/src/Symfony/Component/ErrorHandler/Tests/phpt/fatal_with_nested_handlers.phpt index cfb10d03dafdd..81becafd8e350 100644 --- a/src/Symfony/Component/ErrorHandler/Tests/phpt/fatal_with_nested_handlers.phpt +++ b/src/Symfony/Component/ErrorHandler/Tests/phpt/fatal_with_nested_handlers.phpt @@ -24,7 +24,7 @@ var_dump([ $eHandler[0]->setExceptionHandler('print_r'); if (true) { - class Broken implements \JsonSerializable + class Broken implements \Iterator { } } @@ -37,14 +37,14 @@ array(1) { } object(Symfony\Component\ErrorHandler\Error\FatalError)#%d (%d) { ["message":protected]=> - string(186) "Error: Class Symfony\Component\ErrorHandler\Broken contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (JsonSerializable::jsonSerialize)" + string(209) "Error: Class Symfony\Component\ErrorHandler\Broken contains 5 abstract methods and must therefore be declared abstract or implement the remaining methods (Iterator::current, Iterator::next, Iterator::key, ...)" %a ["error":"Symfony\Component\ErrorHandler\Error\FatalError":private]=> array(4) { ["type"]=> int(1) ["message"]=> - string(179) "Class Symfony\Component\ErrorHandler\Broken contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (JsonSerializable::jsonSerialize)" + string(202) "Class Symfony\Component\ErrorHandler\Broken contains 5 abstract methods and must therefore be declared abstract or implement the remaining methods (Iterator::current, Iterator::next, Iterator::key, ...)" ["file"]=> string(%d) "%s" ["line"]=> From ee400b0b88372e1f496355bfb4708b6ba9ec46a9 Mon Sep 17 00:00:00 2001 From: Sven Nolting Date: Mon, 2 Dec 2024 14:51:36 +0100 Subject: [PATCH 15/28] [Console] Fix division by 0 error --- src/Symfony/Component/Console/Helper/ProgressBar.php | 2 +- .../Component/Console/Tests/Helper/ProgressBarTest.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Helper/ProgressBar.php b/src/Symfony/Component/Console/Helper/ProgressBar.php index b406292b44b3a..23157e3c7b2db 100644 --- a/src/Symfony/Component/Console/Helper/ProgressBar.php +++ b/src/Symfony/Component/Console/Helper/ProgressBar.php @@ -229,7 +229,7 @@ public function getEstimated(): float public function getRemaining(): float { - if (!$this->step) { + if (0 === $this->step || $this->step === $this->startingStep) { return 0; } diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php index a5a0eca245080..c32307720fce8 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php @@ -110,6 +110,14 @@ public function testRegularTimeEstimation() ); } + public function testRegularTimeRemainingWithDifferentStartAtAndCustomDisplay() + { + ProgressBar::setFormatDefinition('custom', ' %current%/%max% [%bar%] %percent:3s%% %remaining% %estimated%'); + $bar = new ProgressBar($output = $this->getOutputStream(), 1_200, 0); + $bar->setFormat('custom'); + $bar->start(1_200, 600); + } + public function testResumedTimeEstimation() { $bar = new ProgressBar($output = $this->getOutputStream(), 1_200, 0); From a35a5b666177e559be90642aeef07ac245929eaa Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Thu, 5 Dec 2024 00:17:16 +0100 Subject: [PATCH 16/28] chore: fix CS --- .../Security/RememberMe/DoctrineTokenProviderPostgresTest.php | 1 + src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php | 2 +- src/Symfony/Component/Cache/Traits/Relay/MoveTrait.php | 4 ++-- src/Symfony/Component/HttpClient/Response/CurlResponse.php | 2 +- src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php | 1 + .../HttpClient/Tests/NoPrivateNetworkHttpClientTest.php | 2 ++ .../HttpKernel/DataCollector/ConfigDataCollector.php | 2 +- src/Symfony/Component/Messenger/Attribute/AsMessage.php | 2 +- .../PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php | 2 ++ src/Symfony/Component/TypeInfo/Type/UnionType.php | 2 +- .../Component/TypeInfo/TypeResolver/StringTypeResolver.php | 2 +- 11 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Security/RememberMe/DoctrineTokenProviderPostgresTest.php b/src/Symfony/Bridge/Doctrine/Tests/Security/RememberMe/DoctrineTokenProviderPostgresTest.php index e0c897ce23232..53cbbb07a211c 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Security/RememberMe/DoctrineTokenProviderPostgresTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Security/RememberMe/DoctrineTokenProviderPostgresTest.php @@ -10,6 +10,7 @@ /** * @requires extension pdo_pgsql + * * @group integration */ class DoctrineTokenProviderPostgresTest extends DoctrineTokenProviderTest diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php index f4281cd21eef8..4dc86130a8cc5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php @@ -86,7 +86,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int ['Timezone', date_default_timezone_get().' ('.(new \DateTimeImmutable())->format(\DateTimeInterface::W3C).')'], ['OPcache', \extension_loaded('Zend OPcache') ? (filter_var(\ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN) ? 'Enabled' : 'Not enabled') : 'Not installed'], ['APCu', \extension_loaded('apcu') ? (filter_var(\ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? 'Enabled' : 'Not enabled') : 'Not installed'], - ['Xdebug', \extension_loaded('xdebug') ? ($xdebugMode && $xdebugMode !== 'off' ? 'Enabled (' . $xdebugMode . ')' : 'Not enabled') : 'Not installed'], + ['Xdebug', \extension_loaded('xdebug') ? ($xdebugMode && 'off' !== $xdebugMode ? 'Enabled (' . $xdebugMode . ')' : 'Not enabled') : 'Not installed'], ]; $io->table([], $rows); diff --git a/src/Symfony/Component/Cache/Traits/Relay/MoveTrait.php b/src/Symfony/Component/Cache/Traits/Relay/MoveTrait.php index 1f1b84c009399..18086f61d68c5 100644 --- a/src/Symfony/Component/Cache/Traits/Relay/MoveTrait.php +++ b/src/Symfony/Component/Cache/Traits/Relay/MoveTrait.php @@ -33,12 +33,12 @@ public function lmove($srckey, $dstkey, $srcpos, $dstpos): mixed */ trait MoveTrait { - public function blmove($srckey, $dstkey, $srcpos, $dstpos, $timeout): \Relay\Relay|false|null|string + public function blmove($srckey, $dstkey, $srcpos, $dstpos, $timeout): \Relay\Relay|false|string|null { return $this->initializeLazyObject()->blmove(...\func_get_args()); } - public function lmove($srckey, $dstkey, $srcpos, $dstpos): \Relay\Relay|false|null|string + public function lmove($srckey, $dstkey, $srcpos, $dstpos): \Relay\Relay|false|string|null { return $this->initializeLazyObject()->lmove(...\func_get_args()); } diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 55c424011de84..119e201b204e1 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -316,7 +316,7 @@ private static function perform(ClientState $multi, ?array &$responses = null): } $multi->handlesActivity[$id][] = null; - $multi->handlesActivity[$id][] = \in_array($result, [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || '_0' === $waitFor || curl_getinfo($ch, \CURLINFO_SIZE_DOWNLOAD) === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) || (curl_error($ch) === 'OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 0' && -1.0 === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) && \in_array('close', array_map('strtolower', $responses[$id]->headers['connection']), true)) ? null : new TransportException(ucfirst(curl_error($ch) ?: curl_strerror($result)).\sprintf(' for "%s".', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL))); + $multi->handlesActivity[$id][] = \in_array($result, [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || '_0' === $waitFor || curl_getinfo($ch, \CURLINFO_SIZE_DOWNLOAD) === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) || ('OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 0' === curl_error($ch) && -1.0 === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) && \in_array('close', array_map('strtolower', $responses[$id]->headers['connection']), true)) ? null : new TransportException(ucfirst(curl_error($ch) ?: curl_strerror($result)).\sprintf(' for "%s".', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL))); } } finally { $multi->performing = false; diff --git a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php index 1a30f16c1ff0e..a18b253203092 100644 --- a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php @@ -17,6 +17,7 @@ /** * @requires extension curl + * * @group dns-sensitive */ class CurlHttpClientTest extends HttpClientTestCase diff --git a/src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php index 181b7f42be28d..c160dff77492a 100644 --- a/src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php @@ -68,6 +68,7 @@ public static function getExcludeHostData(): iterable /** * @dataProvider getExcludeIpData + * * @group dns-sensitive */ public function testExcludeByIp(string $ipAddr, $subnets, bool $mustThrow) @@ -105,6 +106,7 @@ public function testExcludeByIp(string $ipAddr, $subnets, bool $mustThrow) /** * @dataProvider getExcludeHostData + * * @group dns-sensitive */ public function testExcludeByHost(string $ipAddr, $subnets, bool $mustThrow) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php index 747a495036d17..8713dcf1e55d9 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php @@ -57,7 +57,7 @@ public function collect(Request $request, Response $response, ?\Throwable $excep 'php_intl_locale' => class_exists(\Locale::class, false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a', 'php_timezone' => date_default_timezone_get(), 'xdebug_enabled' => \extension_loaded('xdebug'), - 'xdebug_status' => \extension_loaded('xdebug') ? ($xdebugMode && $xdebugMode !== 'off' ? 'Enabled (' . $xdebugMode . ')' : 'Not enabled') : 'Not installed', + 'xdebug_status' => \extension_loaded('xdebug') ? ($xdebugMode && 'off' !== $xdebugMode ? 'Enabled (' . $xdebugMode . ')' : 'Not enabled') : 'Not installed', 'apcu_enabled' => \extension_loaded('apcu') && filter_var(\ini_get('apc.enabled'), \FILTER_VALIDATE_BOOL), 'apcu_status' => \extension_loaded('apcu') ? (filter_var(\ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? 'Enabled' : 'Not enabled') : 'Not installed', 'zend_opcache_enabled' => \extension_loaded('Zend OPcache') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOL), diff --git a/src/Symfony/Component/Messenger/Attribute/AsMessage.php b/src/Symfony/Component/Messenger/Attribute/AsMessage.php index bc60ec032bff9..ee46bd5491fe1 100644 --- a/src/Symfony/Component/Messenger/Attribute/AsMessage.php +++ b/src/Symfony/Component/Messenger/Attribute/AsMessage.php @@ -23,7 +23,7 @@ public function __construct( /** * Name of the transports to which the message should be routed. */ - public null|string|array $transport = null, + public string|array|null $transport = null, ) { } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 13e9db752b2f2..614e7d8a8efbf 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -718,6 +718,7 @@ public function testVirtualProperties() /** * @dataProvider provideAsymmetricVisibilityMutator + * * @requires PHP 8.4 */ public function testAsymmetricVisibilityMutator(string $property, string $readVisibility, string $writeVisibility) @@ -743,6 +744,7 @@ public static function provideAsymmetricVisibilityMutator(): iterable /** * @dataProvider provideVirtualPropertiesMutator + * * @requires PHP 8.4 */ public function testVirtualPropertiesMutator(string $property, string $readVisibility, string $writeVisibility) diff --git a/src/Symfony/Component/TypeInfo/Type/UnionType.php b/src/Symfony/Component/TypeInfo/Type/UnionType.php index fd11214fc306f..91597e2089e3b 100644 --- a/src/Symfony/Component/TypeInfo/Type/UnionType.php +++ b/src/Symfony/Component/TypeInfo/Type/UnionType.php @@ -45,7 +45,7 @@ public function __construct(Type ...$types) } if ($type instanceof BuiltinType) { - if ($type->getTypeIdentifier() === TypeIdentifier::NULL && !is_a(static::class, NullableType::class, allow_string: true)) { + if (TypeIdentifier::NULL === $type->getTypeIdentifier() && !is_a(static::class, NullableType::class, allow_string: true)) { throw new InvalidArgumentException(\sprintf('Cannot create union with "null", please use "%s" instead.', NullableType::class)); } diff --git a/src/Symfony/Component/TypeInfo/TypeResolver/StringTypeResolver.php b/src/Symfony/Component/TypeInfo/TypeResolver/StringTypeResolver.php index 1a8cdfac570a4..4809e9b83bf7e 100644 --- a/src/Symfony/Component/TypeInfo/TypeResolver/StringTypeResolver.php +++ b/src/Symfony/Component/TypeInfo/TypeResolver/StringTypeResolver.php @@ -215,7 +215,7 @@ private function getTypeFromNode(TypeNode $node, ?TypeContext $typeContext): Typ }; } - if ($type instanceof BuiltinType && $type->getTypeIdentifier() !== TypeIdentifier::ARRAY && $type->getTypeIdentifier() !== TypeIdentifier::ITERABLE) { + if ($type instanceof BuiltinType && TypeIdentifier::ARRAY !== $type->getTypeIdentifier() && TypeIdentifier::ITERABLE !== $type->getTypeIdentifier()) { return $type; } From 91f4a2c5ffa396ee919201fa3c21bbab83be52dd Mon Sep 17 00:00:00 2001 From: Klaus Silveira Date: Thu, 5 Dec 2024 12:39:40 -0500 Subject: [PATCH 17/28] add test covering null regions --- .../Transport/SendgridSmtpTransportTest.php | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridSmtpTransportTest.php diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridSmtpTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridSmtpTransportTest.php new file mode 100644 index 0000000000000..77e5135c55cc4 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridSmtpTransportTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Sendgrid\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridSmtpTransport; + +class SendgridSmtpTransportTest extends TestCase +{ + /** + * @dataProvider getTransportData + */ + public function testToString(SendgridSmtpTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public static function getTransportData() + { + return [ + [ + new SendgridSmtpTransport('KEY'), + 'smtps://smtp.sendgrid.net', + ], + [ + new SendgridSmtpTransport('KEY', null, null, 'eu'), + 'smtps://smtp.eu.sendgrid.net', + ], + ]; + } +} From 6262a6271d43fd3bb9fda15c7a956d95821105ca Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sat, 7 Dec 2024 10:09:39 +0100 Subject: [PATCH 18/28] Add tests covering `trans_default_domain` with dynamic expressions --- .../Extension/TranslationExtensionTest.php | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php index 96f707cdfdf2c..f6dd5f623baee 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php @@ -206,6 +206,68 @@ public function testDefaultTranslationDomainWithNamedArguments() $this->assertEquals('foo (custom)foo (foo)foo (custom)foo (custom)foo (fr)foo (custom)foo (fr)', trim($template->render([]))); } + public function testDefaultTranslationDomainWithExpression() + { + $templates = [ + 'index' => ' + {%- extends "base" %} + + {%- trans_default_domain custom_domain %} + + {%- block content %} + {{- "foo"|trans }} + {%- endblock %} + ', + + 'base' => ' + {%- block content "" %} + ', + ]; + + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['foo' => 'foo (messages)'], 'en'); + $translator->addResource('array', ['foo' => 'foo (custom)'], 'en', 'custom'); + $translator->addResource('array', ['foo' => 'foo (foo)'], 'en', 'foo'); + + $template = $this->getTemplate($templates, $translator); + + $this->assertEquals('foo (foo)', trim($template->render(['custom_domain' => 'foo']))); + } + + public function testDefaultTranslationDomainWithExpressionAndInheritance() + { + $templates = [ + 'index' => ' + {%- extends "base" %} + + {%- trans_default_domain foo_domain %} + + {%- block content %} + {{- "foo"|trans }} + {%- endblock %} + ', + + 'base' => ' + {%- trans_default_domain custom_domain %} + + {{- "foo"|trans }} + {%- block content "" %} + {{- "foo"|trans }} + ', + ]; + + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['foo' => 'foo (messages)'], 'en'); + $translator->addResource('array', ['foo' => 'foo (custom)'], 'en', 'custom'); + $translator->addResource('array', ['foo' => 'foo (foo)'], 'en', 'foo'); + + $template = $this->getTemplate($templates, $translator); + + $this->assertEquals('foo (custom)foo (foo)foo (custom)', trim($template->render(['foo_domain' => 'foo', 'custom_domain' => 'custom']))); + } + private function getTemplate($template, ?TranslatorInterface $translator = null): TemplateWrapper { $translator ??= new Translator('en'); From ccd11016e1014b9032b3e31f840b846215918961 Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Sat, 7 Dec 2024 11:49:58 +0100 Subject: [PATCH 19/28] [Scheduler] remove dead code --- .../Scheduler/Tests/RecurringMessageTest.php | 10 +-- .../Trigger/CronExpressionTriggerTest.php | 69 ++++++------------- 2 files changed, 23 insertions(+), 56 deletions(-) diff --git a/src/Symfony/Component/Scheduler/Tests/RecurringMessageTest.php b/src/Symfony/Component/Scheduler/Tests/RecurringMessageTest.php index d668b7d03b02b..1954d4f470402 100644 --- a/src/Symfony/Component/Scheduler/Tests/RecurringMessageTest.php +++ b/src/Symfony/Component/Scheduler/Tests/RecurringMessageTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Scheduler\Tests; use PHPUnit\Framework\TestCase; -use Random\Randomizer; use Symfony\Component\Scheduler\Exception\InvalidArgumentException; use Symfony\Component\Scheduler\RecurringMessage; @@ -22,13 +21,8 @@ public function testCanCreateHashedCronMessage() { $object = new DummyStringableMessage(); - if (class_exists(Randomizer::class)) { - $this->assertSame('30 0 * * *', (string) RecurringMessage::cron('#midnight', $object)->getTrigger()); - $this->assertSame('30 0 * * 3', (string) RecurringMessage::cron('#weekly', $object)->getTrigger()); - } else { - $this->assertSame('36 0 * * *', (string) RecurringMessage::cron('#midnight', $object)->getTrigger()); - $this->assertSame('36 0 * * 6', (string) RecurringMessage::cron('#weekly', $object)->getTrigger()); - } + $this->assertSame('30 0 * * *', (string) RecurringMessage::cron('#midnight', $object)->getTrigger()); + $this->assertSame('30 0 * * 3', (string) RecurringMessage::cron('#weekly', $object)->getTrigger()); } public function testHashedCronContextIsRequiredIfMessageIsNotStringable() diff --git a/src/Symfony/Component/Scheduler/Tests/Trigger/CronExpressionTriggerTest.php b/src/Symfony/Component/Scheduler/Tests/Trigger/CronExpressionTriggerTest.php index cf12a7ceccf52..a700372d4765c 100644 --- a/src/Symfony/Component/Scheduler/Tests/Trigger/CronExpressionTriggerTest.php +++ b/src/Symfony/Component/Scheduler/Tests/Trigger/CronExpressionTriggerTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Scheduler\Tests\Trigger; use PHPUnit\Framework\TestCase; -use Random\Randomizer; use Symfony\Component\Scheduler\Trigger\CronExpressionTrigger; class CronExpressionTriggerTest extends TestCase @@ -33,54 +32,28 @@ public function testHashedExpressionParsing(string $input, string $expected) public static function hashedExpressionProvider(): array { - if (class_exists(Randomizer::class)) { - return [ - ['# * * * *', '30 * * * *'], - ['# # * * *', '30 0 * * *'], - ['# # # * *', '30 0 25 * *'], - ['# # # # *', '30 0 25 10 *'], - ['# # # # #', '30 0 25 10 5'], - ['# # 1,15 1-11 *', '30 0 1,15 1-11 *'], - ['# # 1,15 * *', '30 0 1,15 * *'], - ['#hourly', '30 * * * *'], - ['#daily', '30 0 * * *'], - ['#weekly', '30 0 * * 3'], - ['#weekly@midnight', '30 0 * * 3'], - ['#monthly', '30 0 25 * *'], - ['#monthly@midnight', '30 0 25 * *'], - ['#yearly', '30 0 25 10 *'], - ['#yearly@midnight', '30 0 25 10 *'], - ['#annually', '30 0 25 10 *'], - ['#annually@midnight', '30 0 25 10 *'], - ['#midnight', '30 0 * * *'], - ['#(1-15) * * * *', '1 * * * *'], - ['#(1-15) * * * #(3-5)', '1 * * * 3'], - ['#(1-15) * # * #(3-5)', '1 * 17 * 5'], - ]; - } - return [ - ['# * * * *', '36 * * * *'], - ['# # * * *', '36 0 * * *'], - ['# # # * *', '36 0 14 * *'], - ['# # # # *', '36 0 14 3 *'], - ['# # # # #', '36 0 14 3 5'], - ['# # 1,15 1-11 *', '36 0 1,15 1-11 *'], - ['# # 1,15 * *', '36 0 1,15 * *'], - ['#hourly', '36 * * * *'], - ['#daily', '36 0 * * *'], - ['#weekly', '36 0 * * 6'], - ['#weekly@midnight', '36 0 * * 6'], - ['#monthly', '36 0 14 * *'], - ['#monthly@midnight', '36 0 14 * *'], - ['#yearly', '36 0 14 3 *'], - ['#yearly@midnight', '36 0 14 3 *'], - ['#annually', '36 0 14 3 *'], - ['#annually@midnight', '36 0 14 3 *'], - ['#midnight', '36 0 * * *'], - ['#(1-15) * * * *', '7 * * * *'], - ['#(1-15) * * * #(3-5)', '7 * * * 3'], - ['#(1-15) * # * #(3-5)', '7 * 1 * 5'], + ['# * * * *', '30 * * * *'], + ['# # * * *', '30 0 * * *'], + ['# # # * *', '30 0 25 * *'], + ['# # # # *', '30 0 25 10 *'], + ['# # # # #', '30 0 25 10 5'], + ['# # 1,15 1-11 *', '30 0 1,15 1-11 *'], + ['# # 1,15 * *', '30 0 1,15 * *'], + ['#hourly', '30 * * * *'], + ['#daily', '30 0 * * *'], + ['#weekly', '30 0 * * 3'], + ['#weekly@midnight', '30 0 * * 3'], + ['#monthly', '30 0 25 * *'], + ['#monthly@midnight', '30 0 25 * *'], + ['#yearly', '30 0 25 10 *'], + ['#yearly@midnight', '30 0 25 10 *'], + ['#annually', '30 0 25 10 *'], + ['#annually@midnight', '30 0 25 10 *'], + ['#midnight', '30 0 * * *'], + ['#(1-15) * * * *', '1 * * * *'], + ['#(1-15) * * * #(3-5)', '1 * * * 3'], + ['#(1-15) * # * #(3-5)', '1 * 17 * 5'], ]; } From 97d6e68b2ae92c5dc4131e97425c36f9c3764a8d Mon Sep 17 00:00:00 2001 From: raphael-geffroy Date: Sat, 7 Dec 2024 12:28:46 +0100 Subject: [PATCH 20/28] fix: notifier push channel bus abstract arg --- .../DependencyInjection/FrameworkExtension.php | 2 +- .../Bundle/FrameworkBundle/Resources/config/notifier.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 83518061fed36..36984e7398528 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -2765,7 +2765,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ $container->removeDefinition('notifier.channel.email'); } - foreach (['texter', 'chatter', 'notifier.channel.chat', 'notifier.channel.email', 'notifier.channel.sms'] as $serviceId) { + foreach (['texter', 'chatter', 'notifier.channel.chat', 'notifier.channel.email', 'notifier.channel.sms', 'notifier.channel.push'] as $serviceId) { if (!$container->hasDefinition($serviceId)) { continue; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php index 6ce674148a878..bcc1248208c61 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php @@ -73,7 +73,10 @@ ->tag('notifier.channel', ['channel' => 'email']) ->set('notifier.channel.push', PushChannel::class) - ->args([service('texter.transports'), service('messenger.default_bus')->ignoreOnInvalid()]) + ->args([ + service('texter.transports'), + abstract_arg('message bus'), + ]) ->tag('notifier.channel', ['channel' => 'push']) ->set('notifier.monolog_handler', NotifierHandler::class) From 4cca70ba1dbf996ece9fb2c9622bcf7f2be58f84 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 7 Dec 2024 13:07:30 +0100 Subject: [PATCH 21/28] fix risky test that doesn't perform any assertions --- .../Component/Console/Tests/Helper/ProgressBarTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php index c32307720fce8..a1db94583db49 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php @@ -112,8 +112,10 @@ public function testRegularTimeEstimation() public function testRegularTimeRemainingWithDifferentStartAtAndCustomDisplay() { + $this->expectNotToPerformAssertions(); + ProgressBar::setFormatDefinition('custom', ' %current%/%max% [%bar%] %percent:3s%% %remaining% %estimated%'); - $bar = new ProgressBar($output = $this->getOutputStream(), 1_200, 0); + $bar = new ProgressBar($this->getOutputStream(), 1_200, 0); $bar->setFormat('custom'); $bar->start(1_200, 600); } From a06dab8a1d913232369e4d41a3d61cfdd8636e4d Mon Sep 17 00:00:00 2001 From: raphael-geffroy Date: Sat, 7 Dec 2024 12:21:53 +0100 Subject: [PATCH 22/28] fix: notifier channel bus abstract arg --- .../DependencyInjection/FrameworkExtension.php | 2 +- .../Bundle/FrameworkBundle/Resources/config/notifier.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 9ddf89ac1b82f..a6d5956033d5e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -2784,7 +2784,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ $container->removeDefinition('notifier.channel.email'); } - foreach (['texter', 'chatter', 'notifier.channel.chat', 'notifier.channel.email', 'notifier.channel.sms', 'notifier.channel.push'] as $serviceId) { + foreach (['texter', 'chatter', 'notifier.channel.chat', 'notifier.channel.email', 'notifier.channel.sms', 'notifier.channel.push', 'notifier.channel.desktop'] as $serviceId) { if (!$container->hasDefinition($serviceId)) { continue; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php index 71a3cd1fde7ad..28900ad10d7bd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.php @@ -82,7 +82,10 @@ ->tag('notifier.channel', ['channel' => 'push']) ->set('notifier.channel.desktop', DesktopChannel::class) - ->args([service('texter.transports'), service('messenger.default_bus')->ignoreOnInvalid()]) + ->args([ + service('texter.transports'), + abstract_arg('message bus'), + ]) ->tag('notifier.channel', ['channel' => 'desktop']) ->set('notifier.monolog_handler', NotifierHandler::class) From 640a8d5c35b38df446367978b428690508804b25 Mon Sep 17 00:00:00 2001 From: Mathias Arlaud Date: Mon, 9 Dec 2024 10:37:59 +0100 Subject: [PATCH 23/28] [TypeInfo] Fix handle nullable with mixed --- src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php | 1 + src/Symfony/Component/TypeInfo/TypeFactoryTrait.php | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php b/src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php index 9e8796d09b3c4..60a0ded22c648 100644 --- a/src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php +++ b/src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php @@ -195,6 +195,7 @@ public function testCreateNullable() { $this->assertEquals(new NullableType(new BuiltinType(TypeIdentifier::INT)), Type::nullable(Type::int())); $this->assertEquals(new NullableType(new BuiltinType(TypeIdentifier::INT)), Type::nullable(Type::nullable(Type::int()))); + $this->assertEquals(new BuiltinType(TypeIdentifier::MIXED), Type::nullable(Type::mixed())); $this->assertEquals( new NullableType(new UnionType(new BuiltinType(TypeIdentifier::INT), new BuiltinType(TypeIdentifier::STRING))), diff --git a/src/Symfony/Component/TypeInfo/TypeFactoryTrait.php b/src/Symfony/Component/TypeInfo/TypeFactoryTrait.php index a1d7f8c43b461..d32a97276057c 100644 --- a/src/Symfony/Component/TypeInfo/TypeFactoryTrait.php +++ b/src/Symfony/Component/TypeInfo/TypeFactoryTrait.php @@ -330,11 +330,11 @@ public static function intersection(Type ...$types): IntersectionType * * @param T $type * - * @return ($type is NullableType ? T : NullableType) + * @return T|NullableType */ - public static function nullable(Type $type): NullableType + public static function nullable(Type $type): Type { - if ($type instanceof NullableType) { + if ($type->isNullable()) { return $type; } From 34d30c757e270389a957fd831674d74bcd97d2b7 Mon Sep 17 00:00:00 2001 From: Mathias Arlaud Date: Mon, 9 Dec 2024 16:32:42 +0100 Subject: [PATCH 24/28] [TypeInfo] Fix outdated README --- src/Symfony/Component/TypeInfo/README.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/TypeInfo/README.md b/src/Symfony/Component/TypeInfo/README.md index b654e271a1c6b..d9b3a2e5bbf2f 100644 --- a/src/Symfony/Component/TypeInfo/README.md +++ b/src/Symfony/Component/TypeInfo/README.md @@ -15,6 +15,7 @@ composer require phpstan/phpdoc-parser # to support raw string resolving resolve('bool'); // returns a "bool" Type instance // Types can be instantiated thanks to static factories $type = Type::list(Type::nullable(Type::bool())); -// Type instances have several helper methods -$type->getBaseType(); // returns an "array" Type instance -$type->getCollectionKeyType(); // returns an "int" Type instance -$type->getCollectionValueType()->isNullable(); // returns true +// Type classes have their specific methods +Type::object(FooClass::class)->getClassName(); +Type::enum(FooEnum::class, Type::int())->getBackingType(); +Type::list(Type::int())->isList(); + +// Every type can be cast to string +(string) Type::generic(Type::object(Collection::class), Type::int()) // returns "Collection" + +// You can check that a type (or one of its wrapped/composed parts) is identified by one of some identifiers. +$type->isIdentifiedBy(Foo::class, Bar::class); +$type->isIdentifiedBy(TypeIdentifier::OBJECT); +$type->isIdentifiedBy('float'); + +// You can also check that a type satifies specific conditions +$type->isSatisfiedBy(fn (Type $type): bool => !$type->isNullable() && $type->isIdentifiedBy(TypeIdentifier::INT)); ``` Resources From a81c6d9528b5e489c8da2336a0ae5d41e5965c97 Mon Sep 17 00:00:00 2001 From: Mathias Arlaud Date: Tue, 10 Dec 2024 10:21:20 +0100 Subject: [PATCH 25/28] [TypeInfo] Remove useless dependency --- src/Symfony/Component/TypeInfo/composer.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Symfony/Component/TypeInfo/composer.json b/src/Symfony/Component/TypeInfo/composer.json index a10b6d8785d0e..a246dd94f45fd 100644 --- a/src/Symfony/Component/TypeInfo/composer.json +++ b/src/Symfony/Component/TypeInfo/composer.json @@ -29,12 +29,7 @@ "psr/container": "^1.1|^2.0" }, "require-dev": { - "phpstan/phpdoc-parser": "^1.0|^2.0", - "symfony/dependency-injection": "^6.4|^7.0" - }, - "conflict": { - "phpstan/phpdoc-parser": "<1.0", - "symfony/dependency-injection": "<6.4" + "phpstan/phpdoc-parser": "^1.0|^2.0" }, "autoload": { "psr-4": { "Symfony\\Component\\TypeInfo\\": "" }, From 838eb9591835c3fb420b9757058fec176979c3f1 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Wed, 11 Dec 2024 04:49:26 +0100 Subject: [PATCH 26/28] [Console] Fix tests --- src/Symfony/Component/Console/Tests/ApplicationTest.php | 1 + src/Symfony/Component/Console/Tests/ConsoleEventsTest.php | 1 + .../Console/Tests/SignalRegistry/SignalRegistryTest.php | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 4693535051124..4f6e6cb96cf32 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -79,6 +79,7 @@ protected function tearDown(): void pcntl_signal(\SIGTERM, \SIG_DFL); pcntl_signal(\SIGUSR1, \SIG_DFL); pcntl_signal(\SIGUSR2, \SIG_DFL); + pcntl_signal(\SIGALRM, \SIG_DFL); } } diff --git a/src/Symfony/Component/Console/Tests/ConsoleEventsTest.php b/src/Symfony/Component/Console/Tests/ConsoleEventsTest.php index 9c04d2706e8da..408f8c0d35c58 100644 --- a/src/Symfony/Component/Console/Tests/ConsoleEventsTest.php +++ b/src/Symfony/Component/Console/Tests/ConsoleEventsTest.php @@ -39,6 +39,7 @@ protected function tearDown(): void pcntl_signal(\SIGTERM, \SIG_DFL); pcntl_signal(\SIGUSR1, \SIG_DFL); pcntl_signal(\SIGUSR2, \SIG_DFL); + pcntl_signal(\SIGALRM, \SIG_DFL); } } diff --git a/src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php b/src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php index f997f7c1d8cee..92d500f9ee4e5 100644 --- a/src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php +++ b/src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php @@ -27,6 +27,7 @@ protected function tearDown(): void pcntl_signal(\SIGTERM, \SIG_DFL); pcntl_signal(\SIGUSR1, \SIG_DFL); pcntl_signal(\SIGUSR2, \SIG_DFL); + pcntl_signal(\SIGALRM, \SIG_DFL); } public function testOneCallbackForASignalSignalIsHandled() From 24a2971fd71ce75c07d7b88cdb0167789d235a07 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 11 Dec 2024 13:09:04 +0100 Subject: [PATCH 27/28] Update CHANGELOG for 7.2.1 --- CHANGELOG-7.2.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG-7.2.md b/CHANGELOG-7.2.md index 0e61bef1eaa74..11ad8ff6b9959 100644 --- a/CHANGELOG-7.2.md +++ b/CHANGELOG-7.2.md @@ -7,6 +7,18 @@ in 7.2 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v7.2.0...v7.2.1 +* 7.2.1 (2024-12-11) + + * bug #59145 [TypeInfo] Make `Type::nullable` method no-op on every nullable type (mtarld) + * bug #59122 [Notifier] fix desktop channel bus abstract arg (raphael-geffroy) + * bug #59124 [FrameworkBundle] fix: notifier push channel bus abstract arg (raphael-geffroy) + * bug #59069 [Console] Fix division by 0 error (Rindula) + * bug #59086 [FrameworkBundle] Make uri_signer lazy and improve error when kernel.secret is empty (nicolas-grekas) + * bug #59099 [sendgrid-mailer] Fix null check on region (AUDUL) + * bug #59070 [PropertyInfo] evaluate access flags for properties with asymmetric visibility (xabbuh) + * bug #59062 [HttpClient] Always set CURLOPT_CUSTOMREQUEST to the correct HTTP method in CurlHttpClient (KurtThiemann) + * bug #59059 [TwigBridge] generate conflict-free variable names (xabbuh) + * 7.2.0 (2024-11-29) * bug #59023 [HttpClient] Fix streaming and redirecting with NoPrivateNetworkHttpClient (nicolas-grekas) From f9a8854aff0d5637295ab892f5450d3692e208ea Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 11 Dec 2024 13:09:10 +0100 Subject: [PATCH 28/28] Update VERSION for 7.2.1 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 65162adf1996f..82e6dbfbd0c79 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,12 +73,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ private static array $freshCache = []; - public const VERSION = '7.2.1-DEV'; + public const VERSION = '7.2.1'; public const VERSION_ID = 70201; public const MAJOR_VERSION = 7; public const MINOR_VERSION = 2; public const RELEASE_VERSION = 1; - public const EXTRA_VERSION = 'DEV'; + public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '07/2025'; public const END_OF_LIFE = '07/2025'; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy