13
13
14
14
use Doctrine \Common \Collections \ArrayCollection ;
15
15
use Doctrine \Common \Collections \Collection ;
16
+ use Doctrine \ORM \Mapping \Column ;
17
+ use Doctrine \ORM \Mapping \Embedded ;
18
+ use Doctrine \ORM \Mapping \JoinColumn ;
19
+ use Doctrine \ORM \Mapping \ManyToMany ;
20
+ use Doctrine \ORM \Mapping \ManyToOne ;
21
+ use Doctrine \ORM \Mapping \OneToMany ;
22
+ use Doctrine \ORM \Mapping \OneToOne ;
16
23
use PhpParser \Builder ;
17
24
use PhpParser \BuilderHelpers ;
18
25
use PhpParser \Comment \Doc ;
@@ -93,7 +100,7 @@ public function addEntityField(string $propertyName, array $columnOptions, array
93
100
$ attributes = [];
94
101
95
102
if ($ this ->useAttributesForDoctrineMapping ) {
96
- $ attributes [] = $ this ->buildAttributeNode (' ORM\ Column' , $ columnOptions );
103
+ $ attributes [] = $ this ->buildAttributeNode (Column::class , $ columnOptions, ' ORM ' );
97
104
} else {
98
105
$ comments [] = $ this ->buildAnnotationLine ('@ORM\Column ' , $ columnOptions );
99
106
}
@@ -138,10 +145,9 @@ public function addEmbeddedEntity(string $propertyName, string $className): void
138
145
} else {
139
146
$ attributes = [
140
147
$ this ->buildAttributeNode (
141
- 'ORM \\Embedded ' ,
142
- [
143
- 'class ' => new ClassNameValue ($ className , $ typeHint ),
144
- ]
148
+ Embedded::class,
149
+ ['class ' => new ClassNameValue ($ className , $ typeHint )],
150
+ 'ORM '
145
151
),
146
152
];
147
153
}
@@ -333,6 +339,9 @@ public function createMethodLevelBlankLine()
333
339
return $ this ->createBlankLineNode (self ::CONTEXT_CLASS_METHOD );
334
340
}
335
341
342
+ /**
343
+ * @param array<Node\Attribute|Node\AttributeGroup> $attributes
344
+ */
336
345
public function addProperty (string $ name , array $ annotationLines = [], $ defaultValue = null , array $ attributes = []): void
337
346
{
338
347
if ($ this ->propertyExists ($ name )) {
@@ -342,14 +351,14 @@ public function addProperty(string $name, array $annotationLines = [], $defaultV
342
351
343
352
$ newPropertyBuilder = (new Builder \Property ($ name ))->makePrivate ();
344
353
345
- if ($ annotationLines && $ this ->useAnnotations ) {
354
+ if ($ this ->useAttributesForDoctrineMapping ) {
355
+ foreach ($ attributes as $ attribute ) {
356
+ $ newPropertyBuilder ->addAttribute ($ attribute );
357
+ }
358
+ } elseif ($ annotationLines && $ this ->useAnnotations ) {
346
359
$ newPropertyBuilder ->setDocComment ($ this ->createDocBlock ($ annotationLines ));
347
360
}
348
361
349
- foreach ($ attributes as $ attribute ) {
350
- $ newPropertyBuilder ->addAttribute ($ attribute );
351
- }
352
-
353
362
if (null !== $ defaultValue ) {
354
363
$ newPropertyBuilder ->setDefault ($ defaultValue );
355
364
}
@@ -358,6 +367,17 @@ public function addProperty(string $name, array $annotationLines = [], $defaultV
358
367
$ this ->addNodeAfterProperties ($ newPropertyNode );
359
368
}
360
369
370
+ public function addAttributeToClass (string $ attributeClass , array $ options ): void
371
+ {
372
+ $ this ->addUseStatementIfNecessary ($ attributeClass );
373
+
374
+ $ classNode = $ this ->getClassNode ();
375
+
376
+ $ classNode ->attrGroups [] = new Node \AttributeGroup ([$ this ->buildAttributeNode ($ attributeClass , $ options )]);
377
+
378
+ $ this ->updateSourceCodeFromNewStmts ();
379
+ }
380
+
361
381
public function addAnnotationToClass (string $ annotationClass , array $ options ): void
362
382
{
363
383
$ annotationClassAlias = $ this ->addUseStatementIfNecessary ($ annotationClass );
@@ -532,8 +552,9 @@ private function addSingularRelation(BaseRelation $relation): void
532
552
} else {
533
553
$ attributes = [
534
554
$ this ->buildAttributeNode (
535
- $ relation instanceof RelationManyToOne ? 'ORM \\ManyToOne ' : 'ORM \\OneToOne ' ,
536
- $ annotationOptions
555
+ $ relation instanceof RelationManyToOne ? ManyToOne::class : OneToOne::class,
556
+ $ annotationOptions ,
557
+ 'ORM '
537
558
),
538
559
];
539
560
}
@@ -544,9 +565,7 @@ private function addSingularRelation(BaseRelation $relation): void
544
565
'nullable ' => false ,
545
566
]);
546
567
} else {
547
- $ attributes [] = $ this ->buildAttributeNode ('ORM \\JoinColumn ' , [
548
- 'nullable ' => false ,
549
- ]);
568
+ $ attributes [] = $ this ->buildAttributeNode (JoinColumn::class, ['nullable ' => false ], 'ORM ' );
550
569
}
551
570
}
552
571
@@ -628,8 +647,9 @@ private function addCollectionRelation(BaseCollectionRelation $relation): void
628
647
} else {
629
648
$ attributes = [
630
649
$ this ->buildAttributeNode (
631
- $ relation instanceof RelationManyToMany ? 'ORM \\ManyToMany ' : 'ORM \\OneToMany ' ,
632
- $ annotationOptions
650
+ $ relation instanceof RelationManyToMany ? ManyToMany::class : OneToMany::class,
651
+ $ annotationOptions ,
652
+ 'ORM '
633
653
),
634
654
];
635
655
}
@@ -900,6 +920,30 @@ public function addUseStatementIfNecessary(string $class): string
900
920
return $ shortClassName ;
901
921
}
902
922
923
+ /**
924
+ * Builds a PHPParser attribute node.
925
+ *
926
+ * @param string $attributeClass The attribute class which should be used for the attribute E.g. #[Column()]
927
+ * @param array $options The named arguments for the attribute ($key = argument name, $value = argument value)
928
+ * @param ?string $attributePrefix If a prefix is provided, the node is built using the prefix. E.g. #[ORM\Column()]
929
+ */
930
+ public function buildAttributeNode (string $ attributeClass , array $ options , ?string $ attributePrefix = null ): Node \Attribute
931
+ {
932
+ $ options = $ this ->sortOptionsByClassConstructorParameters ($ options , $ attributeClass );
933
+
934
+ $ context = $ this ;
935
+ $ nodeArguments = array_map (static function ($ option , $ value ) use ($ context ) {
936
+ return new Node \Arg ($ context ->buildNodeExprByValue ($ value ), false , false , [], new Node \Identifier ($ option ));
937
+ }, array_keys ($ options ), array_values ($ options ));
938
+
939
+ $ class = $ attributePrefix ? sprintf ('%s \\%s ' , $ attributePrefix , Str::getShortClassName ($ attributeClass )) : Str::getShortClassName ($ attributeClass );
940
+
941
+ return new Node \Attribute (
942
+ new Node \Name ($ class ),
943
+ $ nodeArguments
944
+ );
945
+ }
946
+
903
947
private function updateSourceCodeFromNewStmts (): void
904
948
{
905
949
$ newCode = $ this ->printer ->printFormatPreserving (
@@ -1421,27 +1465,6 @@ private function buildNodeExprByValue($value): Node\Expr
1421
1465
return $ nodeValue ;
1422
1466
}
1423
1467
1424
- /**
1425
- * builds an PHPParser attribute node.
1426
- *
1427
- * @param string $attributeClass the attribute class which should be used for the attribute
1428
- * @param array $options the named arguments for the attribute ($key = argument name, $value = argument value)
1429
- */
1430
- private function buildAttributeNode (string $ attributeClass , array $ options ): Node \Attribute
1431
- {
1432
- $ options = $ this ->sortOptionsByClassConstructorParameters ($ options , $ attributeClass );
1433
-
1434
- $ context = $ this ;
1435
- $ nodeArguments = array_map (static function ($ option , $ value ) use ($ context ) {
1436
- return new Node \Arg ($ context ->buildNodeExprByValue ($ value ), false , false , [], new Node \Identifier ($ option ));
1437
- }, array_keys ($ options ), array_values ($ options ));
1438
-
1439
- return new Node \Attribute (
1440
- new Node \Name ($ attributeClass ),
1441
- $ nodeArguments
1442
- );
1443
- }
1444
-
1445
1468
/**
1446
1469
* sort the given options based on the constructor parameters for the given $classString
1447
1470
* this prevents code inspections warnings for IDEs like intellij/phpstorm.
0 commit comments