Skip to content

Instantly share code, notes, and snippets.

@Berdir
Created April 19, 2020 16:41
Show Gist options
  • Save Berdir/b0da1c86b8f94ef15da985e52e7401dd to your computer and use it in GitHub Desktop.
Save Berdir/b0da1c86b8f94ef15da985e52e7401dd to your computer and use it in GitHub Desktop.
<?php
namespace Drupal\yourmodule\EventSubscriber;
use Drupal\Core\Cache\CacheableResponseInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Ensures that certain pages are cached correctly for anonymous users.
*/
class CacheResponseSubscriber implements EventSubscriberInterface {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $user;
/**
* Config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The current path.
*
* @var \Drupal\Core\Path\CurrentPathStack
*/
protected $currentPath;
/**
* CacheResponseSubscriber constructor.
*
* @param \Drupal\Core\Session\AccountInterface $user
* Current user.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
* @param \Drupal\Core\Path\CurrentPathStack $current_path
* The current path.
*/
public function __construct(AccountInterface $user, ConfigFactoryInterface $config_factory, CurrentPathStack $current_path) {
$this->user = $user;
$this->configFactory = $config_factory;
$this->currentPath = $current_path;
}
/**
* Updates response cache metadata.
*
* @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
* The kernel response event.
*/
public function onKernelResponse(FilterResponseEvent $event) {
$response = $event->getResponse();
// Do nothing if a response does not have cacheable metadata.
if (!$response instanceof CacheableResponseInterface) {
return;
}
if (!$this->user->isAnonymous()) {
return;
}
$cache_max_age = $response->getCacheableMetadata()->getCacheMaxAge();
// Allow some specific paths override max-age through config.
$pages = $this->configFactory->get('yourmodule_settings.settings')->get('anonymous_cached_pages');
$current_path = $this->currentPath->getPath();
$path_info = $event->getRequest()->getPathInfo();
if (isset($pages[$current_path])) {
$response->setExpires(new \DateTime($pages[$current_path] . 'sec'));
}
if (isset($pages[$path_info])) {
$response->setExpires(new \DateTime($pages[$path_info] . 'sec'));
}
elseif ($cache_max_age > 0) {
$response->setExpires(new \DateTime($cache_max_age . 'sec'));
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::RESPONSE][] = ['onKernelResponse'];
return $events;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment