From f7f3f0816aff828a7ee63cc662484ea3c0a6a022 Mon Sep 17 00:00:00 2001 From: Michal Haltuf Date: Tue, 21 Oct 2025 10:22:58 +0200 Subject: [PATCH 1/4] fix phpstan --- src/DI/OrmExtension.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DI/OrmExtension.php b/src/DI/OrmExtension.php index 37271f8ae..3ae61d1ab 100644 --- a/src/DI/OrmExtension.php +++ b/src/DI/OrmExtension.php @@ -21,21 +21,21 @@ /** * @property-read stdClass $config * @phpstan-type TManagerConfig object{ - * entityManagerDecoratorClass: string, + * entityManagerDecoratorClass: string|null, * configurationClass: string, * lazyNativeObjects: bool|null, * proxyDir: string|null, * autoGenerateProxyClasses: int|bool|Statement, * proxyNamespace: string|null, - * metadataDriverImpl: string, + * metadataDriverImpl: string|null, * entityNamespaces: array, * resolveTargetEntities: array, * customStringFunctions: array, * customNumericFunctions: array, * customDatetimeFunctions: array, * customHydrationModes: array, - * classMetadataFactoryName: string, - * defaultRepositoryClassName: string, + * classMetadataFactoryName: string|null, + * defaultRepositoryClassName: string|null, * namingStrategy: string|Statement|null, * quoteStrategy: string|Statement|null, * entityListenerResolver: string|Statement|null, From e9ea86d0aafe3a24639768262e83abf9bc79750b Mon Sep 17 00:00:00 2001 From: Michal Haltuf Date: Tue, 21 Oct 2025 10:49:20 +0200 Subject: [PATCH 2/4] add options structure into mapping --- src/DI/OrmExtension.php | 6 +++++- src/DI/Pass/ManagerPass.php | 2 +- tests/Cases/DI/OrmExtension.mapping.phpt | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/DI/OrmExtension.php b/src/DI/OrmExtension.php index 3ae61d1ab..bddef8513 100644 --- a/src/DI/OrmExtension.php +++ b/src/DI/OrmExtension.php @@ -42,7 +42,7 @@ * repositoryFactory: string|Statement|null, * defaultQueryHints: array, * filters: array, - * mapping: array, + * mapping: array, * defaultCache: string|Statement|null, * queryCache: string|Statement|null, * resultCache: string|Statement|null, @@ -128,6 +128,10 @@ public function getConfigSchema(): Schema 'type' => Expect::anyOf('attributes', 'xml')->default('attributes'), 'directories' => Expect::listOf(Expect::string())->min(1)->required(), 'namespace' => Expect::string()->required(), + 'options' => Expect::structure([ + 'fileExtension' => Expect::string()->default('.orm.xml'), + 'xsdValidation' => Expect::bool()->default(true), + ]), ]), Expect::string() )->required()->assert(fn ($input) => count($input) > 0, 'At least one mapping must be defined'), diff --git a/src/DI/Pass/ManagerPass.php b/src/DI/Pass/ManagerPass.php index 007d56bea..77f5f18a2 100644 --- a/src/DI/Pass/ManagerPass.php +++ b/src/DI/Pass/ManagerPass.php @@ -277,7 +277,7 @@ public function loadManagerConfiguration(string $managerName, mixed $managerConf ]); } elseif ($mapping->type === 'xml') { $mappingDriver->addSetup('addDriver', [ - new Statement(SimplifiedXmlDriver::class, [array_combine($mapping->directories, array_fill(0, count($mapping->directories), $mapping->namespace))]), + new Statement(SimplifiedXmlDriver::class, [array_combine($mapping->directories, array_fill(0, count($mapping->directories), $mapping->namespace)), $mapping->options->fileExtension, $mapping->options->xsdValidation]), $mapping->namespace, ]); } else { diff --git a/tests/Cases/DI/OrmExtension.mapping.phpt b/tests/Cases/DI/OrmExtension.mapping.phpt index ceeca446f..330d5b387 100644 --- a/tests/Cases/DI/OrmExtension.mapping.phpt +++ b/tests/Cases/DI/OrmExtension.mapping.phpt @@ -93,6 +93,9 @@ Toolkit::test(function (): void { type: xml directories: [%fixturesDir%/Entity, %fixturesDir%/../Toolkit] namespace: Tests\Mocks\Dummy + options: + fileExtension: .custom.xml + xsdValidation: false NEON )); }) @@ -108,6 +111,10 @@ Toolkit::test(function (): void { Assert::type(SimplifiedXmlDriver::class, $xmlDriver); Assert::equal([], $xmlDriver->getAllClassNames()); Assert::count(2, $xmlDriver->getLocator()->getPaths()); + Assert::equal('.custom.xml', $xmlDriver->getLocator()->getFileExtension()); + + $r = (new ReflectionClass($xmlDriver))->getParentClass(); + Assert::false($r->getProperty('isXsdValidationEnabled')->getValue($xmlDriver)); }); // Driver: all From 13ab05d65f3096ead300261a1a909258c7f0d6cc Mon Sep 17 00:00:00 2001 From: Michal Haltuf Date: Tue, 21 Oct 2025 10:49:26 +0200 Subject: [PATCH 3/4] fix cs --- tests/Cases/DI/OrmExtension.proxy.phpt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Cases/DI/OrmExtension.proxy.phpt b/tests/Cases/DI/OrmExtension.proxy.phpt index 5b87730d7..708a14010 100644 --- a/tests/Cases/DI/OrmExtension.proxy.phpt +++ b/tests/Cases/DI/OrmExtension.proxy.phpt @@ -141,10 +141,11 @@ Toolkit::test(function (): void { // Skip on PHP < 8.4 OR doctrine/orm < v3.4.0 if (PHP_VERSION_ID < 80400 || !method_exists(Configuration::class, 'enableNativeLazyObjects')) { Assert::true(true); + return; } - $builder = ContainerBuilder::of() + $container = ContainerBuilder::of() ->withCompiler(function (Compiler $compiler): void { $compiler->addExtension('nettrine.dbal', new DbalExtension()); $compiler->addExtension('nettrine.orm', new OrmExtension()); From 7170b43454e5b8fac0242fdf0122bb2023d03e54 Mon Sep 17 00:00:00 2001 From: Michal Haltuf Date: Tue, 21 Oct 2025 11:02:06 +0200 Subject: [PATCH 4/4] Update README.md --- .docs/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.docs/README.md b/.docs/README.md index c55423e36..1581b0cc6 100755 --- a/.docs/README.md +++ b/.docs/README.md @@ -93,6 +93,9 @@ nettrine.orm: type: directories: namespace: + options: + fileExtension: + xsdValidation: defaultCache: queryCache: @@ -371,8 +374,13 @@ nettrine.orm: type: xml directories: [%appDir%/Database] namespace: App\Database + options: + fileExtension: .orm.xml + xsdValidation: true ``` +Setting `xsdValidation` to `false` will allow using custom XML elements in mapping files, as used by some behavior extensions (e.g. gedmo:sortable-position). + ### Helper You can use `MappingHelper` to add multiple mappings at once. This is useful when you have multiple modules with entities.