/** * Loads the whole menu tree. */ public function expandAll($tree) { foreach ($tree as $key => $element) { if ($element->hasChildren && null !== $element->link && !$element->link instanceof InaccessibleMenuLink) { $menu_tree = \Drupal::menuTree(); $parameters = new MenuTreeParameters(); $parameters->setRoot($element->link->getPluginId())->excludeRoot()->setMaxDepth(1)->onlyEnabledLinks(); $subtree = $menu_tree->load(NULL, $parameters); if ($subtree) { $tree[$key]->subtree = $this->expandAll($subtree); } } } return $tree; }
/** * Provide a hub page for other ea_* modules to attach to. */ public function hubPage() { $content = array(); // Include all menu children on page. $menu_tree = \Drupal::menuTree(); $menu_name = 'hub'; // Build the typical default set of menu tree parameters. $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name); // Load the tree based on this set of parameters. $tree = $menu_tree->load($menu_name, $parameters); $links = array(); if ($tree::count()) { $children = $tree::$subtree; foreach ($children as $child) { $links[] = $child::$link; } } drupal_set_message('Debug: ' . print_r($links, TRUE)); // Finally, build a renderable array from the transformed tree. $menu = $menu_tree->build($tree); $menu_html = drupal_render($menu); $content['title'] = array('#markup' => $this->t('Hub page for EA modules.')); $content['menu_links'] = array('#markup' => $menu_html); return $content; }
/** * Helper method for ::getActiveTrailIds(). */ protected function doGetActiveTrailIds($menu_name) { // Parent ids; used both as key and value to ensure uniqueness. // We always want all the top-level links with parent == ''. $active_trail = array('' => ''); // If a link in the given menu indeed matches the route, then use it to // complete the active trail. if ($active_link = $this->getActiveLink($menu_name)) { if ($parents = $this->menuLinkManager->getParentIds($active_link->getPluginId())) { $active_trail = $parents + $active_trail; } } else { // No matching link, so check paths against current link. $path = $this->getCurrentPathAlias(); $menu_parameters = new MenuTreeParameters(); $tree = \Drupal::menuTree()->load($menu_name, $menu_parameters); foreach ($tree as $menu_link_route => $menu_link) { $menu_url = $menu_link->link->getUrlObject(); $menu_path = $menu_url->toString(); // Check if this item's path exists in the current path. // Also check if there is a langcode prefix. $lang_prefix = '/' . $this->language_manager->getCurrentLanguage()->getId(); if (strpos($path, $menu_path) === 0 || strpos($lang_prefix . $path, $menu_path) === 0) { if ($this->pathIsMoreSimilar($path, $menu_path)) { $parents = array($menu_link_route => $menu_link_route); $active_trail = $parents + $active_trail; } } } } return $active_trail; }
/** * Tests the rediscovering. */ public function testRediscover() { \Drupal::state()->set('menu_link_content_dynamic_route.routes', ['route_name_1' => new Route('/example-path')]); \Drupal::service('router.builder')->rebuild(); // Set up a custom menu link pointing to a specific path. MenuLinkContent::create(['title' => '<script>alert("Welcome to the discovered jungle!")</script>', 'link' => [['uri' => 'internal:/example-path']], 'menu_name' => 'tools'])->save(); $menu_tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertEqual(1, count($menu_tree)); /** @var \Drupal\Core\Menu\MenuLinkTreeElement $tree_element */ $tree_element = reset($menu_tree); $this->assertEqual('route_name_1', $tree_element->link->getRouteName()); // Change the underlying route and trigger the rediscovering. \Drupal::state()->set('menu_link_content_dynamic_route.routes', ['route_name_2' => new Route('/example-path')]); \Drupal::service('router.builder')->rebuild(); // Ensure that the new route name / parameters are captured by the tree. $menu_tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertEqual(1, count($menu_tree)); /** @var \Drupal\Core\Menu\MenuLinkTreeElement $tree_element */ $tree_element = reset($menu_tree); $this->assertEqual('route_name_2', $tree_element->link->getRouteName()); $title = $tree_element->link->getTitle(); $this->assertFalse($title instanceof TranslationWrapper); $this->assertIdentical('<script>alert("Welcome to the discovered jungle!")</script>', $title); $this->assertFalse(SafeMarkup::isSafe($title)); }
/** * Tests the secondary menu. */ function testSecondaryMenu() { // Create a regular user. $user = $this->drupalCreateUser(array()); // Log in and get the homepage. $this->drupalLogin($user); $this->drupalGet('<front>'); // For a logged-in user, expect the secondary menu to have links for "My // account" and "Log out". $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', array(':menu_class' => 'menu', ':href' => 'user', ':text' => 'My account')); $this->assertEqual(count($link), 1, 'My account link is in secondary menu.'); $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', array(':menu_class' => 'menu', ':href' => 'user/logout', ':text' => 'Log out')); $this->assertEqual(count($link), 1, 'Log out link is in secondary menu.'); // Log out and get the homepage. $this->drupalLogout(); $this->drupalGet('<front>'); // For a logged-out user, expect no secondary links. $menu_tree = \Drupal::menuTree(); $tree = $menu_tree->load('account', new MenuTreeParameters()); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess')); $tree = $menu_tree->transform($tree, $manipulators); $this->assertEqual(count($tree), 1, 'The secondary links menu contains only one menu link.'); $element = reset($tree); $this->assertFalse($element->link->isEnabled(), 'The menu link is disabled.'); }
/** * Responds to GET requests. * * Returns a menu tree for the specified menu name. * * @param int $menu_name * The machine name of the Drupal menu. * * @return \Drupal\rest\ResourceResponse * The response containing the menu tree. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function get($menu_name = NULL) { if ($menu_name) { // Get menu tree resource config, set at /admin/config/services/menutree. $config = \Drupal::config('menutree_resource.services_settings'); $services_menus = $config->get('services_menus'); // Only allow a response if the menu is in config if (in_array($menu_name, array_filter(array_values($services_menus)))) { $menu_tree = \Drupal::menuTree(); $parameters = new MenuTreeParameters(); $parameters->onlyEnabledLinks(); $tree = $menu_tree->load($menu_name, $parameters); if (!empty($tree)) { $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $menu_tree->transform($tree, $manipulators); $build = $menu_tree->build($tree); // Clean the menu tree so it's ready for serialisation in a resource response. $items = $this->clean_tree($build['#items']); return new ResourceResponse($items); } throw new NotFoundHttpException(t('Menu with name @menu_name was not found', array('@menu_name' => $menu_name))); } throw new NotFoundHttpException(t('Menu tree @menu_name not allowed.', array('@menu_name' => $menu_name))); } throw new HttpException(t('No menu name was provided')); }
public static function getMenuItem($menu_name, $plugin_id) { $tree = \Drupal::menuTree()->load($menu_name, (new MenuTreeParameters())->onlyEnabledLinks()); // Need to review this. // if (function_exists('i18n_menu_localize_tree')) { // $tree = i18n_menu_localize_tree($tree); // } $item = self::findMenuItem($tree, $plugin_id); return $item; }
/** * Tests bubbleable metadata of menu links' outbound route/path processing. */ public function testOutboundPathAndRouteProcessing() { \Drupal::service('router.builder')->rebuild(); $request_stack = \Drupal::requestStack(); /** @var \Symfony\Component\Routing\RequestContext $request_context */ $request_context = \Drupal::service('router.request_context'); $request = Request::create('/'); $request->attributes->set(RouteObjectInterface::ROUTE_NAME, '<front>'); $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route('/')); $request_stack->push($request); $request_context->fromRequest($request); $menu_tree = \Drupal::menuTree(); $renderer = \Drupal::service('renderer'); $default_menu_cacheability = (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)->setCacheTags(['config:system.menu.tools'])->setCacheContexts(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions']); User::create(['uid' => 1, 'name' => $this->randomString()])->save(); User::create(['uid' => 2, 'name' => $this->randomString()])->save(); // Five test cases, four asserting one outbound path/route processor, and // together covering one of each: // - no cacheability metadata, // - a cache context, // - a cache tag, // - a cache max-age. // Plus an additional test case to verify that multiple links adding // cacheability metadata of the same type is working (two links with cache // tags). $test_cases = [['uri' => 'route:<current>', 'cacheability' => (new BubbleableMetadata())->setCacheContexts(['route'])], ['uri' => 'route:outbound_processing_test.route.csrf', 'cacheability' => (new BubbleableMetadata())->setCacheContexts(['session'])->setAttachments(['placeholders' => []])], ['uri' => 'internal:/', 'cacheability' => new BubbleableMetadata()], ['uri' => 'internal:/user/1', 'cacheability' => (new BubbleableMetadata())->setCacheTags(User::load(1)->getCacheTags())], ['uri' => 'internal:/user/2', 'cacheability' => (new BubbleableMetadata())->setCacheTags(User::load(2)->getCacheTags())]]; // Test each expectation individually. foreach ($test_cases as $expectation) { $menu_link_content = MenuLinkContent::create(['link' => ['uri' => $expectation['uri']], 'menu_name' => 'tools']); $menu_link_content->save(); $tree = $menu_tree->load('tools', new MenuTreeParameters()); $build = $menu_tree->build($tree); $renderer->renderRoot($build); $expected_cacheability = $default_menu_cacheability->merge($expectation['cacheability']); $this->assertEqual($expected_cacheability, BubbleableMetadata::createFromRenderArray($build)); $menu_link_content->delete(); } // Now test them all together in one menu: the rendered menu's cacheability // metadata should be the combination of the cacheability of all links, and // thus of all tested outbound path & route processors. $expected_cacheability = new BubbleableMetadata(); foreach ($test_cases as $expectation) { $menu_link_content = MenuLinkContent::create(['link' => ['uri' => $expectation['uri']], 'menu_name' => 'tools']); $menu_link_content->save(); $expected_cacheability = $expected_cacheability->merge($expectation['cacheability']); } $tree = $menu_tree->load('tools', new MenuTreeParameters()); $build = $menu_tree->build($tree); $renderer->renderRoot($build); $expected_cacheability = $expected_cacheability->merge($default_menu_cacheability); $this->assertEqual($expected_cacheability, BubbleableMetadata::createFromRenderArray($build)); }
/** * {@inheritdoc} */ public function build() { $depth = \Drupal::config('responsive_menu.settings')->get('horizontal_depth'); $menu_name = \Drupal::config('responsive_menu.settings')->get('horizontal_menu'); $menu_tree = \Drupal::menuTree(); $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name); $parameters->setMaxDepth($depth); // Force the entire tree to be build be setting expandParents to an // empty array. $parameters->expandedParents = array(); $tree = $menu_tree->load($menu_name, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkNodeAccess'), array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $menu_tree->transform($tree, $manipulators); $menu = $menu_tree->build($tree); $menu['#theme'] = 'responsive_menu_horizontal'; $output = array('#theme' => 'responsive_menu_block_wrapper', '#element_type' => \Drupal::config('responsive_menu.settings')->get('horizontal_wrapping_element'), '#content' => $menu); // Check whether the generated breakpoint css exists and if not create it. if (!file_exists(_get_breakpoint_css_filepath() . RESPONSIVE_MENU_BREAKPOINT_FILENAME)) { $breakpoint = \Drupal::config('responsive_menu.settings')->get('horizontal_media_query'); responsive_menu_generate_breakpoint_css($breakpoint); } // Add the dynamically generated library with breakpoint styles. $output['#attached']['library'][] = 'responsive_menu/responsive_menu.breakpoint'; // Add the module's css file if the user does not want to disable it. if (\Drupal::config('responsive_menu.settings')->get('include_css')) { $output['#attached']['library'][] = 'responsive_menu/responsive_menu.styling'; } // Add the superfish library if the user has requested it. $superfish_setting = \Drupal::config('responsive_menu.settings')->get('horizontal_superfish'); if ($superfish_setting) { $output['#attached']['library'][] = 'responsive_menu/responsive_menu.superfish'; } // Add superfish's hoverIntent library if the user has requested it. if ($superfish_setting && \Drupal::config('responsive_menu.settings')->get('horizontal_superfish_hoverintent')) { $output['#attached']['library'][] = 'responsive_menu/responsive_menu.superfish_hoverintent'; } // Add the hammerjs library if the user has requested it. $hammerjs_setting = \Drupal::config('responsive_menu.settings')->get('hammerjs'); if ($hammerjs_setting) { $output['#attached']['library'][] = 'responsive_menu/responsive_menu.hammerjs'; } // Add the javascript behaviours. $output['#attached']['library'][] = 'responsive_menu/responsive_menu.javascript'; $output['#attached']['drupalSettings']['responsive_menu'] = array('position' => \Drupal::config('responsive_menu.settings')->get('off_canvas_position'), 'theme' => \Drupal::config('responsive_menu.settings')->get('off_canvas_theme'), 'breakpoint' => \Drupal::config('responsive_menu.settings')->get('horizontal_media_query'), 'superfish' => array('active' => \Drupal::config('responsive_menu.settings')->get('horizontal_superfish'), 'delay' => \Drupal::config('responsive_menu.settings')->get('horizontal_superfish_delay'), 'speed' => \Drupal::config('responsive_menu.settings')->get('horizontal_superfish_speed'), 'speedOut' => \Drupal::config('responsive_menu.settings')->get('horizontal_superfish_speed_out'))); $media_query = \Drupal::config('responsive_menu.settings')->get('horizontal_media_query'); // Attempt to clean up a media query in case it isn't properly enclosed in // brackets. $media_query = preg_replace('/^(min|max)(.+?)$/', '($1$2)', $media_query); $output['#attached']['drupalSettings']['responsive_menu']['mediaQuery'] = $media_query; return $output; }
/** * Provides display_menu function for page layouts. * * @param Twig_Environment $env * The twig environment instance. * @param array $context * An array of parameters passed to the template. */ public function display_menu(\Twig_Environment $env, array $context, $menu_name) { $menu_tree = \Drupal::menuTree(); // Build the typical default set of menu tree parameters. $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name); // Load the tree based on this set of parameters. $tree = $menu_tree->load($menu_name, $parameters); // Transform the tree using the manipulators you want. $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $menu_tree->transform($tree, $manipulators); // Finally, build a renderable array from the transformed tree. $menu = $menu_tree->build($tree); return array('#markup' => drupal_render($menu)); }
/** * Tests the rediscovering. */ public function testRediscover() { \Drupal::state()->set('menu_link_content_dynamic_route.routes', ['route_name_1' => new Route('/example-path')]); \Drupal::service('router.builder')->rebuild(); // Set up a custom menu link pointing to a specific path. $parent = MenuLinkContent::create(['title' => '<script>alert("Welcome to the discovered jungle!")</script>', 'link' => [['uri' => 'internal:/example-path']], 'menu_name' => 'tools']); $parent->save(); $menu_tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertEqual(1, count($menu_tree)); /** @var \Drupal\Core\Menu\MenuLinkTreeElement $tree_element */ $tree_element = reset($menu_tree); $this->assertEqual('route_name_1', $tree_element->link->getRouteName()); // Change the underlying route and trigger the rediscovering. \Drupal::state()->set('menu_link_content_dynamic_route.routes', ['route_name_2' => new Route('/example-path')]); \Drupal::service('router.builder')->rebuild(); // Ensure that the new route name / parameters are captured by the tree. $menu_tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertEqual(1, count($menu_tree)); /** @var \Drupal\Core\Menu\MenuLinkTreeElement $tree_element */ $tree_element = reset($menu_tree); $this->assertEqual('route_name_2', $tree_element->link->getRouteName()); $title = $tree_element->link->getTitle(); $this->assertFalse($title instanceof TranslatableMarkup); $this->assertIdentical('<script>alert("Welcome to the discovered jungle!")</script>', $title); $this->assertFalse(SafeMarkup::isSafe($title)); // Create a hierarchy. \Drupal::state()->set('menu_link_content_dynamic_route.routes', ['route_name_1' => new Route('/example-path'), 'route_name_2' => new Route('/example-path/child')]); $child = MenuLinkContent::create(['title' => 'Child', 'link' => [['uri' => 'entity:/example-path/child']], 'menu_name' => 'tools', 'parent' => 'menu_link_content:' . $parent->uuid()]); $child->save(); $parent->set('link', [['uri' => 'entity:/example-path']]); $parent->save(); $menu_tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertEqual(1, count($menu_tree)); /** @var \Drupal\Core\Menu\MenuLinkTreeElement $tree_element */ $tree_element = reset($menu_tree); $this->assertTrue($tree_element->hasChildren); $this->assertEqual(1, count($tree_element->subtree)); // Edit child element link to use 'internal' instead of 'entity'. $child->set('link', [['uri' => 'internal:/example-path/child']]); $child->save(); \Drupal::service('plugin.manager.menu.link')->rebuild(); $menu_tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertEqual(1, count($menu_tree)); /** @var \Drupal\Core\Menu\MenuLinkTreeElement $tree_element */ $tree_element = reset($menu_tree); $this->assertTrue($tree_element->hasChildren); $this->assertEqual(1, count($tree_element->subtree)); }
/** * Pre-processes variables for the "page" theme hook. * * See template for list of available variables. * * @see page.tpl.php * * @ingroup theme_preprocess */ function bootstrap_preprocess_page(&$variables) { // Add information about the number of sidebars. $variables['content_column_attributes'] = new Attribute(); $variables['content_column_attributes']['class'] = array(); if (!empty($variables['page']['sidebar_first']) && !empty($variables['page']['sidebar_second'])) { $variables['content_column_attributes']['class'][] = 'col-sm-6'; } elseif (!empty($variables['page']['sidebar_first']) || !empty($variables['page']['sidebar_second'])) { $variables['content_column_attributes']['class'][] = 'col-sm-9'; } else { $variables['content_column_attributes']['class'][] = 'col-sm-12'; } $variables['navbar_attributes'] = new Attribute(); $variables['navbar_attributes']['class'] = array('navbar'); if (bootstrap_setting('navbar_position') !== '') { $variables['navbar_attributes']['class'][] = 'navbar-' . bootstrap_setting('navbar_position'); } else { $variables['navbar_attributes']['class'][] = 'container'; } if (bootstrap_setting('navbar_inverse')) { $variables['navbar_attributes']['class'][] = 'navbar-inverse'; } else { $variables['navbar_attributes']['class'][] = 'navbar-default'; } // Primary nav. $menu_tree = \Drupal::menuTree(); // Render the top-level administration menu links. $parameters = new MenuTreeParameters(); $tree = $menu_tree->load('main', $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $menu_tree->transform($tree, $manipulators); $variables['primary_nav'] = $menu_tree->build($tree); $variables['primary_nav']['#attributes']['class'][] = 'navbar-nav'; // Primary nav. $menu_tree = \Drupal::menuTree(); // Render the top-level administration menu links. $parameters = new MenuTreeParameters(); $tree = $menu_tree->load('account', $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $menu_tree->transform($tree, $manipulators); $variables['secondary_nav'] = $menu_tree->build($tree); $variables['secondary_nav']['#attributes']['class'][] = 'navbar-nav'; $variables['secondary_nav']['#attributes']['class'][] = 'secondary'; }
public function content($menu_name) { $menu_tree = \Drupal::menuTree(); // Build the typical default set of menu tree parameters. $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name); // Load the tree based on this set of parameters. $tree = $menu_tree->load($menu_name, $parameters); // Transform the tree using the manipulators you want. $manipulators = array( // Only show links that are accessible for the current user. array('callable' => 'menu.default_tree_manipulators:checkAccess'), // Use the default sorting of menu links. array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), ); $tree = $menu_tree->transform($tree, $manipulators); // Finally, build a renderable array from the transformed tree. $menu = $menu_tree->build($tree); $menu_item_weight = 0; foreach($menu['#items'] as $key => $item){ $menu_link_attributes = menu_link_attributes_get_attributes($menu['#items'][$key]['original_link']); $menu['#items'][$key]['attributes'] = $menu_link_attributes; $menu['#items'][$key]['url'] = str_replace('/drupal', '', $item['url']->toString()); $menu['#items'][$key]['weight'] = $menu_item_weight; $menu_item_weight++; if (!$menu['#items'][$key]['below']){ unset($menu['#items'][$key]['below']); } else { foreach($menu['#items'][$key]['below'] as $subKey => $subItem){ $menu['#items'][$key]['below'][$subKey]['url'] = str_replace('/drupal', '', $subItem['url']->toString()); } } } return new JsonResponse($menu); }
/** * This is menu callback. Save configuration of TB Mega Menu. */ public function saveConfiguration() { $action = isset($_POST['action']) ? $_POST['action'] : NULL; $result = ''; switch ($action) { case 'load': $renderable_array = TBMegaMenuBuilder::renderBlock($_POST['menu_name'], $_POST['theme']); $result = \Drupal::service('renderer')->render($renderable_array)->__toString(); break; case 'save': $menu_config = isset($_POST['menu_config']) ? $_POST['menu_config'] : NULL; $block_config = isset($_POST['block_config']) ? $_POST['block_config'] : NULL; $menu_name = isset($_POST['menu_name']) ? $_POST['menu_name'] : NULL; $theme = isset($_POST['theme']) ? $_POST['theme'] : NULL; if ($menu_config && $menu_name) { // This is parameter to load menu_tree with the enabled links. $menu_tree_parameters = (new MenuTreeParameters())->onlyEnabledLinks(); // Load menu items with condition. $menu_items = \Drupal::menuTree()->load($menu_name, $menu_tree_parameters); // Sync mega menu before store. TBMegaMenuBuilder::syncConfigAll($menu_items, $menu_config, 'backend'); TBMegaMenuBuilder::syncOrderMenus($menu_config); $result = \Drupal::service('database')->merge('tb_megamenus')->key(array('menu_name' => $menu_name, 'theme' => $theme))->fields(array('block_config' => json_encode($block_config), 'menu_config' => json_encode($menu_config)))->execute(); } break; case 'load_block': $block_id = isset($_POST['block_id']) ? $_POST['block_id'] : NULL; $id = isset($_POST['id']) ? $_POST['id'] : NULL; $showblocktitle = isset($_POST['showblocktitle']) ? $_POST['showblocktitle'] : NULL; if ($block_id) { $render = array('#theme' => 'tb_megamenu_block', '#block_id' => $block_id, '#section' => 'backend', '#showblocktitle' => $showblocktitle); $content = \Drupal::service('renderer')->render($render)->__toString(); $result = json_encode(array('content' => $content, 'id' => $id)); } break; default: break; } return new Response($result); }
/** * @param null $menu_name * @return ResourceResponse */ public function get($menu_name = null) { $menu_tree = \Drupal::menuTree( ); $generator = \Drupal::urlGenerator(); // Load the tree based on this set of parameters. $tree = $menu_tree->load($menu_name, new \Drupal\Core\Menu\MenuTreeParameters()); // Transform the tree using the manipulators you want. $manipulators = array( // Only show links that are accessible for the current user. array('callable' => 'menu.default_tree_manipulators:checkAccess'), // Use the default sorting of menu links. array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), ); $tree = $menu_tree->transform($tree, $manipulators); foreach ($tree as $element) { /** @var \Drupal\Core\Menu\MenuLinkInterface $link */ $link = $element->link; $link_param = $link->pluginDefinition['route_parameters']; // echo "<pre>" . print_r($link->pluginDefinition, true) . "</pre>"; $path = $generator->getPathFromRoute($link->getRouteName(), $link_param); $menu[$link->getRouteName()]['title'] = $link->getTitle(); $menu[$link->getRouteName()]['url'] = $path; if ($element->subtree) { $subtree = $menu_tree->build($element->subtree); foreach ($subtree['#items'] as $key => $value) { // print_r($value['url']->getRouteParameters()); //$path = $generator->getPathFromRoute($key, $value['url']->getRouteParameters()); $menu[$key]['title'] = $value['title']; $menu[$key]['url'] = $path; } } } return new ResourceResponse($menu); }
/** * Outputs the data that is used for the Coffee autocompletion in JSON. */ public function coffeeData() { $output = array(); // Get configured menus from configuration. $menus = \Drupal::config('coffee.configuration')->get('coffee_menus'); if ($menus !== NULL) { foreach ($menus as $v) { if ($v === '0') { continue; } // Build the menu tree. $menu_tree_parameters = new MenuTreeParameters(); $tree = \Drupal::menuTree()->load($v, $menu_tree_parameters); foreach ($tree as $key => $link) { $command = $v == 'user-menu' ? ':user' : NULL; $this->coffee_traverse_below($link, $output, $command); } } } module_load_include('inc', 'coffee', 'coffee.hooks'); $commands = array(); foreach (\Drupal::moduleHandler()->getImplementations('coffee_commands') as $module) { $commands = array_merge($commands, \Drupal::moduleHandler()->invoke($module, 'coffee_commands', array())); } if (!empty($commands)) { $output = array_merge($output, $commands); } foreach ($output as $k => $v) { if ($v['value'] == '<front>') { unset($output[$k]); continue; } // Filter out XSS. $output[$k]['label'] = Xss::filter($output[$k]['label']); } // Re-index the array. $output = array_values($output); return new JsonResponse($output); }
/** * Tests the path aliasing changing. */ public function testPathAliasChange() { \Drupal::service('router.builder')->rebuild(); /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */ $path_alias_storage = \Drupal::service('path.alias_storage'); $alias = $path_alias_storage->save('/test-page', '/my-blog'); $pid = $alias['pid']; $menu_link_content = MenuLinkContent::create(['title' => 'Menu title', 'link' => ['uri' => 'internal:/my-blog'], 'menu_name' => 'tools']); $menu_link_content->save(); $tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertEqual('test_page_test.test_page', $tree[$menu_link_content->getPluginId()]->link->getPluginDefinition()['route_name']); // Saving an alias should clear the alias manager cache. $path_alias_storage->save('/test-render-title', '/my-blog', LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid); $tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertEqual('test_page_test.render_title', $tree[$menu_link_content->getPluginId()]->link->getPluginDefinition()['route_name']); // Delete the alias. $path_alias_storage->delete(['pid' => $pid]); $tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters()); $this->assertTrue(isset($tree[$menu_link_content->getPluginId()])); $this->assertEqual('', $tree[$menu_link_content->getPluginId()]->link->getRouteName()); // Verify the plugin now references a path that does not match any route. $this->assertEqual('base:my-blog', $tree[$menu_link_content->getPluginId()]->link->getUrlObject()->getUri()); }
/** * Tests moving a static menu link without a specified menu to the root. */ public function testMoveToRoot() { /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); $menu_link_manager->rebuild(); $menu_link = $menu_link_manager->getDefinition('menu_test.child'); $this->assertEqual($menu_link['parent'], 'menu_test.parent'); $this->assertEqual($menu_link['menu_name'], 'test'); $tree = \Drupal::menuTree()->load('test', new MenuTreeParameters()); $this->assertEqual(count($tree), 1); $this->assertEqual($tree['menu_test.parent']->link->getPluginId(), 'menu_test.parent'); $this->assertEqual($tree['menu_test.parent']->subtree['menu_test.child']->link->getPluginId(), 'menu_test.child'); // Ensure that the menu name is not forgotten. $menu_link_manager->updateDefinition('menu_test.child', array('parent' => '')); $menu_link = $menu_link_manager->getDefinition('menu_test.child'); $this->assertEqual($menu_link['parent'], ''); $this->assertEqual($menu_link['menu_name'], 'test'); $tree = \Drupal::menuTree()->load('test', new MenuTreeParameters()); $this->assertEqual(count($tree), 2); $this->assertEqual($tree['menu_test.parent']->link->getPluginId(), 'menu_test.parent'); $this->assertEqual($tree['menu_test.child']->link->getPluginId(), 'menu_test.child'); $this->assertTrue(TRUE); }
/** * Tests the generated menu links of views. */ public function testMenuLinks() { \Drupal::service('plugin.manager.menu.link')->rebuild(); $tree = \Drupal::menuTree()->load('admin', new MenuTreeParameters()); $this->assertTrue(isset($tree['system.admin']->subtree['views_view:views.test_page_display_menu.page_4'])); $menu_link = $tree['system.admin']->subtree['views_view:views.test_page_display_menu.page_4']->link; $this->assertEqual($menu_link->getTitle(), 'Test child (with parent)'); $this->assertEqual($menu_link->isExpanded(), TRUE); $this->assertEqual($menu_link->getDescription(), 'Sample description.'); }
public function getRenderArrayForMenu($menu_name) { $menu_tree = \Drupal::menuTree(); // Build the typical default set of menu tree parameters. $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name); // Load the tree based on this set of parameters. $tree = $menu_tree->load($menu_name, $parameters); // Transform the tree using the manipulators you want. $manipulators = array(array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $menu_tree->transform($tree, $manipulators); $menu = $menu_tree->build($tree); return $menu; }
/** * Tests the regression in https://www.drupal.org/node/2532490. */ public function testDefaultMenuTabRegression() { $this->container->get('module_installer')->install(['menu_ui', 'menu_link_content', 'toolbar', 'system']); $admin_user = $this->drupalCreateUser(['administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions', 'administer permissions', 'administer menu', 'link to any page', 'access toolbar']); $this->drupalLogin($admin_user); $edit = ['title[0][value]' => 'Menu title', 'link[0][uri]' => '/admin/foo', 'menu_parent' => 'admin:system.admin']; $this->drupalPostForm('admin/structure/menu/manage/admin/add', $edit, t('Save')); $menu_items = \Drupal::entityManager()->getStorage('menu_link_content')->getQuery()->sort('id', 'DESC')->pager(1)->execute(); $menu_item = end($menu_items); /** @var \Drupal\menu_link_content\MenuLinkContentInterface $menu_link_content */ $menu_link_content = MenuLinkContent::load($menu_item); $edit = []; $edit['label'] = $this->randomMachineName(16); $view_id = $edit['id'] = strtolower($this->randomMachineName(16)); $edit['description'] = $this->randomMachineName(16); $edit['page[create]'] = TRUE; $edit['page[path]'] = 'admin/foo'; $this->drupalPostForm('admin/structure/views/add', $edit, t('Save and edit')); $parameters = new MenuTreeParameters(); $parameters->addCondition('id', $menu_link_content->getPluginId()); $result = \Drupal::menuTree()->load('admin', $parameters); $plugin_definition = end($result)->link->getPluginDefinition(); $this->assertEqual('view.' . $view_id . '.page_1', $plugin_definition['route_name']); $this->clickLink(t('No menu')); $this->drupalPostForm(NULL, ['menu[type]' => 'default tab', 'menu[title]' => 'Menu title'], t('Apply')); $this->assertText('Default tab options'); $this->drupalPostForm(NULL, ['tab_options[type]' => 'normal', 'tab_options[title]' => 'Parent title'], t('Apply')); $this->drupalPostForm(NULL, [], t('Save')); // Assert that saving the view will not cause an exception. $this->assertResponse(200); }
/** * Returns all top level menu links. * * @return \Drupal\Core\Menu\MenuLinkInterface[] */ protected function getTopLevelMenuLinks() { $menu_tree = \Drupal::menuTree(); // The system.admin link is normally the parent of all top-level admin links. $parameters = new MenuTreeParameters(); $parameters->setRoot('system.admin')->excludeRoot()->setTopLevelOnly()->excludeHiddenLinks(); $tree = $menu_tree->load(NULL, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:flatten')); $tree = $menu_tree->transform($tree, $manipulators); // Transform the tree to a list of menu links. $menu_links = array(); foreach ($tree as $element) { $menu_links[] = $element->link; } return $menu_links; }
/** * Form constructor to edit an entire menu tree at once. * * Shows for one menu the menu links accessible to the current user and * relevant operations. * * This form constructor can be integrated as a section into another form. It * relies on the following keys in $form_state: * - menu: A menu entity. * - menu_overview_form_parents: An array containing the parent keys to this * form. * Forms integrating this section should call menu_overview_form_submit() from * their form submit handler. */ protected function buildOverviewForm(array &$form, FormStateInterface $form_state) { // Ensure that menu_overview_form_submit() knows the parents of this form // section. if (!$form_state->has('menu_overview_form_parents')) { $form_state->set('menu_overview_form_parents', []); } $form['#attached']['library'][] = 'menu_ui/drupal.menu_ui.adminforms'; $tree = $this->menuTree->load($this->entity->id(), new MenuTreeParameters()); // We indicate that a menu administrator is running the menu access check. $this->getRequest()->attributes->set('_menu_admin', TRUE); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $this->menuTree->transform($tree, $manipulators); $this->getRequest()->attributes->set('_menu_admin', FALSE); // Determine the delta; the number of weights to be made available. $count = function (array $tree) { $sum = function ($carry, MenuLinkTreeElement $item) { return $carry + $item->count(); }; return array_reduce($tree, $sum); }; $delta = max($count($tree), 50); $form['links'] = array('#type' => 'table', '#theme' => 'table__menu_overview', '#header' => array($this->t('Menu link'), array('data' => $this->t('Enabled'), 'class' => array('checkbox')), $this->t('Weight'), array('data' => $this->t('Operations'), 'colspan' => 3)), '#attributes' => array('id' => 'menu-overview'), '#tabledrag' => array(array('action' => 'match', 'relationship' => 'parent', 'group' => 'menu-parent', 'subgroup' => 'menu-parent', 'source' => 'menu-id', 'hidden' => TRUE, 'limit' => \Drupal::menuTree()->maxDepth() - 1), array('action' => 'order', 'relationship' => 'sibling', 'group' => 'menu-weight'))); $form['links']['#empty'] = $this->t('There are no menu links yet. <a href=":url">Add link</a>.', [':url' => $this->url('entity.menu.add_link_form', ['menu' => $this->entity->id()], ['query' => ['destination' => $this->entity->url('edit-form')]])]); $links = $this->buildOverviewTreeForm($tree, $delta); foreach (Element::children($links) as $id) { if (isset($links[$id]['#item'])) { $element = $links[$id]; $form['links'][$id]['#item'] = $element['#item']; // TableDrag: Mark the table row as draggable. $form['links'][$id]['#attributes'] = $element['#attributes']; $form['links'][$id]['#attributes']['class'][] = 'draggable'; $form['links'][$id]['#item'] = $element['#item']; // TableDrag: Sort the table row according to its existing/configured weight. $form['links'][$id]['#weight'] = $element['#item']->link->getWeight(); // Add special classes to be used for tabledrag.js. $element['parent']['#attributes']['class'] = array('menu-parent'); $element['weight']['#attributes']['class'] = array('menu-weight'); $element['id']['#attributes']['class'] = array('menu-id'); $form['links'][$id]['title'] = array(array('#theme' => 'indentation', '#size' => $element['#item']->depth - 1), $element['title']); $form['links'][$id]['enabled'] = $element['enabled']; $form['links'][$id]['enabled']['#wrapper_attributes']['class'] = array('checkbox', 'menu-enabled'); $form['links'][$id]['weight'] = $element['weight']; // Operations (dropbutton) column. $form['links'][$id]['operations'] = $element['operations']; $form['links'][$id]['id'] = $element['id']; $form['links'][$id]['parent'] = $element['parent']; } } return $form; }
/** * Tests the menuTree() method. * * @covers ::menuTree */ public function testMenuTree() { $this->setMockContainerService('menu.link_tree'); $this->assertNotNull(\Drupal::menuTree()); }