vendor/friendsofsymfony/rest-bundle/EventListener/ViewResponseListener.php line 41
<?php/** This file is part of the FOSRestBundle package.** (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>** For the full copyright and license information, please view the LICENSE* file that was distributed with this source code.*/namespace FOS\RestBundle\EventListener;use Doctrine\Common\Annotations\Reader;use Doctrine\Persistence\Proxy;use FOS\RestBundle\Controller\Annotations\View as ViewAnnotation;use FOS\RestBundle\FOSRestBundle;use FOS\RestBundle\View\View;use FOS\RestBundle\View\ViewHandlerInterface;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpKernel\Event\ControllerEvent;use Symfony\Component\HttpKernel\Event\ViewEvent;use Symfony\Component\HttpKernel\KernelEvents;/*** The ViewResponseListener class handles the kernel.view event and creates a {@see Response} for a {@see View} provided by the controller result.** @author Lukas Kahwe Smith <[email protected]>** @internal*/class ViewResponseListener implements EventSubscriberInterface{/*** @var ViewHandlerInterface*/private $viewHandler;private $forceView;/*** @var Reader|null*/private $annotationReader;public function __construct(ViewHandlerInterface $viewHandler, bool $forceView, ?Reader $annotationReader = null){$this->viewHandler = $viewHandler;$this->forceView = $forceView;$this->annotationReader = $annotationReader;}/*** Extracts configuration for a {@see ViewAnnotation} from the controller if present.*/public function onKernelController(ControllerEvent $event){$request = $event->getRequest();if (!$request->attributes->get(FOSRestBundle::ZONE_ATTRIBUTE, true)) {return;}$controller = $event->getController();if (!\is_array($controller) && method_exists($controller, '__invoke')) {$controller = [$controller, '__invoke'];}if (!\is_array($controller)) {return;}$className = $this->getRealClass(\get_class($controller[0]));$object = new \ReflectionClass($className);$method = $object->getMethod($controller[1]);/** @var ViewAnnotation|null $classConfiguration */$classConfiguration = null;/** @var ViewAnnotation|null $methodConfiguration */$methodConfiguration = null;if (null !== $this->annotationReader) {$classConfiguration = $this->getViewConfiguration($this->annotationReader->getClassAnnotations($object));$methodConfiguration = $this->getViewConfiguration($this->annotationReader->getMethodAnnotations($method));}if (80000 <= \PHP_VERSION_ID) {if (null === $classConfiguration) {$classAttributes = array_map(function (\ReflectionAttribute $attribute) {return $attribute->newInstance();},$object->getAttributes(ViewAnnotation::class, \ReflectionAttribute::IS_INSTANCEOF));$classConfiguration = $this->getViewConfiguration($classAttributes);}if (null === $methodConfiguration) {$methodAttributes = array_map(function (\ReflectionAttribute $attribute) {return $attribute->newInstance();},$method->getAttributes(ViewAnnotation::class, \ReflectionAttribute::IS_INSTANCEOF));$methodConfiguration = $this->getViewConfiguration($methodAttributes);}}// An annotation/attribute on the method takes precedence over the class levelif (null !== $methodConfiguration) {$request->attributes->set(FOSRestBundle::VIEW_ATTRIBUTE, $methodConfiguration);} elseif (null !== $classConfiguration) {$request->attributes->set(FOSRestBundle::VIEW_ATTRIBUTE, $classConfiguration);}}public function onKernelView(ViewEvent $event): void{$request = $event->getRequest();if (!$request->attributes->get(FOSRestBundle::ZONE_ATTRIBUTE, true)) {return;}/** @var ViewAnnotation|null $configuration */$configuration = $request->attributes->get(FOSRestBundle::VIEW_ATTRIBUTE);$view = $event->getControllerResult();if (!$view instanceof View) {if (!$configuration instanceof ViewAnnotation && !$this->forceView) {return;}$view = new View($view);}if ($configuration instanceof ViewAnnotation) {if (null !== $configuration->getStatusCode() && (null === $view->getStatusCode() || Response::HTTP_OK === $view->getStatusCode())) {$view->setStatusCode($configuration->getStatusCode());}$context = $view->getContext();if ($configuration->getSerializerGroups()) {if (null === $context->getGroups()) {$context->setGroups($configuration->getSerializerGroups());} else {$context->setGroups(array_merge($context->getGroups(), $configuration->getSerializerGroups()));}}if (true === $configuration->getSerializerEnableMaxDepthChecks()) {$context->enableMaxDepth();} elseif (false === $configuration->getSerializerEnableMaxDepthChecks()) {$context->disableMaxDepth();}}if (null === $view->getFormat()) {$view->setFormat($request->getRequestFormat());}$event->setResponse($this->viewHandler->handle($view, $request));}public static function getSubscribedEvents(): array{return [KernelEvents::CONTROLLER => 'onKernelController',KernelEvents::VIEW => ['onKernelView', 30],];}/*** @param object[] $annotations*/private function getViewConfiguration(array $annotations): ?ViewAnnotation{$viewAnnotation = null;foreach ($annotations as $annotation) {if (!$annotation instanceof ViewAnnotation) {continue;}if (null === $viewAnnotation) {$viewAnnotation = $annotation;} else {throw new \LogicException('Multiple "view" annotations are not allowed.');}}return $viewAnnotation;}private function getRealClass(string $class): string{if (class_exists(Proxy::class)) {if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) {return $class;}return substr($class, $pos + Proxy::MARKER_LENGTH + 2);}return $class;}}