1313
1414namespace ApiPlatform \State \Util ;
1515
16+ use ApiPlatform \Metadata \Error ;
1617use ApiPlatform \Metadata \Exception \HttpExceptionInterface ;
1718use ApiPlatform \Metadata \Exception \InvalidArgumentException ;
1819use ApiPlatform \Metadata \Exception \ItemNotFoundException ;
1920use ApiPlatform \Metadata \Exception \RuntimeException ;
2021use ApiPlatform \Metadata \HttpOperation ;
2122use ApiPlatform \Metadata \IriConverterInterface ;
2223use ApiPlatform \Metadata \Operation \Factory \OperationMetadataFactoryInterface ;
24+ use ApiPlatform \Metadata \Resource \Factory \ResourceMetadataCollectionFactoryInterface ;
25+ use ApiPlatform \Metadata \ResourceClassResolverInterface ;
2326use ApiPlatform \Metadata \UrlGeneratorInterface ;
2427use ApiPlatform \Metadata \Util \ClassInfoTrait ;
2528use ApiPlatform \Metadata \Util \CloneTrait ;
@@ -38,6 +41,8 @@ trait HttpResponseHeadersTrait
3841 use CloneTrait;
3942 private ?IriConverterInterface $ iriConverter ;
4043 private ?OperationMetadataFactoryInterface $ operationMetadataFactory ;
44+ private ?ResourceClassResolverInterface $ resourceClassResolver ;
45+ private ?ResourceMetadataCollectionFactoryInterface $ resourceMetadataCollectionFactory ;
4146
4247 /**
4348 * @param array<string, mixed> $context
@@ -122,6 +127,41 @@ private function getHeaders(Request $request, HttpOperation $operation, array $c
122127 }
123128 }
124129
130+ if (
131+ !$ operation instanceof Error
132+ && $ operation ->getUriTemplate ()
133+ && $ this ->resourceClassResolver ?->isResourceClass($ operation ->getClass ())
134+ ) {
135+ $ this ->addLinkedDataPlatformHeaders ($ headers , $ operation );
136+ }
137+
125138 return $ headers ;
126139 }
140+
141+ private function addLinkedDataPlatformHeaders (array &$ headers , HttpOperation $ operation ): void
142+ {
143+ if (!$ this ->resourceMetadataCollectionFactory ) {
144+ return ;
145+ }
146+
147+ $ acceptPost = null ;
148+ $ allowedMethods = ['OPTIONS ' , 'HEAD ' ];
149+ $ resourceCollection = $ this ->resourceMetadataCollectionFactory ->create ($ operation ->getClass ());
150+ foreach ($ resourceCollection as $ resource ) {
151+ foreach ($ resource ->getOperations () as $ op ) {
152+ if ($ op ->getUriTemplate () === $ operation ->getUriTemplate ()) {
153+ $ allowedMethods [] = $ method = $ op ->getMethod ();
154+ if ('POST ' === $ method && \is_array ($ outputFormats = $ op ->getOutputFormats ())) {
155+ $ acceptPost = implode (', ' , array_merge (...array_values ($ outputFormats )));
156+ }
157+ }
158+ }
159+ }
160+
161+ if ($ acceptPost ) {
162+ $ headers ['Accept-Post ' ] = $ acceptPost ;
163+ }
164+
165+ $ headers ['Allow ' ] = implode (', ' , $ allowedMethods );
166+ }
127167}
0 commit comments