diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php index 483eac8..154ab59 100644 --- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php +++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php @@ -81,15 +81,15 @@ public function blockForm($form, &$form_state) { '#title' => $this->t('Starting level'), '#default_value' => $this->configuration['level'], '#options' => array( - '0' => $this->t('1st level (primary)'), - '1' => $this->t('2nd level (secondary)'), - '2' => $this->t('3rd level (tertiary)'), - '3' => $this->t('4th level'), - '4' => $this->t('5th level'), - '5' => $this->t('6th level'), - '6' => $this->t('7th level'), - '7' => $this->t('8th level'), - '8' => $this->t('9th level'), + '1' => $this->t('1st level (primary)'), + '2' => $this->t('2nd level (secondary)'), + '3' => $this->t('3rd level (tertiary)'), + '4' => $this->t('4th level'), + '5' => $this->t('5th level'), + '6' => $this->t('6th level'), + '7' => $this->t('7th level'), + '8' => $this->t('8th level'), + '9' => $this->t('9th level'), ), '#description' => t('Blocks that start with the 1st level will always be visible. Blocks that start with the 2nd level or deeper will only be visible when the trail to the active menu item passes though the block’s starting level.'), '#required' => TRUE, @@ -110,7 +110,7 @@ public function blockForm($form, &$form_state) { '9' => '9', '0' => $this->t('Unlimited'), ), - '#description' => t('When following the active menu item, specify if the starting level should be the active menu item or its children.'), + '#description' => t('From the starting level, specify the maximum depth of the menu tree.'), '#required' => TRUE, ); @@ -132,28 +132,39 @@ public function build() { $menu_output = &drupal_static(__FUNCTION__, array()); $menu = $this->getDerivativeId(); + $level = $this->configuration['level']; $depth = $this->configuration['depth']; + // Config has a 0 for no limit on depth, but our functions want NULL for this. if (empty($depth)) { - $depth = NULL; + $max_depth = NULL; + } else { + $max_depth = $level + $depth; } + $only_active_trail = TRUE; + // Get the menu hierarchy for the current page. - // TODO: depth needs figuring out! - $menu_tree = menu_tree_page_data($menu, $level + $depth + 1); - - // Go down the active trail until the right level is reached. - $loop_level = $level + 1; - while ($loop_level-- > 0 && $menu_tree) { - // Loop through the current level's items until we find one that is in trail. - while ($item = array_shift($menu_tree)) { - if ($item['link']['in_active_trail']) { - // If the item is in the active trail, we continue in the subtree. - $menu_tree = empty($item['below']) ? array() : $item['below']; + $menu_tree = menu_tree_page_data($menu, $max_depth, $only_active_trail); + + // Prune the tree along the active trail to the specified level. + for ($i = 1; $i < $level; $i++) { + $found_active_trail = FALSE; + // Examine each element at this level for the active trail. + foreach ($menu_tree AS $key => &$value) { + if ($menu_tree[$key]['link']['in_active_trail']) { + // Prune the tree to the children of the item in the active trail. + $menu_tree = $menu_tree[$key]['below'] ? $menu_tree[$key]['below'] : array(); + $found_active_trail = TRUE; break; } } + // If we don't find the active trail, the active item isn't in the tree we want. + if (!$found_active_trail) { + $menu_tree = array(); + break; + } } $menu_output[$menu] = menu_tree_output($menu_tree);