Skip to content

Commit

Permalink
Better menu cach invalidation
Browse files Browse the repository at this point in the history
  • Loading branch information
pookmish committed Oct 6, 2024
1 parent f5f414b commit d45c922
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

namespace Drupal\stanford_decoupled\EventSubscriber;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\next\Event\EntityActionEvent;
use Drupal\next\Event\EntityEvents;
use Drupal\stanford_profile_helper\Event\MenuCacheEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
Expand All @@ -20,11 +22,18 @@ final class DecoupledEventSubscriber implements EventSubscriberInterface {
*/
public static function getSubscribedEvents(): array {
return [
MenuCacheEvent::CACHE_CLEARED => ['onMenuCacheClear'],
EntityEvents::ENTITY_ACTION => ['onNextEntityAction', 10],
];
}

public function __construct() {}
/**
* Event subscriber constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* Entity type manager service.
*/
public function __construct(protected EntityTypeManagerInterface $entityTypeManager) {}

/**
* Stop propagation of the event if on local environment and CLI execution.
Expand All @@ -40,4 +49,16 @@ public function onNextEntityAction(EntityActionEvent $event) {
}
}

/**
* Invalidate next menu caches after the drupal menus cache is cleared.
*
* @param \Drupal\stanford_profile_helper\Event\MenuCacheEvent $event
* Triggered event.
*/
public function onMenuCacheClear(MenuCacheEvent $event){
$fake_menu_link = $this->entityTypeManager->getStorage('menu_link_content')
->create(['id' => 'id']);
next_entity_insert($fake_menu_link);
}

}
52 changes: 0 additions & 52 deletions modules/stanford_decoupled/stanford_decoupled.module
Original file line number Diff line number Diff line change
Expand Up @@ -85,58 +85,6 @@ function stanford_decoupled_cron() {
\Drupal::state()->set('stanford-decoupled-last-ran', $now);
}

/**
* Implements hook_ENTITY_TYPE_insert().
*/
function stanford_decoupled_node_insert(NodeInterface $node) {
if (
$node->hasField('field_menulink') &&
$node->get('field_menulink')->count()
) {
_stanford_decoupled_invalidate_menus();
}
}

/**
* Implements hook_ENTITY_TYPE_update().
*/
function stanford_decoupled_node_update(NodeInterface $node) {
if (!$node->hasField('field_menulink')) {
return;
}

// Compare the original field values with the new field values. If there are
// any differences, invalidate the menu.
$original = $node->original?->get('field_menulink')?->get(0)?->getValue() ?: [];
$new = $node->get('field_menulink')?->get(0)?->getValue() ?: [];
unset($new['menu_link_weight'], $new['db_weights']);
ksort($original);
ksort($new);

$original = implode(':', $original);
$new = implode(':', $new);
if (md5($original) != md5($new)) {
_stanford_decoupled_invalidate_menus();
}
}

/**
* Implements hook_ENTITY_TYPE_delete().
*/
function stanford_decoupled_node_delete(NodeInterface $node) {
stanford_decoupled_node_insert($node);
}

/**
* Create a temporary menu link entity to trigger any invalidations.
*/
function _stanford_decoupled_invalidate_menus(){
$fake_menu_link = \Drupal::entityTypeManager()
->getStorage('menu_link_content')
->create(['id' => 'id']);
next_entity_insert($fake_menu_link);
}

/**
* Implements hook_entity_insert().
*/
Expand Down
2 changes: 1 addition & 1 deletion modules/stanford_decoupled/stanford_decoupled.services.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
stanford_decoupled.event_subscriber:
class: Drupal\stanford_decoupled\EventSubscriber\DecoupledEventSubscriber
arguments: []
arguments: ['@entity_type.manager']
tags:
- { name: event_subscriber }
13 changes: 13 additions & 0 deletions src/Event/MenuCacheEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Drupal\stanford_profile_helper\Event;

use Drupal\Component\EventDispatcher\Event;

