@@ -117,69 +117,35 @@ public function buildSchema(string $className, string $format = 'jsonld', string
117117 $ format = 'json ' ;
118118 }
119119
120- if ('jsonld ' !== $ format ) {
120+ if ('jsonld ' !== $ format || ! $ this -> isResourceClass ( $ className ) ) {
121121 return $ this ->schemaFactory ->buildSchema ($ className , $ format , $ type , $ operation , $ schema , $ serializerContext , $ forceCollection );
122122 }
123- if (!$ this ->isResourceClass ($ className )) {
124- $ operation = null ;
125- $ inputOrOutputClass = null ;
126- $ serializerContext ??= [];
127- } else {
128- $ operation = $ this ->findOperation ($ className , $ type , $ operation , $ serializerContext , $ format );
129- $ inputOrOutputClass = $ this ->findOutputClass ($ className , $ type , $ operation , $ serializerContext );
130- $ serializerContext ??= $ this ->getSerializerContext ($ operation , $ type );
131- }
123+
124+ $ operation = $ this ->findOperation ($ className , $ type , $ operation , $ serializerContext , $ format );
125+ $ inputOrOutputClass = $ this ->findOutputClass ($ className , $ type , $ operation , $ serializerContext );
126+ $ serializerContext ??= $ this ->getSerializerContext ($ operation , $ type );
132127
133128 if (null === $ inputOrOutputClass ) {
134129 // input or output disabled
135130 return $ this ->schemaFactory ->buildSchema ($ className , $ format , $ type , $ operation , $ schema , $ serializerContext , $ forceCollection );
136131 }
137132
138- $ definitionName = $ this ->definitionNameFactory ->create ($ className , $ format , $ inputOrOutputClass , $ operation , $ serializerContext );
139-
140- // JSON-LD is slightly different then JSON:API or HAL
141- // All the references that are resources must also be in JSON-LD therefore combining
142- // the HydraItemBaseSchema and the JSON schema is harder (unless we loop again through all relationship)
143- // The less intensive path is to compute the jsonld schemas, then to combine in an allOf
144133 $ schema = $ this ->schemaFactory ->buildSchema ($ className , 'jsonld ' , $ type , $ operation , $ schema , $ serializerContext , $ forceCollection );
145134 $ definitions = $ schema ->getDefinitions ();
146-
147135 $ prefix = $ this ->getSchemaUriPrefix ($ schema ->getVersion ());
148136 $ collectionKey = $ schema ->getItemsDefinitionKey ();
149- $ key = $ schema ->getRootDefinitionKey () ?? $ collectionKey ;
150137
151138 if (!$ collectionKey ) {
152- if ($ this ->transformed [$ definitionName ] ?? false ) {
153- return $ schema ;
154- }
155-
156- $ hasNoId = Schema::TYPE_OUTPUT === $ type && false === ($ serializerContext ['gen_id ' ] ?? true );
157- $ baseName = self ::ITEM_BASE_SCHEMA_NAME ;
158-
159- if ($ hasNoId ) {
160- $ baseName = self ::ITEM_WITHOUT_ID_BASE_SCHEMA_NAME ;
139+ $ definitionName = $ schema ->getRootDefinitionKey () ?? $ this ->definitionNameFactory ->create ($ className , $ format , $ inputOrOutputClass , $ operation , $ serializerContext );
140+ $ this ->decorateItemDefinition ($ definitionName , $ definitions , $ prefix , $ type , $ serializerContext );
141+
142+ if (isset ($ definitions [$ definitionName ])) {
143+ $ currentDefinitions = $ schema ->getDefinitions ();
144+ $ schema ->exchangeArray ([]); // Clear the schema
145+ $ schema ['$ref ' ] = $ prefix .$ definitionName ;
146+ $ schema ->setDefinitions ($ currentDefinitions );
161147 }
162148
163- if (!isset ($ definitions [$ baseName ])) {
164- $ definitions [$ baseName ] = $ hasNoId ? self ::ITEM_BASE_SCHEMA_WITHOUT_ID : self ::ITEM_BASE_SCHEMA_WITH_ID ;
165- }
166-
167- $ allOf = new \ArrayObject (['allOf ' => [
168- ['$ref ' => $ prefix .$ baseName ],
169- $ definitions [$ key ],
170- ]]);
171-
172- if (isset ($ definitions [$ key ]['description ' ])) {
173- $ allOf ['description ' ] = $ definitions [$ key ]['description ' ];
174- }
175-
176- $ definitions [$ definitionName ] = $ allOf ;
177- unset($ definitions [$ definitionName ]['allOf ' ][1 ]['description ' ]);
178-
179- $ schema ['$ref ' ] = $ prefix .$ definitionName ;
180-
181- $ this ->transformed [$ definitionName ] = true ;
182-
183149 return $ schema ;
184150 }
185151
@@ -206,11 +172,11 @@ public function buildSchema(string $className, string $format = 'jsonld', string
206172 'type ' => 'object ' ,
207173 'required ' => [
208174 $ hydraPrefix .'member ' ,
209- 'items ' => ['type ' => 'object ' ],
210175 ],
211176 'properties ' => [
212177 $ hydraPrefix .'member ' => [
213178 'type ' => 'array ' ,
179+ 'items ' => ['type ' => 'object ' ],
214180 ],
215181 $ hydraPrefix .'totalItems ' => [
216182 'type ' => 'integer ' ,
@@ -276,6 +242,7 @@ public function buildSchema(string $className, string $format = 'jsonld', string
276242 ];
277243 }
278244
245+ $ definitionName = $ this ->definitionNameFactory ->create ($ className , $ format , $ inputOrOutputClass , $ operation , $ serializerContext );
279246 $ schema ['type ' ] = 'object ' ;
280247 $ schema ['description ' ] = "$ definitionName collection. " ;
281248 $ schema ['allOf ' ] = [
@@ -293,6 +260,10 @@ public function buildSchema(string $className, string $format = 'jsonld', string
293260
294261 unset($ schema ['items ' ]);
295262
263+ if (isset ($ definitions [$ collectionKey ])) {
264+ $ this ->decorateItemDefinition ($ collectionKey , $ definitions , $ prefix , $ type , $ serializerContext );
265+ }
266+
296267 return $ schema ;
297268 }
298269
@@ -302,4 +273,35 @@ public function setSchemaFactory(SchemaFactoryInterface $schemaFactory): void
302273 $ this ->schemaFactory ->setSchemaFactory ($ schemaFactory );
303274 }
304275 }
276+
277+ private function decorateItemDefinition (string $ definitionName , \ArrayObject $ definitions , string $ prefix , string $ type , ?array $ serializerContext ): void
278+ {
279+ if (!isset ($ definitions [$ definitionName ]) || ($ this ->transformed [$ definitionName ] ?? false )) {
280+ return ;
281+ }
282+
283+ $ hasNoId = Schema::TYPE_OUTPUT === $ type && false === ($ serializerContext ['gen_id ' ] ?? true );
284+ $ baseName = self ::ITEM_BASE_SCHEMA_NAME ;
285+ if ($ hasNoId ) {
286+ $ baseName = self ::ITEM_WITHOUT_ID_BASE_SCHEMA_NAME ;
287+ }
288+
289+ if (!isset ($ definitions [$ baseName ])) {
290+ $ definitions [$ baseName ] = $ hasNoId ? self ::ITEM_BASE_SCHEMA_WITHOUT_ID : self ::ITEM_BASE_SCHEMA_WITH_ID ;
291+ }
292+
293+ $ allOf = new \ArrayObject (['allOf ' => [
294+ ['$ref ' => $ prefix .$ baseName ],
295+ $ definitions [$ definitionName ],
296+ ]]);
297+
298+ if (isset ($ definitions [$ definitionName ]['description ' ])) {
299+ $ allOf ['description ' ] = $ definitions [$ definitionName ]['description ' ];
300+ }
301+
302+ $ definitions [$ definitionName ] = $ allOf ;
303+ unset($ definitions [$ definitionName ]['allOf ' ][1 ]['description ' ]);
304+
305+ $ this ->transformed [$ definitionName ] = true ;
306+ }
305307}
0 commit comments