|
7 | 7 | use Doctrine\DBAL\Schema\Schema;
|
8 | 8 | use Doctrine\DBAL\Schema\Table;
|
9 | 9 | use Doctrine\DBAL\Types\Type;
|
| 10 | +use Psr\Container\ContainerInterface; |
| 11 | +use TheCodingMachine\TDBM\Schema\ForeignKeys; |
| 12 | +use TheCodingMachine\TDBM\TDBMService; |
| 13 | +use Zend\Code\Generator\AbstractMemberGenerator; |
| 14 | +use Zend\Code\Generator\ClassGenerator; |
| 15 | +use Zend\Code\Generator\DocBlock\Tag\VarTag; |
| 16 | +use Zend\Code\Generator\DocBlockGenerator; |
| 17 | +use Zend\Code\Generator\FileGenerator; |
| 18 | +use Zend\Code\Generator\MethodGenerator; |
| 19 | +use Zend\Code\Generator\ParameterGenerator; |
| 20 | +use Zend\Code\Generator\PropertyGenerator; |
10 | 21 | use function str_replace;
|
11 | 22 | use TheCodingMachine\TDBM\ConfigurationInterface;
|
12 | 23 | use TheCodingMachine\TDBM\TDBMException;
|
13 | 24 | use TheCodingMachine\TDBM\TDBMSchemaAnalyzer;
|
14 | 25 | use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
15 | 26 | use Symfony\Component\Filesystem\Filesystem;
|
| 27 | +use function strpos; |
| 28 | +use function substr; |
| 29 | +use function var_export; |
16 | 30 |
|
17 | 31 | /**
|
18 | 32 | * This class generates automatically DAOs and Beans for TDBM.
|
@@ -88,7 +102,7 @@ public function generateAllDaosAndBeans(): void
|
88 | 102 | }
|
89 | 103 |
|
90 | 104 |
|
91 |
| - $this->generateFactory($tableList); |
| 105 | + $this->generateFactory($beanDescriptors); |
92 | 106 |
|
93 | 107 | // Let's call the list of listeners
|
94 | 108 | $this->eventDispatcher->onGenerate($this->configuration, $beanDescriptors);
|
@@ -279,93 +293,105 @@ private function psr2Fix(string $content): string
|
279 | 293 | /**
|
280 | 294 | * Generates the factory bean.
|
281 | 295 | *
|
282 |
| - * @param Table[] $tableList |
| 296 | + * @param BeanDescriptor[] $beanDescriptors |
283 | 297 | * @throws TDBMException
|
284 | 298 | */
|
285 |
| - private function generateFactory(array $tableList) : void |
| 299 | + private function generateFactory(array $beanDescriptors) : void |
286 | 300 | {
|
287 | 301 | $daoNamespace = $this->configuration->getDaoNamespace();
|
288 | 302 | $daoFactoryClassName = $this->namingStrategy->getDaoFactoryClassName();
|
289 | 303 |
|
| 304 | + $file = new FileGenerator(); |
| 305 | + $file->setDocBlock( |
| 306 | + new DocBlockGenerator( |
| 307 | + <<<DOC |
| 308 | +This file has been automatically generated by TDBM. |
| 309 | +DO NOT edit this file, as it might be overwritten. |
| 310 | +DOC |
| 311 | + ) |
| 312 | + ); |
| 313 | + $class = new ClassGenerator(); |
| 314 | + $file->setClass($class); |
| 315 | + $class->setName($daoFactoryClassName); |
| 316 | + $file->setNamespace($daoNamespace.'\\Generated'); |
| 317 | + |
| 318 | + $class->setDocBlock(new DocBlockGenerator("The $daoFactoryClassName provides an easy access to all DAOs generated by TDBM.")); |
| 319 | + |
| 320 | + $containerProperty = new PropertyGenerator('container'); |
| 321 | + $containerProperty->setVisibility(AbstractMemberGenerator::VISIBILITY_PRIVATE); |
| 322 | + $containerProperty->setDocBlock(new DocBlockGenerator(null, null, [new VarTag(null, ['\\'.ContainerInterface::class])])); |
| 323 | + $class->addPropertyFromGenerator($containerProperty); |
| 324 | + |
| 325 | + $constructorMethod = new MethodGenerator( |
| 326 | + '__construct', |
| 327 | + [ new ParameterGenerator('container', ContainerInterface::class) ], |
| 328 | + MethodGenerator::FLAG_PUBLIC, |
| 329 | + '$this->container = $container;' |
| 330 | + ); |
| 331 | + $constructorMethod = $this->configuration->getCodeGeneratorListener()->onDaoFactoryConstructorGenerated($constructorMethod, $beanDescriptors, $this->configuration, $class); |
| 332 | + if ($constructorMethod !== null) { |
| 333 | + $class->addMethodFromGenerator($constructorMethod); |
| 334 | + } |
| 335 | + |
290 | 336 | // For each table, let's write a property.
|
| 337 | + foreach ($beanDescriptors as $beanDescriptor) { |
| 338 | + $daoClassName = $beanDescriptor->getDaoClassName(); |
| 339 | + $daoInstanceName = self::toVariableName($daoClassName); |
291 | 340 |
|
292 |
| - $str = "<?php |
293 |
| -declare(strict_types=1); |
| 341 | + $daoInstanceProperty = new PropertyGenerator($daoInstanceName); |
| 342 | + $daoInstanceProperty->setVisibility(AbstractMemberGenerator::VISIBILITY_PRIVATE); |
| 343 | + $daoInstanceProperty->setDocBlock(new DocBlockGenerator(null, null, [new VarTag(null, ['\\' . $daoNamespace . '\\' . $daoClassName, 'null'])])); |
| 344 | + $class->addPropertyFromGenerator($daoInstanceProperty); |
294 | 345 |
|
295 |
| -/* |
296 |
| - * This file has been automatically generated by TDBM. |
297 |
| - * DO NOT edit this file, as it might be overwritten. |
298 |
| - */ |
| 346 | + $fullClassNameVarExport = var_export($daoNamespace.'\\'.$daoClassName, true); |
| 347 | + $getterBody = <<<BODY |
| 348 | +if (!\$this->$daoInstanceName) { |
| 349 | + \$this->$daoInstanceName = \$this->container->get($fullClassNameVarExport); |
| 350 | +} |
299 | 351 |
|
300 |
| -namespace {$daoNamespace}\\Generated; |
| 352 | +return \$this->$daoInstanceName; |
| 353 | +BODY; |
| 354 | + |
| 355 | + $getterMethod = new MethodGenerator( |
| 356 | + 'get' . $daoClassName, |
| 357 | + [], |
| 358 | + MethodGenerator::FLAG_PUBLIC, |
| 359 | + $getterBody |
| 360 | + ); |
| 361 | + $getterMethod->setReturnType($daoNamespace.'\\'.$daoClassName); |
| 362 | + $getterMethod = $this->configuration->getCodeGeneratorListener()->onDaoFactoryGetterGenerated($getterMethod, $beanDescriptor, $this->configuration, $class); |
| 363 | + if ($getterMethod !== null) { |
| 364 | + $class->addMethodFromGenerator($getterMethod); |
| 365 | + } |
301 | 366 |
|
302 |
| -use Psr\Container\ContainerInterface; |
303 |
| -"; |
304 |
| - foreach ($tableList as $table) { |
305 |
| - $tableName = $table->getName(); |
306 |
| - $daoClassName = $this->namingStrategy->getDaoClassName($tableName); |
307 |
| - $str .= "use {$daoNamespace}\\".$daoClassName.";\n"; |
| 367 | + $setterMethod = new MethodGenerator( |
| 368 | + 'set' . $daoClassName, |
| 369 | + [new ParameterGenerator($daoInstanceName, '\\' . $daoNamespace . '\\' . $daoClassName)], |
| 370 | + MethodGenerator::FLAG_PUBLIC, |
| 371 | + '$this->' . $daoInstanceName . ' = $' . $daoInstanceName . ';' |
| 372 | + ); |
| 373 | + $setterMethod->setReturnType('void'); |
| 374 | + $setterMethod = $this->configuration->getCodeGeneratorListener()->onDaoFactorySetterGenerated($setterMethod, $beanDescriptor, $this->configuration, $class); |
| 375 | + if ($setterMethod !== null) { |
| 376 | + $class->addMethodFromGenerator($setterMethod); |
| 377 | + } |
308 | 378 | }
|
309 | 379 |
|
310 |
| - $str .= " |
311 |
| -/** |
312 |
| - * The $daoFactoryClassName provides an easy access to all DAOs generated by TDBM. |
313 |
| - * |
314 |
| - */ |
315 |
| -class $daoFactoryClassName |
316 |
| -{ |
317 |
| - private \$container; |
318 |
| -
|
319 |
| - public function __construct(ContainerInterface \$container) |
320 |
| - { |
321 |
| - \$this->container = \$container; |
322 |
| - } |
323 |
| -
|
| 380 | + $file = $this->configuration->getCodeGeneratorListener()->onDaoFactoryGenerated($file, $beanDescriptors, $this->configuration); |
324 | 381 |
|
325 |
| -"; |
| 382 | + if ($file !== null) { |
| 383 | + $possibleFileName = $this->configuration->getPathFinder()->getPath($daoNamespace.'\\Generated\\'.$daoFactoryClassName)->getPathname(); |
326 | 384 |
|
327 |
| - foreach ($tableList as $table) { |
328 |
| - $tableName = $table->getName(); |
329 |
| - $daoClassName = $this->namingStrategy->getDaoClassName($tableName); |
330 |
| - $daoInstanceName = self::toVariableName($daoClassName); |
| 385 | + $fileContent = $file->generate(); |
331 | 386 |
|
332 |
| - $str .= ' /** |
333 |
| - * @var '.$daoClassName.'|null |
334 |
| - */ |
335 |
| - private $'.$daoInstanceName.'; |
336 |
| -
|
337 |
| - /** |
338 |
| - * Returns an instance of the '.$daoClassName.' class. |
339 |
| - * |
340 |
| - * @return '.$daoClassName.' |
341 |
| - */ |
342 |
| - public function get'.$daoClassName.'() : '.$daoClassName.' |
343 |
| - { |
344 |
| - if (!$this->'.$daoInstanceName.') { |
345 |
| - $this->'.$daoInstanceName.' = $this->container->get('.$daoClassName.'::class); |
346 |
| - } |
347 |
| - |
348 |
| - return $this->'.$daoInstanceName.'; |
349 |
| - } |
| 387 | + // Hard code PSR-2 fix |
| 388 | + $fileContent = $this->psr2Fix($fileContent); |
| 389 | + // Add the declare strict-types directive |
| 390 | + $commentEnd = strpos($fileContent, ' */') + 3; |
| 391 | + $fileContent = substr($fileContent, 0, $commentEnd) . "\n\ndeclare(strict_types=1);" . substr($fileContent, $commentEnd + 1); |
350 | 392 |
|
351 |
| - /** |
352 |
| - * Override the instance of the '.$daoClassName.' class that will be returned by the factory getter. |
353 |
| - * |
354 |
| - * @param '.$daoClassName.' $'.$daoInstanceName.' |
355 |
| - */ |
356 |
| - public function set'.$daoClassName.'('.$daoClassName.' $'.$daoInstanceName.') : void |
357 |
| - { |
358 |
| - $this->'.$daoInstanceName.' = $'.$daoInstanceName.'; |
359 |
| - }'; |
| 393 | + $this->dumpFile($possibleFileName, $fileContent); |
360 | 394 | }
|
361 |
| - |
362 |
| - $str .= ' |
363 |
| -} |
364 |
| -'; |
365 |
| - |
366 |
| - $possibleFileName = $this->configuration->getPathFinder()->getPath($daoNamespace.'\\Generated\\'.$daoFactoryClassName)->getPathname(); |
367 |
| - |
368 |
| - $this->dumpFile($possibleFileName, $str); |
369 | 395 | }
|
370 | 396 |
|
371 | 397 | /**
|
|
0 commit comments