/**
  * Tests creating links with an expected tree structure.
  */
 public function testCreateLinksInMenu()
 {
     // This creates a tree with the following structure:
     // - 1
     // - 2
     //   - 3
     //     - 4
     // - 5
     //   - 7
     // - 6
     // - 8
     // With link 6 being the only external link.
     $links = array(1 => MenuLinkMock::create(array('id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '')), 2 => MenuLinkMock::create(array('id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => 'test.example1', 'route_parameters' => array('foo' => 'bar'))), 3 => MenuLinkMock::create(array('id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'route_parameters' => array('baz' => 'qux'))), 4 => MenuLinkMock::create(array('id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3')), 5 => MenuLinkMock::create(array('id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '')), 6 => MenuLinkMock::create(array('id' => 'test.example6', 'route_name' => '', 'url' => 'https://drupal.org/', 'title' => 'barbar', 'parent' => '')), 7 => MenuLinkMock::create(array('id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => '')), 8 => MenuLinkMock::create(array('id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '')));
     foreach ($links as $instance) {
         $this->menuLinkManager->addDefinition($instance->getPluginId(), $instance->getPluginDefinition());
     }
     $parameters = new MenuTreeParameters();
     $tree = $this->linkTree->load('mock', $parameters);
     $count = function (array $tree) {
         $sum = function ($carry, MenuLinkTreeElement $item) {
             return $carry + $item->count();
         };
         return array_reduce($tree, $sum);
     };
     $this->assertEqual($count($tree), 8);
     $parameters = new MenuTreeParameters();
     $parameters->setRoot('test.example2');
     $tree = $this->linkTree->load($instance->getMenuName(), $parameters);
     $top_link = reset($tree);
     $this->assertEqual(count($top_link->subtree), 1);
     $child = reset($top_link->subtree);
     $this->assertEqual($child->link->getPluginId(), $links[3]->getPluginId());
     $height = $this->linkTree->getSubtreeHeight('test.example2');
     $this->assertEqual($height, 3);
 }
 /**
  * @covers ::build
  *
  * MenuLinkTree::build() gathers both:
  * 1. the tree's access cacheability: the cacheability of the access result
  *    of checking a link in a menu tree's access. Callers can opt out of
  *    this by MenuLinkTreeElement::access to NULL (the default) value, in
  *    which case the menu link is always visible. Only when an
  *    AccessResultInterface object is specified, we gather this cacheability
  *    metadata.
  *    This means there are three cases:
  *    a. no access result (NULL): menu link is visible
  *    b. AccessResultInterface object that is allowed: menu link is visible
  *    c. AccessResultInterface object that is not allowed: menu link is
  *       invisible, but cacheability metadata is still applicable
  * 2. the tree's menu links' cacheability: the cacheability of a menu link
  *    itself, because it may be dynamic. For this reason, MenuLinkInterface
  *    extends CacheableDependencyInterface. It allows any menu link plugin to
  *    mark itself as uncacheable (max-age=0) or dynamic (by specifying cache
  *    tags and/or contexts), to indicate the extent of dynamism.
  *    This means there are two cases:
  *    a. permanently cacheable, no cache tags, no cache contexts
  *    b. anything else: non-permanently cacheable, and/or cache tags, and/or
  *       cache contexts.
  *
  * Finally, there are four important shapes of trees, all of which we want to
  * test:
  * 1. the empty tree
  * 2. a single-element tree
  * 3. a single-level tree (>1 element; just 1 element is case 2)
  * 4. a multi-level tree
  *
  * The associated data provider aims to test the handling of both of these
  * types of cacheability, and for all four tree shapes, for each of the types
  * of values for the two types of cacheability.
  *
  * There is another level of cacheability involved when actually rendering
  * built menu trees (i.e. when invoking RendererInterface::render() on the
  * return value of MenuLinkTreeInterface::build()): the cacheability of the
  * generated URLs.
  * Fortunately, that doesn't need additional test coverage here because that
  * cacheability is handled at the level of the Renderer (i.e. menu.html.twig
  * template's link() function invocation). It also has its own test coverage.
  *
  * @see \Drupal\menu_link_content\Tests\MenuLinkContentCacheabilityBubblingTest
  *
  * @dataProvider providerTestBuildCacheability
  */
 public function testBuildCacheability($description, $tree, $expected_build, $access, array $access_cache_contexts = [])
 {
     if ($access !== NULL) {
         $access->addCacheContexts($access_cache_contexts);
     }
     $build = $this->menuLinkTree->build($tree);
     sort($expected_build['#cache']['contexts']);
     $this->assertEquals($expected_build, $build, $description);
 }
