Skip to content

Commit f3c1b25

Browse files
committed
Fixing a bug where the wrong ManagerRegistry was sometimes used in repositories
This problem occurs if using DoctrineBundle 1.11 or lower, where the newer Persistence alias is not available. This also centralizes the creation of the repository classes to fix this in all places.
1 parent ac73a72 commit f3c1b25

File tree

9 files changed

+80
-29
lines changed

9 files changed

+80
-29
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass;
4+
5+
use Doctrine\Persistence\ManagerRegistry;
6+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
7+
use Symfony\Component\DependencyInjection\ContainerBuilder;
8+
9+
/**
10+
* Helps determine which "ManagerRegistry" autowiring alias is available.
11+
*/
12+
class SetDoctrineManagerRegistryClassPass implements CompilerPassInterface
13+
{
14+
public function process(ContainerBuilder $container)
15+
{
16+
if ($container->hasAlias(ManagerRegistry::class)) {
17+
$definition = $container->getDefinition('maker.entity_class_generator');
18+
$definition->addMethodCall('setMangerRegistryClassName', [ManagerRegistry::class]);
19+
}
20+
}
21+
}

src/Doctrine/EntityClassGenerator.php

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Doctrine\Common\Persistence\ManagerRegistry as LegacyManagerRegistry;
1515
use Doctrine\Persistence\ManagerRegistry;
1616
use Symfony\Bundle\MakerBundle\Generator;
17+
use Symfony\Bundle\MakerBundle\Str;
1718
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
1819

1920
/**
@@ -23,6 +24,7 @@ final class EntityClassGenerator
2324
{
2425
private $generator;
2526
private $doctrineHelper;
27+
private $managerRegistryClassName = LegacyManagerRegistry::class;
2628

2729
public function __construct(Generator $generator, DoctrineHelper $doctrineHelper)
2830
{
@@ -51,19 +53,37 @@ public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $
5153
]
5254
);
5355

54-
$entityAlias = strtolower($entityClassDetails->getShortName()[0]);
55-
$this->generator->generateClass(
56+
$this->generateRepositoryClass(
5657
$repoClassDetails->getFullName(),
58+
$entityClassDetails->getFullName(),
59+
$withPasswordUpgrade)
60+
;
61+
62+
return $entityPath;
63+
}
64+
65+
public function generateRepositoryClass(string $repositoryClass, string $entityClass, bool $withPasswordUpgrade)
66+
{
67+
$shortEntityClass = Str::getShortClassName($entityClass);
68+
$entityAlias = strtolower($shortEntityClass[0]);
69+
$this->generator->generateClass(
70+
$repositoryClass,
5771
'doctrine/Repository.tpl.php',
5872
[
59-
'entity_full_class_name' => $entityClassDetails->getFullName(),
60-
'entity_class_name' => $entityClassDetails->getShortName(),
73+
'entity_full_class_name' => $entityClass,
74+
'entity_class_name' => $shortEntityClass,
6175
'entity_alias' => $entityAlias,
6276
'with_password_upgrade' => $withPasswordUpgrade,
63-
'doctrine_registry_class' => interface_exists(ManagerRegistry::class) ? ManagerRegistry::class : LegacyManagerRegistry::class,
77+
'doctrine_registry_class' => $this->managerRegistryClassName,
6478
]
6579
);
80+
}
6681

67-
return $entityPath;
82+
/**
83+
* Called by a compiler pass to inject the non-legacy value if available.
84+
*/
85+
public function setMangerRegistryClassName(string $managerRegistryClassName)
86+
{
87+
$this->managerRegistryClassName = $managerRegistryClassName;
6888
}
6989
}

src/Doctrine/EntityRegenerator.php

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@
1515
use Doctrine\Common\Persistence\Mapping\MappingException as CommonMappingException;
1616
use Doctrine\ORM\Mapping\ClassMetadata;
1717
use Doctrine\ORM\Mapping\MappingException;
18-
use Doctrine\Persistence\ManagerRegistry;
1918
use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException;
2019
use Symfony\Bundle\MakerBundle\FileManager;
2120
use Symfony\Bundle\MakerBundle\Generator;
22-
use Symfony\Bundle\MakerBundle\Str;
2321
use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
2422

