entity_hierarchy-8.x-2.24/modules/entity_hierarchy_microsite/src/EntityHooks.php
modules/entity_hierarchy_microsite/src/EntityHooks.php
<?php namespace Drupal\entity_hierarchy_microsite; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Menu\Form\MenuLinkDefaultForm; use Drupal\Core\Menu\MenuLinkManagerInterface; use Drupal\Core\Menu\MenuLinkTreeInterface; use Drupal\entity_hierarchy\Information\ParentCandidateInterface; use Drupal\entity_hierarchy_microsite\Entity\MicrositeInterface; use Drupal\entity_hierarchy_microsite\Entity\MicrositeMenuItemOverrideInterface; use Drupal\entity_hierarchy_microsite\Form\MicrositeMenuItemForm; use Drupal\node\NodeInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Defines a class for entity hooks for the module. * * @todo revisit a lot of this when * https://www.drupal.org/project/drupal/issues/3001284 is in as that would * allow us to specify cache tags which would trigger refreshing the * derivatives automatically. * * @internal */ class EntityHooks implements ContainerInjectionInterface { /** * Menu link tree. * * @var \Drupal\Core\Menu\MenuLinkTreeInterface */ protected $menuLinkTree; /** * Menu link manager. * * @var \Drupal\Core\Menu\MenuLinkManagerInterface */ protected $menuLinkManager; /** * Parent candidate. * * @var \Drupal\entity_hierarchy\Information\ParentCandidateInterface */ protected $parentCandidate; /** * Microsite lookup. * * @var \Drupal\entity_hierarchy_microsite\ChildOfMicrositeLookupInterface */ protected $childOfMicrositeLookup; /** * Discovery. * * @var \Drupal\entity_hierarchy_microsite\MicrositeMenuLinkDiscoveryInterface */ protected $menuLinkDiscovery; /** * Menu rebuild service. * * @var \Drupal\entity_hierarchy_microsite\MenuRebuildProcessor */ private MenuRebuildProcessor $menuRebuildProcessor; /** * Constructs a new EntityHooks. * * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager * Menu link manager. * @param \Drupal\entity_hierarchy\Information\ParentCandidateInterface $parentCandidate * Parent candidate. * @param \Drupal\entity_hierarchy_microsite\ChildOfMicrositeLookupInterface $childOfMicrositeLookup * Microsite lookup. * @param \Drupal\entity_hierarchy_microsite\MicrositeMenuLinkDiscoveryInterface $menuLinkDiscovery * Discovery. * @param \Drupal\Core\Menu\MenuLinkTreeInterface $menuLinkTree * Menu link tree. * @param \Drupal\entity_hierarchy_microsite\MenuRebuildProcessor $menuRebuildProcessor * Menu rebuild processor. */ final public function __construct( MenuLinkManagerInterface $menuLinkManager, ParentCandidateInterface $parentCandidate, ChildOfMicrositeLookupInterface $childOfMicrositeLookup, MicrositeMenuLinkDiscoveryInterface $menuLinkDiscovery, MenuLinkTreeInterface $menuLinkTree, MenuRebuildProcessor $menuRebuildProcessor, ) { $this->menuLinkTree = $menuLinkTree; $this->menuLinkManager = $menuLinkManager; $this->parentCandidate = $parentCandidate; $this->childOfMicrositeLookup = $childOfMicrositeLookup; $this->menuLinkDiscovery = $menuLinkDiscovery; $this->menuRebuildProcessor = $menuRebuildProcessor; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('plugin.manager.menu.link'), $container->get('entity_hierarchy.information.parent_candidate'), $container->get('entity_hierarchy_microsite.microsite_lookup'), $container->get('entity_hierarchy_microsite.menu_link_discovery'), $container->get('menu.link_tree'), $container->get('entity_hierarchy_microsite.menu_rebuild_processor') ); } /** * React to node insert. * * @param \Drupal\node\NodeInterface $node * Node. */ public function onNodeInsert(NodeInterface $node) { foreach ($this->parentCandidate->getCandidateFields($node) as $field) { foreach ($this->getMicrositesForNodeAndField($node, $field) as $microsite) { $this->updateMenuForMicrosite($microsite); } } } /** * Gets the possible microsites for a particular field and node. * * @param \Drupal\node\NodeInterface $node * Node. * @param string $field * Field name. * * @return \Drupal\entity_hierarchy_microsite\Entity\MicrositeInterface[] * Microsites the node belongs to with the given field. */ protected function getMicrositesForNodeAndField(NodeInterface $node, string $field) : array { if (!$node->hasField($field)) { return []; } if ($node->get($field)->isEmpty()) { return []; } return $this->childOfMicrositeLookup->findMicrositesForNodeAndField($node, $field); } /** * React to node update. * * @param \Drupal\node\NodeInterface $node * Node update. */ public function onNodeUpdate(NodeInterface $node) { $original = $node->original; foreach ($this->parentCandidate->getCandidateFields($node) as $field) { if ($node->hasField($field) && ( // Either the new version or the old version has no parent. $node->get($field)->isEmpty() !== $original->get($field)->isEmpty() || // Or the parent changed. (int) $node->{$field}->target_id !== (int) $original->{$field}->target_id || // Or the weight changed. (int) $node->{$field}->weight !== (int) $original->{$field}->weight ) ) { if ($microsites = $this->childOfMicrositeLookup->findMicrositesForNodeAndField($node, $field)) { foreach ($microsites as $microsite) { $this->updateMenuForMicrosite($microsite); } continue; } if ($microsites = $this->childOfMicrositeLookup->findMicrositesForNodeAndField($original, $field)) { // This item is no longer in the microsite, so we need to trigger // its removal. $plugin_id = 'entity_hierarchy_microsite:' . $original->uuid(); if ($this->menuLinkManager->hasDefinition($plugin_id)) { $this->menuLinkManager->removeDefinition($plugin_id); } } } } } /** * React to node delete. * * @param \Drupal\node\NodeInterface $node * Node update. */ public function onNodeDelete(NodeInterface $node) { foreach ($this->parentCandidate->getCandidateFields($node) as $field) { if ($this->getMicrositesForNodeAndField($node, $field)) { $plugin_id = 'entity_hierarchy_microsite:' . $node->uuid(); if ($this->menuLinkManager->hasDefinition($plugin_id)) { $this->menuLinkManager->removeDefinition($plugin_id); continue; } } } } /** * React to microsite being saved. * * @param \Drupal\entity_hierarchy_microsite\Entity\MicrositeInterface $microsite * Microsite. * @param bool $isUpdate * TRUE if is an update. */ public function onMicrositePostSave(MicrositeInterface $microsite, $isUpdate) { if ($microsite->shouldGenerateMenu() || ($microsite->original instanceof MicrositeInterface && $microsite->original->shouldGenerateMenu())) { $this->updateMenuForMicrosite($microsite); } } /** * Updates menu for the microsite. * * @param \Drupal\entity_hierarchy_microsite\Entity\MicrositeInterface $microsite * Microsite. */ protected function updateMenuForMicrosite(MicrositeInterface $microsite) { $this->menuRebuildProcessor->markRebuildNeeded(); } /** * Post save handler for overrides. * * @param \Drupal\entity_hierarchy_microsite\Entity\MicrositeMenuItemOverrideInterface $item * Item saved. * @param bool $update * TRUE if is an update. */ public function onMenuOverridePostSave(MicrositeMenuItemOverrideInterface $item, $update = FALSE) { if ($item->isSyncing()) { return; } $plugin_id = 'entity_hierarchy_microsite:' . $item->getTarget(); if ($this->menuLinkManager->hasDefinition($plugin_id) && ($original = $this->menuLinkManager->getDefinition($plugin_id))) { $definition = [ 'title' => $item->label(), 'weight' => $item->getWeight(), 'form_class' => MicrositeMenuItemForm::class, 'enabled' => $item->isEnabled(), 'expanded' => $item->isExpanded(), 'parent' => $item->getParent(), ] + $original; if (!$update) { $definition['metadata'] = [ 'original' => array_intersect_key($original, [ 'title' => TRUE, 'weight' => TRUE, 'enabled' => TRUE, 'expanded' => TRUE, 'parent' => TRUE, ]), ] + $original['metadata']; } $this->menuLinkManager->updateDefinition($plugin_id, $definition); } } /** * Post delete handler for microsite items. * * @param \Drupal\entity_hierarchy_microsite\Entity\MicrositeMenuItemOverrideInterface[] $items * Deleted items. */ public function onMenuOverridePostDelete(array $items) { foreach ($items as $item) { $plugin_id = 'entity_hierarchy_microsite:' . $item->getTarget(); if ($this->menuLinkManager->hasDefinition($plugin_id) && ($definition = $this->menuLinkManager->getDefinition($plugin_id)) && isset($definition['metadata']['original'])) { $definition = $definition['metadata']['original'] + $definition; $definition['form_class'] = MenuLinkDefaultForm::class; unset($definition['metadata']['original']); $this->menuLinkManager->updateDefinition($plugin_id, $definition, FALSE); continue; } } } }