Skip to content

Commit d12c2f9

Browse files
author
Simon Marx
committed
add attribute support
1 parent f093d90 commit d12c2f9

File tree

6 files changed

+172
-28
lines changed

6 files changed

+172
-28
lines changed

src/DependencyInjection/CompilerPass/SetDoctrineAnnotatedPrefixesPass.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ public function process(ContainerBuilder $container)
4141
$methodCalls = $metadataDriverImpl->getMethodCalls();
4242

4343
foreach ($methodCalls as $i => [$method, $arguments]) {
44-
if ('addDriver' !== $method) {
45-
continue;
46-
}
47-
4844
if ($arguments[0] instanceof Definition) {
4945
$class = $arguments[0]->getClass();
5046
$namespace = substr($class, 0, strrpos($class, '\\'));
@@ -59,10 +55,9 @@ public function process(ContainerBuilder $container)
5955
$methodCalls[$i] = $arguments;
6056
}
6157

62-
$isAnnotated = false !== strpos($arguments[0], '_annotation_metadata_driver');
6358
$annotatedPrefixes[$managerName][] = [
6459
$arguments[1],
65-
$isAnnotated ? new Reference($arguments[0]) : null,
60+
new Reference($arguments[0]),
6661
];
6762
}
6863

src/Doctrine/DoctrineHelper.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;
2424
use Doctrine\Persistence\Mapping\ClassMetadata;
2525
use Doctrine\Persistence\Mapping\Driver\AnnotationDriver;
26+
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
2627
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
2728
use Doctrine\Persistence\Mapping\MappingException as PersistenceMappingException;
2829
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
@@ -85,6 +86,7 @@ public function getEntityNamespace(): string
8586
return $this->entityNamespace;
8687
}
8788

89+
// check is not needed anymore
8890
public function isClassAnnotated(string $className): bool
8991
{
9092
/** @var EntityManagerInterface $em */
@@ -268,4 +270,22 @@ public function isKeyword(string $name): bool
268270

269271
return $connection->getDatabasePlatform()->getReservedKeywordsList()->isKeyword($name);
270272
}
273+
274+
public function getMappingDriverForNamespace(string $namespace): ?MappingDriver
275+
{
276+
$lowestCharacterDiff = null;
277+
$foundDriver = null;
278+
279+
foreach ($this->annotatedPrefixes as $key => $mappings) {
280+
foreach($mappings as [$prefix, $driver]) {
281+
$diff = substr_compare($namespace, $prefix, 0);
282+
283+
if (null === $lowestCharacterDiff || $diff < $lowestCharacterDiff) {
284+
$foundDriver = $driver;
285+
}
286+
}
287+
}
288+
289+
return $foundDriver;
290+
}
271291
}

src/Doctrine/EntityClassGenerator.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function __construct(Generator $generator, DoctrineHelper $doctrineHelper
3333
$this->doctrineHelper = $doctrineHelper;
3434
}
3535

36-
public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $apiResource, bool $withPasswordUpgrade = false, bool $generateRepositoryClass = true, bool $broadcast = false): string
36+
public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $apiResource, bool $withPasswordUpgrade = false, bool $generateRepositoryClass = true, bool $broadcast = false, bool $doctrineAttributes = false): string
3737
{
3838
$repoClassDetails = $this->generator->createClassNameDetails(
3939
$entityClassDetails->getRelativeName(),
@@ -53,6 +53,7 @@ public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $
5353
'broadcast' => $broadcast,
5454
'should_escape_table_name' => $this->doctrineHelper->isKeyword($tableName),
5555
'table_name' => $tableName,
56+
'doctrine_use_attributes' => $doctrineAttributes
5657
]
5758
);
5859

src/Maker/MakeEntity.php

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
use ApiPlatform\Core\Annotation\ApiResource;
1515
use Doctrine\DBAL\Types\Type;
16+
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
17+
use Doctrine\Persistence\Mapping\Driver\AnnotationDriver;
18+
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
1619
use Symfony\Bundle\MakerBundle\ConsoleStyle;
1720
use Symfony\Bundle\MakerBundle\DependencyBuilder;
1821
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
@@ -160,6 +163,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
160163
'Entity\\'
161164
);
162165

166+
$mappingDriver = $this->doctrineHelper->getMappingDriverForNamespace($entityClassDetails->getFullName());
163167
$classExists = class_exists($entityClassDetails->getFullName());
164168
if (!$classExists) {
165169
$broadcast = $input->getOption('broadcast');
@@ -168,7 +172,8 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
168172
$input->getOption('api-resource'),
169173
false,
170174
true,
171-
$broadcast
175+
$broadcast,
176+
$mappingDriver instanceof AttributeDriver
172177
);
173178

174179
if ($broadcast) {
@@ -186,10 +191,6 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
186191
$generator->writeChanges();
187192
}
188193

