<?phpnamespace GC\SanityBundle\EventListener;use GC\SanityBundle\ESIAdapter;use GC\SanityBundle\ControllerResult;use GC\SanityBundle\Configuration\ExplicitHTTPCacheLayer;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpKernel\KernelEvents;use Symfony\Component\HttpKernel\Event\ViewEvent;use Symfony\Component\HttpKernel\Event\ResponseEvent;use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;use Symfony\Component\HttpFoundation\Response;class ResponseListener implements EventSubscriberInterface{ protected $esi; protected $httpCacheLayer; protected $lastModified; public function __construct( ESIAdapter $esi ) { $this->esi = $esi; } public static function getSubscribedEvents() { return array( KernelEvents::VIEW => array('onKernelView', 128), KernelEvents::RESPONSE => array('onKernelResponse'), ); } /** * @param GetResponseForControllerResultEvent $event A GetResponseForControllerResultEvent instance */ public function onKernelView(ViewEvent $event) { $request = $event->getRequest(); $controllerResult = $event->getControllerResult(); $this->httpCacheLayer = $request->attributes->get('_http_cache_layer'); if($controllerResult instanceOf ControllerResult){ $this->lastModified = $controllerResult->getLatestDateTime(); if( !$this->httpCacheLayer ) $this->httpCacheLayer = new ExplicitHTTPCacheLayer([]); if( !$controllerResult->hasResult() ){ if( $controllerResult->throwOnNoResult() ) throw new NotFoundHttpException; if( $controllerResult->emptyResponseOnNoResult() ) $event->setResponse( new Response ); return; } } else if ($this->httpCacheLayer) { // just a twig template, use git date or default $this->lastModified = $this->esi->getBaseLastModified(); } if( $this->lastModified ) { if( $this->esi->getProductionMode() ){ $response = new Response; $response->setLastModified( $this->lastModified ); if ($response->isNotModified( $request )){ $event->setResponse( $response ); return; } } if($controllerResult instanceOf ControllerResult){ // fetch and hydrate the objects $result = $controllerResult->getResult(); $event->setControllerResult($result + [ '_controller_result' => [ 'name' => $controllerResult->getName(), 'last_modified' => $this->lastModified, 'result' => $result ] ]); } } } /** * @param FilterResponseEvent $event A FilterResponseEvent instance */ public function onKernelResponse(ResponseEvent $event) { if($this->lastModified && $this->httpCacheLayer){ $response = $event->getResponse(); $response->setLastModified( $this->lastModified ); $response->headers->set('x-esi-last-modified', $this->lastModified->format('r')); if( $this->esi->getProductionMode() ){ $maxAge = $this->httpCacheLayer->getMaxAge(); if(!is_null($maxAge)) $response->setMaxAge( $maxAge ); $response->setSharedMaxAge( $this->httpCacheLayer->getSharedMaxAge() ); } } }}