From 09729e3dbd63b10625c478680495fe1eff28f3f1 Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Tue, 12 Aug 2025 15:54:19 -0600 Subject: [PATCH 1/9] Add docker setup --- .docker/conf/xdebug.ini | 8 ++++++++ Dockerfile | 28 ++++++++++++++++++++++++++++ docker-compose.yaml | 15 +++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 .docker/conf/xdebug.ini create mode 100644 Dockerfile create mode 100644 docker-compose.yaml diff --git a/.docker/conf/xdebug.ini b/.docker/conf/xdebug.ini new file mode 100644 index 00000000..ff5e70d3 --- /dev/null +++ b/.docker/conf/xdebug.ini @@ -0,0 +1,8 @@ +[xdebug] +xdebug.mode=develop,debug +xdebug.idekey=docker +xdebug.start_with_request=yes +xdebug.log=/dev/stdout +xdebug.log_level=0 +xdebug.client_port=9003 +xdebug.client_host=host.docker.internal diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..a4e82194 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +# Use official PHP 8.1 CLI image as base +FROM php:8.2-apache + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + git \ + libzip-dev \ + && docker-php-ext-install zip \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# Install Xdebug +RUN pecl install xdebug && docker-php-ext-enable xdebug + +# Set working directory +WORKDIR /var/www/html/laravel-doctrine-orm + +# Install Laravel dependencies +RUN composer install --no-interaction --optimize-autoloader --dev || true + +# Expose port for Laravel development server +EXPOSE 8000 + +# Start Laravel development server +CMD ["apache2-foreground"] diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 00000000..b384ff6f --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,15 @@ +services: + php: + build: + context: . + dockerfile: Dockerfile + container_name: laravel-doctrine-orm + volumes: + - ./:/var/www/html/laravel-doctrine-orm + - ./.docker/conf/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini + ports: + - "8000:80" + environment: + - XDEBUG_MODE=debug + - XDEBUG_CONFIG=client_host=host.docker.internal client_port=9003 + - PHP_IDE_CONFIG=serverName=laravel-doctrine-orm From 161400c671b7431e5dab34877251a735e6d354d3 Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Tue, 12 Aug 2025 15:54:26 -0600 Subject: [PATCH 2/9] Add fluent driver --- src/Configuration/MetaData/Fluent.php | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/Configuration/MetaData/Fluent.php diff --git a/src/Configuration/MetaData/Fluent.php b/src/Configuration/MetaData/Fluent.php new file mode 100644 index 00000000..022b2a3c --- /dev/null +++ b/src/Configuration/MetaData/Fluent.php @@ -0,0 +1,64 @@ +container = $container; + } + + /** + * @param array $settings + * + * @return mixed + * + * @throws BindingResolutionException + */ + public function resolve(array $settings = []): FluentDriver + { + $driver = new FluentDriver(Arr::get($settings, 'mappings', [])); + + $namingStrategy = $this->getNamingStrategy($settings); + + $driver->setFluentFactory(function (ClassMetadata $meta) use ($namingStrategy) { + return new Builder(new ClassMetadataBuilder($meta), $namingStrategy); + }); + + return $driver; + } + + /** + * @throws BindingResolutionException + */ + protected function getNamingStrategy(array $settings = []): mixed + { + return $this->container->make(Arr::get($settings, 'naming_strategy', LaravelNamingStrategy::class)); + } + + /** + * @throws BindingResolutionException + */ + protected function getQuoteStrategy(array $settings = []): mixed + { + return $this->container->make(Arr::get($settings, 'quote_strategy')); + } + + public function getClassMetadataFactoryName(): string + { + return ExtensibleClassMetadataFactory::class; + } +} From 172887462cd6e14845d42e850d495fcd63871d2e Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Tue, 12 Aug 2025 15:54:37 -0600 Subject: [PATCH 3/9] Fix tests for doctrine/orm 3.5 updates --- tests/Feature/EntityManagerFactoryTest.php | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/Feature/EntityManagerFactoryTest.php b/tests/Feature/EntityManagerFactoryTest.php index af9434a2..5feca1f9 100644 --- a/tests/Feature/EntityManagerFactoryTest.php +++ b/tests/Feature/EntityManagerFactoryTest.php @@ -119,6 +119,8 @@ public function testEntityManagerGetsInstantiatedCorrectly(): void $this->disableCustomFunctions(); $this->enableLaravelNamingStrategy(); + $this->mockConfiguration(); + $manager = $this->factory->create($this->settings); $this->assertEntityManager($manager); @@ -916,24 +918,19 @@ protected function disableCustomFunctions(): void protected function mockORMConfiguration(): void { - $this->configuration = m::mock(Configuration::class); - $this->configuration->shouldReceive('setSQLLogger'); - - $this->configuration->shouldReceive('getMetadataDriverImpl') - ->andReturn($this->mappingDriver); - + $this->mockConfiguration(); $this->configuration->shouldReceive('setMetadataDriverImpl') - ->atLeast()->once(); + ->atLeast()->once(); $this->configuration->shouldReceive('setMiddlewares') ->atLeast()->once(); $this->configuration->shouldReceive('getAutoCommit') - ->atLeast()->once() - ->andReturn(true); + ->atLeast()->once() + ->andReturn(true); $this->configuration->shouldReceive('getClassMetadataFactoryName') - ->atLeast()->once() - ->andReturn('Doctrine\ORM\Mapping\ClassMetadataFactory'); + ->atLeast()->once() + ->andReturn('Doctrine\ORM\Mapping\ClassMetadataFactory'); $this->configuration->shouldReceive('setMetadataCache')->once(); $this->configuration->shouldReceive('setQueryCache')->once(); @@ -993,6 +990,17 @@ protected function mockORMConfiguration(): void $this->configuration->shouldReceive('getSchemaManagerFactory')->once()->andReturn($schemaManagerFactory); } + protected function mockConfiguration(): void + { + $this->configuration = m::mock(Configuration::class); + $this->configuration->shouldReceive('setSQLLogger'); + + $this->configuration->shouldReceive('isNativeLazyObjectsEnabled'); + + $this->configuration->shouldReceive('getMetadataDriverImpl') + ->andReturn($this->mappingDriver); + } + protected function enableLaravelNamingStrategy(): void { $strategy = m::mock(LaravelNamingStrategy::class); From e008fb2843855837b2525a3e60572305326210d5 Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Tue, 12 Aug 2025 15:57:32 -0600 Subject: [PATCH 4/9] Formatting --- tests/Feature/EntityManagerFactoryTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Feature/EntityManagerFactoryTest.php b/tests/Feature/EntityManagerFactoryTest.php index 5feca1f9..48241f94 100644 --- a/tests/Feature/EntityManagerFactoryTest.php +++ b/tests/Feature/EntityManagerFactoryTest.php @@ -920,17 +920,17 @@ protected function mockORMConfiguration(): void { $this->mockConfiguration(); $this->configuration->shouldReceive('setMetadataDriverImpl') - ->atLeast()->once(); + ->atLeast()->once(); $this->configuration->shouldReceive('setMiddlewares') ->atLeast()->once(); $this->configuration->shouldReceive('getAutoCommit') - ->atLeast()->once() - ->andReturn(true); + ->atLeast()->once() + ->andReturn(true); $this->configuration->shouldReceive('getClassMetadataFactoryName') - ->atLeast()->once() - ->andReturn('Doctrine\ORM\Mapping\ClassMetadataFactory'); + ->atLeast()->once() + ->andReturn('Doctrine\ORM\Mapping\ClassMetadataFactory'); $this->configuration->shouldReceive('setMetadataCache')->once(); $this->configuration->shouldReceive('setQueryCache')->once(); From 17d4945722caa8db387b22bdd6a2400d5b9ca16c Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Tue, 12 Aug 2025 16:03:12 -0600 Subject: [PATCH 5/9] Clean up test updates --- tests/Feature/EntityManagerFactoryTest.php | 23 ++++++++-------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/tests/Feature/EntityManagerFactoryTest.php b/tests/Feature/EntityManagerFactoryTest.php index 48241f94..a311f8ac 100644 --- a/tests/Feature/EntityManagerFactoryTest.php +++ b/tests/Feature/EntityManagerFactoryTest.php @@ -119,8 +119,6 @@ public function testEntityManagerGetsInstantiatedCorrectly(): void $this->disableCustomFunctions(); $this->enableLaravelNamingStrategy(); - $this->mockConfiguration(); - $manager = $this->factory->create($this->settings); $this->assertEntityManager($manager); @@ -918,11 +916,17 @@ protected function disableCustomFunctions(): void protected function mockORMConfiguration(): void { - $this->mockConfiguration(); + $this->configuration = m::mock(Configuration::class); + $this->configuration->shouldReceive('setSQLLogger'); + $this->configuration->shouldReceive('isNativeLazyObjectsEnabled'); + + $this->configuration->shouldReceive('getMetadataDriverImpl') + ->andReturn($this->mappingDriver); + $this->configuration->shouldReceive('setMetadataDriverImpl') ->atLeast()->once(); $this->configuration->shouldReceive('setMiddlewares') - ->atLeast()->once(); + ->atLeast()->once(); $this->configuration->shouldReceive('getAutoCommit') ->atLeast()->once() @@ -990,17 +994,6 @@ protected function mockORMConfiguration(): void $this->configuration->shouldReceive('getSchemaManagerFactory')->once()->andReturn($schemaManagerFactory); } - protected function mockConfiguration(): void - { - $this->configuration = m::mock(Configuration::class); - $this->configuration->shouldReceive('setSQLLogger'); - - $this->configuration->shouldReceive('isNativeLazyObjectsEnabled'); - - $this->configuration->shouldReceive('getMetadataDriverImpl') - ->andReturn($this->mappingDriver); - } - protected function enableLaravelNamingStrategy(): void { $strategy = m::mock(LaravelNamingStrategy::class); From 5e2361a36c21cd75b6292c10359f1bb8bf5d48c9 Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Tue, 12 Aug 2025 16:51:52 -0600 Subject: [PATCH 6/9] Follow their phpcs --- src/Configuration/MetaData/Fluent.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Configuration/MetaData/Fluent.php b/src/Configuration/MetaData/Fluent.php index 022b2a3c..d7b43c97 100644 --- a/src/Configuration/MetaData/Fluent.php +++ b/src/Configuration/MetaData/Fluent.php @@ -1,5 +1,7 @@ container = $container; } /** - * @param array $settings - * - * @return mixed + * @param mixed[] $settings * * @throws BindingResolutionException */ public function resolve(array $settings = []): FluentDriver { - $driver = new FluentDriver(Arr::get($settings, 'mappings', [])); + $driver = new FluentDriver(Arr::get($settings, 'mappings', [])); $namingStrategy = $this->getNamingStrategy($settings); - $driver->setFluentFactory(function (ClassMetadata $meta) use ($namingStrategy) { + $driver->setFluentFactory(static function (ClassMetadata $meta) use ($namingStrategy) { return new Builder(new ClassMetadataBuilder($meta), $namingStrategy); }); @@ -42,6 +39,8 @@ public function resolve(array $settings = []): FluentDriver } /** + * @param mixed[] $settings + * * @throws BindingResolutionException */ protected function getNamingStrategy(array $settings = []): mixed @@ -50,6 +49,8 @@ protected function getNamingStrategy(array $settings = []): mixed } /** + * @param mixed[] $settings + * * @throws BindingResolutionException */ protected function getQuoteStrategy(array $settings = []): mixed From d439537d523d71ae2a97421f1014d9a58e5d4f04 Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Thu, 28 Aug 2025 13:40:10 -0600 Subject: [PATCH 7/9] Get ready for upstream PR --- .docker/conf/xdebug.ini | 8 -------- Dockerfile | 28 ---------------------------- docker-compose.yaml | 15 --------------- 3 files changed, 51 deletions(-) delete mode 100644 .docker/conf/xdebug.ini delete mode 100644 Dockerfile delete mode 100644 docker-compose.yaml diff --git a/.docker/conf/xdebug.ini b/.docker/conf/xdebug.ini deleted file mode 100644 index ff5e70d3..00000000 --- a/.docker/conf/xdebug.ini +++ /dev/null @@ -1,8 +0,0 @@ -[xdebug] -xdebug.mode=develop,debug -xdebug.idekey=docker -xdebug.start_with_request=yes -xdebug.log=/dev/stdout -xdebug.log_level=0 -xdebug.client_port=9003 -xdebug.client_host=host.docker.internal diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index a4e82194..00000000 --- a/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# Use official PHP 8.1 CLI image as base -FROM php:8.2-apache - -# Install system dependencies -RUN apt-get update && apt-get install -y \ - git \ - libzip-dev \ - && docker-php-ext-install zip \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Install Composer -RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer - -# Install Xdebug -RUN pecl install xdebug && docker-php-ext-enable xdebug - -# Set working directory -WORKDIR /var/www/html/laravel-doctrine-orm - -# Install Laravel dependencies -RUN composer install --no-interaction --optimize-autoloader --dev || true - -# Expose port for Laravel development server -EXPOSE 8000 - -# Start Laravel development server -CMD ["apache2-foreground"] diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index b384ff6f..00000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,15 +0,0 @@ -services: - php: - build: - context: . - dockerfile: Dockerfile - container_name: laravel-doctrine-orm - volumes: - - ./:/var/www/html/laravel-doctrine-orm - - ./.docker/conf/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini - ports: - - "8000:80" - environment: - - XDEBUG_MODE=debug - - XDEBUG_CONFIG=client_host=host.docker.internal client_port=9003 - - PHP_IDE_CONFIG=serverName=laravel-doctrine-orm From 6d3f7f0d11b2708e7885c3c3862e1a4ed821e80b Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Thu, 28 Aug 2025 18:06:36 -0600 Subject: [PATCH 8/9] Add suggestion back --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 34e37fae..28cef46c 100644 --- a/composer.json +++ b/composer.json @@ -69,6 +69,7 @@ } }, "suggest": { + "laravel-doctrine/fluent": "Fluent mapping driver (alternative to xml, yaml, ... (~2.0).", "fzaninotto/faker": "Required to use the entity factory builder (~1.4).", "laravel-doctrine/acl": "to integrate Doctrine roles & permissions with Laravel's Authorization system (~1.0)", "laravel-doctrine/extensions": "to add Behavioral and Query/Type Extensions for Laravel Doctrine (~1.0)", From c3ef8253ce63a4e434bd0f52e6187c50a5fd2079 Mon Sep 17 00:00:00 2001 From: Mason Eyre Date: Tue, 2 Sep 2025 13:54:03 -0600 Subject: [PATCH 9/9] Add fluent as a type option for meta --- docs/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index b9e9df67..26fa22bd 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -35,7 +35,7 @@ Within the entity manager name array are configuration settings. These are conditional clauses of queries, regardless the place where the SQL is generated * ``mapping_types`` - Link a database type to a local Doctrine type * ``meta`` - The type of metadata configuration. Valid values are - ``attributes``, ``xml``, ``simplified_xml``, ``static_php``, ``php``. + ``attributes``, ``fluent``, ``xml``, ``simplified_xml``, ``static_php``, ``php``. The majority of configurations use ``attributes`` or ``xml`` and these metadata configurations are recommended. * ``namespaces`` - If your entities are not located in the configured app