Рейтинг:1

Как аннулировать кеш Breadcrumbs для дочерних узлов на graphQl

флаг gb

у меня например Узел А с псевдонимом узел-а и Узел Б с псевдонимом узел-а/узел-б так что на моем Узел Б у меня есть эта хлебная крошка Главная > Узел А > Узел Б

Результат GraphQl:

"хлебные крошки": [
                {
                    "текст": "Дом",
                    "адрес": {
                        "дорожка": "/",
                        "маршрутизирован": правда
                    }
                },
                {
                    "текст": "Узел А",
                    "адрес": {
                        "путь": "http://example.com/node-a",
                        "маршрутизирован": правда
                    }
                },
                {
                    "текст": "Узел B",
                    "адрес": {
                        "дорожка": "",
                        "маршрутизирован": правда
                    }
                }
            ]

Но когда я меняю Узел А title я всегда получаю один и тот же результат (хлебные крошки не изменились), но когда я повторно сохраняю узел А или очистить кэш изменения результата graphQl.

Вот что я пробовал:

  1. Очистите кэш graphQl (результаты и определения) при обновлении узла:

     /**
     * Реализует hook_ENTITY_TYPE_update().
     */
    функция MYMODULE_node_update (EntityInterface $ сущность) {
      // Очистить кэш graphql.
      /** @var \Drupal\Core\Cache\CacheBackendInterface $graphql_results_cache */
      $graphql_results_cache = \Drupal::service('cache.graphql.results');
      $graphql_results_cache->invalidateAll();
      /** @var \Drupal\Core\Cache\CacheBackendInterface $graphql_definitions_cache */
      $graphql_definitions_cache = \Drupal::service('cache.graphql.definitions');
      $graphql_definitions_cache->invalidateAll();
    }

это не работает!

  1. Очистите кеш всех дочерних узлов при обновлении узла следующим образом:

    /**
     * Реализует hook_ENTITY_TYPE_update().
     */
    функция MYMODULE_node_update (EntityInterface $ сущность) {
      $database = \Drupal::database();
      // Получить текущий псевдоним пути к узлу.
      $alias = \Drupal::service('path_alias.manager')
        ->getAliasByPath('/node/' . $entity->id());
      // Получить все дочерние узлы текущего узла.
      $child_nodes_alias = $database->select('path_alias', 'pa')->fields('pa', [
        'дорожка',
        'псевдоним',
      ])->условие('путь', '/узел/%', 'НРАВИТСЯ')
        ->условие('псевдоним', $псевдоним . '%', 'НРАВИТСЯ')
        ->выполнить()
        ->выбрать все();
      // Недействительный кеш для каждого дочернего узла текущего узла.
      foreach ($child_nodes_alias как $alias_data) {
        $nid = взорвать('/', $alias_data->path)[2] ?? НОЛЬ;
        если ($nid && $nid != $entity->id()) {
          $теги = ['узел:' . $нид];
          Кэш::invalidateTags($tags);
          \Drupal::entityTypeManager()->getStorage('node')->resetCache([$nid]);
        }
      }
    }

это тоже не работает

  1. Я объединил два предыдущих способа, это тоже не работает.

Когда я очищаю все кеши при обновлении узла, это работает, но это не лучший способ повлиять на кеш сайта.


/**
 * Реализует hook_ENTITY_TYPE_update().
 */
функция MYMODULE_node_update (EntityInterface $ сущность) {
  drupal_flush_all_caches();
}

Каков наилучший способ очистить кэш хлебных крошек или дочерние узлы без очистки всего кеша сайта?

Редактировать: Спасибо @4K4 за ваш комментарий, я пытался добавить CacheTags в хлебные крошки, но у меня тоже не получилось!


/**
 * Реализует hook_system_breadcrumb_alter().
 */
function MYMODULE_system_breadcrumb_alter(Breadcrumb &$breadcrumb, RouteMatchInterface $route_match, массив $context) {
  // Добавляем заголовок текущей страницы в навигационную цепочку для маршрутов без прав администратора.
  if ($breadcrumb && !\Drupal::service('router.admin_context')->isAdminRoute()) {
    $links = $breadcrumb->getLinks();
    foreach ($ ссылки как $ ссылка) {
      $parameters = $link->getUrl()->getRouteParameters();
      если ($ параметры) {
        // Убедитесь, что навигационная цепочка обновляется при изменении заголовка узла.
        $breadcrumb->addCacheTags(['узел:' . $parameters['узел']]);
        $breadcrumb->addCacheContexts(['url']);
      }
    }
  }
}

