Verified Commit 9d31bbf3 authored by Lee Rowlands's avatar Lee Rowlands Committed by Lee Rowlands
Browse files

Issue #3284026 by larowlan, nterbogt: Menu Link Discovery takes forever on huge websites

parent d7f81ba4
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Contains entity hierarchy microsite updates.
 */

declare(strict_types=1);

use Drupal\Core\Field\BaseFieldDefinition;

/**
 * Flag any existing menu links as discovered.
 */
function entity_hierarchy_microsite_update_9401(): void {
  // Mark all menu items from entity-hierarchy microsite as 'discovered'.
  \Drupal::database()->update('menu_tree')
    ->fields(['discovered' => 1])
    ->condition('menu_name', 'entity-hierarchy-microsite')
    ->condition('provider', 'entity_hierarchy_microsite')
    ->execute();
}

/**
 * Add the generate_menu field.
 */
function entity_hierarchy_microsite_update_9402(): void {
  $menu_field = BaseFieldDefinition::create('boolean')
    ->setLabel('Generate menu')
    ->setDisplayOptions('view', [
      'label' => 'hidden',
      'type' => 'boolean',
      'weight' => -5,
    ])
    ->setDisplayOptions('form', [
      'type' => 'checkbox',
      'weight' => -5,
    ])
    ->setDisplayConfigurable('view', TRUE)
    ->setDisplayConfigurable('form', TRUE);
  \Drupal::entityDefinitionUpdateManager()->installFieldStorageDefinition('generate_menu', 'entity_hierarchy_microsite', 'entity_hierarchy_microsite', $menu_field);

  // Set value to replicate existing, but not setInitialValue because we want
  // the default off.
  /** @var \Drupal\entity_hierarchy_microsite\Entity\Microsite[] $microsites */
  $microsites = \Drupal::entityTypeManager()->getStorage('entity_hierarchy_microsite')->loadMultiple();
  foreach ($microsites as $microsite) {
    $microsite->set('generate_menu', TRUE);
    $microsite->save();
  }
}
+21 −0
Original line number Diff line number Diff line
@@ -91,6 +91,20 @@ class Microsite extends ContentEntityBase implements MicrositeInterface {
      ->setDisplayConfigurable('view', TRUE)
      ->setDisplayConfigurable('form', TRUE);

    $fields['generate_menu'] = BaseFieldDefinition::create('boolean')
      ->setLabel('Generate menu')
      ->setDisplayOptions('view', [
        'label' => 'hidden',
        'type' => 'boolean',
        'weight' => -5,
      ])
      ->setDisplayOptions('form', [
        'type' => 'checkbox',
        'weight' => -5,
      ])
      ->setDisplayConfigurable('view', TRUE)
      ->setDisplayConfigurable('form', TRUE);

    $fields['logo'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel('Logo')
      ->setSetting('target_type', 'media')
@@ -123,6 +137,13 @@ class Microsite extends ContentEntityBase implements MicrositeInterface {
    return $this->get('logo')->entity;
  }

  /**
   * {@inheritdoc}
   */
  public function shouldGenerateMenu() : bool {
    return (bool) $this->get('generate_menu')->value;
  }

  /**
   * {@inheritdoc}
   */
+8 −0
Original line number Diff line number Diff line
@@ -25,4 +25,12 @@ interface MicrositeInterface extends ContentEntityInterface {
   */
  public function getLogo();

  /**
   * Whether the microsite should generate a menu.
   *
   * @return bool
   *   True if a menu should be built, false otherwise.
   */
  public function shouldGenerateMenu();

}
+1 −15
Original line number Diff line number Diff line
@@ -196,21 +196,7 @@ class EntityHooks implements ContainerInjectionInterface {
   *   Microsite.
   */
  protected function updateMenuForMicrosite(MicrositeInterface $microsite) {
    $menu_max_depth = $this->menuLinkTree->maxDepth();
    foreach ($this->menuLinkDiscovery->getMenuLinkDefinitions($microsite) as $uuid => $definition) {
      $plugin_id = 'entity_hierarchy_microsite:' . $uuid;
      if ($this->menuLinkManager->hasDefinition($plugin_id)) {
        if ($definition['metadata']['entity_hierarchy_depth'] < $menu_max_depth) {
          $this->menuLinkManager->updateDefinition($plugin_id, $definition, FALSE);
          continue;
        }
        $this->menuLinkManager->removeDefinition($plugin_id);
        continue;
      }
      if ($definition['metadata']['entity_hierarchy_depth'] < $menu_max_depth) {
        $this->menuLinkManager->addDefinition($plugin_id, $definition);
      }
    }
    $this->menuLinkManager->rebuild();
  }

  /**
+10 −5
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ namespace Drupal\entity_hierarchy_microsite;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Menu\MenuTreeStorage;
use Drupal\Core\Menu\Form\MenuLinkDefaultForm;
use Drupal\entity_hierarchy\Information\ParentCandidateInterface;
use Drupal\entity_hierarchy\Storage\EntityTreeNodeMapperInterface;
@@ -104,7 +105,8 @@ class MicrositeMenuLinkDiscovery implements MicrositeMenuLinkDiscoveryInterface
    /** @var \Drupal\entity_hierarchy_microsite\Entity\MicrositeInterface $microsite */
    foreach ($microsites as $microsite) {
      $home = $microsite->getHome();
      if (!$home) {
      $generate_menu = $microsite->shouldGenerateMenu();
      if (!$home || !$generate_menu) {
        continue;
      }
      $key = $this->keyFactory->fromEntity($home);
@@ -134,11 +136,11 @@ class MicrositeMenuLinkDiscovery implements MicrositeMenuLinkDiscoveryInterface
          'enabled' => 1,
          'expanded' => 1,
          'provider' => 'entity_hierarchy_microsite',
          'discovered' => 0,
          'discovered' => 1,
        ];
        /** @var \PNX\NestedSet\Node $treeNode */
        foreach ($nodes as $treeNode) {
          if (!$nodes->contains($treeNode)) {
          if (!$nodes->contains($treeNode) || $treeNode->getDepth() >= MenuTreeStorage::MAX_DEPTH) {
            continue;
          }
          /** @var \Drupal\node\NodeInterface $item */
@@ -157,12 +159,15 @@ class MicrositeMenuLinkDiscovery implements MicrositeMenuLinkDiscoveryInterface
            'description' => '',
            'weight' => $treeNode->getLeft(),
            'id' => 'entity_hierarchy_microsite:' . $itemUuid,
            'metadata' => ['entity_id' => $item->id(), 'entity_hierarchy_depth' => $treeNode->getDepth()],
            'metadata' => [
              'entity_id' => $item->id(),
              'entity_hierarchy_depth' => $treeNode->getDepth()
            ],
            'form_class' => MenuLinkDefaultForm::class,
            'enabled' => 1,
            'expanded' => 1,
            'provider' => 'entity_hierarchy_microsite',
            'discovered' => 0,
            'discovered' => 1,
            'parent' => 'entity_hierarchy_microsite:' . $home->uuid(),
          ];
          $parent = $tree->findParent($treeNode->getNodeKey());
Loading