예제 #1
0
 /**
  * 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, array &$form_state)
 {
     // Ensure that menu_overview_form_submit() knows the parents of this form
     // section.
     $form['#tree'] = TRUE;
     $form['#theme'] = 'menu_overview_form';
     $form_state += array('menu_overview_form_parents' => array());
     $form['#attached']['css'] = array(drupal_get_path('module', 'menu') . '/css/menu.admin.css');
     $links = array();
     $query = $this->entityQueryFactory->get('menu_link')->condition('menu_name', $this->entity->id());
     for ($i = 1; $i <= MENU_MAX_DEPTH; $i++) {
         $query->sort('p' . $i, 'ASC');
     }
     $result = $query->execute();
     if (!empty($result)) {
         $links = $this->menuLinkStorage->loadMultiple($result);
     }
     $delta = max(count($links), 50);
     // We indicate that a menu administrator is running the menu access check.
     $this->getRequest()->attributes->set('_menu_admin', TRUE);
     $tree = $this->menuTree->buildTreeData($links);
     $this->getRequest()->attributes->set('_menu_admin', FALSE);
     $form = array_merge($form, $this->buildOverviewTreeForm($tree, $delta));
     $form['#empty_text'] = t('There are no menu links yet. <a href="@link">Add link</a>.', array('@link' => url('admin/structure/menu/manage/' . $this->entity->id() . '/add')));
     return $form;
 }
예제 #2
0
 /**
  * Overrides EntityForm::form().
  */
 public function form(array $form, array &$form_state)
 {
     $menu_link = $this->entity;
     // Since menu_link_load() no longer returns a translated and access checked
     // item, do it here instead.
     _menu_link_translate($menu_link);
     $form['link_title'] = array('#type' => 'textfield', '#title' => t('Menu link title'), '#default_value' => $menu_link->link_title, '#description' => t('The text to be used for this link in the menu.'), '#required' => TRUE);
     foreach (array('link_path', 'mlid', 'module', 'has_children', 'options') as $key) {
         $form[$key] = array('#type' => 'value', '#value' => $menu_link->{$key});
     }
     // Any item created or edited via this interface is considered "customized".
     $form['customized'] = array('#type' => 'value', '#value' => 1);
     // We are not using url() when constructing this path because it would add
     // $base_path.
     $path = $menu_link->link_path;
     if (isset($menu_link->options['query'])) {
         $path .= '?' . $this->urlGenerator->httpBuildQuery($menu_link->options['query']);
     }
     if (isset($menu_link->options['fragment'])) {
         $path .= '#' . $menu_link->options['fragment'];
     }
     if ($menu_link->module == 'menu_ui') {
         $form['link_path'] = array('#type' => 'textfield', '#title' => t('Path'), '#maxlength' => 255, '#default_value' => $path, '#description' => t('The path for this menu link. This can be an internal Drupal path such as %add-node or an external URL such as %drupal. Enter %front to link to the front page.', array('%front' => '<front>', '%add-node' => 'node/add', '%drupal' => 'http://drupal.org')), '#required' => TRUE);
     } else {
         $form['_path'] = array('#type' => 'item', '#title' => t('Path'), '#description' => l($menu_link->link_title, $menu_link->href, $menu_link->options));
     }
     $form['description'] = array('#type' => 'textarea', '#title' => t('Description'), '#default_value' => isset($menu_link->options['attributes']['title']) ? $menu_link->options['attributes']['title'] : '', '#rows' => 1, '#description' => t('Shown when hovering over the menu link.'));
     $form['enabled'] = array('#type' => 'checkbox', '#title' => t('Enabled'), '#default_value' => !$menu_link->hidden, '#description' => t('Menu links that are not enabled will not be listed in any menu.'));
     $form['expanded'] = array('#type' => 'checkbox', '#title' => t('Show as expanded'), '#default_value' => $menu_link->expanded, '#description' => t('If selected and this menu link has children, the menu will always appear expanded.'));
     // Generate a list of possible parents (not including this link or descendants).
     $options = menu_ui_parent_options(menu_ui_get_menus(), $menu_link);
     $default = $menu_link->menu_name . ':' . $menu_link->plid;
     if (!isset($options[$default])) {
         $default = 'tools:0';
     }
     $form['parent'] = array('#type' => 'select', '#title' => t('Parent link'), '#default_value' => $default, '#options' => $options, '#description' => t('The maximum depth for a link and all its children is fixed at !maxdepth. Some menu links may not be available as parents if selecting them would exceed this limit.', array('!maxdepth' => MENU_MAX_DEPTH)), '#attributes' => array('class' => array('menu-title-select')));
     // Get number of items in menu so the weight selector is sized appropriately.
     $delta = $this->menuLinkStorage->countMenuLinks($menu_link->menu_name);
     $form['weight'] = array('#type' => 'weight', '#title' => t('Weight'), '#delta' => max($delta, 50), '#default_value' => $menu_link->weight, '#description' => t('Optional. In the menu, the heavier links will sink and the lighter links will be positioned nearer the top.'));
     // Language module allows to configure the menu link language independently
     // of the menu language. It also allows to optionally show the language
     // selector on the menu link form so that the language of each menu link can
     // be configured individually.
     if ($this->moduleHandler->moduleExists('language')) {
         $language_configuration = language_get_default_configuration('menu_link', $menu_link->bundle());
         $default_langcode = $menu_link->isNew() ? $language_configuration['langcode'] : $menu_link->langcode;
         $language_show = $language_configuration['language_show'];
     } else {
         $default_langcode = $menu_link->isNew() ? entity_load('menu', $menu_link->menu_name)->language()->getId() : $menu_link->langcode;
         $language_show = FALSE;
     }
     $form['langcode'] = array('#type' => 'language_select', '#title' => t('Language'), '#languages' => LanguageInterface::STATE_ALL, '#default_value' => $default_langcode, '#access' => $language_show);
     return parent::form($form, $form_state, $menu_link);
 }
