From 1d5c4f36bfdc00ea438098ed289361ceda414543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Guzm=C3=A1n=20Maeso?= Date: Mon, 5 Jan 2026 23:18:46 +0100 Subject: [PATCH 1/5] feat: rise phpstan level 8 and resolve errors (#2165) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gabriel Ostrolucký --- composer.json | 4 +- phpstan.neon.dist | 2 +- src/Controller/ProfilerController.php | 6 +- src/DataCollector/DoctrineDataCollector.php | 16 ++--- .../Compiler/MiddlewaresPass.php | 3 +- src/DependencyInjection/Configuration.php | 8 --- src/DependencyInjection/DoctrineExtension.php | 8 ++- src/DoctrineBundle.php | 4 ++ src/Twig/DoctrineExtension.php | 18 ++++- tests/Command/DropDatabaseDoctrineTest.php | 2 +- .../DoctrineDataCollectorTest.php | 65 ++++++++++++++++++- tests/DependencyInjection/XMLSchemaTest.php | 36 +++++----- 12 files changed, 128 insertions(+), 44 deletions(-) diff --git a/composer.json b/composer.json index 346012623..f1359bd65 100644 --- a/composer.json +++ b/composer.json @@ -45,10 +45,10 @@ "require-dev": { "doctrine/coding-standard": "^14", "doctrine/orm": "^3.4.4", - "phpstan/phpstan": "2.1.1", + "phpstan/phpstan": "^2.1.13", "phpstan/phpstan-phpunit": "2.0.3", "phpstan/phpstan-strict-rules": "^2", - "phpstan/phpstan-symfony": "^2.0", + "phpstan/phpstan-symfony": "^2.0.9", "phpunit/phpunit": "^12.3.10", "psr/log": "^3.0", "symfony/doctrine-messenger": "^6.4 || ^7.0 || ^8.0", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 36d34a370..692096747 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,7 +1,7 @@ includes: - vendor/phpstan/phpstan-symfony/extension.neon parameters: - level: 7 + level: 8 reportUnmatchedIgnoredErrors: true paths: - config diff --git a/src/Controller/ProfilerController.php b/src/Controller/ProfilerController.php index 3ea193134..69f62f997 100644 --- a/src/Controller/ProfilerController.php +++ b/src/Controller/ProfilerController.php @@ -40,7 +40,11 @@ public function explainAction(string $token, string $connectionName, int $query) { $this->profiler->disable(); - $profile = $this->profiler->loadProfile($token); + $profile = $this->profiler->loadProfile($token); + if ($profile === null) { + return new Response('Profile not found.', 404); + } + $collector = $profile->getCollector('db'); assert($collector instanceof DoctrineDataCollector); diff --git a/src/DataCollector/DoctrineDataCollector.php b/src/DataCollector/DoctrineDataCollector.php index 88e436cc2..7b62373a7 100644 --- a/src/DataCollector/DoctrineDataCollector.php +++ b/src/DataCollector/DoctrineDataCollector.php @@ -66,10 +66,7 @@ class DoctrineDataCollector extends BaseCollector private int|null $managedEntityCount = null; - /** - * @var mixed[][]|null - * @phpstan-var ?GroupedQueriesType - */ + /** @var GroupedQueriesType|null */ private array|null $groupedQueries = null; public function __construct( @@ -77,6 +74,10 @@ public function __construct( private readonly bool $shouldValidateSchema = true, DebugDataHolder|null $debugDataHolder = null, ) { + if ($debugDataHolder === null) { + $debugDataHolder = new DebugDataHolder(); + } + parent::__construct($registry, $debugDataHolder); } @@ -307,10 +308,9 @@ public function getGroupedQueries(): array $this->groupedQueries[$connection] = $connectionGroupedQueries; } - foreach ($this->groupedQueries as $connection => $queries) { - foreach ($queries as $i => $query) { - $this->groupedQueries[$connection][$i]['executionPercent'] = - $this->executionTimePercentage($query['executionMS'], $totalExecutionMS); + foreach ($this->groupedQueries as &$queries) { + foreach ($queries as &$query) { + $query['executionPercent'] = $this->executionTimePercentage($query['executionMS'], $totalExecutionMS); } } diff --git a/src/DependencyInjection/Compiler/MiddlewaresPass.php b/src/DependencyInjection/Compiler/MiddlewaresPass.php index df884b043..1502d07d6 100644 --- a/src/DependencyInjection/Compiler/MiddlewaresPass.php +++ b/src/DependencyInjection/Compiler/MiddlewaresPass.php @@ -64,7 +64,8 @@ public function process(ContainerBuilder $container): void ); $middlewareRefs[$id] = [new Reference($childId), ++$i]; - if (! is_subclass_of($abstractDef->getClass(), ConnectionNameAwareInterface::class)) { + $class = $abstractDef->getClass(); + if ($class === null || ! is_subclass_of($class, ConnectionNameAwareInterface::class)) { continue; } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index f2591c7b1..b74499458 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -67,7 +67,6 @@ private function addDbalSection(ArrayNodeDefinition $node): void // Key that should not be rewritten to the connection config $excludedKeys = ['default_connection' => true, 'driver_schemes' => true, 'driver_scheme' => true, 'types' => true, 'type' => true]; - /** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */ $node ->children() ->arrayNode('dbal') @@ -167,7 +166,6 @@ private function getDbalConnectionsNode(): ArrayNodeDefinition $this->configureDbalDriverNode($connectionNode); - /** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */ $connectionNode ->fixXmlConfig('option') ->fixXmlConfig('mapping_type') @@ -214,7 +212,6 @@ private function getDbalConnectionsNode(): ArrayNodeDefinition ->scalarNode('result_cache')->end() ->end(); - /** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */ $replicaNode = $connectionNode ->children() ->arrayNode('replicas') @@ -232,7 +229,6 @@ private function getDbalConnectionsNode(): ArrayNodeDefinition */ private function configureDbalDriverNode(ArrayNodeDefinition $node): void { - /** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */ $node ->validate() ->always(static function (array $values) { @@ -370,7 +366,6 @@ private function addOrmSection(ArrayNodeDefinition $node): void 'controller_resolver' => true, ]; - /** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */ $node ->children() ->arrayNode('orm') @@ -518,7 +513,6 @@ private function getOrmEntityListenersNode(): NodeDefinition return ['entities' => $entities]; }; - /** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */ $node ->beforeNormalization() // Yaml normalization @@ -564,7 +558,6 @@ private function getOrmEntityManagersNode(): ArrayNodeDefinition $treeBuilder = new TreeBuilder('entity_managers'); $node = $treeBuilder->getRootNode(); - /** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */ $node ->requiresAtLeastOneElement() ->useAttributeAsKey('name') @@ -739,7 +732,6 @@ private function getOrmCacheDriverNode(string $name): ArrayNodeDefinition $treeBuilder = new TreeBuilder($name); $node = $treeBuilder->getRootNode(); - /** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */ $node ->beforeNormalization() ->ifString() diff --git a/src/DependencyInjection/DoctrineExtension.php b/src/DependencyInjection/DoctrineExtension.php index c4573e654..5f372cc42 100644 --- a/src/DependencyInjection/DoctrineExtension.php +++ b/src/DependencyInjection/DoctrineExtension.php @@ -173,9 +173,11 @@ private function loadMappingInformation(array $objectManager, ContainerBuilder $ throw new InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled.', $mappingName)); } - $mappingConfig = $this->getMappingDriverBundleConfigDefaults($mappingConfig, $bundle, $container, $bundleMetadata['path']); - if (! $mappingConfig) { - continue; + if ($bundleMetadata !== null) { + $mappingConfig = $this->getMappingDriverBundleConfigDefaults($mappingConfig, $bundle, $container, $bundleMetadata['path']); + if (! $mappingConfig) { + continue; + } } } elseif (! $mappingConfig['type']) { $mappingConfig['type'] = 'attribute'; diff --git a/src/DoctrineBundle.php b/src/DoctrineBundle.php index e27277708..02d6856cd 100644 --- a/src/DoctrineBundle.php +++ b/src/DoctrineBundle.php @@ -78,6 +78,10 @@ public function process(ContainerBuilder $container): void public function shutdown(): void { + if ($this->container === null) { + return; + } + // Clear all entity managers to clear references to entities for GC if ($this->container->hasParameter('doctrine.entity_managers')) { foreach ($this->container->getParameter('doctrine.entity_managers') as $id) { diff --git a/src/Twig/DoctrineExtension.php b/src/Twig/DoctrineExtension.php index ca466250b..bcf33af5d 100644 --- a/src/Twig/DoctrineExtension.php +++ b/src/Twig/DoctrineExtension.php @@ -7,6 +7,7 @@ use Doctrine\SqlFormatter\HtmlHighlighter; use Doctrine\SqlFormatter\NullHighlighter; use Doctrine\SqlFormatter\SqlFormatter; +use RuntimeException; use Stringable; use Symfony\Component\VarDumper\Cloner\Data; use Twig\Extension\AbstractExtension; @@ -24,11 +25,15 @@ use function is_array; use function is_bool; use function is_string; +use function preg_last_error; use function preg_match; use function preg_replace_callback; +use function sprintf; use function strtoupper; use function substr; +use const PREG_NO_ERROR; + /** * This class contains the needed functions in order to do the query highlighting * @@ -116,7 +121,7 @@ public function replaceQueryParameters(string $query, array|Data $parameters): s $i = 0; - return preg_replace_callback( + $result = preg_replace_callback( '/(? $params Connection parameters + * @param array{url?: string, path?: string, driver: string} $params Connection parameters * @psalm-param Params $params * * @return Stub&Container diff --git a/tests/DataCollector/DoctrineDataCollectorTest.php b/tests/DataCollector/DoctrineDataCollectorTest.php index 6fd7593b3..4b9e57019 100644 --- a/tests/DataCollector/DoctrineDataCollectorTest.php +++ b/tests/DataCollector/DoctrineDataCollectorTest.php @@ -5,6 +5,7 @@ namespace Doctrine\Bundle\DoctrineBundle\Tests\DataCollector; use Doctrine\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector; +use Doctrine\DBAL\Types\Type; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; @@ -21,6 +22,21 @@ use function interface_exists; +/** + * @phpstan-type GroupedQueryItemType = array{ + * executionMS: float, + * explainable: bool, + * sql: string, + * params: ?array, + * runnable: bool, + * types: ?array, + * count: int, + * index: int, + * executionPercent?: float + * } + * @phpstan-type GroupedQueriesType = array> + */ + class DoctrineDataCollectorTest extends TestCase { public const string FIRST_ENTITY = 'TestBundle\Test\Entity\Test1'; @@ -139,6 +155,47 @@ public function testGetGroupedQueries(): void $this->assertSame(1, $groupedQueries['default'][1]['count']); } + public function testGetGroupedQueriesExecutionPercent(): void + { + $debugDataHolder = $this->createStub(DebugDataHolder::class); + + $queries = [ + 'default' => [ + [ + 'sql' => 'SELECT * FROM foo', + 'params' => [], + 'types' => null, + 'executionMS' => 100.0, + ], + [ + 'sql' => 'SELECT * FROM bar', + 'params' => [], + 'types' => null, + 'executionMS' => 200.0, + ], + ], + ]; + + $debugDataHolder->method('getData') + ->willReturnCallback(static function () use (&$queries) { + return $queries; + }); + + $collector = $this->createCollector([], true, $debugDataHolder); + $collector->collect(new Request(), new Response()); + + $groupedQueries = $collector->getGroupedQueries(); + + $this->assertCount(2, $groupedQueries['default']); + + $firstItem = $groupedQueries['default'][0]; + $this->assertEqualsWithDelta(66.667, $firstItem['executionPercent'] ?? null, 0.001); + $this->assertSame('SELECT * FROM bar', $firstItem['sql']); + $secondItem = $groupedQueries['default'][1]; + $this->assertEqualsWithDelta(33.333, $secondItem['executionPercent'] ?? null, 0.001); + $this->assertSame('SELECT * FROM foo', $secondItem['sql']); + } + /** * @param class-string $entityFQCN * @@ -146,9 +203,11 @@ public function testGetGroupedQueries(): void */ private function createEntityMetadata(string $entityFQCN): ClassMetadata { - $metadata = new ClassMetadata($entityFQCN); - $metadata->name = $entityFQCN; - $metadata->reflClass = new ReflectionClass('stdClass'); + $metadata = new ClassMetadata($entityFQCN); + $metadata->name = $entityFQCN; + /** @var ReflectionClass $stdClassReflection */ + $stdClassReflection = new ReflectionClass('stdClass'); + $metadata->reflClass = $stdClassReflection; return $metadata; } diff --git a/tests/DependencyInjection/XMLSchemaTest.php b/tests/DependencyInjection/XMLSchemaTest.php index c2b9aea9e..37410b578 100644 --- a/tests/DependencyInjection/XMLSchemaTest.php +++ b/tests/DependencyInjection/XMLSchemaTest.php @@ -41,28 +41,34 @@ public function testValidateSchema(string $file): void $dbalElements = $dom->getElementsByTagNameNS($xmlns, 'dbal'); if ($dbalElements->length) { - $dbalDom = new DOMDocument('1.0', 'UTF-8'); - $dbalNode = $dbalDom->importNode($dbalElements->item(0)); - $configNode = $dbalDom->createElementNS($xmlns, 'config'); - $configNode->appendChild($dbalNode); - $dbalDom->appendChild($configNode); + $dbalDom = new DOMDocument('1.0', 'UTF-8'); + $dbalElement = $dbalElements->item(0); + if ($dbalElement !== null) { + $dbalNode = $dbalDom->importNode($dbalElement); + $configNode = $dbalDom->createElementNS($xmlns, 'config'); + $configNode->appendChild($dbalNode); + $dbalDom->appendChild($configNode); - $ret = $dbalDom->schemaValidate(__DIR__ . '/../../config/schema/doctrine-1.0.xsd'); - $this->assertTrue($ret, 'DoctrineBundle Dependency Injection XMLSchema did not validate this XML instance.'); - $found = true; + $ret = $dbalDom->schemaValidate(__DIR__ . '/../../config/schema/doctrine-1.0.xsd'); + $this->assertTrue($ret, 'DoctrineBundle Dependency Injection XMLSchema did not validate this XML instance.'); + $found = true; + } } $ormElements = $dom->getElementsByTagNameNS($xmlns, 'orm'); if ($ormElements->length) { $ormDom = new DOMDocument('1.0', 'UTF-8'); - $ormNode = $ormDom->importNode($ormElements->item(0)); - $configNode = $ormDom->createElementNS($xmlns, 'config'); - $configNode->appendChild($ormNode); - $ormDom->appendChild($configNode); + $ormElement = $ormElements->item(0); + if ($ormElement !== null) { + $ormNode = $ormDom->importNode($ormElement); + $configNode = $ormDom->createElementNS($xmlns, 'config'); + $configNode->appendChild($ormNode); + $ormDom->appendChild($configNode); - $ret = $ormDom->schemaValidate(__DIR__ . '/../../config/schema/doctrine-1.0.xsd'); - $this->assertTrue($ret, 'DoctrineBundle Dependency Injection XMLSchema did not validate this XML instance.'); - $found = true; + $ret = $ormDom->schemaValidate(__DIR__ . '/../../config/schema/doctrine-1.0.xsd'); + $this->assertTrue($ret, 'DoctrineBundle Dependency Injection XMLSchema did not validate this XML instance.'); + $found = true; + } } $this->assertTrue($found, 'Neither nor elements found in given XML. Are namespaces configured correctly?'); From a9438aea01b74aa8ec958b3fadd375f88d3550bb Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Sat, 10 Jan 2026 10:46:27 +0100 Subject: [PATCH 2/5] Fix typo in `dbal.connections.default_dbname` configuration --- src/DependencyInjection/Configuration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 196c8e942..10c9f5404 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -357,7 +357,7 @@ private function configureDbalDriverNode(ArrayNodeDefinition $node): void ->end() ->scalarNode('default_dbname') ->info( - 'Override the default database (postgres) to connect to for PostgreSQL connexion.', + 'Override the default database (postgres) to connect to for PostgreSQL connection.', ) ->end() ->scalarNode('sslmode') From 30e0f7336faf922f4f7adc0a91ff01d2c6dcb176 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Fri, 23 Jan 2026 16:27:37 +0100 Subject: [PATCH 3/5] Fix attribute driver mapping pass compatibility with ORM 3 (#2120) --- .../Compiler/DoctrineOrmMappingsPass.php | 11 ++++++- .../Compiler/DoctrineOrmMappingsPassTest.php | 32 +++++++++++++++++++ tests/TestCase.php | 7 +++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php b/src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php index 4ec6bd378..2ec6cb7ad 100644 --- a/src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php +++ b/src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php @@ -16,6 +16,8 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; +use function method_exists; + /** * Class for Symfony bundles to configure mappings for model classes not in the * auto-mapped folder. @@ -177,7 +179,14 @@ public static function createAnnotationMappingDriver(array $namespaces, array $d */ public static function createAttributeMappingDriver(array $namespaces, array $directories, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [], bool $reportFieldsWhereDeclared = false) { - $driver = new Definition(AttributeDriver::class, [$directories, $reportFieldsWhereDeclared]); + $driverArgs = [$directories]; + + // Add additional args for ORM <3.0 + if (method_exists(AttributeDriver::class, 'getReader')) { + $driverArgs[] = $reportFieldsWhereDeclared; + } + + $driver = new Definition(AttributeDriver::class, $driverArgs); return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap); } diff --git a/tests/DependencyInjection/Compiler/DoctrineOrmMappingsPassTest.php b/tests/DependencyInjection/Compiler/DoctrineOrmMappingsPassTest.php index 1736cef2a..ae992a50b 100644 --- a/tests/DependencyInjection/Compiler/DoctrineOrmMappingsPassTest.php +++ b/tests/DependencyInjection/Compiler/DoctrineOrmMappingsPassTest.php @@ -7,7 +7,15 @@ use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass; use Doctrine\Bundle\DoctrineBundle\Tests\TestCase; use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Mapping\Driver\AttributeDriver; +use Doctrine\Persistence\Mapping\Driver\MappingDriverChain; use PHPUnit\Framework\Attributes\IgnoreDeprecations; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +use function assert; +use function interface_exists; +use function realpath; class DoctrineOrmMappingsPassTest extends TestCase { @@ -31,4 +39,28 @@ public function testCreateAnnotationMappingDriverIsDeprecated(): void ['/path/to/entities'], ); } + + public function testAttributeDriverIsRegistered(): void + { + if (! interface_exists(EntityManagerInterface::class)) { + self::markTestSkipped('This test requires ORM'); + } + + $driverNamespace = 'DoctrineBundle\Entity'; + $container = $this->createXmlBundleTestContainer( + static function (ContainerBuilder $containerBuilder) use ($driverNamespace): void { + $containerBuilder->addCompilerPass(DoctrineOrmMappingsPass::createAttributeMappingDriver( + [$driverNamespace], + [realpath(__DIR__ . '/Entity')], + reportFieldsWhereDeclared: true, + )); + }, + ); + + $metadataDriver = $container->get('doctrine.orm.default_metadata_driver'); + assert($metadataDriver instanceof MappingDriverChain); + + $driver = $metadataDriver->getDrivers()[$driverNamespace]; + $this->assertTrue($driver instanceof AttributeDriver); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 137460c26..962e05730 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -22,7 +22,7 @@ class TestCase extends BaseTestCase { - public function createXmlBundleTestContainer(): ContainerBuilder + public function createXmlBundleTestContainer(callable|null $func = null): ContainerBuilder { $container = new ContainerBuilder(new ParameterBag([ 'kernel.debug' => false, @@ -90,6 +90,11 @@ public function createXmlBundleTestContainer(): ContainerBuilder $compilerPassConfig->addPass(new CacheCompatibilityPass()); // make all Doctrine services public, so we can fetch them in the test $compilerPassConfig->addPass(new TestCaseAllPublicCompilerPass()); + + if ($func !== null) { + $func($container); + } + $container->compile(); return $container; From 00f7a51136518abc53c1e5d617de849e38732e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Wed, 11 Feb 2026 20:28:26 +0100 Subject: [PATCH 4/5] Address PHPUnit deprecation Using with() on a stub is deprecated. We don't want to check that we call this object with 'doctrine', we just want to only return $mockDoctrine when it is called with 'doctrine' and nothing else. --- tests/Command/CreateDatabaseDoctrineTest.php | 2 +- tests/Command/DropDatabaseDoctrineTest.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/Command/CreateDatabaseDoctrineTest.php b/tests/Command/CreateDatabaseDoctrineTest.php index 113ee347e..700d935e5 100644 --- a/tests/Command/CreateDatabaseDoctrineTest.php +++ b/tests/Command/CreateDatabaseDoctrineTest.php @@ -77,7 +77,7 @@ private function getMockContainer(string $connectionName, array|null $params = n $mockContainer = $this->createStub(Container::class); - $mockContainer->method('get')->with('doctrine')->willReturn($mockDoctrine); + $mockContainer->method('get')->willReturnMap([['doctrine', $mockDoctrine]]); return $mockContainer; } diff --git a/tests/Command/DropDatabaseDoctrineTest.php b/tests/Command/DropDatabaseDoctrineTest.php index c691867ef..aa706c31f 100644 --- a/tests/Command/DropDatabaseDoctrineTest.php +++ b/tests/Command/DropDatabaseDoctrineTest.php @@ -156,8 +156,7 @@ private function getMockContainer(string $connectionName, array $params): Stub $mockContainer = $this->createStub(Container::class); $mockContainer->method('get') - ->with('doctrine') - ->willReturn($mockDoctrine); + ->willReturnMap([['doctrine', $mockDoctrine]]); return $mockContainer; } From 4f222e03bf170da679d9402c31da27453ca2e530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Wed, 11 Feb 2026 20:29:17 +0100 Subject: [PATCH 5/5] Add dev dependency on symfony/http-kernel Not having a version constraint for this package causes deprecations because it expects the framework bundle to define its extension by extending a non deprecated class, and that is not the case with v7 of that bundle. --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 4a0309ff0..a2688cbda 100644 --- a/composer.json +++ b/composer.json @@ -55,6 +55,7 @@ "psr/log": "^1.1.4 || ^2.0 || ^3.0", "symfony/doctrine-messenger": "^6.4 || ^7.0", "symfony/expression-language": "^6.4 || ^7.0", + "symfony/http-kernel": "^6.4 || ^7.0", "symfony/messenger": "^6.4 || ^7.0", "symfony/property-info": "^6.4 || ^7.0", "symfony/security-bundle": "^6.4 || ^7.0",