13
13
14
14
use Doctrine \Persistence \Mapping \Driver \ClassLocator ;
15
15
use Doctrine \Persistence \Mapping \Driver \FileClassLocator ;
16
+ use Doctrine \Persistence \Mapping \Driver \MappingDriver ;
17
+ use ReflectionFunction ;
18
+ use ReflectionMethod ;
19
+ use ReflectionParameter ;
20
+ use ReflectionType ;
16
21
use Symfony \Component \DependencyInjection \Alias ;
17
22
use Symfony \Component \DependencyInjection \ContainerBuilder ;
18
23
use Symfony \Component \DependencyInjection \Definition ;
19
24
use Symfony \Component \DependencyInjection \Reference ;
20
25
use Symfony \Component \Finder \Finder ;
21
26
use Symfony \Component \HttpKernel \DependencyInjection \Extension ;
27
+ use Symfony \Component \TypeInfo \Type ;
28
+ use Symfony \Component \TypeInfo \TypeIdentifier ;
29
+ use Symfony \Component \TypeInfo \TypeResolver \TypeResolver ;
22
30
23
31
/**
24
32
* This abstract classes groups common code that Doctrine Object Manager extensions (ORM, MongoDB, CouchDB) need.
@@ -190,7 +198,8 @@ protected function registerMappingDrivers(array $objectManager, ContainerBuilder
190
198
}
191
199
192
200
foreach ($ this ->drivers as $ driverType => $ driverPaths ) {
193
- $ mappingService = $ this ->getObjectManagerElementName ($ objectManager ['name ' ].'_ ' .$ driverType .'_metadata_driver ' );
201
+ $ driverName = $ objectManager ['name ' ].'_ ' .$ driverType ;
202
+ $ mappingService = $ this ->getObjectManagerElementName ($ driverName .'_metadata_driver ' );
194
203
if ($ container ->hasDefinition ($ mappingService )) {
195
204
$ mappingDriverDef = $ container ->getDefinition ($ mappingService );
196
205
$ args = $ mappingDriverDef ->getArguments ();
@@ -207,14 +216,19 @@ protected function registerMappingDrivers(array $objectManager, ContainerBuilder
207
216
$ mappingDriverDef ->setArguments ([array_flip ($ driverPaths )]);
208
217
$ mappingDriverDef ->addMethodCall ('setGlobalBasename ' , ['mapping ' ]);
209
218
}
219
+
210
220
// Available since doctrine/persistence >= 4.1
211
- if (interface_exists (ClassLocator::class)
212
- && \in_array ( $ driverType , [ ' annotation ' , ' attribute ' ], true )
213
- ) {
221
+ if (interface_exists (ClassLocator::class) && ' attribute ' === $ driverType ) {
222
+ $ driverClass = $ mappingDriverDef -> getClass ();
223
+
214
224
/** @var string[] $directoryPaths */
215
225
$ directoryPaths = $ mappingDriverDef ->getArgument (0 );
216
- $ classLocator = $ this ->registerMappingClassLocatorService ($ objectManager ['name ' ].'_ ' .$ driverType , $ container , $ directoryPaths );
217
- $ mappingDriverDef ->replaceArgument (0 , new Reference ($ classLocator ));
226
+
227
+ $ classLocator = $ this ->registerMappingClassLocatorService ($ driverClass , $ driverName , $ container , $ directoryPaths );
228
+
229
+ if (null !== $ classLocator ) {
230
+ $ mappingDriverDef ->replaceArgument (0 , new Reference ($ classLocator ));
231
+ }
218
232
}
219
233
220
234
$ container ->setDefinition ($ mappingService , $ mappingDriverDef );
@@ -227,9 +241,22 @@ protected function registerMappingDrivers(array $objectManager, ContainerBuilder
227
241
$ container ->setDefinition ($ this ->getObjectManagerElementName ($ objectManager ['name ' ].'_metadata_driver ' ), $ chainDriverDef );
228
242
}
229
243
230
- /** @param string[] $dirs */
231
- private function registerMappingClassLocatorService (string $ driverName , ContainerBuilder $ container , array $ dirs ): string
244
+ /**
245
+ * @param class-string<MappingDriver> $driverClass
246
+ * @param string[] $dirs
247
+ */
248
+ private function registerMappingClassLocatorService (string $ driverClass , string $ driverName , ContainerBuilder $ container , array $ dirs ): ?string
232
249
{
250
+ $ parameter = new ReflectionParameter ([$ driverClass , '__construct ' ], 0 );
251
+
252
+ $ parameterType = TypeResolver::create ()->resolve ($ parameter );
253
+
254
+ // It's possible that doctrine/persistence:^4.1 is installed with the older versions of ORM/ODM.
255
+ // Therefore, checking for actual driver support.
256
+ if (!$ parameterType ->isIdentifiedBy (ClassLocator::class)) {
257
+ return null ;
258
+ }
259
+
233
260
$ classLocator = $ this ->getObjectManagerElementName ($ driverName .'_mapping_class_locator ' );
234
261
235
262
$ iteratorDefinition = new Definition (
0 commit comments