Same filename in this branch
- 10 core/modules/jsonapi/src/EventSubscriber/ResourceResponseSubscriber.php
- 10 core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php
Same filename and directory in other branches
- 8.9.x core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php
- 9 core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php
Namespace
Drupal\rest\EventSubscriber
File
core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php
View source
<?php
namespace Drupal\rest\EventSubscriber;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\CacheableResponse;
use Drupal\Core\Cache\CacheableResponseInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\rest\ResourceResponseInterface;
use Drupal\serialization\Normalizer\CacheableNormalizerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Serializer\SerializerInterface;
class ResourceResponseSubscriber implements EventSubscriberInterface {
protected $serializer;
protected $renderer;
protected $routeMatch;
public function __construct(SerializerInterface $serializer, RendererInterface $renderer, RouteMatchInterface $route_match) {
$this->serializer = $serializer;
$this->renderer = $renderer;
$this->routeMatch = $route_match;
}
public function onResponse(ResponseEvent $event) {
$response = $event
->getResponse();
if (!$response instanceof ResourceResponseInterface) {
return;
}
$request = $event
->getRequest();
$format = $this
->getResponseFormat($this->routeMatch, $request);
$this
->renderResponseBody($request, $response, $this->serializer, $format);
$event
->setResponse($this
->flattenResponse($response));
}
public function getResponseFormat(RouteMatchInterface $route_match, Request $request) {
$route = $route_match
->getRouteObject();
$acceptable_response_formats = $route
->hasRequirement('_format') ? explode('|', $route
->getRequirement('_format')) : [];
$acceptable_request_formats = $route
->hasRequirement('_content_type_format') ? explode('|', $route
->getRequirement('_content_type_format')) : [];
$acceptable_formats = $request
->isMethodCacheable() ? $acceptable_response_formats : $acceptable_request_formats;
$requested_format = $request
->getRequestFormat();
$content_type_format = $request
->getContentTypeFormat();
if (in_array($requested_format, $acceptable_response_formats, TRUE)) {
return $requested_format;
}
if (!empty($request
->getContent()) && in_array($content_type_format, $acceptable_request_formats, TRUE)) {
return $content_type_format;
}
if (!empty($acceptable_formats)) {
return $acceptable_formats[0];
}
return NULL;
}
protected function renderResponseBody(Request $request, ResourceResponseInterface $response, SerializerInterface $serializer, $format) {
$data = $response
->getResponseData();
if ($data !== NULL) {
$serialization_context = [
'request' => $request,
CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY => new CacheableMetadata(),
];
$output = $serializer
->serialize($data, $format, $serialization_context);
if ($response instanceof CacheableResponseInterface) {
$response
->addCacheableDependency($serialization_context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY]);
}
$response
->setContent($output);
$response->headers
->set('Content-Type', $request
->getMimeType($format));
}
}
protected function flattenResponse(ResourceResponseInterface $response) {
$final_response = $response instanceof CacheableResponseInterface ? new CacheableResponse() : new Response();
$final_response
->setContent($response
->getContent());
$final_response
->setStatusCode($response
->getStatusCode());
$final_response
->setProtocolVersion($response
->getProtocolVersion());
if ($response
->getCharset()) {
$final_response
->setCharset($response
->getCharset());
}
$final_response->headers = clone $response->headers;
if ($final_response instanceof CacheableResponseInterface) {
$final_response
->addCacheableDependency($response
->getCacheableMetadata());
}
return $final_response;
}
public static function getSubscribedEvents() : array {
$events[KernelEvents::RESPONSE][] = [
'onResponse',
128,
];
return $events;
}
}
Classes