class MenuCacheEvent extends Event {

const CACHE_CLEARED = 'cache_cleared';

public function __construct() {}

}
58 changes: 24 additions & 34 deletions src/EventSubscriber/EntityEventSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Drupal\layout_builder\LayoutBuilderEvents;
use Drupal\menu_link_content\MenuLinkContentInterface;
use Drupal\node\NodeInterface;
use Drupal\stanford_profile_helper\Event\MenuCacheEvent;
use Drupal\stanford_profile_helper\StanfordDefaultContentInterface;
use Drupal\user\RoleInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
Expand All @@ -36,27 +37,6 @@ class EntityEventSubscriber implements EventSubscriberInterface {
use MessengerTrait;
use StringTranslationTrait;

/**
* Default content importer service.
*
* @var \Drupal\stanford_profile_helper\StanfordDefaultContentInterface
*/
protected $defaultContent;

/**
* Core state service.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;

/**
* Core entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;

/**
* {@inheritDoc}
*/
Expand All @@ -73,18 +53,14 @@ public static function getSubscribedEvents(): array {
/**
* Event subscriber constructor.
*
* @param \Drupal\stanford_profile_helper\StanfordDefaultContentInterface $stanford_default_content
* @param \Drupal\stanford_profile_helper\StanfordDefaultContentInterface $defaultContent
* Default content importer service.
* @param \Drupal\Core\State\StateInterface $state
* Core state service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* Core entity type manager service.
*/
public function __construct(StanfordDefaultContentInterface $stanford_default_content, StateInterface $state, EntityTypeManagerInterface $entity_type_manager) {
$this->defaultContent = $stanford_default_content;
$this->state = $state;
$this->entityTypeManager = $entity_type_manager;
}
public function __construct(protected StanfordDefaultContentInterface $defaultContent, protected StateInterface $state, protected EntityTypeManagerInterface $entityTypeManager) {}

/**
* Call individual methods for each entity type for the events.
Expand Down Expand Up @@ -198,7 +174,7 @@ protected static function insertNode(NodeInterface $node): void {
$node->hasField('field_menulink') &&
!$node->get('field_menulink')->isEmpty()
) {
Cache::invalidateTags(['stanford_profile_helper:menu_links']);
self::clearMenuCacheTag();
}
}

Expand All @@ -219,6 +195,11 @@ protected static function updateNode(NodeInterface $node, NodeInterface $origina
!$original_node->get('field_menulink')->isEmpty()
)
) {
if ($original_node->isPublished() != $node->isPublished()) {
self::clearMenuCacheTag();
return;
}

$keys = ['title', 'description', 'weight', 'expanded', 'parent'];
$changes = $node->get('field_menulink')->getValue();
$original = $original_node->get('field_menulink')->getValue();
Expand All @@ -228,7 +209,7 @@ protected static function updateNode(NodeInterface $node, NodeInterface $origina
$original_value = $original[0][$key] ?? NULL;

if ($change_value != $original_value) {
Cache::invalidateTags(['stanford_profile_helper:menu_links']);
self::clearMenuCacheTag();
return;
}
}
Expand All @@ -252,7 +233,7 @@ protected static function deleteNode(NodeInterface $node): void {
->condition('route_param_key', 'node=' . $node->id())
->execute();
\Drupal::service('router.builder')->rebuildIfNeeded();
Cache::invalidateTags(['stanford_profile_helper:menu_links']);
self::clearMenuCacheTag();
}
}

Expand Down Expand Up @@ -345,7 +326,7 @@ protected static function preSaveFieldStorageConfig(FieldStorageConfigInterface
* Menu item being saved.
*/
protected function insertMenuLinkContent(MenuLinkContentInterface $entity) {
Cache::invalidateTags(['stanford_profile_helper:menu_links']);
self::clearMenuCacheTag();
}

/**
Expand All @@ -355,7 +336,7 @@ protected function insertMenuLinkContent(MenuLinkContentInterface $entity) {
* Menu item being deleted.
*/
protected function deleteMenuLinkContent(MenuLinkContentInterface $entity) {
Cache::invalidateTags(['stanford_profile_helper:menu_links']);
self::clearMenuCacheTag();
}

/**
Expand All @@ -374,7 +355,7 @@ protected function updateMenuLinkContent(MenuLinkContentInterface $entity, MenuL
$updated[] = $entity->get($field_name)->getValue();
}
if (md5(json_encode($original)) != md5(json_encode($updated))) {
Cache::invalidateTags(['stanford_profile_helper:menu_links']);
self::clearMenuCacheTag();
}
}

Expand Down Expand Up @@ -525,4 +506,13 @@ protected static function lookupInternalPath(string $uri): ?string {
return NULL;
}

/**
* Clear the menu cache tags and dispatch an event.
*/
public static function clearMenuCacheTag(){
Cache::invalidateTags(['stanford_profile_helper:menu_links']);
\Drupal::service('event_dispatcher')
->dispatch(new MenuCacheEvent(), MenuCacheEvent::CACHE_CLEARED);
}

}

0 comments on commit d45c922

Please sign in to comment.