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