Skip to content

Commit e30c802

Browse files
Merge branch '5.4' into 6.2
* 5.4: [DependencyInjection] Skip errored definitions deep-referenced as runtime exceptions [Messenger] Preserve existing Doctrine schema [HttpClient] Explicitly exclude CURLOPT_POSTREDIR
2 parents 2e7e0ee + 201d9fb commit e30c802

File tree

13 files changed

+193
-54
lines changed

13 files changed

+193
-54
lines changed

.github/expected-missing-return-types.diff

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ head=$(sed '/^diff /Q' .github/expected-missing-return-types.diff)
66
(echo "$head" && echo && git diff -U2 src/) > .github/expected-missing-return-types.diff
77
git checkout composer.json src/
88

9+
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php
10+
index f52a1ce1e9..1fb72535e1 100644
11+
--- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php
12+
+++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php
13+
@@ -285,5 +285,5 @@ class QueryMock extends AbstractQuery
14+
* @return array|string
15+
*/
16+
- public function getSQL()
17+
+ public function getSQL(): array|string
18+
{
19+
}
20+
@@ -292,5 +292,5 @@ class QueryMock extends AbstractQuery
21+
* @return Result|int
22+
*/
23+
- protected function _doExecute()
24+
+ protected function _doExecute(): Result|int
25+
{
26+
}
927
diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
1028
index bb5560a7b5..be86cbf98e 100644
1129
--- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
@@ -167,7 +185,7 @@ index 6b1c6c5fbe..bb80ed461e 100644
167185
+ public function isFresh(ResourceInterface $resource, int $timestamp): bool;
168186
}
169187
diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php
170-
index d4ec1be090..747e093b1b 100644
188+
index 41548a3e9d..f99739454f 100644
171189
--- a/src/Symfony/Component/Console/Application.php
172190
+++ b/src/Symfony/Component/Console/Application.php
173191
@@ -215,5 +215,5 @@ class Application implements ResetInterface
@@ -276,7 +294,7 @@ index 2762cdf05c..737334268a 100644
276294
+ public function getName(): string;
277295
}
278296
diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php
279-
index 893b3192e9..94822ed191 100644
297+
index 907c9f505c..3bfd23061a 100644
280298
--- a/src/Symfony/Component/Console/Helper/Table.php
281299
+++ b/src/Symfony/Component/Console/Helper/Table.php
282300
@@ -193,5 +193,5 @@ class Table
@@ -322,6 +340,17 @@ index 08bab02ee4..1181f0795e 100644
322340
+ protected function processValue(mixed $value, bool $isRoot = false): mixed
323341
{
324342
if (\is_array($value)) {
343+
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php b/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php
344+
index 895c155e07..3955c902d4 100644
345+
--- a/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php
346+
+++ b/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php
347+
@@ -33,5 +33,5 @@ class DefinitionErrorExceptionPass extends AbstractRecursivePass
348+
* @return void
349+
*/
350+
- public function process(ContainerBuilder $container)
351+
+ public function process(ContainerBuilder $container): void
352+
{
353+
try {
325354
diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php
326355
index f5d33682ff..e644489097 100644
327356
--- a/src/Symfony/Component/DependencyInjection/Container.php
@@ -595,10 +624,10 @@ index 1cb865fd66..f6f4efe7a7 100644
595624
+ public function getName(): string;
596625
}
597626
diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
598-
index f77a99e0ff..a6829efa75 100644
627+
index fb84d96428..8ab979360a 100644
599628
--- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
600629
+++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
601-
@@ -457,5 +457,5 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
630+
@@ -459,5 +459,5 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
602631
* @return Response
603632
*/
604633
- protected function forward(Request $request, bool $catch = false, Response $entry = null)
@@ -922,7 +951,7 @@ index 84a84ad1f3..6f66b6d32a 100644
922951
+ public function supportsDecoding(string $format): bool;
923952
}
924953
diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php
925-
index 829e178407..1ac8101771 100644
954+
index e2b6c1bc8d..3c742d8cab 100644
926955
--- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php
927956
+++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php
928957
@@ -210,5 +210,5 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
@@ -947,7 +976,7 @@ index 829e178407..1ac8101771 100644
947976
{
948977
if (null !== $object = $this->extractObjectToPopulate($class, $context, self::OBJECT_TO_POPULATE)) {
949978
diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
950-
index 7c4c5fb41b..840dd2bcdb 100644
979+
index 98ccfca4e4..0b1bc69b00 100644
951980
--- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
952981
+++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
953982
@@ -139,10 +139,10 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
@@ -969,15 +998,15 @@ index 7c4c5fb41b..840dd2bcdb 100644
969998
- protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, array|bool $allowedAttributes, string $format = null)
970999
+ protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, array|bool $allowedAttributes, string $format = null): object
9711000
{
972-
if ($this->classDiscriminatorResolver && $mapping = $this->classDiscriminatorResolver->getMappingForClass($class)) {
973-
@@ -287,5 +287,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
1001+
if ($class !== $mappedClass = $this->getMappedClass($data, $class, $context)) {
1002+
@@ -276,5 +276,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
9741003
* @return string[]
9751004
*/
9761005
- abstract protected function extractAttributes(object $object, string $format = null, array $context = []);
9771006
+ abstract protected function extractAttributes(object $object, string $format = null, array $context = []): array;
9781007

9791008
/**
980-
@@ -294,15 +294,15 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
1009+
@@ -283,15 +283,15 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
9811010
* @return mixed
9821011
*/
9831012
- abstract protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []);
@@ -997,7 +1026,7 @@ index 7c4c5fb41b..840dd2bcdb 100644
9971026
{
9981027
if (!isset($context['cache_key'])) {
9991028
diff --git a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php
1000-
index ae3adbfe33..3a38429cf1 100644
1029+
index 1786d6fff1..04a2e62ed2 100644
10011030
--- a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php
10021031
+++ b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php
10031032
@@ -45,5 +45,5 @@ interface DenormalizerInterface
@@ -1014,7 +1043,7 @@ index ae3adbfe33..3a38429cf1 100644
10141043
+ public function supportsDenormalization(mixed $data, string $type, string $format = null /* , array $context = [] */): bool;
10151044
}
10161045
diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
1017-
index 691e9c70f0..fc87f672e1 100644
1046+
index cb43d78cc7..d215ffe997 100644
10181047
--- a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
10191048
+++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
10201049
@@ -37,5 +37,5 @@ interface NormalizerInterface
@@ -1090,10 +1119,10 @@ index ee1d68c78f..9baaabb04c 100644
10901119
{
10911120
return self::PROPERTY_CONSTRAINT;
10921121
diff --git a/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php b/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php
1093-
index 9aa01a9dec..c18b07ac46 100644
1122+
index 744a2cd720..b656f2885f 100644
10941123
--- a/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php
10951124
+++ b/src/Symfony/Component/Validator/Test/ConstraintValidatorTestCase.php
1096-
@@ -307,5 +307,5 @@ abstract class ConstraintValidatorTestCase extends TestCase
1125+
@@ -303,5 +303,5 @@ abstract class ConstraintValidatorTestCase extends TestCase
10971126
* @psalm-return T
10981127
*/
10991128
- abstract protected function createValidator();

src/Symfony/Component/Cache/Adapter/DoctrineDbalAdapter.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
2323
use Doctrine\DBAL\Schema\Schema;
2424
use Doctrine\DBAL\Tools\DsnParser;
25-
use Doctrine\ORM\ORMSetup;
2625
use Symfony\Component\Cache\Exception\InvalidArgumentException;
2726
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
2827
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
@@ -87,7 +86,7 @@ public function __construct(Connection|string $connOrDsn, string $namespace = ''
8786
$params = ['url' => $connOrDsn];
8887
}
8988

90-
$config = class_exists(ORMSetup::class) ? ORMSetup::createConfiguration() : new Configuration();
89+
$config = new Configuration();
9190
if (class_exists(DefaultSchemaManagerFactory::class)) {
9291
$config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());
9392
}

src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Compiler;
1313

14+
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
1416
use Symfony\Component\DependencyInjection\ContainerInterface;
1517
use Symfony\Component\DependencyInjection\Definition;
1618
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
@@ -23,31 +25,98 @@
2325
*/
2426
class DefinitionErrorExceptionPass extends AbstractRecursivePass
2527
{
26-
protected function processValue(mixed $value, bool $isRoot = false): mixed
28+
private $erroredDefinitions = [];
29+
private $targetReferences = [];
30+
private $sourceReferences = [];
31+
32+
/**
33+
* @return void
34+
*/
35+
public function process(ContainerBuilder $container)
2736
{
28-
if (!$value instanceof Definition || !$value->hasErrors()) {
29-
return parent::processValue($value, $isRoot);
30-
}
37+
try {
38+
parent::process($container);
39+
40+
if (!$this->erroredDefinitions) {
41+
return;
42+
}
43+
44+
$runtimeIds = [];
45+
46+
foreach ($this->sourceReferences as $id => $sourceIds) {
47+
foreach ($sourceIds as $sourceId => $isRuntime) {
48+
if (!$isRuntime) {
49+
continue 2;
50+
}
51+
}
52+
53+
unset($this->erroredDefinitions[$id]);
54+
$runtimeIds[$id] = $id;
55+
}
56+
57+
if (!$this->erroredDefinitions) {
58+
return;
59+
}
60+
61+
foreach ($this->targetReferences as $id => $targetIds) {
62+
if (!isset($this->sourceReferences[$id]) || isset($runtimeIds[$id]) || isset($this->erroredDefinitions[$id])) {
63+
continue;
64+
}
65+
foreach ($this->targetReferences[$id] as $targetId => $isRuntime) {
66+
foreach ($this->sourceReferences[$id] as $sourceId => $isRuntime) {
67+
if ($sourceId !== $targetId) {
68+
$this->sourceReferences[$targetId][$sourceId] = false;
69+
$this->targetReferences[$sourceId][$targetId] = false;
70+
}
71+
}
72+
}
3173

32-
if ($isRoot && !$value->isPublic()) {
33-
$graph = $this->container->getCompiler()->getServiceReferenceGraph();
34-
$runtimeException = false;
35-
foreach ($graph->getNode($this->currentId)->getInEdges() as $edge) {
36-
if (!$edge->getValue() instanceof Reference || ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE !== $edge->getValue()->getInvalidBehavior()) {
37-
$runtimeException = false;
38-
break;
74+
unset($this->sourceReferences[$id]);
75+
}
76+
77+
foreach ($this->erroredDefinitions as $id => $definition) {
78+
if (isset($this->sourceReferences[$id])) {
79+
continue;
3980
}
40-
$runtimeException = true;
81+
82+
// only show the first error so the user can focus on it
83+
$errors = $definition->getErrors();
84+
85+
throw new RuntimeException(reset($errors));
4186
}
42-
if ($runtimeException) {
43-
return parent::processValue($value, $isRoot);
87+
} finally {
88+
$this->erroredDefinitions = [];
89+
$this->targetReferences = [];
90+
$this->sourceReferences = [];
91+
}
92+
}
93+
94+
protected function processValue(mixed $value, bool $isRoot = false): mixed
95+
{
96+
if ($value instanceof ArgumentInterface) {
97+
parent::processValue($value->getValues());
98+
99+
return $value;
100+
}
101+
102+
if ($value instanceof Reference && $this->currentId !== $targetId = (string) $value) {
103+
if (ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) {
104+
$this->sourceReferences[$targetId][$this->currentId] ??= true;
105+
$this->targetReferences[$this->currentId][$targetId] ??= true;
106+
} else {
107+
$this->sourceReferences[$targetId][$this->currentId] = false;
108+
$this->targetReferences[$this->currentId][$targetId] = false;
44109
}
110+
111+
return $value;
112+
}
113+
114+
if (!$value instanceof Definition || !$value->hasErrors()) {
115+
return parent::processValue($value, $isRoot);
45116
}
46117

47-
// only show the first error so the user can focus on it
48-
$errors = $value->getErrors();
49-
$message = reset($errors);
118+
$this->erroredDefinitions[$this->currentId] = $value;
50119

51-
throw new RuntimeException($message);
120+
return parent::processValue($value);
52121
}
53122
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/DefinitionErrorExceptionPassTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
1717
use Symfony\Component\DependencyInjection\Definition;
1818
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
19+
use Symfony\Component\DependencyInjection\Reference;
1920

2021
class DefinitionErrorExceptionPassTest extends TestCase
2122
{
@@ -49,4 +50,25 @@ public function testNoExceptionThrown()
4950
$pass->process($container);
5051
$this->assertSame($def, $container->getDefinition('foo_service_id')->getArgument(0));
5152
}
53+
54+
public function testSkipNestedErrors()
55+
{
56+
$container = new ContainerBuilder();
57+
58+
$container->register('nested_error', 'stdClass')
59+
->addError('Things went wrong!');
60+
61+
$container->register('bar', 'stdClass')
62+
->addArgument(new Reference('nested_error'));
63+
64+
$container->register('foo', 'stdClass')
65+
->addArgument(new Reference('bar', ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE));
66+
67+
$pass = new DefinitionErrorExceptionPass();
68+
$pass->process($container);
69+
70+
$this->expectException(RuntimeException::class);
71+
$this->expectExceptionMessage('Things went wrong!');
72+
$container->get('foo');
73+
}
5274
}

src/Symfony/Component/HttpClient/CurlHttpClient.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ private function validateExtraCurlOptions(array $options): void
459459
\CURLOPT_TIMEOUT_MS => 'max_duration',
460460
\CURLOPT_TIMEOUT => 'max_duration',
461461
\CURLOPT_MAXREDIRS => 'max_redirects',
462+
\CURLOPT_POSTREDIR => 'max_redirects',
462463
\CURLOPT_PROXY => 'proxy',
463464
\CURLOPT_NOPROXY => 'no_proxy',
464465
\CURLOPT_SSL_VERIFYPEER => 'verify_peer',

src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use Doctrine\DBAL\DriverManager;
1616
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
1717
use Doctrine\DBAL\Tools\DsnParser;
18-
use Doctrine\ORM\ORMSetup;
1918
use Symfony\Component\Cache\Adapter\AbstractAdapter;
2019

2120
/**
@@ -71,7 +70,7 @@ public static function createHandler(object|string $connection, array $options =
7170
}
7271
$connection[3] = '-';
7372
$params = class_exists(DsnParser::class) ? (new DsnParser())->parse($connection) : ['url' => $connection];
74-
$config = class_exists(ORMSetup::class) ? ORMSetup::createConfiguration(true) : new Configuration();
73+
$config = new Configuration();
7574
if (class_exists(DefaultSchemaManagerFactory::class)) {
7675
$config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());
7776
}

src/Symfony/Component/Lock/Store/DoctrineDbalPostgreSqlStore.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
1818
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
1919
use Doctrine\DBAL\Tools\DsnParser;
20-
use Doctrine\ORM\ORMSetup;
2120
use Symfony\Component\Lock\BlockingSharedLockStoreInterface;
2221
use Symfony\Component\Lock\BlockingStoreInterface;
2322
use Symfony\Component\Lock\Exception\InvalidArgumentException;
@@ -69,7 +68,7 @@ public function __construct(Connection|string $connOrUrl)
6968
$params = ['url' => $this->filterDsn($connOrUrl)];
7069
}
7170

72-
$config = class_exists(ORMSetup::class) ? ORMSetup::createConfiguration() : new Configuration();
71+
$config = new Configuration();
7372
if (class_exists(DefaultSchemaManagerFactory::class)) {
7473
$config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());
7574
}

src/Symfony/Component/Lock/Store/DoctrineDbalStore.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
2121
use Doctrine\DBAL\Schema\Schema;
2222
use Doctrine\DBAL\Tools\DsnParser;
23-
use Doctrine\ORM\ORMSetup;
2423
use Symfony\Component\Lock\Exception\InvalidArgumentException;
2524
use Symfony\Component\Lock\Exception\InvalidTtlException;
2625
use Symfony\Component\Lock\Exception\LockConflictedException;
@@ -88,7 +87,7 @@ public function __construct(Connection|string $connOrUrl, array $options = [], f
8887
$params = ['url' => $connOrUrl];
8988
}
9089

91-
$config = class_exists(ORMSetup::class) ? ORMSetup::createConfiguration() : new Configuration();
90+
$config = new Configuration();
9291
if (class_exists(DefaultSchemaManagerFactory::class)) {
9392
$config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());
9493
}

src/Symfony/Component/Lock/Tests/Store/DoctrineDbalPostgreSqlStoreTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Doctrine\DBAL\Exception as DBALException;
1818
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
1919
use Doctrine\DBAL\Tools\DsnParser;
20-
use Doctrine\ORM\ORMSetup;
2120
use Symfony\Component\Lock\Exception\InvalidArgumentException;
2221
use Symfony\Component\Lock\Exception\LockConflictedException;
2322
use Symfony\Component\Lock\Key;
@@ -173,7 +172,7 @@ public function testWaitAndSaveReadAfterConflictReleasesLockFromInternalStore()
173172
private static function getDbalConnection(string $dsn): Connection
174173
{
175174
$params = class_exists(DsnParser::class) ? (new DsnParser(['sqlite' => 'pdo_sqlite']))->parse($dsn) : ['url' => $dsn];
176-
$config = class_exists(ORMSetup::class) ? ORMSetup::createConfiguration(true) : new Configuration();
175+
$config = new Configuration();
177176
if (class_exists(DefaultSchemaManagerFactory::class)) {
178177
$config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());
179178
}

0 commit comments

Comments
 (0)