Remove items from a menu based on node type efficiently I am trying to remove items from a menu based on the type of node it links to. 

I'm currently achieving this using hook_menu_link and menu_get_object. I'm running into problems because the size of the menu is 500+ items, resulting in 5000+ DB queries to generate the page.

If I remove the hook_menu_link function and show all menu items, the DB queries drop to around 700.

Here is the current code:

function amoss_menu_link(&amp;$variables) {

  // Hide book sections from the menu;.
  if (isset($variables['element']['#original_link']['link_path'])) {
    if ($variables['element']['#original_link']['menu_name'] == 'book-toc-1') {
      if (book_modifications_is_book_section($variables['element']['#original_link']['link_path'])) {
        return '';
      }
    }
  }

  // Output a menu link.
  $element = $variables['element'];
  $sub_menu = '';

  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  }
  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return '&lt;li' . drupal_attributes($element['#attributes']) . '&gt;' . $output . $sub_menu . "&lt;/li&gt;\n";
}

function book_modifications_is_book_section($link_path) {

  if (book_modifications_get_type_from_link_path($link_path) == 'book_section') {
    return TRUE;
  }

  return FALSE;
}

function book_modifications_get_type_from_link_path($link_path) {
  $node = menu_get_object('node', 1, $link_path);

  if (isset($node-&gt;type)) {
    return $node-&gt;type;
  }
  else {
    return '';
  }

}


I tried to use drupal_static in the book_modifications_get_type_from_link_path function, that killed the conditional checks.

I tried caching the results for each item with set_cache, but this was not successful either.

function book_modifications_get_type_from_link_path( $link_path ) {

    if ($cache = cache_get('book_modifications_'. $link_path )) {
        $type = $cache-&gt;data;
    }
    else {
        // Do your expensive calculations here, and populate $my_data
        // with the correct stuff..
        $node = menu_get_object('node', 1, $link_path);
        $type = isset( $node-&gt;type ) ? $node-&gt;type : '';
        // dpm('miss');
        cache_set('book_modifications_'. $link_path, $type, 'CACHE_TEMPORARY');
    }

        // dpm($type);
    return $type;
}


I appreciate any suggestions for making this slow operation faster.
Gathering node paths for the book_section nodes in a function cached with drupal_static and using removing items from the menu based on that, rather than loading node objects for each menu item removed thousands or surplus DB queries. 

Refactored code

function amoss_menu_link(&amp;$variables) {

  // Hide book sections from the menu;.
  if (isset($variables['element']['#original_link']['link_path'])) {
    if ($variables['element']['#original_link']['menu_name'] == 'book-toc-1') {
        $book_sections = book_modifications_get_book_section_paths();

      if ( in_array( $variables['element']['#original_link']['link_path'], $book_sections ) ) {
        return '';
      }
    }
  }

  // Output a menu link.
  $element = $variables['element'];
  $sub_menu = '';

  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  }
  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return '&lt;li' . drupal_attributes($element['#attributes']) . '&gt;' . $output . $sub_menu . "&lt;/li&gt;\n";
}



function book_modifications_get_book_section_paths() {
    $book_section_paths = &amp;drupal_static(__FUNCTION__);

    if (!isset($book_section_paths)) {
        $book_section_paths = array();
        $nids = db_select('node', 'n')
        -&gt;fields('n', array('nid'))
        -&gt;condition('type', 'book_section', '=')
        -&gt;execute()
        -&gt;fetchCol();

        foreach ( $nids as $id ) {
            $book_section_paths[] = 'node/'.$id;
        }

    }

    return $book_section_paths;
}