@@ -26,16 +26,44 @@ final class ConfigurationAttributeGenerator extends AbstractAttributeGenerator
26
26
*/
27
27
public function generateClassAttributes (Class_ $ class ): array
28
28
{
29
- $ typeConfig = $ this ->config ['types ' ][$ class ->name ()] ?? null ;
30
- $ vocabConfig = null ;
29
+ $ typeAttributes = $ this ->config ['types ' ][$ class ->name ()][ ' attributes ' ] ?? [[]] ;
30
+ $ vocabAttributes = [[]] ;
31
31
if ($ class instanceof SchemaClass) {
32
- $ vocabConfig = $ this ->config ['vocabularies ' ][$ class ->resource ()->getGraph ()->getUri ()] ?? null ;
32
+ $ vocabAttributes = $ this ->config ['vocabularies ' ][$ class ->resource ()->getGraph ()->getUri ()][ ' attributes ' ] ?? [[]] ;
33
33
}
34
34
35
+ $ getAttributesNames = static fn (array $ config ) => $ config === [[]]
36
+ ? []
37
+ : array_unique (array_map (fn (array $ v ) => array_keys ($ v )[0 ], $ config ));
38
+ $ typeAttributesNames = $ getAttributesNames ($ typeAttributes );
39
+ $ vocabAttributesNames = $ getAttributesNames ($ vocabAttributes );
40
+
41
+ $ getAttribute = static fn (string $ name , array $ args ) => new Attribute (
42
+ $ name ,
43
+ $ args + [
44
+ // An attribute from a vocabulary cannot be appended if a same one has not
45
+ // previously been generated or if the same one is not mergeable.
46
+ // It allows vocabulary attributes configuration to only merge the attributes args.
47
+ 'alwaysGenerate ' => !\in_array ($ name , $ vocabAttributesNames , true ) ||
48
+ \in_array ($ name , $ typeAttributesNames , true ),
49
+ // Custom explicitly configured attributes is not mergeable with next one
50
+ // but treated as repeated if given more than once.
51
+ 'mergeable ' => false ,
52
+ ]
53
+ );
54
+
35
55
$ attributes = [];
36
- $ configAttributes = array_merge ($ vocabConfig ['attributes ' ] ?? [], $ typeConfig ['attributes ' ] ?? []);
37
- foreach ($ configAttributes as $ attributeName => $ attributeArgs ) {
38
- $ attributes [] = new Attribute ($ attributeName , ($ attributeArgs ?? []) + ['alwaysGenerate ' => !isset ($ vocabConfig ['attributes ' ][$ attributeName ]) || isset ($ typeConfig ['attributes ' ][$ attributeName ])]);
56
+ foreach ($ vocabAttributes as $ configAttributes ) {
57
+ foreach ($ configAttributes as $ attributeName => $ attributeArgs ) {
58
+ if (!\in_array ($ attributeName , $ typeAttributesNames , true )) {
59
+ $ attributes [] = $ getAttribute ($ attributeName , $ attributeArgs ?? []);
60
+ }
61
+ }
62
+ }
63
+ foreach ($ typeAttributes as $ configAttributes ) {
64
+ foreach ($ configAttributes as $ attributeName => $ attributeArgs ) {
65
+ $ attributes [] = $ getAttribute ($ attributeName , $ attributeArgs ?? []);
66
+ }
39
67
}
40
68
41
69
return $ attributes ;
@@ -47,11 +75,16 @@ public function generateClassAttributes(Class_ $class): array
47
75
public function generatePropertyAttributes (Property $ property , string $ className ): array
48
76
{
49
77
$ typeConfig = $ this ->config ['types ' ][$ className ] ?? null ;
50
- $ propertyConfig = $ typeConfig ['properties ' ][$ property ->name ()] ?? null ;
78
+ $ propertyAttributes = $ typeConfig ['properties ' ][$ property ->name ()][ ' attributes ' ] ?? [[]] ;
51
79
52
80
$ attributes = [];
53
- foreach ($ propertyConfig ['attributes ' ] ?? [] as $ attributeName => $ attributeArgs ) {
54
- $ attributes [] = new Attribute ($ attributeName , $ attributeArgs ?? []);
81
+ foreach ($ propertyAttributes as $ configAttributes ) {
82
+ foreach ($ configAttributes as $ attributeName => $ attributeArgs ) {
83
+ $ attributes [] = new Attribute (
84
+ $ attributeName ,
85
+ ($ attributeArgs ?? []) + ['mergeable ' => false ]
86
+ );
87
+ }
55
88
}
56
89
57
90
return $ attributes ;
0 commit comments