/** * {@inheritdoc} */ public function build() { $menu_name = $this->getDerivativeId(); $parameters = $this->menuTree->getCurrentRouteMenuTreeParameters($menu_name); $tree = $this->menuTree->load($menu_name, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $this->menuTree->transform($tree, $manipulators); return $this->menuTree->build($tree); }
/** * @return array * Array containing Devel Menu links */ protected function develMenuLinks() { $parameters = new MenuTreeParameters(); $parameters->setMaxDepth(1)->onlyEnabledLinks(); $tree = $this->menuLinkTree->load('devel', $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $this->menuLinkTree->transform($tree, $manipulators); $links = array(); foreach ($tree as $item) { if ($item->access->isAllowed()) { $links[] = array('title' => $item->link->getTitle(), 'description' => $item->link->getDescription(), 'url' => $item->link->getUrlObject()->toString()); } } return $links; }
/** * Provide a single block on the administration overview page. * * @param \Drupal\Core\Menu\MenuLinkInterface $instance * The menu item to be displayed. * * @return array * An array of menu items, as expected by admin-block-content.html.twig. */ public function getAdminBlock(MenuLinkInterface $instance) { $content = array(); // Only find the children of this link. $link_id = $instance->getPluginId(); $parameters = new MenuTreeParameters(); $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks(); $tree = $this->menuTree->load(NULL, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $this->menuTree->transform($tree, $manipulators); foreach ($tree as $key => $element) { // Only render accessible links. if (!$element->access->isAllowed()) { // @todo Bubble cacheability metadata of both accessible and // inaccessible links. Currently made impossible by the way admin // blocks are rendered. continue; } /** @var $link \Drupal\Core\Menu\MenuLinkInterface */ $link = $element->link; $content[$key]['title'] = $link->getTitle(); $content[$key]['options'] = $link->getOptions(); $content[$key]['description'] = $link->getDescription(); $content[$key]['url'] = $link->getUrlObject(); } ksort($content); return $content; }
/** * Provide the administration overview page. * * @param string $link_id * The ID of the administrative path link for which to display child links. * * @return array * A renderable array of the administration overview page. */ public function overview($link_id) { // Check for status report errors. if ($this->systemManager->checkRequirements() && $this->currentUser()->hasPermission('administer site configuration')) { drupal_set_message($this->t('One or more problems were detected with your Drupal installation. Check the <a href="@status">status report</a> for more information.', array('@status' => $this->url('system.status'))), 'error'); } // Load all menu links below it. $parameters = new MenuTreeParameters(); $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks(); $tree = $this->menuLinkTree->load(NULL, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $this->menuLinkTree->transform($tree, $manipulators); $blocks = array(); foreach ($tree as $key => $element) { $link = $element->link; $block['title'] = $link->getTitle(); $block['description'] = $link->getDescription(); $block['content'] = array('#theme' => 'admin_block_content', '#content' => $this->systemManager->getAdminBlock($link)); if (!empty($block['content']['#content'])) { $blocks[$key] = $block; } } if ($blocks) { ksort($blocks); return array('#theme' => 'admin_page', '#blocks' => $blocks); } else { return array('#markup' => $this->t('You do not have any administrative items.')); } }
/** * 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. $form['#tree'] = TRUE; $form['#theme'] = 'menu_overview_form'; 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 = array_merge($form, $this->buildOverviewTreeForm($tree, $delta)); $destination = $this->getUrlGenerator()->getPathFromRoute('entity.menu.edit_form', array('menu' => $this->entity->id())); $url = $destination = $this->url('entity.menu.add_link_form', array('menu' => $this->entity->id()), array('query' => array('destination' => $destination))); $form['#empty_text'] = $this->t('There are no menu links yet. <a href="@url">Add link</a>.', array('@url' => $url)); return $form; }
/** * {@inheritdoc} */ public function getParentSelectOptions($id = '', array $menus = NULL) { if (!isset($menus)) { $menus = $this->getMenuOptions(); } $options = array(); $depth_limit = $this->getParentDepthLimit($id); foreach ($menus as $menu_name => $menu_title) { $options[$menu_name . ':'] = '<' . $menu_title . '>'; $parameters = new MenuTreeParameters(); $parameters->setMaxDepth($depth_limit); $tree = $this->menuLinkTree->load($menu_name, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $this->menuLinkTree->transform($tree, $manipulators); $this->parentSelectOptionsTreeWalk($tree, $menu_name, '--', $options, $id, $depth_limit); } return $options; }
/** * 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; }
/** * {@inheritdoc} */ public function build() { $menu_name = $this->getDerivativeId(); $parameters = $this->menuTree->getCurrentRouteMenuTreeParameters($menu_name); // Adjust the menu tree parameters based on the block's configuration. $level = $this->configuration['level']; $depth = $this->configuration['depth']; $parameters->setMinDepth($level); // When the depth is configured to zero, there is no depth limit. When depth // is non-zero, it indicates the number of levels that must be displayed. // Hence this is a relative depth that we must convert to an actual // (absolute) depth, that may never exceed the maximum depth. if ($depth > 0) { $parameters->setMaxDepth(min($level + $depth - 1, $this->menuTree->maxDepth())); } $tree = $this->menuTree->load($menu_name, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $this->menuTree->transform($tree, $manipulators); return $this->menuTree->build($tree); }
/** * Provide a single block on the administration overview page. * * @param \Drupal\Core\Menu\MenuLinkInterface $instance * The menu item to be displayed. * * @return array * An array of menu items, as expected by theme_admin_block_content(). */ public function getAdminBlock(MenuLinkInterface $instance) { $content = array(); // Only find the children of this link. $link_id = $instance->getPluginId(); $parameters = new MenuTreeParameters(); $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->excludeHiddenLinks(); $tree = $this->menuTree->load(NULL, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort')); $tree = $this->menuTree->transform($tree, $manipulators); foreach ($tree as $key => $element) { /** @var $link \Drupal\Core\Menu\MenuLinkInterface */ $link = $element->link; $content[$key]['title'] = $link->getTitle(); $content[$key]['options'] = $link->getOptions(); $content[$key]['description'] = $link->getDescription(); $content[$key]['url'] = $link->getUrlObject(); } ksort($content); return $content; }