11
11
12
12
namespace Symfony \Bridge \Doctrine \DependencyInjection ;
13
13
14
+ use Doctrine \Persistence \Mapping \Driver \ClassLocator ;
15
+ use Doctrine \Persistence \Mapping \Driver \FileClassLocator ;
14
16
use Symfony \Component \DependencyInjection \Alias ;
15
17
use Symfony \Component \DependencyInjection \ContainerBuilder ;
16
18
use Symfony \Component \DependencyInjection \Definition ;
17
19
use Symfony \Component \DependencyInjection \Reference ;
20
+ use Symfony \Component \Finder \Finder ;
18
21
use Symfony \Component \HttpKernel \DependencyInjection \Extension ;
19
22
20
23
/**
@@ -30,6 +33,8 @@ abstract class AbstractDoctrineExtension extends Extension
30
33
protected array $ aliasMap = [];
31
34
32
35
/**
36
+ * @var array<string,array<string,string>> An array of directory paths by namespace, indexed by driver type.
37
+ *
33
38
* Used inside metadata driver method to simplify aggregation of data.
34
39
*/
35
40
protected array $ drivers = [];
@@ -202,6 +207,15 @@ protected function registerMappingDrivers(array $objectManager, ContainerBuilder
202
207
$ mappingDriverDef ->setArguments ([array_flip ($ driverPaths )]);
203
208
$ mappingDriverDef ->addMethodCall ('setGlobalBasename ' , ['mapping ' ]);
204
209
}
210
+ // Available since doctrine/persistence >= 4.1
211
+ if (interface_exists (ClassLocator::class)
212
+ && \in_array ($ driverType , ['annotation ' , 'attribute ' ], true )
213
+ ) {
214
+ /** @var string[] $directoryPaths */
215
+ $ directoryPaths = $ mappingDriverDef ->getArgument (0 );
216
+ $ classLocator = $ this ->registerMappingClassLocatorService ($ objectManager ['name ' ].'_ ' .$ driverType , $ container , $ directoryPaths );
217
+ $ mappingDriverDef ->replaceArgument (0 , new Reference ($ classLocator ));
218
+ }
205
219
206
220
$ container ->setDefinition ($ mappingService , $ mappingDriverDef );
207
221
@@ -213,6 +227,40 @@ protected function registerMappingDrivers(array $objectManager, ContainerBuilder
213
227
$ container ->setDefinition ($ this ->getObjectManagerElementName ($ objectManager ['name ' ].'_metadata_driver ' ), $ chainDriverDef );
214
228
}
215
229
230
+ /** @param string[] $dirs */
231
+ private function registerMappingClassLocatorService (string $ driverName , ContainerBuilder $ container , array $ dirs ): string
232
+ {
233
+ $ classLocator = $ this ->getObjectManagerElementName ($ driverName .'_mapping_class_locator ' );
234
+
235
+ $ iteratorDefinition = new Definition (
236
+ FileClassLocator::class,
237
+ [new Reference ($ this ->registerMappingClassFinderService ($ driverName , $ container , $ dirs ))],
238
+ );
239
+
240
+ $ container ->setDefinition ($ classLocator , $ iteratorDefinition );
241
+
242
+ return $ classLocator ;
243
+ }
244
+
245
+ private function registerMappingClassFinderService (string $ driverName , ContainerBuilder $ container , array $ dirs ): string
246
+ {
247
+ $ finderService = $ this ->getObjectManagerElementName ($ driverName .'_mapping_class_finder ' );
248
+
249
+ if ($ container ->hasDefinition ($ finderService )) {
250
+ $ finderDefinition = $ container ->getDefinition ($ finderService );
251
+ } else {
252
+ $ finderDefinition = new Definition (Finder::class, []);
253
+ }
254
+
255
+ $ finderDefinition ->addMethodCall ('files ' );
256
+ $ finderDefinition ->addMethodCall ('name ' , ['*.php ' ]);
257
+ $ finderDefinition ->addMethodCall ('in ' , [$ dirs ]);
258
+
259
+ $ container ->setDefinition ($ finderService , $ finderDefinition );
260
+
261
+ return $ finderService ;
262
+ }
263
+
216
264
/**
217
265
* Assertion if the specified mapping information is valid.
218
266
*
0 commit comments