diff --git a/modules/stanford_decoupled/src/EventSubscriber/DecoupledEventSubscriber.php b/modules/stanford_decoupled/src/EventSubscriber/DecoupledEventSubscriber.php index 604d8cf9..9430b765 100644 --- a/modules/stanford_decoupled/src/EventSubscriber/DecoupledEventSubscriber.php +++ b/modules/stanford_decoupled/src/EventSubscriber/DecoupledEventSubscriber.php @@ -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; /** @@ -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. @@ -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); + } + } diff --git a/modules/stanford_decoupled/stanford_decoupled.module b/modules/stanford_decoupled/stanford_decoupled.module index 27f59961..fc80d109 100644 --- a/modules/stanford_decoupled/stanford_decoupled.module +++ b/modules/stanford_decoupled/stanford_decoupled.module @@ -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(). */ diff --git a/modules/stanford_decoupled/stanford_decoupled.services.yml b/modules/stanford_decoupled/stanford_decoupled.services.yml index d55fd609..9af69ec1 100644 --- a/modules/stanford_decoupled/stanford_decoupled.services.yml +++ b/modules/stanford_decoupled/stanford_decoupled.services.yml @@ -1,6 +1,6 @@ services: stanford_decoupled.event_subscriber: class: Drupal\stanford_decoupled\EventSubscriber\DecoupledEventSubscriber - arguments: [] + arguments: ['@entity_type.manager'] tags: - { name: event_subscriber } diff --git a/src/Event/MenuCacheEvent.php b/src/Event/MenuCacheEvent.php new file mode 100644 index 00000000..b5466502 --- /dev/null +++ b/src/Event/MenuCacheEvent.php @@ -0,0 +1,13 @@ +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. @@ -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(); } } @@ -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(); @@ -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; } } @@ -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(); } } @@ -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(); } /** @@ -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(); } /** @@ -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(); } } @@ -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); + } + }