예제 #3
0
 /**
  * Builds a menu tree.
  *
  * This function may be used build the data for a menu tree only, for example
  * to further massage the data manually before further processing happens.
  * MenuTree::checkAccess() needs to be invoked afterwards.
  *
  * @param string $menu_name
  *   The name of the menu.
  * @param array $parameters
  *   The parameters passed into static::buildTree()
  *
  * @see static::buildTree()
  */
 protected function doBuildTree($menu_name, array $parameters = array())
 {
     $language_interface = $this->languageManager->getCurrentLanguage();
     // Build the cache id; sort parents to prevent duplicate storage and remove
     // default parameter values.
     if (isset($parameters['expanded'])) {
         sort($parameters['expanded']);
     }
     $tree_cid = 'links:' . $menu_name . ':tree-data:' . $language_interface->id . ':' . hash('sha256', serialize($parameters));
     // If we do not have this tree in the static cache, check {cache_menu}.
     if (!isset($this->menuTree[$tree_cid])) {
         $cache = $this->cache->get($tree_cid);
         if ($cache && $cache->data) {
             $this->menuTree[$tree_cid] = $cache->data;
         }
     }
     if (!isset($this->menuTree[$tree_cid])) {
         $query = $this->queryFactory->get('menu_link');
         for ($i = 1; $i <= MENU_MAX_DEPTH; $i++) {
             $query->sort('p' . $i, 'ASC');
         }
         $query->condition('menu_name', $menu_name);
         if (!empty($parameters['expanded'])) {
             $query->condition('plid', $parameters['expanded'], 'IN');
         } elseif (!empty($parameters['only_active_trail'])) {
             $query->condition('mlid', $parameters['active_trail'], 'IN');
         }
         $min_depth = isset($parameters['min_depth']) ? $parameters['min_depth'] : 1;
         if ($min_depth != 1) {
             $query->condition('depth', $min_depth, '>=');
         }
         if (isset($parameters['max_depth'])) {
             $query->condition('depth', $parameters['max_depth'], '<=');
         }
         // Add custom query conditions, if any were passed.
         if (isset($parameters['conditions'])) {
             foreach ($parameters['conditions'] as $column => $value) {
                 $query->condition($column, $value);
             }
         }
         // Build an ordered array of links using the query result object.
         $links = array();
         if ($result = $query->execute()) {
             $links = $this->menuLinkStorage->loadMultiple($result);
         }
         $active_trail = isset($parameters['active_trail']) ? $parameters['active_trail'] : array();
         $tree = $this->doBuildTreeData($links, $active_trail, $min_depth);
         // Cache the data, if it is not already in the cache.
         $this->cache->set($tree_cid, $tree, Cache::PERMANENT, array('menu' => $menu_name));
         $this->menuTree[$tree_cid] = $tree;
     }
     return $this->menuTree[$tree_cid];
 }
예제 #4
0
 /**
  * Provide a single block on the administration overview page.
  *
  * @param \Drupal\menu_link\MenuLinkInterface|array $item
  *   The menu item to be displayed.
  *
  * @return array
  *   An array of menu items, as expected by theme_admin_block_content().
  */
 public function getAdminBlock($item)
 {
     if (!isset($item['mlid'])) {
         $menu_links = $this->menuLinkStorage->loadByProperties(array('link_path' => $item['path'], 'module' => 'system'));
         if ($menu_links) {
             $menu_link = reset($menu_links);
             $item['mlid'] = $menu_link->id();
             $item['menu_name'] = $menu_link->menu_name;
         } else {
             return array();
         }
     }
     if (isset($this->menuItems[$item['mlid']])) {
         return $this->menuItems[$item['mlid']];
     }
     $content = array();
     $menu_links = $this->menuLinkStorage->loadByProperties(array('plid' => $item['mlid'], 'menu_name' => $item['menu_name'], 'hidden' => 0));
     foreach ($menu_links as $link) {
         _menu_link_translate($link);
         if ($link['access']) {
             // The link description, either derived from 'description' in
             // hook_menu() or customized via Menu UI module is used as title attribute.
             if (!empty($link['localized_options']['attributes']['title'])) {
                 $link['description'] = $link['localized_options']['attributes']['title'];
                 unset($link['localized_options']['attributes']['title']);
             }
             // Prepare for sorting as in function _menu_tree_check_access().
             // The weight is offset so it is always positive, with a uniform 5-digits.
             $key = 50000 + $link['weight'] . ' ' . Unicode::strtolower($link['title']) . ' ' . $link['mlid'];
             $content[$key] = $link;
         }
     }
     ksort($content);
     $this->menuItems[$item['mlid']] = $content;
     return $content;
 }