17
17
use ApiPlatform \Metadata \FilterInterface ;
18
18
use ApiPlatform \Metadata \JsonSchemaFilterInterface ;
19
19
use ApiPlatform \Metadata \OpenApiParameterFilterInterface ;
20
+ use ApiPlatform \Metadata \Operation ;
20
21
use ApiPlatform \Metadata \Parameter ;
21
22
use ApiPlatform \Metadata \Parameters ;
22
23
use ApiPlatform \Metadata \Property \Factory \PropertyMetadataFactoryInterface ;
34
35
*/
35
36
final class ParameterResourceMetadataCollectionFactory implements ResourceMetadataCollectionFactoryInterface
36
37
{
38
+ private array $ localPropertyCache ;
39
+
37
40
public function __construct (
38
41
private readonly PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory ,
39
42
private readonly PropertyMetadataFactoryInterface $ propertyMetadataFactory ,
@@ -47,51 +50,12 @@ public function create(string $resourceClass): ResourceMetadataCollection
47
50
{
48
51
$ resourceMetadataCollection = $ this ->decorated ?->create($ resourceClass ) ?? new ResourceMetadataCollection ($ resourceClass );
49
52
50
- $ propertyNames = [];
51
- $ properties = [];
52
- foreach ($ this ->propertyNameCollectionFactory ->create ($ resourceClass ) as $ i => $ property ) {
53
- $ propertyMetadata = $ this ->propertyMetadataFactory ->create ($ resourceClass , $ property );
54
- if ($ propertyMetadata ->isReadable ()) {
55
- $ propertyNames [] = $ property ;
56
- $ properties [$ property ] = $ propertyMetadata ;
57
- }
58
- }
59
-
60
53
foreach ($ resourceMetadataCollection as $ i => $ resource ) {
61
54
$ operations = $ resource ->getOperations ();
62
55
63
56
$ internalPriority = -1 ;
64
57
foreach ($ operations as $ operationName => $ operation ) {
65
- $ parameters = $ operation ->getParameters () ?? new Parameters ();
66
- foreach ($ parameters as $ key => $ parameter ) {
67
- if (':property ' === $ key ) {
68
- foreach ($ propertyNames as $ property ) {
69
- $ converted = $ this ->nameConverter ?->denormalize($ property ) ?? $ property ;
70
- $ propertyParameter = $ this ->setDefaults ($ converted , $ parameter , $ resourceClass , $ properties );
71
- $ priority = $ propertyParameter ->getPriority () ?? $ internalPriority --;
72
- $ parameters ->add ($ converted , $ propertyParameter ->withPriority ($ priority )->withKey ($ converted ));
73
- }
74
-
75
- $ parameters ->remove ($ key , $ parameter ::class);
76
- continue ;
77
- }
78
-
79
- $ key = $ parameter ->getKey () ?? $ key ;
80
-
81
- if (str_contains ($ key , ':property ' )) {
82
- $ p = [];
83
- foreach ($ propertyNames as $ prop ) {
84
- $ p [$ this ->nameConverter ?->denormalize($ prop ) ?? $ prop ] = $ prop ;
85
- }
86
-
87
- $ parameter = $ parameter ->withExtraProperties (($ parameter ->getExtraProperties () ?? []) + ['_properties ' => $ p ]);
88
- }
89
-
90
- $ parameter = $ this ->setDefaults ($ key , $ parameter , $ resourceClass , $ properties );
91
- $ priority = $ parameter ->getPriority () ?? $ internalPriority --;
92
- $ parameters ->add ($ key , $ parameter ->withPriority ($ priority ));
93
- }
94
-
58
+ $ parameters = $ this ->getDefaultParameters ($ operation , $ resourceClass , $ internalPriority );
95
59
if (\count ($ parameters ) > 0 ) {
96
60
$ operations ->add ($ operationName , $ operation ->withParameters ($ parameters ));
97
61
}
@@ -105,15 +69,10 @@ public function create(string $resourceClass): ResourceMetadataCollection
105
69
106
70
$ internalPriority = -1 ;
107
71
foreach ($ graphQlOperations as $ operationName => $ operation ) {
108
- $ parameters = $ operation ->getParameters () ?? new Parameters ();
109
- foreach ($ operation ->getParameters () ?? [] as $ key => $ parameter ) {
110
- $ key = $ parameter ->getKey () ?? $ key ;
111
- $ parameter = $ this ->setDefaults ($ key , $ parameter , $ resourceClass , $ properties );
112
- $ priority = $ parameter ->getPriority () ?? $ internalPriority --;
113
- $ parameters ->add ($ key , $ parameter ->withPriority ($ priority ));
72
+ $ parameters = $ this ->getDefaultParameters ($ operation , $ resourceClass , $ internalPriority );
73
+ if (\count ($ parameters ) > 0 ) {
74
+ $ graphQlOperations [$ operationName ] = $ operation ->withParameters ($ parameters );
114
75
}
115
-
116
- $ graphQlOperations [$ operationName ] = $ operation ->withParameters ($ parameters );
117
76
}
118
77
119
78
$ resourceMetadataCollection [$ i ] = $ resource ->withGraphQlOperations ($ graphQlOperations );
@@ -122,6 +81,66 @@ public function create(string $resourceClass): ResourceMetadataCollection
122
81
return $ resourceMetadataCollection ;
123
82
}
124
83
84
+ /**
85
+ * @return array{propertyNames: string[], properties: array<string, ApiProperty>}
86
+ */
87
+ private function getProperties (string $ resourceClass ): array
88
+ {
89
+ if (isset ($ this ->localPropertyCache [$ resourceClass ])) {
90
+ return $ this ->localPropertyCache [$ resourceClass ];
91
+ }
92
+
93
+ $ propertyNames = [];
94
+ $ properties = [];
95
+ foreach ($ this ->propertyNameCollectionFactory ->create ($ resourceClass ) as $ property ) {
96
+ $ propertyMetadata = $ this ->propertyMetadataFactory ->create ($ resourceClass , $ property );
97
+ if ($ propertyMetadata ->isReadable ()) {
98
+ $ propertyNames [] = $ property ;
99
+ $ properties [$ property ] = $ propertyMetadata ;
100
+ }
101
+ }
102
+
103
+ $ this ->localPropertyCache = [$ resourceClass => ['propertyNames ' => $ propertyNames , 'properties ' => $ properties ]];
104
+
105
+ return $ this ->localPropertyCache [$ resourceClass ];
106
+ }
107
+
108
+ private function getDefaultParameters (Operation $ operation , string $ resourceClass , int &$ internalPriority ): Parameters
109
+ {
110
+ ['propertyNames ' => $ propertyNames , 'properties ' => $ properties ] = $ this ->getProperties ($ resourceClass );
111
+ $ parameters = $ operation ->getParameters () ?? new Parameters ();
112
+ foreach ($ parameters as $ key => $ parameter ) {
113
+ if (':property ' === $ key ) {
114
+ foreach ($ propertyNames as $ property ) {
115
+ $ converted = $ this ->nameConverter ?->denormalize($ property ) ?? $ property ;
116
+ $ propertyParameter = $ this ->setDefaults ($ converted , $ parameter , $ resourceClass , $ properties );
117
+ $ priority = $ propertyParameter ->getPriority () ?? $ internalPriority --;
118
+ $ parameters ->add ($ converted , $ propertyParameter ->withPriority ($ priority )->withKey ($ converted ));
119
+ }
120
+
121
+ $ parameters ->remove ($ key , $ parameter ::class);
122
+ continue ;
123
+ }
124
+
125
+ $ key = $ parameter ->getKey () ?? $ key ;
126
+
127
+ if (str_contains ($ key , ':property ' )) {
128
+ $ p = [];
129
+ foreach ($ propertyNames as $ prop ) {
130
+ $ p [$ this ->nameConverter ?->denormalize($ prop ) ?? $ prop ] = $ prop ;
131
+ }
132
+
133
+ $ parameter = $ parameter ->withExtraProperties ($ parameter ->getExtraProperties () + ['_properties ' => $ p ]);
134
+ }
135
+
136
+ $ parameter = $ this ->setDefaults ($ key , $ parameter , $ resourceClass , $ properties );
137
+ $ priority = $ parameter ->getPriority () ?? $ internalPriority --;
138
+ $ parameters ->add ($ key , $ parameter ->withPriority ($ priority ));
139
+ }
140
+
141
+ return $ parameters ;
142
+ }
143
+
125
144
private function addFilterMetadata (Parameter $ parameter ): Parameter
126
145
{
127
146
if (!($ filterId = $ parameter ->getFilter ())) {
0 commit comments