0

Is there a way to set cache headers in symfony controller annotations only for specific status codes?

I am currently doing it like in the code below, utilizing the annotations provided by the SensioFrameworkExtraBundle:

 /**
 * @Get("", name="product.list")
 * @Cache(public=true, maxage="432000", smaxage="432000")
 */
public function listAction()
{
    // ...
}

But this annotation sets the cache headers for all responses no matter what status code. I would like to set the cache headers only for specific status codes.

Thomas
  • 385
  • 5
  • 8
  • What other status codes are you referring to and how are you setting these? – Gerry Oct 12 '16 at 12:17
  • For example a 404 Error also gets those cache headers. And in particular i create a 404 Response through throwing a HttpNoutFound exception. – Thomas Oct 13 '16 at 08:43

1 Answers1

1

Looking at the code in SensioFrameworkExtraBundle, the most straight-forward solution would be to either not use annotations but set the cache headers manually on the response (in the controller or an event listener for example), or create an event listener that prevents the SensioFrameworkExtraBundle to set the cache headers.

Regarding the second option, looking at the code (https://github.com/sensiolabs/SensioFrameworkExtraBundle/blob/master/EventListener/HttpCacheListener.php#L86-L88), you could unset the _cache request attribute before the HttpCacheListener is triggered.

<?php

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class MyCacheListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::RESPONSE => ['onKernelResponse', 16] // use a priority higher than the HttpCacheListener
        ];
    }

    public function onKernelResponse(FilterResponseEvent $event)
    {
        $request = $event->getRequest();
        $response = $event->getResponse();

        if (!$response->isSuccessful()) {
            $request->attributes->remove('_cache');
        }
    }
}

Register your event subscriber, for example in services.yml:

services:
    my_cache_listener:
        class: MyCacheListener
        tags:
            - { name: kernel.event_subscriber }
Gerry
  • 6,012
  • 21
  • 33
  • Thank you! I guess that is exactly what i am going to do. I just thought there might be a solution through annotations. – Thomas Oct 14 '16 at 11:46