From 8fad83c42de4865c49c489e22ba1a423487829ac Mon Sep 17 00:00:00 2001
From: Roderik Muit <35514-roderik@users.noreply.drupalcode.org>
Date: Fri, 7 Feb 2025 04:39:20 +0000
Subject: [PATCH] Issue #3504944 by roderik: Fix error when enabling
 layout_builder

---
 custom_elements.module                        | 35 ++++++++++++++++---
 .../src/Kernel/CustomElementGeneratorTest.php |  2 ++
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/custom_elements.module b/custom_elements.module
index 3350772..b9229d3 100644
--- a/custom_elements.module
+++ b/custom_elements.module
@@ -11,9 +11,11 @@ use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\Render\Markup;
 use Drupal\Core\Template\Attribute;
+use Drupal\Core\Update\UpdateHookRegistry;
 use Drupal\custom_elements\CustomElement;
 use Drupal\custom_elements\CustomElementsEntityViewDisplay;
 use Drupal\custom_elements\CustomElementsLayoutBuilderEntityViewDisplay;
+use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay;
 
 /**
  * Implements hook_theme().
@@ -150,11 +152,24 @@ function custom_elements_prepare_slots_as_vue_3(CustomElement $custom_element) {
  * @see custom_elements_module_implements_alter()
  */
 function custom_elements_entity_type_alter(array &$entity_types) {
-  // Use the right class depending on layout builder being used.
-  $class = \Drupal::moduleHandler()->moduleExists('layout_builder') ? CustomElementsLayoutBuilderEntityViewDisplay::class : CustomElementsEntityViewDisplay::class;
+  // Check if this call is made during layout_builder installation; changing
+  // the entity class would make the loadMultiple() call in
+  // layout_builder_install() fail fatally in that case. This check depends on
+  // ModuleInstaller implementation details, i.e. entity info is
+  // - (re)built before the module (version) is registered
+  // - not rebuilt between registering the module and invoking hook_install.
   /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
-  $entity_types['entity_view_display']
-    ->setClass($class);
+  $layout_builder_module_install_in_progress =
+    $entity_types['entity_view_display']->getClass() === LayoutBuilderEntityViewDisplay::class
+    && \Drupal::service('update.update_hook_registry')->getInstalledVersion('layout_builder')
+       == UpdateHookRegistry::SCHEMA_UNINSTALLED;
+
+  if (!$layout_builder_module_install_in_progress) {
+    // Use the right class depending on layout builder being used.
+    $class = \Drupal::moduleHandler()->moduleExists('layout_builder') ? CustomElementsLayoutBuilderEntityViewDisplay::class : CustomElementsEntityViewDisplay::class;
+    $entity_types['entity_view_display']
+      ->setClass($class);
+  }
 }
 
 /**
@@ -182,6 +197,18 @@ function custom_elements_module_implements_alter(&$implementations, $hook) {
   }
 }
 
+/**
+ * Implements hook_modules_installed().
+ *
+ * @see custom_elements_entity_type_alter()
+ */
+function custom_elements_modules_installed($modules, $is_syncing) {
+  if (in_array('layout_builder', $modules, TRUE)) {
+    // Rebuild info that was not changed yet during installation.
+    \Drupal::entityTypeManager()->clearCachedDefinitions();
+  }
+}
+
 /**
  * Implements hook_entity_view_display_alter().
  */
diff --git a/tests/src/Kernel/CustomElementGeneratorTest.php b/tests/src/Kernel/CustomElementGeneratorTest.php
index 47d8e11..3624a43 100644
--- a/tests/src/Kernel/CustomElementGeneratorTest.php
+++ b/tests/src/Kernel/CustomElementGeneratorTest.php
@@ -72,6 +72,8 @@ class CustomElementGeneratorTest extends KernelTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
+    // custom_elements_entity_type_alter() needs a layout_builder version.
+    \Drupal::service('update.update_hook_registry')->setInstalledVersion('layout_builder', '12345');
     $this->installEntitySchema('user');
   }
 
-- 
GitLab