示例#3
0
 /**
  * {@inheritdoc}
  */
 public function build(array $tree)
 {
     $build = parent::build($tree);
     /** @var \Drupal\Core\Menu\MenuLinkInterface $first_link */
     $first_link = reset($tree)->link;
     $menu_name = $first_link->getMenuName();
     // Add a more specific theme suggestion to differentiate this rendered
     // menu from others.
     $build['#menu_name'] = $menu_name;
     $build['#theme'] = 'menu__mega_menu__' . strtr($menu_name, '-', '_');
     return $build;
 }
 /**
 * {@inheritdoc}
 */
 protected function buildItems(array $tree, CacheableMetadata &$tree_access_cacheability, CacheableMetadata &$tree_link_cacheability)
 {
     $items = parent::buildItems($tree, $tree_access_cacheability, $tree_link_cacheability);
     foreach ($items as $key => $item) {
         // Only operate if there is a menu item that points
         // to the route that should get the active-trail class.
         if ($item['url']->getRouteName() == 'view.blog.page_1') {
             // Add cacheability metadata.
             $tree_link_cacheability->addCacheContexts(['url']);
             // Set the in_active_trail key to TRUE if a blog node is displayed.
             $node = $this->routeMatch->getParameter('node');
             if ($node instanceof NodeInterface && $node->bundle() == 'blog') {
                 $items[$key]['in_active_trail'] = TRUE;
             }
         }
     }
     return $items;
 }
 /**
  * {@inheritdoc}
  */
 public function build(array $tree, $level = 0)
 {
     if ($level == 0) {
         if (!$tree) {
             return array();
         }
         $build = parent::build($tree, $level);
         /** @var \Drupal\Core\Menu\MenuLinkInterface $link */
         $first_link = reset($tree)->link;
         // Get the menu name of the first link.
         $menu_name = $first_link->getMenuName();
         // Add a more specific theme suggestion to differentiate this rendered
         // menu from others.
         $build['#theme'] = 'menu__toolbar__' . strtr($menu_name, '-', '_');
         return $build;
     } else {
         return parent::build($tree, $level);
     }
 }
示例#6
0
 /**
  * @covers ::build
  *
  * MenuLinkTree::build() gathers both:
  * 1. the tree's access cacheability: the cacheability of the access result
  *    of checking a link in a menu tree's access. Callers can opt out of
  *    this by MenuLinkTreeElement::access to NULL (the default) value, in
  *    which case the menu link is always visible. Only when an
  *    AccessResultInterface object is specified, we gather this cacheability
  *    metadata.
  *    This means there are three cases:
  *    a. no access result (NULL): menu link is visible
  *    b. AccessResultInterface object that is allowed: menu link is visible
  *    c. AccessResultInterface object that is not allowed: menu link is
  *       invisible, but cacheability metadata is still applicable
  * 2. the tree's menu links' cacheability: the cacheability of a menu link
  *    itself, because it may be dynamic. For this reason, MenuLinkInterface
  *    extends CacheableDependencyInterface. It allows any menu link plugin to
  *    mark itself as uncacheable (max-age=0) or dynamic (by specifying cache
  *    tags and/or contexts), to indicate the extent of dynamism.
  *    This means there are two cases:
  *    a. permanently cacheable, no cache tags, no cache contexts
  *    b. anything else: non-permanently cacheable, and/or cache tags, and/or
  *       cache contexts.
  *
  * Finally, there are four important shapes of trees, all of which we want to
  * test:
  * 1. the empty tree
  * 2. a single-element tree
  * 3. a single-level tree (>1 element; just 1 element is case 2)
  * 4. a multi-level tree
  *
  * The associated data provider aims to test the handling of both of these
  * types of cacheability, and for all four tree shapes, for each of the types
  * of values for the two types of cacheability.
  *
  * There is another level of cacheability involved when actually rendering
  * built menu trees (i.e. when invoking RendererInterface::render() on the
  * return value of MenuLinkTreeInterface::build()): the cacheability of the
  * generated URLs.
  * Fortunately, that doesn't need additional test coverage here because that
  * cacheability is handled at the level of the Renderer (i.e. menu.html.twig
  * template's link() function invocation). It also has its own test coverage.
  *
  * @see \Drupal\menu_link_content\Tests\MenuLinkContentCacheabilityBubblingTest
  *
  * @dataProvider providerTestBuildCacheability
  */
 public function testBuildCacheability($description, $tree, $expected_build)
 {
     $build = $this->menuLinkTree->build($tree);
     sort($expected_build['#cache']['contexts']);
     $this->assertEquals($expected_build, $build, $description);
 }