diff --git a/.doctrine-project.json b/.doctrine-project.json index 73ba9db54..3dacd1753 100644 --- a/.doctrine-project.json +++ b/.doctrine-project.json @@ -5,22 +5,40 @@ "slug": "doctrine-bundle", "versions": [ { - "name": "3.0", - "branchName": "3.0.x", + "name": "4.0", + "branchName": "4.0.x", "slug": "latest", "upcoming": true }, + { + "name": "3.1", + "branchName": "3.1.x", + "slug": "3.1", + "upcoming": true + }, + { + "name": "3.0", + "branchName": "3.0.x", + "slug": "3.0", + "current": true + }, + { + "name": "2.19", + "branchName": "2.19.x", + "slug": "2.19", + "maintained": true + }, { "name": "2.18", "branchName": "2.18.x", "slug": "2.18", - "upcoming": true + "maintained": true }, { "name": "2.17", "branchName": "2.17.x", "slug": "2.17", - "current": true + "maintained": false }, { "name": "2.16", diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 15bd17299..b789cbb46 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,4 @@ updates: interval: "weekly" labels: - "CI" + target-branch: "2.18.x" diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 52b7ea770..8e159f1d5 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -26,6 +26,6 @@ on: jobs: coding-standards: name: "Coding Standards" - uses: "doctrine/.github/.github/workflows/coding-standards.yml@8.0.0" + uses: "doctrine/.github/.github/workflows/coding-standards.yml@v12.2.0" with: composer-options: "--prefer-dist --prefer-stable" diff --git a/.github/workflows/composer-lint.yml b/.github/workflows/composer-lint.yml index d679fb032..a9876185a 100644 --- a/.github/workflows/composer-lint.yml +++ b/.github/workflows/composer-lint.yml @@ -17,4 +17,4 @@ on: jobs: composer-lint: name: "Composer Lint" - uses: "doctrine/.github/.github/workflows/composer-lint.yml@8.0.0" + uses: "doctrine/.github/.github/workflows/composer-lint.yml@v12.2.0" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 6b74226f5..c6073130d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -113,7 +113,7 @@ jobs: run: "vendor/bin/phpunit --coverage-clover=coverage.xml" - name: "Upload coverage file" - uses: "actions/upload-artifact@v4" + uses: "actions/upload-artifact@v5" with: name: "phpunit-${{ matrix.php-version }}-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}.coverage" path: "coverage.xml" @@ -133,7 +133,7 @@ jobs: fetch-depth: 2 - name: "Download coverage files" - uses: "actions/download-artifact@v5" + uses: "actions/download-artifact@v6" with: path: "reports" diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 1a6b13918..7722f764f 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -17,4 +17,4 @@ on: jobs: documentation: name: "Documentation" - uses: "doctrine/.github/.github/workflows/documentation.yml@8.0.0" \ No newline at end of file + uses: "doctrine/.github/.github/workflows/documentation.yml@v12.2.0" \ No newline at end of file diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index 29770e22e..634210120 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -8,7 +8,7 @@ on: jobs: release: name: "Git tag, release & create merge-up PR" - uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@8.0.0" + uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@v12.2.0" secrets: GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }} GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }} diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index a951d95be..19cd93448 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -26,4 +26,4 @@ on: jobs: static-analysis: name: "Static Analysis" - uses: "doctrine/.github/.github/workflows/phpstan.yml@8.0.0" + uses: "doctrine/.github/.github/workflows/phpstan.yml@v12.2.0" diff --git a/.github/workflows/website-schema.yml b/.github/workflows/website-schema.yml index e7c8e15bb..80312010a 100644 --- a/.github/workflows/website-schema.yml +++ b/.github/workflows/website-schema.yml @@ -18,4 +18,4 @@ on: jobs: json-validate: name: "Validate JSON schema" - uses: "doctrine/.github/.github/workflows/website-schema.yml@8.0.0" + uses: "doctrine/.github/.github/workflows/website-schema.yml@v12.2.0" diff --git a/.symfony.bundle.yaml b/.symfony.bundle.yaml index f06cf8cb6..ee9e166a6 100644 --- a/.symfony.bundle.yaml +++ b/.symfony.bundle.yaml @@ -13,9 +13,16 @@ branches: - "2.16.x" - "2.17.x" - "2.18.x" + - "2.19.x" + - "3.0.x" + - "3.1.x" + - "4.0.x" maintained_branches: - - "2.17.x" - "2.18.x" + - "2.19.x" + - "3.0.x" + - "3.1.x" + - "4.0.x" doc_dir: "docs/en/" -current_branch: "2.17.x" -dev_branch: "2.18.x" +current_branch: "3.0.x" +dev_branch: "3.1.x" diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 6289a936e..733262d46 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -57,6 +57,13 @@ have been removed: - `doctrine.orm.entity_managers.some_em.report_fields_where_declared` - `doctrine.orm.enable_lazy_ghost_objects` +Also, the 3 following options were no-ops when enabling native lazy objects +and have been removed as well: + +- `doctrine.orm.auto_generate_proxy_classes` +- `doctrine.orm.proxy_dir` +- `doctrine.orm.proxy_namespace` + ### The `doctrine.dbal.default_table_options.collate` default table option is removed Use `doctrine.dbal.default_table_options.collation` instead. diff --git a/docs/composer.json b/docs/composer.json new file mode 100644 index 000000000..5072d501c --- /dev/null +++ b/docs/composer.json @@ -0,0 +1,8 @@ +{ + "require-dev": { + "doctrine/docs-builder": "^1.0" + }, + "config": { + "sort-packages": true + } +} diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 29a8c8a53..b75095f71 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -4,8 +4,6 @@ parameters: - config - src - tests - scanFiles: - - vendor/symfony/dependency-injection/Loader/Configurator/functions.php ignoreErrors: # phpstan has no array shape intersection support https://github.com/phpstan/phpstan/issues/12414 - message: '#unresolvable type.#' diff --git a/src/Twig/DoctrineExtension.php b/src/Twig/DoctrineExtension.php index 822e446ff..db8057cc0 100644 --- a/src/Twig/DoctrineExtension.php +++ b/src/Twig/DoctrineExtension.php @@ -57,7 +57,7 @@ public function getFilters(): array * * @internal */ - public static function escapeFunction(mixed $parameter): string|int + public static function escapeFunction(mixed $parameter): string|int|float { $result = $parameter; diff --git a/tests/CacheSchemaSubscriberTest.php b/tests/CacheSchemaSubscriberTest.php index f74eccc1b..7dfe2967f 100644 --- a/tests/CacheSchemaSubscriberTest.php +++ b/tests/CacheSchemaSubscriberTest.php @@ -32,8 +32,10 @@ public function testSchemaSubscriberWiring(): void 'kernel.build_dir' => sys_get_temp_dir(), 'kernel.environment' => 'test', 'kernel.runtime_environment' => '%%env(default:kernel.environment:APP_RUNTIME_ENV)%%', + 'kernel.runtime_mode.web' => false, 'kernel.root_dir' => __DIR__ . '/../../../../', // src dir 'kernel.project_dir' => __DIR__ . '/../../../../', // src dir + 'kernel.share_dir' => sys_get_temp_dir(), 'kernel.bundles_metadata' => [], 'kernel.charset' => 'UTF-8', 'kernel.container_class' => ContainerBuilder::class, diff --git a/tests/Command/CreateDatabaseDoctrineTest.php b/tests/Command/CreateDatabaseDoctrineTest.php index 849c4e061..113ee347e 100644 --- a/tests/Command/CreateDatabaseDoctrineTest.php +++ b/tests/Command/CreateDatabaseDoctrineTest.php @@ -11,7 +11,7 @@ use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Schema\SchemaManagerFactory; use Doctrine\Persistence\ManagerRegistry; -use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\DependencyInjection\Container; @@ -59,25 +59,23 @@ public function testExecute(): void * @param mixed[]|null $params Connection parameters * @psalm-param Params $params * - * @return MockObject&Container + * @return Stub&Container */ - private function getMockContainer(string $connectionName, array|null $params = null): MockObject + private function getMockContainer(string $connectionName, array|null $params = null): Stub { // Mock the container and everything you'll need here $mockDoctrine = $this->createStub(ManagerRegistry::class); $mockDoctrine->method('getDefaultConnectionName')->willReturn($connectionName); - $config = (new Configuration())->setSchemaManagerFactory($this->createMock(SchemaManagerFactory::class)); + $config = (new Configuration())->setSchemaManagerFactory($this->createStub(SchemaManagerFactory::class)); $mockConnection = $this->createStub(Connection::class); $mockConnection->method('getConfiguration')->willReturn($config); $mockConnection->method('getParams')->willReturn($params); $mockDoctrine->method('getConnection')->willReturn($mockConnection); - $mockContainer = $this->getMockBuilder(Container::class) - ->onlyMethods(['get']) - ->getMock(); + $mockContainer = $this->createStub(Container::class); $mockContainer->method('get')->with('doctrine')->willReturn($mockDoctrine); diff --git a/tests/Command/DropDatabaseDoctrineTest.php b/tests/Command/DropDatabaseDoctrineTest.php index f7176499d..c691867ef 100644 --- a/tests/Command/DropDatabaseDoctrineTest.php +++ b/tests/Command/DropDatabaseDoctrineTest.php @@ -14,7 +14,7 @@ use Doctrine\Persistence\ManagerRegistry; use Generator; use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\DependencyInjection\Container; @@ -137,9 +137,9 @@ public static function provideIncompatibleDriverOptions(): Generator * @param list $params Connection parameters * @psalm-param Params $params * - * @return MockObject&Container + * @return Stub&Container */ - private function getMockContainer(string $connectionName, array $params): MockObject + private function getMockContainer(string $connectionName, array $params): Stub { // Mock the container and everything you'll need here $mockDoctrine = $this->createStub(ManagerRegistry::class); @@ -148,18 +148,16 @@ private function getMockContainer(string $connectionName, array $params): MockOb $config = (new Configuration())->setSchemaManagerFactory(new DefaultSchemaManagerFactory()); - $mockConnection = $this->createMock(Connection::class); + $mockConnection = $this->createStub(Connection::class); $mockConnection->method('getConfiguration')->willReturn($config); $mockConnection->method('getParams')->willReturn($params); $mockDoctrine->method('getConnection')->willReturn($mockConnection); - $mockContainer = $this->getMockBuilder(Container::class) - ->onlyMethods(['get']) - ->getMock(); + $mockContainer = $this->createStub(Container::class); $mockContainer->method('get') - ->with('doctrine') - ->willReturn($mockDoctrine); + ->with('doctrine') + ->willReturn($mockDoctrine); return $mockContainer; } diff --git a/tests/DataCollector/DoctrineDataCollectorTest.php b/tests/DataCollector/DoctrineDataCollectorTest.php index de4a0be1e..4bb573642 100644 --- a/tests/DataCollector/DoctrineDataCollectorTest.php +++ b/tests/DataCollector/DoctrineDataCollectorTest.php @@ -35,8 +35,8 @@ public function testCollectEntities(): void $manager = $this->createStub(EntityManagerInterface::class); $config = $this->createMock(Configuration::class); $factory = $this->createMock(ClassMetadataFactory::class); - $collector = $this->createCollector(['default' => $manager], true, $this->createMock(DebugDataHolder::class)); - $unitOfWork = $this->createMock(UnitOfWork::class); + $collector = $this->createCollector(['default' => $manager], true, $this->createStub(DebugDataHolder::class)); + $unitOfWork = $this->createStub(UnitOfWork::class); $manager->method('getMetadataFactory')->willReturn($factory); $manager->method('getConfiguration')->willReturn($config); @@ -74,8 +74,8 @@ public function testDoesNotCollectEntities(): void } $manager = $this->createMock(EntityManager::class); - $config = $this->createMock(Configuration::class); - $collector = $this->createCollector(['default' => $manager], false, $this->createMock(DebugDataHolder::class)); + $config = $this->createStub(Configuration::class); + $collector = $this->createCollector(['default' => $manager], false, $this->createStub(DebugDataHolder::class)); $unitOfWork = $this->createStub(UnitOfWork::class); $manager->expects($this->never())->method('getMetadataFactory'); @@ -91,7 +91,7 @@ public function testDoesNotCollectEntities(): void public function testGetGroupedQueries(): void { - $debugDataHolder = $this->createMock(DebugDataHolder::class); + $debugDataHolder = $this->createStub(DebugDataHolder::class); $queries = [ 'default' => [ diff --git a/tests/DependencyInjection/Compiler/IdGeneratorPassTest.php b/tests/DependencyInjection/Compiler/IdGeneratorPassTest.php index ad1576fd6..8b450e765 100644 --- a/tests/DependencyInjection/Compiler/IdGeneratorPassTest.php +++ b/tests/DependencyInjection/Compiler/IdGeneratorPassTest.php @@ -48,8 +48,10 @@ public function testRepositoryServiceWiring(): void 'kernel.bundles' => $bundles, 'kernel.cache_dir' => sys_get_temp_dir(), 'kernel.build_dir' => sys_get_temp_dir(), + 'kernel.share_dir' => sys_get_temp_dir(), 'kernel.environment' => 'test', 'kernel.runtime_environment' => '%%env(default:kernel.environment:APP_RUNTIME_ENV)%%', + 'kernel.runtime_mode.web' => false, 'kernel.root_dir' => __DIR__ . '/../../../../', // src dir 'kernel.project_dir' => __DIR__ . '/../../../../', // src dir 'kernel.bundles_metadata' => [], diff --git a/tests/LockStoreSchemaListenerTest.php b/tests/LockStoreSchemaListenerTest.php index dd0989c28..d9e9bc730 100644 --- a/tests/LockStoreSchemaListenerTest.php +++ b/tests/LockStoreSchemaListenerTest.php @@ -31,8 +31,10 @@ public function testLockStoreSchemaSubscriberWiring(array $config, int $expected 'kernel.bundles' => [], 'kernel.cache_dir' => sys_get_temp_dir(), 'kernel.build_dir' => sys_get_temp_dir(), + 'kernel.share_dir' => sys_get_temp_dir(), 'kernel.environment' => 'test', 'kernel.runtime_environment' => '%%env(default:kernel.environment:APP_RUNTIME_ENV)%%', + 'kernel.runtime_mode.web' => false, 'kernel.root_dir' => __DIR__ . '/../../../../', // src dir 'kernel.project_dir' => __DIR__ . '/../../../../', // src dir 'kernel.bundles_metadata' => [], diff --git a/tests/Middleware/IdleConnectionMiddlewareTest.php b/tests/Middleware/IdleConnectionMiddlewareTest.php index 947103e2a..eab572ff2 100644 --- a/tests/Middleware/IdleConnectionMiddlewareTest.php +++ b/tests/Middleware/IdleConnectionMiddlewareTest.php @@ -25,7 +25,7 @@ public function testWrap(): void $middleware = new IdleConnectionMiddleware($connectionExpiries, $ttlByConnection); $middleware->setConnectionName('connectionone'); - $driverMock = $this->createMock(Driver::class); + $driverMock = $this->createStub(Driver::class); $wrappedDriver = $middleware->wrap($driverMock); $this->assertInstanceOf(IdleConnectionDriver::class, $wrappedDriver); diff --git a/tests/ProfilerTest.php b/tests/ProfilerTest.php index 3e9e30318..ae2cbcad1 100644 --- a/tests/ProfilerTest.php +++ b/tests/ProfilerTest.php @@ -43,7 +43,7 @@ class ProfilerTest extends BaseTestCase public function setUp(): void { $this->debugDataHolder = new DebugDataHolder(); - $registry = $this->getMockBuilder(ManagerRegistry::class)->getMock(); + $registry = $this->createStub(ManagerRegistry::class); $registry->method('getConnectionNames')->willReturn([]); $registry->method('getManagerNames')->willReturn([]); $registry->method('getManagers')->willReturn([]); @@ -53,14 +53,12 @@ public function setUp(): void $twigLoaderFilesystem->addPath(__DIR__ . '/../vendor/symfony/web-profiler-bundle/Resources/views', 'WebProfiler'); $this->twig = new Environment($twigLoaderFilesystem, ['debug' => true, 'strict_variables' => true]); - $fragmentHandler = $this->getMockBuilder(FragmentHandler::class); - $fragmentHandler->disableOriginalConstructor(); - $fragmentHandler = $fragmentHandler->getMock(); + $fragmentHandler = $this->createStub(FragmentHandler::class); $fragmentHandler->method('render')->willReturn(''); $kernelRuntime = new HttpKernelRuntime($fragmentHandler); - $urlGenerator = $this->getMockBuilder(UrlGeneratorInterface::class)->getMock(); + $urlGenerator = $this->createStub(UrlGeneratorInterface::class); $urlGenerator->method('generate')->willReturn(''); if (class_exists(CodeExtension::class)) { diff --git a/tests/RegistryTest.php b/tests/RegistryTest.php index 8384693dd..a643a2c16 100644 --- a/tests/RegistryTest.php +++ b/tests/RegistryTest.php @@ -36,7 +36,7 @@ public function testGetDefaultEntityManagerName(): void public function testGetDefaultConnection(): void { - $conn = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); + $conn = $this->createStub(Connection::class); $container = new Container(); $container->set('doctrine.dbal.default_connection', $conn); @@ -47,7 +47,7 @@ public function testGetDefaultConnection(): void public function testGetConnection(): void { - $conn = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); + $conn = $this->createStub(Connection::class); $container = new Container(); $container->set('doctrine.dbal.default_connection', $conn); @@ -74,7 +74,7 @@ public function testGetConnectionNames(): void public function testGetDefaultEntityManager(): void { - $em = $this->createMock(ObjectManager::class); + $em = $this->createStub(ObjectManager::class); $container = new Container(); $container->set('doctrine.orm.default_entity_manager', $em); @@ -85,7 +85,7 @@ public function testGetDefaultEntityManager(): void public function testGetEntityManager(): void { - $em = $this->createMock(ObjectManager::class); + $em = $this->createStub(ObjectManager::class); $container = new Container(); $container->set('doctrine.orm.default_entity_manager', $em); diff --git a/tests/Repository/ServiceEntityRepositoryTest.php b/tests/Repository/ServiceEntityRepositoryTest.php index eab026a84..db1f91c14 100644 --- a/tests/Repository/ServiceEntityRepositoryTest.php +++ b/tests/Repository/ServiceEntityRepositoryTest.php @@ -25,7 +25,7 @@ public static function setUpBeforeClass(): void public function testConstructorThrowsExceptionWhenNoManagerFound(): void { - $registry = $this->getMockBuilder(ManagerRegistry::class)->getMock(); + $registry = $this->createStub(ManagerRegistry::class); $this->expectException(LogicException::class); $this->expectExceptionMessage(<<<'EXCEPTION' Could not find the entity manager for class "Doctrine\Bundle\DoctrineBundle\Tests\Repository\TestEntity". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata. diff --git a/tests/ServiceRepositoryTest.php b/tests/ServiceRepositoryTest.php index 6cde5b384..1e99c19f4 100644 --- a/tests/ServiceRepositoryTest.php +++ b/tests/ServiceRepositoryTest.php @@ -44,8 +44,10 @@ public function testRepositoryServiceWiring(): void 'kernel.build_dir' => sys_get_temp_dir(), 'kernel.environment' => 'test', 'kernel.runtime_environment' => '%%env(default:kernel.environment:APP_RUNTIME_ENV)%%', + 'kernel.runtime_mode.web' => false, 'kernel.root_dir' => __DIR__ . '/../../../../', // src dir 'kernel.project_dir' => __DIR__ . '/../../../../', // src dir + 'kernel.share_dir' => sys_get_temp_dir(), 'kernel.bundles_metadata' => [], 'kernel.charset' => 'UTF-8', 'kernel.container_class' => ContainerBuilder::class, diff --git a/tests/Twig/DoctrineExtensionTest.php b/tests/Twig/DoctrineExtensionTest.php index 02e613034..78bb14512 100644 --- a/tests/Twig/DoctrineExtensionTest.php +++ b/tests/Twig/DoctrineExtensionTest.php @@ -113,6 +113,11 @@ public function testEscapeBooleanParameter(): void { $this->assertEquals('1', DoctrineExtension::escapeFunction(true)); } + + public function testNoEscapeFloatParameter(): void + { + $this->assertEquals(1.1, DoctrineExtension::escapeFunction(1.1)); + } } class DummyClass