Skip to content

Conversation

rela589n
Copy link
Contributor

Q A
Branch? 7.4
Bug fix? no
New feature? yes
Deprecations? no
Issues #61535
License MIT

This PR introduces support for ClassLocator, added to Persistence in doctrine/persistence#433, integrated into ORM in doctrine/orm#12131, and ODM doctrine/mongodb-odm#2802.

The new AttributeDriver can now accept ClassLocator instead of $paths array:

-    public function __construct(array $paths, bool $reportFieldsWhereDeclared = true)
+    public function __construct(array|ClassLocator $paths, bool $reportFieldsWhereDeclared = true)
     {
         if (! $reportFieldsWhereDeclared) {
             throw new InvalidArgumentException(sprintf(
@@ -48,7 +49,12 @@ public function __construct(array $paths, bool $reportFieldsWhereDeclared = true
         }
 
         $this->reader = new AttributeReader();
-        $this->addPaths($paths);
+
+        if ($paths instanceof ClassLocator) {
+            $this->classLocator = $paths;
+        } else {
+            $this->addPaths($paths);
+        }
     }

The PR introduces a new ClassLocator service $driverName.'_mapping_class_locator' that will be used in the AttributeDriver.

Also it registers Finder service $driverName.'_mapping_class_finder' that is needed for the locator to operate:

$finderDefinition->addMethodCall('files');
$finderDefinition->addMethodCall('name', ['*.php']);
$finderDefinition->addMethodCall('in', [$dirs]);

This is an otherwise identical Finder-based alternative for FileClassLocator::createFromDirectories().

The changes opt in if the installed ORM/ODM libraries support it (doctrine/persistence >= 4.1, doctrine/orm >= 3.6, doctrine/mongodb-odm >= 2.12).

Replacing the array argument in $mappingDriverDef with new Reference($classLocator) could be considered a Breaking Change, since one could've modified the array of paths afterwards; however, it's unlikely that anybody used a Compiler Pass to modify it - GitHub search found no occurrences of it.

@rela589n rela589n force-pushed the 7.4-doctrine-persistence-4.1-class-locator branch from fac4257 to 1b5a0c6 Compare August 27, 2025 12:12
In the scope of doctrine/persistence#433
(available from `doctrine/persistence` >= 4.1) there was added
`ColocatedMappingDriver::$classLocator`, which allows passing any
instance of `ClassLocator` for the mapping driver to use.

This commit integrates those changes into `AbstractDoctrineExtension`,
used by respective ORM, MongoDB-ODM, PHPCR-ODM bundles. The solution
registers a "mapping_class_finder" service that can be used by the
client code to customize class finding logic.

The changes come into play starting with doctrine/persistence >= 4.1,
and the actual registration happens only if `AttributeDriver` supports
`ClassLocator`.

Dependent libraries would adhere to the same interface, where
`ClassLocator` is in the first argument.

The changes were introduced for:
- ORM: doctrine/orm#12131;
- ODM: doctrine/mongodb-odm#2802;
- PHPCR ODM: doctrine/phpcr-odm#875.
@rela589n rela589n force-pushed the 7.4-doctrine-persistence-4.1-class-locator branch from 1b5a0c6 to ad2b74b Compare August 27, 2025 12:15
Copy link
Member

@GromNaN GromNaN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the moment, I don't see what functionality it brings to the users. Is the idea to overload the $driverName.'_mapping_class_finder' service with custom constraints?


// It's possible that doctrine/persistence:^4.1 is installed with the older versions of ORM/ODM.
// In this case it's necessary to check for actual driver support.
if (!$parameterType->isIdentifiedBy(ClassLocator::class)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the behavior when ClassLocator does not exist (persistence version < 4.1) but the driver constructor is updated? We need this condition to be true.

I see that interface_exist(ClassLocator) is already checked in registerMappingDrivers.

$finderService = $this->getObjectManagerElementName($driverName.'_mapping_class_finder');

if ($container->hasDefinition($finderService)) {
$finderDefinition = $container->getDefinition($finderService);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the service has already be declared in the application, it should not be modified. Otherwise I fail to see the purpose of customizing this service.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants