You are here

class CacheableResponseSubscriber in Pantheon Advanced Page Cache 8

Same name in this branch
  1. 8 src/EventSubscriber/CacheableResponseSubscriber.php \Drupal\pantheon_advanced_page_cache\EventSubscriber\CacheableResponseSubscriber
  2. 8 tests/modules/pantheon_advanced_page_cache_test/src/EventSubscriber/CacheableResponseSubscriber.php \Drupal\pantheon_advanced_page_cache_test\EventSubscriber\CacheableResponseSubscriber

Adds Surrogate-Key header to cacheable master responses.

Hierarchy

  • class \Drupal\pantheon_advanced_page_cache\EventSubscriber\CacheableResponseSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface

Expanded class hierarchy of CacheableResponseSubscriber

1 string reference to 'CacheableResponseSubscriber'
pantheon_advanced_page_cache.services.yml in ./pantheon_advanced_page_cache.services.yml
pantheon_advanced_page_cache.services.yml
1 service uses CacheableResponseSubscriber
pantheon_advanced_page_cache.cacheable_response_subscriber in ./pantheon_advanced_page_cache.services.yml
Drupal\pantheon_advanced_page_cache\EventSubscriber\CacheableResponseSubscriber

File

src/EventSubscriber/CacheableResponseSubscriber.php, line 16

Namespace

Drupal\pantheon_advanced_page_cache\EventSubscriber
View source
class CacheableResponseSubscriber implements EventSubscriberInterface {

  /**
   * The logger instance.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * Configuration Factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Constructs a new DefaultExceptionHtmlSubscriber.
   *
   * @param \Psr\Log\LoggerInterface $logger
   *   The logger service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   Configuration for this module.
   */
  public function __construct(LoggerInterface $logger, ConfigFactoryInterface $config_factory = NULL) {
    if (!$config_factory instanceof ConfigFactoryInterface) {
      @trigger_error('Not passing the config factory service as the second parameter to ' . __METHOD__ . ' is deprecated in pantheon_advanced_page_cache:8.x-1.2 and will throw a type error in pantheon_advanced_page_cache:8.x-2.0. Pass an instance of \\Drupal\\Core\\Config\\ConfigFactoryInterface. See https://www.drupal.org/node/2944229', E_USER_DEPRECATED);
      $config_factory = \Drupal::service('config.factory');
    }
    $this->logger = $logger;
    $this->configFactory = $config_factory;
  }

  /**
   * Returns whether entity_list tags should be overridden.
   *
   * Overriding these tags was the initial behavior of the 1.0 version of this
   * module. That is no longer recommended.
   */
  public function getOverrideListTagsSetting() {
    $config = $this->configFactory
      ->get('pantheon_advanced_page_cache.settings');

    // Only return FALSE if this config value is really set to false.
    // A null value should return TRUE for backwards compatibility.
    if ($config
      ->get('override_list_tags') === FALSE) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * Adds Surrogate-Key header to cacheable master responses.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   The event to process.
   */
  public function onRespond(FilterResponseEvent $event) {
    if (!$event
      ->isMasterRequest()) {
      return;
    }
    $response = $event
      ->getResponse();
    if ($response instanceof CacheableResponseInterface) {
      $tags = $response
        ->getCacheableMetadata()
        ->getCacheTags();

      // Rename all _list cache tags to _emit_list to avoid clearing list cache
      // tags by default.
      if ($this
        ->getOverrideListTagsSetting()) {
        foreach ($tags as $key => $tag) {
          $tags[$key] = str_replace('_list', '_emit_list', $tag);
        }
      }
      $tags_string = implode(' ', $tags);
      if (25000 < strlen($tags_string)) {
        $tags_string = substr($tags_string, 0, 25000);

        // The string might have cut of in the middle of a tag.
        // So now find the the last occurence of a space and cut to that length.
        $tags_string = substr($tags_string, 0, strrpos($tags_string, ' '));
        $this->logger
          ->log(RfcLogLevel::WARNING, 'More cache tags were present than could be passed in the Surrogate-Key HTTP Header due to length constraints. To avoid a 502 error the list of surrogate keys was trimmed to a maximum length of 25,000 bytes. Since keys beyond the 25,000 maximum were removed this page will not be cleared from the cache when any of the removed keys are cleared (usually by entity save operations) as they have been stripped from the surrogate key header. See https://www.drupal.org/project/pantheon_advanced_page_cache/issues/2973861 for more information about how you can filter out redundant or unnecessary cache metadata.');
      }
      $response->headers
        ->set('Surrogate-Key', $tags_string);
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = [
      'onRespond',
    ];
    return $events;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CacheableResponseSubscriber::$configFactory protected property Configuration Factory.
CacheableResponseSubscriber::$logger protected property The logger instance.
CacheableResponseSubscriber::getOverrideListTagsSetting public function Returns whether entity_list tags should be overridden.
CacheableResponseSubscriber::getSubscribedEvents public static function Returns an array of event names this subscriber wants to listen to.
CacheableResponseSubscriber::onRespond public function Adds Surrogate-Key header to cacheable master responses.
CacheableResponseSubscriber::__construct public function Constructs a new DefaultExceptionHtmlSubscriber.