Je travaillais avec graphql, mais le fil d'Ariane ne change pas lorsque nous mettons à jour les nœuds parents, il est donc toujours en cache, même si j'ajoutais le cachetag au fil d'Ariane via hook_system_breadcrumb_alter.

La seule solution que nous avons pu trouver est d'invalider le cache pour tous les nœuds enfants lors de la mise à jour des nœuds, donc :

Comment désactiver le cache de tous les nœuds enfants ?

La première chose à réaliser est de collecter tous les nœuds enfants du nœud actuel comme suit :

$database = \Drupal::database();
  // Get the current node path alias.
  $alias = \Drupal::service('path_alias.manager')
    ->getAliasByPath('/node/' . $entity->id());
  // Get all node child of the current node.
  $child_nodes_alias = $database->select('path_alias', 'pa')->fields('pa', [
    'path',
    'alias',
  ])->condition('path', '/node/%', 'LIKE')
    ->condition('alias', $alias . '%', 'LIKE')
    ->execute()
    ->fetchAll();

Et après cela, bouclons à travers celle-ci et désactivons le cache pour chaque nœud comme :

// Invalidate cache for each node child of current node.
  foreach ($child_nodes_alias as $alias_data) {
    $nid = explode('/', $alias_data->path)[2] ?? NULL;
    if ($nid && $nid != $entity->id()) {
      $tags = ['node:' . $nid];
      Cache::invalidateTags($tags);
      \Drupal::entityTypeManager()->getStorage('node')->resetCache([$nid]);
    }
  }

Donc, les fonctions d'aide finales sont :

/**
 * Reset all child nodes of passed node.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   Current entity.
 */
function reset_cache_all_node_child(EntityInterface $entity) {
  $database = \Drupal::database();
  // Get the current node path alias.
  $alias = \Drupal::service('path_alias.manager')
    ->getAliasByPath('/node/' . $entity->id());
  // Get all node child of the current node.
  $child_nodes_alias = $database->select('path_alias', 'pa')->fields('pa', [
    'path',
    'alias',
  ])->condition('path', '/node/%', 'LIKE')
    ->condition('alias', $alias . '%', 'LIKE')
    ->execute()
    ->fetchAll();
  // Invalidate cache for each node child of current node.
  foreach ($child_nodes_alias as $alias_data) {
    $nid = explode('/', $alias_data->path)[2] ?? NULL;
    if ($nid && $nid != $entity->id()) {
      $tags = ['node:' . $nid];
      Cache::invalidateTags($tags);
      \Drupal::entityTypeManager()->getStorage('node')->resetCache([$nid]);
    }
  }
}

Et nous appelons cette fonction dans hook_ENTITY_TYPE_update comme ceci :

use Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_ENTITY_TYPE_update().
 */
function MODULENAME_node_update(EntityInterface $entity) {
  reset_cache_all_node_child($entity);
}

Ainsi, à chaque mise à jour d'un nœud, le cache de tous les nœuds enfants sera désactivé !

Vous avez un projet ? Contactez-nous pour en parler davantage : Contact

Auteur : Azz-eddine BERRAMOU

Share this article: