vendor/can/rest/src/Can/RestBundle/EventListener/ContentHeadersListener.php line 52

Open in your IDE?
  1. <?php
  2. namespace Can\RestBundle\EventListener;
  3. use Can\RestBundle\CanRestBundle;
  4. use Can\RestBundle\Http\Method;
  5. use Can\RestBundle\Mapping\MetadataStore;
  6. use Can\RestBundle\Negotiation\NegotiationConfiguration;
  7. use Can\RestBundle\Negotiation\NegotiationHeader;
  8. use Can\RestBundle\URI\ServiceNode;
  9. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  10. /**
  11.  * Adds the response Content-like headers.
  12.  *
  13.  * @group negotiation
  14.  *
  15.  * @package can/rest-bundle
  16.  * @author lechecacharro <lechecacharro@gmail.com>
  17.  */
  18. class ContentHeadersListener
  19. {
  20.     /**
  21.      * @var NegotiationConfiguration
  22.      */
  23.     private $configuration;
  24.     /**
  25.      * @var MetadataStore
  26.      */
  27.     private $store;
  28.     /**
  29.      * ContentHeadersListener constructor.
  30.      *
  31.      * @param NegotiationConfiguration $configuration
  32.      * @param MetadataStore            $store
  33.      */
  34.     public function __construct(NegotiationConfiguration $configurationMetadataStore $store)
  35.     {
  36.         $this->configuration $configuration;
  37.         $this->store $store;
  38.     }
  39.     /**
  40.      * @param ResponseEvent $event
  41.      */
  42.     public function onResponse(ResponseEvent $event): void
  43.     {
  44.         if (! $this->configuration->isEnabled()) {
  45.             return;
  46.         }
  47.         $request $event->getRequest();
  48.         if (! $request->attributes->get(CanRestBundle::ATTR_SERVICE_ZONE)) {
  49.             return;
  50.         }
  51.         $response $event->getResponse();
  52.         // Don't add content headers to empty responses
  53.         if ($response->isEmpty() || empty($response->getContent())) {
  54.             return;
  55.         }
  56.         if ($charset $request->attributes->get(CanRestBundle::ATTR_NEGOTIATION_CHARSET)) {
  57.             $response->setCharset($charset);
  58.         }
  59.         //if ($encoding = $request->attributes->get(CanRestBundle::ATTR_NEGOTIATION_ENCODING)) {
  60.             //$response->headers->set(NegotiationHeader::CONTENT_ENCODING, $encoding);
  61.         //}
  62.         if ($language $request->attributes->get(CanRestBundle::ATTR_NEGOTIATION_LANGUAGE)) {
  63.             $response->headers->set(NegotiationHeader::CONTENT_LANGUAGE$language);
  64.         }
  65.         if ($mediaType $request->attributes->get(CanRestBundle::ATTR_NEGOTIATION_MEDIA_TYPE)) {
  66.             $response->headers->set(NegotiationHeader::CONTENT_TYPE$mediaType);
  67.             if ($this->configuration->isPreventBrowserSniffing()) {
  68.                 $response->headers->set(NegotiationHeader::X_CONTENT_TYPE_OPTIONS'nosniff');
  69.             }
  70.         }
  71.         $serviceNode $request->attributes->get(CanRestBundle::ATTR_SERVICE_NODE);
  72.         if (! $serviceNode instanceof ServiceNode) {
  73.             return;
  74.         }
  75.         if ($this->configuration->isAdvertiseAcceptedPatches() && $this->currentNodeSupportsPatch($serviceNode)) {
  76.             $patchFormats $this->configuration->getPatchFormats();
  77.             if ($patchFormats) {
  78.                 $response->headers->set(NegotiationHeader::ACCEPT_PATCHimplode(','array_merge(...array_values($patchFormats))));
  79.             }
  80.         }
  81.         if ($this->configuration->isAdvertiseAcceptedSearches() && $this->currentNodeSupportsSearch($serviceNode)) {
  82.             $searchFormats $this->configuration->getSearchFormats();
  83.             if ($searchFormats) {
  84.                 $response->headers->set(NegotiationHeader::ACCEPT_SEARCHimplode(','array_merge(...array_values($searchFormats))));
  85.             }
  86.         }
  87.     }
  88.     /**
  89.      * @param ServiceNode $node
  90.      *
  91.      * @return bool
  92.      */
  93.     protected function currentNodeSupportsPatch(ServiceNode $node): bool
  94.     {
  95.         if ($node->isCollection()) {
  96.             // We DO NOT support collection patches
  97.             return false;
  98.         }
  99.         if (! $this->store->hasMetadataFor($node)) {
  100.             return false;
  101.         }
  102.         return $this->store->getMetadataFor($node)->supportsMethod(Method::PATCH);
  103.     }
  104.     /**
  105.      * @param ServiceNode $node
  106.      *
  107.      * @return bool
  108.      */
  109.     protected function currentNodeSupportsSearch(ServiceNode $node): bool
  110.     {
  111.         if (! $this->store->hasMetadataFor($node)) {
  112.             return false;
  113.         }
  114.         return $this->store->getMetadataFor($node)->supportsOperation(Method::SEARCH$node->isCollection());
  115.     }
  116. }