189-
if (!$this->doesEntityUseAnnotationMapping($entityClassDetails->getFullName())) {
190-
throw new RuntimeCommandException(sprintf('Only annotation mapping is supported by make:entity, but the <info>%s</info> class uses a different format. If you would like this command to generate the properties & getter/setter methods, add your mapping configuration, and then re-run this command with the <info>--regenerate</info> flag.', $entityClassDetails->getFullName()));
191-
}
192-
193194
if ($classExists) {
194195
$entityPath = $this->getPathOfClass($entityClassDetails->getFullName());
195196
$io->text([
@@ -204,7 +205,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
204205
}
205206

206207
$currentFields = $this->getPropertyNames($entityClassDetails->getFullName());
207-
$manipulator = $this->createClassManipulator($entityPath, $io, $overwrite);
208+
$manipulator = $this->createClassManipulator($entityPath, $io, $overwrite, $mappingDriver);
208209

209210
$isFirstField = true;
210211
while (true) {
@@ -232,7 +233,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
232233
$otherManipulator = $manipulator;
233234
} else {
234235
$otherManipulatorFilename = $this->getPathOfClass($newField->getInverseClass());
235-
$otherManipulator = $this->createClassManipulator($otherManipulatorFilename, $io, $overwrite);
236+
$otherManipulator = $this->createClassManipulator($otherManipulatorFilename, $io, $overwrite, $mappingDriver);
236237
}
237238
switch ($newField->getType()) {
238239
case EntityRelation::MANY_TO_ONE:
@@ -247,7 +248,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
247248
// the new field being added to THIS entity is the inverse
248249
$newFieldName = $newField->getInverseProperty();
249250
$otherManipulatorFilename = $this->getPathOfClass($newField->getOwningClass());
250-
$otherManipulator = $this->createClassManipulator($otherManipulatorFilename, $io, $overwrite);
251+
$otherManipulator = $this->createClassManipulator($otherManipulatorFilename, $io, $overwrite, $mappingDriver);
251252

252253
// The *other* class will receive the ManyToOne
253254
$otherManipulator->addManyToOneRelation($newField->getOwningRelation());
@@ -791,9 +792,13 @@ private function askRelationType(ConsoleStyle $io, string $entityClass, string $
791792
return $io->askQuestion($question);
792793
}
793794

794-
private function createClassManipulator(string $path, ConsoleStyle $io, bool $overwrite): ClassSourceManipulator
795+
private function createClassManipulator(string $path, ConsoleStyle $io, bool $overwrite, ?MappingDriver $mappingDriver = null): ClassSourceManipulator
795796
{
796-
$manipulator = new ClassSourceManipulator($this->fileManager->getFileContents($path), $overwrite);
797+
$useAnnotations = null === $mappingDriver || $mappingDriver instanceof AnnotationDriver && !$mappingDriver instanceof AttributeDriver;
798+
$useAttributes = $mappingDriver instanceof AttributeDriver;
799+
800+
$manipulator = new ClassSourceManipulator($this->fileManager->getFileContents($path), $overwrite, $useAnnotations, true, $useAttributes);
801+
797802
$manipulator->setIo($io);
798803

799804
return $manipulator;
@@ -832,6 +837,7 @@ private function getPropertyNames(string $class): array
832837
}, $reflClass->getProperties());
833838
}
834839

840+
// not needed anymore
835841
private function doesEntityUseAnnotationMapping(string $className): bool
836842
{
837843
if (!class_exists($className)) {

src/Resources/skeleton/doctrine/Entity.tpl.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,39 @@
99
<?php if ($broadcast): ?>use Symfony\UX\Turbo\Attribute\Broadcast;
1010
<?php endif ?>
1111

12+
<?php if(!$use_attributes || !$doctrine_use_attributes): ?>
1213
/**
1314
<?php if ($api_resource && !$use_attributes): ?> * @ApiResource()
1415
<?php endif ?>
1516
<?php if ($broadcast && !$use_attributes): ?> * @Broadcast()
1617
<?php endif ?>
17-
* @ORM\Entity(repositoryClass=<?= $repository_class_name ?>::class)
18+
<?php if(!$doctrine_use_attributes): ?> * @ORM\Entity(repositoryClass=<?= $repository_class_name ?>::class)
19+
<?php endif ?>
1820
<?php if ($should_escape_table_name): ?> * @ORM\Table(name="`<?= $table_name ?>`")
1921
<?php endif ?>
2022
*/
23+
<?php endif ?>
2124
<?php if ($api_resource && $use_attributes): ?>
2225
#[ApiResource]
2326
<?php endif ?>
2427
<?php if ($broadcast && $use_attributes): ?>
2528
#[Broadcast]
2629
<?php endif ?>
30+
<?php if($doctrine_use_attributes): ?>
31+
#[ORM\Entity(repositoryClass: <?= $repository_class_name ?>::class)]
32+
<?php if($should_escape_table_name): ?> #[ORM\Table(name: '`<?= $table_name ?>`')]<?php endif ?>
33+
<?php endif?>
2734
class <?= $class_name."\n" ?>
2835
{
29-
/**
36+
<?php if(!$doctrine_use_attributes): ?>/**
3037
* @ORM\Id
3138
* @ORM\GeneratedValue
3239
* @ORM\Column(type="integer")
3340
*/
34-
private $id;
41+
<?php else: ?>#[ORM\Id]
42+
#[ORM\GeneratedValue]
43+
#[ORM\Column(type: 'integer')]
44+
<?php endif ?>private $id;
3545

3646
public function getId(): ?int
3747
{

0 commit comments

Comments
 (0)