2523
/**
@@ -30,13 +28,15 @@ final class EntityRegenerator
3028
private $doctrineHelper;
3129
private $fileManager;
3230
private $generator;
31+
private $entityClassGenerator;
3332
private $overwrite;
3433

35-
public function __construct(DoctrineHelper $doctrineHelper, FileManager $fileManager, Generator $generator, bool $overwrite)
34+
public function __construct(DoctrineHelper $doctrineHelper, FileManager $fileManager, Generator $generator, EntityClassGenerator $entityClassGenerator, bool $overwrite)
3635
{
3736
$this->doctrineHelper = $doctrineHelper;
3837
$this->fileManager = $fileManager;
3938
$this->generator = $generator;
39+
$this->entityClassGenerator = $entityClassGenerator;
4040
$this->overwrite = $overwrite;
4141
}
4242

@@ -226,19 +226,10 @@ private function generateRepository(ClassMetadata $metadata)
226226
return;
227227
}
228228

229-
// duplication in MakeEntity
230-
$entityClassName = Str::getShortClassName($metadata->name);
231-
232-
$this->generator->generateClass(
229+
$this->entityClassGenerator->generateRepositoryClass(
233230
$metadata->customRepositoryClassName,
234-
'doctrine/Repository.tpl.php',
235-
[
236-
'entity_full_class_name' => $metadata->name,
237-
'entity_class_name' => $entityClassName,
238-
'entity_alias' => strtolower($entityClassName[0]),
239-
'with_password_upgrade' => false,
240-
'doctrine_registry_class' => interface_exists(ManagerRegistry::class) ? ManagerRegistry::class : LegacyManagerRegistry::class,
241-
]
231+
$metadata->name,
232+
false
242233
);
243234

244235
$this->generator->writeChanges();

src/Maker/MakeEntity.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ final class MakeEntity extends AbstractMaker implements InputAwareMakerInterface
4747
private $fileManager;
4848
private $doctrineHelper;
4949
private $generator;
50+
private $entityClassGenerator;
5051

51-
public function __construct(FileManager $fileManager, DoctrineHelper $doctrineHelper, string $projectDirectory, Generator $generator = null)
52+
public function __construct(FileManager $fileManager, DoctrineHelper $doctrineHelper, string $projectDirectory, Generator $generator = null, EntityClassGenerator $entityClassGenerator = null)
5253
{
5354
$this->fileManager = $fileManager;
5455
$this->doctrineHelper = $doctrineHelper;
@@ -60,6 +61,13 @@ public function __construct(FileManager $fileManager, DoctrineHelper $doctrineHe
6061
} else {
6162
$this->generator = $generator;
6263
}
64+
65+
if (null === $entityClassGenerator) {
66+
@trigger_error(sprintf('Passing a "%s" instance as 5th argument is mandatory since version 1.15.1', Generator::class), E_USER_DEPRECATED);
67+
$this->entityClassGenerator = new EntityClassGenerator($generator, $this->doctrineHelper);
68+
} else {
69+
$this->entityClassGenerator = $entityClassGenerator;
70+
}
6371
}
6472

6573
public static function getCommandName(): string
@@ -137,8 +145,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
137145

138146
$classExists = class_exists($entityClassDetails->getFullName());
139147
if (!$classExists) {
140-
$entityClassGenerator = new EntityClassGenerator($generator, $this->doctrineHelper);
141-
$entityPath = $entityClassGenerator->generateEntityClass(
148+
$entityPath = $this->entityClassGenerator->generateEntityClass(
142149
$entityClassDetails,
143150
$input->getOption('api-resource')
144151
);
@@ -766,7 +773,7 @@ private function isClassInVendor(string $class): bool
766773

767774
private function regenerateEntities(string $classOrNamespace, bool $overwrite, Generator $generator)
768775
{
769-
$regenerator = new EntityRegenerator($this->doctrineHelper, $this->fileManager, $generator, $overwrite);
776+
$regenerator = new EntityRegenerator($this->doctrineHelper, $this->fileManager, $generator, $this->entityClassGenerator, $overwrite);
770777
$regenerator->regenerateEntities($classOrNamespace);
771778
}
772779

src/Maker/MakeUser.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ final class MakeUser extends AbstractMaker
5151
private $configUpdater;
5252

5353
private $doctrineHelper;
54+
private $entityClassGenerator;
5455

55-
public function __construct(FileManager $fileManager, UserClassBuilder $userClassBuilder, SecurityConfigUpdater $configUpdater, DoctrineHelper $doctrineHelper)
56+
public function __construct(FileManager $fileManager, UserClassBuilder $userClassBuilder, SecurityConfigUpdater $configUpdater, DoctrineHelper $doctrineHelper, EntityClassGenerator $entityClassGenerator)
5657
{
5758
$this->fileManager = $fileManager;
5859
$this->userClassBuilder = $userClassBuilder;
5960
$this->configUpdater = $configUpdater;
6061
$this->doctrineHelper = $doctrineHelper;
62+
$this->entityClassGenerator = $entityClassGenerator;
6163
}
6264

6365
public static function getCommandName(): string
@@ -139,8 +141,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
139141

140142
// A) Generate the User class
141143
if ($userClassConfiguration->isEntity()) {
142-
$entityClassGenerator = new EntityClassGenerator($generator, $this->doctrineHelper);
143-
$classPath = $entityClassGenerator->generateEntityClass(
144+
$classPath = $this->entityClassGenerator->generateEntityClass(
144145
$userClassNameDetails,
145146
false, // api resource
146147
$userClassConfiguration->hasPassword() && interface_exists(PasswordUpgraderInterface::class) // security user

src/MakerBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\MakeCommandRegistrationPass;
1515
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\RemoveMissingParametersPass;
16+
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\SetDoctrineManagerRegistryClassPass;
1617
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
1718
use Symfony\Component\DependencyInjection\ContainerBuilder;
1819
use Symfony\Component\HttpKernel\Bundle\Bundle;
@@ -28,5 +29,6 @@ public function build(ContainerBuilder $container)
2829
// add a priority so we run before the core command pass
2930
$container->addCompilerPass(new MakeCommandRegistrationPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 10);
3031
$container->addCompilerPass(new RemoveMissingParametersPass());
32+
$container->addCompilerPass(new SetDoctrineManagerRegistryClassPass());
3133
}
3234
}

src/Resources/config/makers.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<argument type="service" id="maker.doctrine_helper" />
3636
<argument>%kernel.project_dir%</argument>
3737
<argument type="service" id="maker.generator" />
38+
<argument type="service" id="maker.entity_class_generator" />
3839
<tag name="maker.command" />
3940
</service>
4041

@@ -107,6 +108,7 @@
107108
<argument type="service" id="maker.user_class_builder" />
108109
<argument type="service" id="maker.security_config_updater" />
109110
<argument type="service" id="maker.doctrine_helper" />
111+
<argument type="service" id="maker.entity_class_generator" />
110112
<tag name="maker.command" />
111113
</service>
112114

src/Resources/config/services.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
<service id="maker.entity_class_generator" class="Symfony\Bundle\MakerBundle\Doctrine\EntityClassGenerator">
5050
<argument type="service" id="maker.generator" />
51+
<argument type="service" id="maker.doctrine_helper" />
5152
</service>
5253

5354
<service id="maker.user_class_builder" class="Symfony\Bundle\MakerBundle\Security\UserClassBuilder" />

tests/Doctrine/EntityRegeneratorTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
namespace Symfony\Bundle\MakerBundle\Tests\Doctrine;
1313

1414
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
15+
use Doctrine\Persistence\ManagerRegistry;
1516
use PHPUnit\Framework\TestCase;
1617
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
1718
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
1819
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
20+
use Symfony\Bundle\MakerBundle\Doctrine\EntityClassGenerator;
1921
use Symfony\Bundle\MakerBundle\Doctrine\EntityRegenerator;
2022
use Symfony\Bundle\MakerBundle\FileManager;
2123
use Symfony\Bundle\MakerBundle\Generator;
@@ -110,10 +112,14 @@ private function doTestRegeneration(string $sourceDir, Kernel $kernel, string $n
110112

111113
$fileManager = new FileManager($fs, $autoloaderUtil, $tmpDir);
112114
$doctrineHelper = new DoctrineHelper('App\\Entity', $container->get('doctrine'));
115+
$generator = new Generator($fileManager, 'App\\');
116+
$entityClassGenerator = new EntityClassGenerator($generator, $doctrineHelper);
117+
$entityClassGenerator->setMangerRegistryClassName(ManagerRegistry::class);
113118
$regenerator = new EntityRegenerator(
114119
$doctrineHelper,
115120
$fileManager,
116-
new Generator($fileManager, 'App\\'),
121+
$generator,
122+
$entityClassGenerator,
117123
$overwrite
118124
);
119125

0 commit comments

Comments
 (0)