cache_review-1.0.x-dev/src/StackMiddleware/CacheReview.php

src/StackMiddleware/CacheReview.php
<?php

namespace Drupal\cache_review\StackMiddleware;

use Drupal\cache_review\Form\CacheReviewConfigForm;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;

/**
 * Show cache variables before page load.
 */
class CacheReview implements HttpKernelInterface {

  use StringTranslationTrait;

  /**
   * The wrapped HTTP kernel.
   *
   * @var \Symfony\Component\HttpKernel\HttpKernelInterface
   */
  protected $httpKernel;

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The renderer configuration array.
   *
   * @var array
   */
  protected $rendererConfig;

  /**
   * The request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  /**
   * The config factory service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The response object.
   *
   * @var \Symfony\Component\HttpFoundation\Response
   */
  protected $response;

  /**
   * The date formatter service.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * Constructs a PageCache object.
   *
   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
   *   The decorated kernel.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param array $renderer_config
   *   The renderer configuration array.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory for retrieving required config objects.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter service.
   */
  public function __construct(HttpKernelInterface $http_kernel, ModuleHandlerInterface $module_handler, array $renderer_config, RequestStack $request_stack, ConfigFactoryInterface $config_factory, DateFormatterInterface $date_formatter) {
    $this->httpKernel = $http_kernel;
    $this->moduleHandler = $module_handler;
    $this->rendererConfig = $renderer_config;
    $this->requestStack = $request_stack;
    $this->configFactory = $config_factory;
    $this->dateFormatter = $date_formatter;
  }

  /**
   * {@inheritdoc}
   */
  public function handle(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE): Response {
    $message = $page_cache_info = $ipc = $dpc = $dpc_header = '';
    if (!isset($this->response)) {
      $this->response = $this->httpKernel->handle($request, $type, $catch);
    }
    $content = $this->response->getContent();

    // Check if it needs to show cache info on admin routes.
    $cache_review_config = $this->configFactory->get(CacheReviewConfigForm::CACHE_REVIEW_CONF);
    if (!$cache_review_config->get('check_admin_routes')) {
      if ($route_object = $request->attributes->get('_route_object')) {
        if ($route_object->getOption('_admin_route')) {
          return $this->response;
        }
      }
    }

    // Bypass JS and CSS requests from cache reviewing.
    if ($request->get('_route') == 'system.js_asset' || $request->get('_route') == 'system.css_asset') {
      return $this->response;
    }

    // Add Big Pipe module status.
    $big_pipe_status = $this->moduleHandler->moduleExists('big_pipe') ? 'enabled' : 'disabled';
    $big_pipe_message = $this->t('<br><small>Big Pipe status: @status</small><br>', ['@status' => $big_pipe_status]);

    // Get APC values.
    $apc = $this->rendererConfig['auto_placeholder_conditions'];

    // Get IPC and DPC cache values.
    if (!$this->moduleHandler->moduleExists('page_cache')) {
      $message .= $this->t("The module IPC (page_cache) <b>disabled</b><br>");
    }
    else {
      $ipc = $this->response->headers->get('X-Drupal-Cache') ?? '';
    }

    if (!$this->moduleHandler->moduleExists('dynamic_page_cache')) {
      $message .= $this->t("The module dynamic_page_cache disabled<br>");
    }
    else {
      $dpc_header = DynamicPageCacheSubscriber::HEADER;
      $dpc = $this->response->headers->get(DynamicPageCacheSubscriber::HEADER) ?? '';
    }
    if ($this->response->isSuccessful()) {
      $ipc_dpc_output = $this->t("IPC response status 'X-Drupal-Cache': <b>@ipc</b><br>DPC response status '@dpc_header': <b>@dpc</b>", [
        '@ipc' => $ipc,
        '@dpc_header' => $dpc_header,
        '@dpc' => $dpc,
      ]);

      $page_cache_info = $message . $ipc_dpc_output;
    }

    $apc_text = !empty($apc) ? json_encode($apc) : '{}';

    $timezone = date_default_timezone_get();
    $time = $this->dateFormatter->format(time(), 'custom', 'H:i:s', $timezone);

    $label = $this->t('Page Cache Status | @time', ['@time' => $time]);

    $apc_link_title = $this->t('If we have an item on the page with appropriate auto_placeholder_conditions, and it is not wrapped automatically or by developer into lazy-builder (so it will not have placeholder), in this case the cache options of such item (like max-age = 0) will bubble up in html to page level and will disable cache for whole request.');
    $auto_placeholder_link = sprintf('<a href="https://www.drupal.org/docs/drupal-apis/render-api/auto-placeholdering" target="_blank" title="%s">auto_placeholder_conditions</a>', $apc_link_title);

    $miss_hit_text = $this->t('MISS = cache can be created, refresh page. HIT = you see page data from cache');
    $info = sprintf("<ul><li>%s</li><li>%s</li><li>%s<br>%s: %s.</li></ul>",
      $this->t("Note: timezone for anonymous is set to 'GTM'"),
      $this->t('<b>C</b> - item cached, <b>L</b> - item wrapped by Lazy builder, <b>N</b> - no specific cache properties'),
      $this->t('If <span class=\"cache_caught\">C, N</span> are in bold, it means that items has cache options matched to the'), $auto_placeholder_link, $apc_text);
    $content = sprintf('<div class="cache-status-wrapper"><details><summary class="cache-status-label">%s </summary><div class="cache-designation">%s %s <br><small>(%s)</small>%s</div></details></div>%s', $label, $info, $page_cache_info, $miss_hit_text, $big_pipe_message, $content);

    $this->response->setContent($content);

    return $this->response;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc