diff --git a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php index 95278ec..61df197 100644 --- a/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php +++ b/core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php @@ -125,21 +125,11 @@ public function buildConfigurationForm(array $form, array &$form_state) { '#description' => $this->t('Optional. In the menu, the links with high weight will sink and links with a low weight will be positioned nearer the top.'), ); - $options = $this->menuTree->getParentSelectOptions($this->menuLink->getPluginId()); $menu_parent = $this->menuLink->getMenuName() . ':' . $this->menuLink->getParent(); - - if (!isset($options[$menu_parent])) { - // Put it at the top level in the current menu. - $menu_parent = $this->menuLink->getMenuName() . ':'; - } - $form['menu_parent'] = array( - '#type' => 'select', - '#title' => $this->t('Parent link'), - '#options' => $options, - '#default_value' => $menu_parent, - '#description' => $this->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' => $this->menuTree->maxDepth())), - '#attributes' => array('class' => array('menu-title-select')), - ); + $form['menu_parent'] = $this->menuTree->parentSelectElement($menu_parent, $this->menuLink->getPluginId()); + $form['menu_parent']['#title'] = $this->t('Parent link'); + $form['menu_parent']['#description'] = $this->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' => $this->menuTree->maxDepth())); + $form['menu_parent']['#attributes']['class'][] = 'menu-title-select'; return $form; } diff --git a/core/lib/Drupal/Core/Menu/MenuLinkTree.php b/core/lib/Drupal/Core/Menu/MenuLinkTree.php index 3604886..3dd424a 100644 --- a/core/lib/Drupal/Core/Menu/MenuLinkTree.php +++ b/core/lib/Drupal/Core/Menu/MenuLinkTree.php @@ -1069,6 +1069,29 @@ public function getParentSelectOptions($id = '', array $menus = array()) { /** * {@inheritdoc} */ + public function parentSelectElement($menu_parent, $id = '', array $menus = array()) { + $options = $this->getParentSelectOptions($id, $menus); + // If no options were found, there is nothing to select. + if ($options) { + if (!isset($options[$menu_parent])) { + // Try putting it at the top level in the current menu. + list($menu_name, $parent) = explode(':', $menu_parent, 2); + $menu_parent = $menu_name . ':'; + } + if (isset($options[$menu_parent])) { + return array( + '#type' => 'select', + '#options' => $options, + '#default_value' => $menu_parent, + ); + } + } + return array(); + } + + /** + * {@inheritdoc} + */ public function getParentDepthLimit($id) { if ($id) { $limit = $this->treeStorage->maxDepth() - $this->treeStorage->getSubtreeHeight($id); diff --git a/core/lib/Drupal/Core/Menu/MenuLinkTreeInterface.php b/core/lib/Drupal/Core/Menu/MenuLinkTreeInterface.php index 4d9e415..0910717 100644 --- a/core/lib/Drupal/Core/Menu/MenuLinkTreeInterface.php +++ b/core/lib/Drupal/Core/Menu/MenuLinkTreeInterface.php @@ -329,7 +329,7 @@ public function updateLink($id, array $new_definition_values, $persist = TRUE); public function resetLink($id); /** - * Gets the options for a select element to choose and menu and parent. + * Gets the options for a select element to choose a menu and parent. * * @param string $id * Optional ID of a link plugin. This will exclude the link and its @@ -345,6 +345,31 @@ public function resetLink($id); public function getParentSelectOptions($id = '', array $menus = array()); /** + * Get a form element to choose a menu and parent. + * + * The specific type of form element will vary depending on the + * implementation, but callers will normally need to set the #title for the + * element. + * + * @param string $menu_parent + * A menu name and parent ID concatenated with a ':' character to use as the + * default value. + * @param string $id + * Optional ID of a link plugin. This will exclude the link and its + * children from being selected. + * @param array $menus + * Optional array of menu names as keys and titles as values to limit + * the values that may be selected. + * + * @return array + * A form element to choose a parent, or an empty array if no possible + * parents exist for the given parameters. The resulting form value will be + * a single string containing the chosen menu name and parent ID separated + * by a ':' character. + */ + public function parentSelectElement($menu_parent, $id = '', array $menus = array()); + + /** * Gets a list of menu names for use as options. * * @param array $menu_names diff --git a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php index 5dc37fe..44e75e7 100644 --- a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php +++ b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php @@ -131,6 +131,7 @@ public function buildEditForm(array &$form, array &$form_state) { return $this->form($form, $form_state); } + /** * {@inheritdoc} */ @@ -302,22 +303,11 @@ public function form(array $form, array &$form_state) { '#default_value' => $default_value, '#required' => TRUE, ); - - $options = $this->menuTree->getParentSelectOptions($this->entity->getPluginId()); - $menu_parent = $this->entity->getMenuName() . ':' . $this->entity->getParentId(); - - if (!isset($options[$menu_parent])) { - // Put it at the top level in the current menu. - $menu_parent = $this->entity->getMenuName() . ':'; - } - $form['menu_parent'] = array( - '#type' => 'select', - '#title' => $this->t('Parent link'), - '#options' => $options, - '#default_value' => $menu_parent, - '#description' => $this->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' => $this->menuTree->maxDepth())), - '#attributes' => array('class' => array('menu-title-select')), - ); + $default = $this->entity->getMenuName() . ':' . $this->entity->getParentId(); + $form['menu_parent'] = $this->menuTree->parentSelectElement($default, $this->entity->getPluginId()); + $form['menu_parent']['#title'] = $this->t('Parent link'); + $form['menu_parent']['#description'] = $this->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' => $this->menuTree->maxDepth())); + $form['menu_parent']['#attributes']['class'][] = 'menu-title-select'; return $form; } diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module index 0ca4ac1..ca35d99 100644 --- a/core/modules/menu_ui/menu_ui.module +++ b/core/modules/menu_ui/menu_ui.module @@ -363,9 +363,15 @@ function menu_ui_form_node_form_alter(&$form, $form_state) { foreach ($type_menus as $menu) { $available_menus[$menu] = $menu_names[$menu]; } - $options = !$available_menus ? FALSE : $link_tree->getParentSelectOptions($definition['id'], $available_menus); + if ($definition['id']) { + $default = $definition['menu_name'] . ':' . $definition['parent']; + } + else { + $default = \Drupal::config('menu.entity.node.'.$type)->get('parent'); + } + $parent_element = $this->menuTree->parentSelectElement($default, $definition['id'], $available_menus); // If no possible parent menu items were found, there is nothing to display. - if (empty($options)) { + if (empty($parent_element)) { return; } @@ -416,27 +422,9 @@ function menu_ui_form_node_form_alter(&$form, $form_state) { '#description' => t('Shown when hovering over the menu link.'), ); - if ($definition['id']) { - $default = $definition['menu_name'] . ':' . $definition['parent']; - } - else { - $default = \Drupal::config('menu.entity.node.'.$type)->get('parent'); - } - // If the current parent menu item is not present in options, use the first - // available option as default value. - // @todo User should not be allowed to access menu link settings in such a - // case. - if (!isset($options[$default])) { - $array = array_keys($options); - $default = reset($array); - } - $form['menu']['link']['menu_parent'] = array( - '#type' => 'select', - '#title' => t('Parent item'), - '#default_value' => $default, - '#options' => $options, - '#attributes' => array('class' => array('menu-parent-select')), - ); + $form['menu']['link']['menu_parent'] = $parent_element; + $form['menu']['link']['menu_parent']['#title'] = t('Parent item'); + $form['menu']['link']['menu_parent']['#attributes']['class'][] = 'menu-parent-select'; // Get number of items in menu so the weight selector is sized appropriately. $delta = $link_tree->countMenuLinks($definition['menu_name']); @@ -523,7 +511,7 @@ function menu_ui_form_node_type_form_alter(&$form, $form_state) { // To avoid an 'illegal option' error after saving the form we have to load // all available menu items. // Otherwise it is not possible to dynamically add options to the list. - // @todo Convert menu_ui_parent_options() into a #process callback. + // @todo Convert getParentSelectOptions() into a #process callback. $options = $link_tree->getParentSelectOptions(''); $form['menu']['menu_parent'] = array( '#type' => 'select',