web-dev-qa-db-fra.com

Existe-t-il un moyen de reconstruire partiellement le routeur ou d'invalider un cache d'itinéraire?

J'utilise le module Groupes ( http://dgo.to/group ) pour configurer des groupes sur un projet SaaS sur lequel je travaille. Je ' ve a configuré un champ de domaine sur les groupes, permettant aux groupes d'avoir un domaine personnalisé. En tant que tel, les groupes peuvent avoir des pages de garde personnalisées, qui sont affichées à l'itinéraire du site. La page de garde est définie comme un champ sur l'entité Groupe. Par exemple, le groupe 1 peut définir son chemin de première page comme /page/1 et le groupe 2 peut le définir comme /page/2.

Pour afficher cette première page, j'utilise le traitement des URL entrantes, montrant les différents chemins sur les différents domaines. Pour obtenir les différents chemins à mettre en cache indépendamment, j'ai remplacé Drupal\Core\Routing\RouteProviderRouteProvider::getRouteCollectionCacheId():

  /**
   * {@inheritdoc}
   */
  protected function getRouteCollectionCacheId(Request $request) {
    $cache_id = parent::getRouteCollectionCacheId($request);

    // Get the current domain.
    $domain = $this->currentPath->getRequestStack()->getCurrentRequest()->getHost();

    $cache_id .= ':' . $domain;

    return $cache_id;
  }

J'ai tout cela fonctionne, mais j'ai rencontré un problème en ce que lorsque le chemin d'accès à la page d'accueil d'un groupe est mis à jour, le contenu de la page ne se met pas à jour jusqu'à ce que le routeur soit reconstruit.

J'ai trouvé une solution, reconstruisant le routeur dans hook_entity_update() en utilisant \Drupal::service('router.builder')->rebuild(). Cela fonctionne, mais il semble très lourd.

J'ai essayé de trouver un moyen d'invalider les balises de cache pour l'itinéraire à l'aide de l'invalidateur de balises de cache, mais je n'ai pas pu déterminer quelles balises de cache passer.

Mes questions sont donc:

  1. Existe-t-il un moyen de reconstruire partiellement le routeur, plutôt que de reconstruire le tout? Ou...

  2. Existe-t-il un moyen d'invalider le cache d'un itinéraire?

5
Jaypan

Au lieu de \Drupal::service('router.builder')->rebuild(), vous pouvez invalider les correspondances de route:

Cache::invalidateTags(['route_match']);

Vous n'avez pas besoin de reconstruire la table du routeur, car les routes statiques ne changent pas. Ce que vous devez effacer, ce sont les correspondances de route, qui sont calculées sur le chemin traité, puis stockées pour le chemin non traité. Et c'est la relation qui change dans votre cas.

Le générateur de routeur invalide les correspondances de route car après une reconstruction de route, il peut y avoir des routes manquantes qui sont toujours dans les collections de correspondances de route.

Pour être plus sélectif, vous pouvez ajouter une deuxième balise de cache pour la page d'accueil dans RouteProviderRouteProvider::getRouteCollectionForRequest, puis invalide uniquement cette balise.

Bien sûr, vous devez également invalider les entrées de la page d'accueil stockées dans les caches de page, mais la page d'accueil a probablement déjà une balise de cache spécifique que vous pouvez cibler.

5
4k4