KernelEvents :: ЗАПИТАННЯ не запускається на кешованих сторінках


13

Я намагаюся реалізувати абонент події KernelEvents :: ЗАПИТАННЯ, щоб виконати певну дію при завантаженні сторінки.

Мені потрібна ця подія для запуску незалежно від того, чи існує запитувана сторінка в кеші Drupal - схоже, що KernelEvents :: ЗАПИТАННЯ не спрацьовує, коли Drupal подає щось із кешу.

Чи є подія, яку я можу використати для досягнення цього, або я повинен реалізувати свої вимоги як якусь форму проміжного програмного забезпечення?


1
ЗАПИТАННЯ подія ВИПУСКОВАНО, інакше відповіді не було б. IMHO ваш ES має малу вагу, і служба http_middleware.page_cache (або динамічний кеш сторінки) надалі зупиняє розповсюдження події, отже, ваш ES не буде спрацьовувати.

Вага / пріоритет ЕС встановлено на 20

Як писав 4k4, page_cache для анонімних користувачів є проміжним програмним забезпеченням і відбувається задовго до події ЗАПИТАННЯ. Ви можете написати власне проміжне програмне забезпечення, яке з’явиться раніше, але, можливо, ви захочете переглянути свого додатка. Що саме має статися так рано? Майте на увазі, що анонімне кешування сторінок може траплятися навіть в іншому іншому зовнішньому програмному забезпеченні або навіть у самих браузерах. Подивіться, як основний модуль статистики відстежує відвідування сторінки: з javascript, який пінг-сервер, коли користувач виконує його.
Бердір

@Berdir Це надати http-аутентифікацію для сайту, подібно до модуля Shield - тому я вважаю, що це дійсно є прикладом того, що потрібно обробляти якомога раніше у запиті. (Я знаю, що патч модулів D8 Shield реалізований як проміжне програмне забезпечення - я припускаю через це обмеження).

Відповіді:


14

Динамічний кеш передплачує подію з пріоритетом 27. Якщо ви хочете, щоб ваш код запускався до цього, ви повинні використовувати пріоритет> 27:

  public static function getSubscribedEvents() {
    $events = [];

    // Run after AuthenticationSubscriber (necessary for the 'user' cache
    // context; priority 300) and MaintenanceModeSubscriber (Dynamic Page Cache
    // should not be polluted by maintenance mode-specific behavior; priority
    // 30), but before ContentControllerSubscriber (updates _controller, but
    // that is a no-op when Dynamic Page Cache runs; priority 25).
    $events[KernelEvents::REQUEST][] = ['onRequest', 27];

Що запускає DynamicPageCacheSubscriber :: onRequest ..


Пріоритет встановлено на 20

Я думаю, що у вас є проблема з подією з динамічного кешу, я змінив свою відповідь.
4k4

дякую @ 4k4, але навіть при встановленому пріоритеті 30 він все одно поводиться так само (я перевстановив модуль і очистив усі кеші після внесення змін). Будь-які інші ідеї?

Є два кеша. Тепер, коли ви маєте пріоритет над динамічним кешем, ще є кеш сторінок. Кеш сторінок виконується перед головним ядром. Ви можете видалити цей модуль і перевірити, чи продуктивність без нього нормальна.
4к4

Я можу підтвердити, що це працювало на мене. У мене було переспрямовування, яке відбудеться лише один раз - до того, як сторінка буде кешована. Коли я додав пріоритет, ['checkForRediret', 30];він працював так, як очікувалося.
Cyclonecode

6

Drupal 8 має дворівневий кеш, кеш сторінки та динамічний кеш сторінки.

Так, ви можете перехопити динамічний кеш сторінки як те, що згадується @ 4k4. Проблема, яка виникає, швидше перехопить кеш сторінки. Ключ тут .

Для цього є кілька рішень:

  1. Додайте новий клас, який реалізує 'HttpKernelInterface' та зареєструйте 'http_middleware' з більш високим пріоритетом, ніж 200 (буде робити 280). Дивіться клас "PageCache" та його реалізації для посилань.

  2. Створіть новий клас, щоб змінити існуючий "PageCache", перейшовши на "ServiceProviderBase". Ознайомтесь з посиланнями тут . Потім створіть новий клас, щоб розширити 'PageCache'.

Ось посилання на код:

Це StaticCacheServiceProvider.php:

/**
 * Modifies the language manager service.
 */
class StaticCacheServiceProvider extends ServiceProviderBase
{
  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container)
  {
    // Overrides language_manager class to test domain language negotiation.
    $definition = $container->getDefinition('http_middleware.page_cache');
    $definition->setClass('Drupal\your_module\StackMiddleware\StaticCache');
  }
}

Це StaticCache.php:

/**
 * Executes the page caching before the main kernel takes over the request.
 */
class StaticCache extends PageCache
{
  /**
   * {@inheritdoc}
   */
  public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
  {
    // do special logic here.

    $response = parent::handle($request, $type, $catch);

    return $response;
  }
}

Надія допомагає.


Це було дуже корисно, я вирішив проблему,
втіливши
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.