From 4ab64263749771534c72a6f82fca98ea365d6f53 Mon Sep 17 00:00:00 2001
From: Matthieu SCARSET <m@matthieuscarset.com>
Date: Sun, 31 Mar 2024 17:30:01 +0200
Subject: [PATCH] Check menu_link_content storage exists #3251578

---
 src/Menu/MenuLinkTreeManipulators.php | 50 ++++++++++++++++-----------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/src/Menu/MenuLinkTreeManipulators.php b/src/Menu/MenuLinkTreeManipulators.php
index f7cdc79..7522046 100644
--- a/src/Menu/MenuLinkTreeManipulators.php
+++ b/src/Menu/MenuLinkTreeManipulators.php
@@ -26,6 +26,13 @@ use Drupal\Core\Url;
  */
 class MenuLinkTreeManipulators {
 
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
   /**
    * The entity repository.
    *
@@ -40,13 +47,6 @@ class MenuLinkTreeManipulators {
    */
   protected $langcode;
 
-  /**
-   * The menu_link_content storage.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageInterface
-   */
-  protected $menuLinkContentStorage;
-
   /**
    * Our custom configuration.
    *
@@ -83,7 +83,7 @@ class MenuLinkTreeManipulators {
     Router $router
   ) {
     $this->entityRepository = $entity_repository;
-    $this->menuLinkContentStorage = $entity_type_manager->getStorage('menu_link_content');
+    $this->entityTypeManager = $entity_type_manager;
     $this->langcode = $language_manager->getCurrentLanguage()->getId();
     $this->config = $config_factory->get('menu_manipulator.settings');
     $this->router = $router;
@@ -117,8 +117,8 @@ class MenuLinkTreeManipulators {
       if ($element->hasChildren && !empty($tree[$key]->subtree)) {
         $element->subtree = $this->filterTreeByCurrentLanguage($element->subtree);
       }
-
     }
+
     return $tree;
   }
 
@@ -182,20 +182,23 @@ class MenuLinkTreeManipulators {
    * Force the MenuLinkBase to tell us its language code.
    *
    * @param \Drupal\Core\Menu\MenuLinkBase $link
-   *   `The Menu Link Content entity.
+   *   The Menu Link item - usually an menu_link_content entity but it can be a
+   *   config from Views or something else we don't even know about yet.
    *
    * @return string
    *   The menu Link language ID or a default value.
+   *
+   * @todo Handle config links such as those added by Views (e.g. get language).
    */
   protected function getLinkLanguage(MenuLinkBase $link) {
     $metadata = $link->getMetaData();
-    if (!isset($metadata['entity_id'])) {
-      return LanguageInterface::LANGCODE_NOT_APPLICABLE;
-    }
+    $entity_id = $metadata['entity_id'] ?? NULL;
 
-    if ($loaded_link = $this->menuLinkContentStorage->load($metadata['entity_id'])) {
-      if ($loaded_lang_link = $this->entityRepository->getTranslationFromContext($loaded_link)) {
-        return $loaded_lang_link->language()->getId();
+    if ($entity_id && $this->entityTypeManager->hasHandler('menu_link_content', 'storage')) {
+      if ($loaded_link = $this->entityTypeManager->getStorage('menu_link_content')->load($entity_id)) {
+        if ($loaded_lang_link = $this->entityRepository->getTranslationFromContext($loaded_link)) {
+          return $loaded_lang_link->language()->getId();
+        }
       }
     }
 
@@ -217,11 +220,16 @@ class MenuLinkTreeManipulators {
       return NULL;
     }
 
-    $loaded_link = $this->menuLinkContentStorage->load($metadata['entity_id']);
-    $uri = $loaded_link->get('link')->getString();
-    $url = Url::fromUri($uri);
-    if (!$url instanceof Url || !$url->isRouted()) {
-      return FALSE;
+    if ($this->entityTypeManager->hasHandler('menu_link_content', 'storage')) {
+      /** @var \Drupal\Core\Menu\MenuLinkInterface $loaded_link */
+      $loaded_link = $this->entityTypeManager->getStorage('menu_link_content')
+        ->load($metadata['entity_id']);
+      $uri = $loaded_link->get('link')->getString();
+      $url = Url::fromUri($uri);
+
+      if (!$url instanceof Url || !$url->isRouted()) {
+        return FALSE;
+      }
     }
 
     try {
-- 
GitLab