Примечание: Легкая хлебная крошка модуль установлен.

Kevin avatar
флаг in
Они действительно связаны в меню? Как они связаны иначе? Псевдонимы не подразумевают зависимости кэша.
4uk4 avatar
флаг cn
Обычно вы не решаете проблемы кэширования в hook_node_update(). Плагин GraphQL, создающий навигационную цепочку, должен добавить теги кеша, а затем они автоматически становятся недействительными при сохранении узла.
berramou avatar
флаг gb
я пытался добавить кештег узла в панировочные сухари, как я упоминал в своем редактировании, и это не сработало, может быть, мне следует добавить еще один кештег, что я упускаю?
berramou avatar
флаг gb
@Kevin нет, они не связаны в меню, панировочные сухари создаются автоматически с помощью модуля Easy Breadcrumb.
4uk4 avatar
флаг cn
Хорошо, при условии, что в панировочных сухарях есть все необходимые теги кеша, все еще неясно, какой код строит результат GraphQL. Не удалось найти такой плагин в основном модуле. У вас есть дополнительный модуль для этого?
berramou avatar
флаг gb
Нет дополнительного модуля для хлебных крошек, я использую официальный модуль qraphQl версии 3.X. Я нашел поле Breadcrumb, определенное здесь **graphql/modules/graphql_core/src/Plugin/GraphQL/Fields/Breadcrumbs/Breadcrumbs.php**
4uk4 avatar
флаг cn
Это предыдущая версия.[Последнее обновление] (https://git.drupalcode.org/project/graphql/-/commit/58a9b7464bc6cf4aa78632a0efee83f911c8522e) для этого объекта кода решает именно эту проблему, но я не знаю, было ли это обновление успешным. Вы можете сообщить о проблеме, если сможете воспроизвести отсутствующие теги кеша и эта версия все еще поддерживается.
berramou avatar
флаг gb
Да, у меня есть это обновление, это последняя версия 3.X!
4uk4 avatar
флаг cn
Вы можете подтвердить, что обновление прошло успешно? Например, проверив, что теги кеша, которые вы добавили в «хлебные крошки», попадают в кешированный ответ.
Рейтинг:0
флаг cn

Я не знаю реализацию кеширования плагинов полей GraphQL 3.x, но насколько я могу судить об этом коде (даже после последнее обновление с 2018 года) не собирает метаданные хлебных крошек, потому что получает только ссылки:

защищенная функция resolveValues($value, массив $args, ResolveContext $context, ResolveInfo $info) {
    если ($ значение экземпляр URL) {
      $resolve = $this->subRequestBuffer->add($value, function () {
        $links = $this->breadcrumbManager->build($this->routeMatch)->getLinks();
        вернуть $ссылки;
      });

      функция возврата ($значение, массив $args, ResolveContext $context, ResolveInfo $info) использование ($resolve) {
        /** @var \Drupal\graphql\GraphQL\Cache\CacheableValue $response */
        $ответ = $разрешить();
        $links = $response->getValue();

        foreach ($ ссылки как $ ссылка) {
          yield new CacheableValue($link, [$response]);
        }
      };
    }
  }

Разве он не должен получить объект хлебных крошек для добавления кэшируемых метаданных?

защищенная функция resolveValues($value, массив $args, ResolveContext $context, ResolveInfo $info) {
    если ($ значение экземпляр URL) {
      $resolve = $this->subRequestBuffer->add($value, function () {
        $breadcrumb = $this->breadcrumbManager->build($this->routeMatch);
        вернуть $breadcrumb;
      });

      функция возврата ($значение, массив $args, ResolveContext $context, ResolveInfo $info) использование ($resolve) {
        /** @var \Drupal\graphql\GraphQL\Cache\CacheableValue $response */
        $ответ = $разрешить();
        $breadcrumb = $response->getValue();
        $links = $breadcrumb->getLinks();

        foreach ($ ссылки как $ ссылка) {
          yield new CacheableValue($link, [$response, $breadcrumb]);
        }
      };
    }
  }

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.