How to get all parent nodes from a menu item? Imagine the following menu structure:


Page 1 type: article
Page 2 comes from a view


Page 3 type: desirable &lt; want this


Page 4 type: random


Page 5 type: random



Page 6 type: article


Lets say I'm on Page 5. I want to know if any parent menu item's node has the content type desirable.

I got a menu item id menu_link_content:uuid for Page 5. My current approach is the following:

&lt;?php

$values['menu_parent'] = 'main:menu_link_content:uuid';
list($menuName, $entityName, $uuid) = explode(':', $values['menu_parent'], 3);
$menuLinkManager = \Drupal::service('plugin.manager.menu.link');
$parents = $menuLinkManager-&gt;getParentIds($entityName . ':' . $uuid);

foreach ($parents as $parentPluginId) {

  $mlc_ids = \Drupal::database()
    -&gt;select('menu_tree', 'mt')
    -&gt;fields('mt', ['route_param_key'])
    -&gt;condition('route_name', 'entity.node.canonical')
    -&gt;condition('id', $parentPluginId)
    -&gt;execute()
    -&gt;fetchCol();

  // menu_tree gives back node=nid
  if ($mlc_id &amp;&amp; strpos($mlc_id, 'node=') !== false) {
    // split node=nid into separate values
    list($entityString, $nid) = explode("=", $mlc_id, 2);

    // load the respective node and see if it is a project
    $parentNode = \Drupal::entityManager()-&gt;getStorage('node')-&gt;load($nid);

    if ($parentNode) {
      $parentType = $parentNode-&gt;getType();

      // we found the parent project node
      if ('project' == $parentType) {
        $node-&gt;set('field_project_ref', $nid);
        $node-&gt;save();
        drupal_set_message(
          t("The content was automatically added a project reference due to it's parent menu items."),
          'status'
        );

        break;
      }
    }
  }
}


So I would go on and load the node if the database statement found something and check the node type etc. I just wonder if there was a more performant/ better, out of the box way of doing that?

Something like

$menuLinkContent-&gt;getTargetEntity()-&gt;getType()


or

entityManager()-&gt;loadEntityFromMenu()


would be nice.
I don't think there's anything as simple as $menuLinkContent->getTargetEntity()->getType(). Though that would be nice and I'd love for someone to correct me on that. 

Below I wrote a method that loads the menu, loops through the menulink objects, grabs the url objects from them and loads the nodes based on the path of the url object. Once it has the node it gets the content type from it. I doubt it's better performance wise, but it does take advantage of more of the out of the box stuff and might be a bit easier to read. 

$menu_tree = \Drupal::menuTree();
$menu = reset(\Drupal::entityTypeManager()-&gt;getStorage('menu')-&gt;loadByProperties(['uuid' =&gt; $uuid]));
$menu_parameters = $menu_tree-&gt;getCurrentRouteMenuTreeParameters($menu-&gt;id());
$menu_tree_elements = $menu_tree-&gt;load($menu-&gt;id());

foreach($menu_tree_elements as $menu_tree_element){
    $path = $menu_tree_element-&gt;link-&gt;getUrlObject()-&gt;toString();
    $node = self::nodeFromPath($path);
    $contentType = $node-&gt;getType();
    foreach($menu_tree_elements-&gt;subtree as $subtree_menu_element){
        $path = $subtree_menu_element-&gt;link-&gt;getUrlObject()-&gt;toString();
        $node = self::nodeFromPath($path);
        $contentType = $node-&gt;getType();             
    }
}

function nodeFromPath($path){
        $path = \Drupal::service('path.alias_manager')
            -&gt;getPathByAlias($path);
        preg_match('/node\/(\d+)/', $path, $matches)) {
        $nid = $matches[1];
        return Node::load($nid);
}