diff --git a/core/includes/menu.inc b/core/includes/menu.inc index bf94563..7dcb151 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -2202,6 +2202,9 @@ function menu_contextual_links($module, $parent_path, $args) { if (!$item['access']) { continue; } + if ($item['type'] == MENU_DEFAULT_LOCAL_TASK) { + $item['href'] = $item['tab_parent_href']; + } // All contextual links are keyed by the actual "task" path argument, // prefixed with the name of the implementing module. $links[$module . '-' . $key] = $item; diff --git a/core/modules/menu/lib/Drupal/menu/Controller/MenuController.php b/core/modules/menu/lib/Drupal/menu/Controller/MenuController.php new file mode 100644 index 0000000..a2b69a8 --- /dev/null +++ b/core/modules/menu/lib/Drupal/menu/Controller/MenuController.php @@ -0,0 +1,98 @@ +entityManager = $entity_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin.manager.entity') + ); + } + + /** + * Shows an overview page of all the custom menus and their descriptions. + * + * @return array + * A render array of the listing page. + */ + public function overview() { + return $this->entityManager->getListController('menu')->render(); + } + + /** + * Gets all the available menus and menu items as a JavaScript array. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request of the page. + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + * The available menu and menu items. + */ + public function getParentOptions(Request $request) { + $available_menus = array(); + if ($menus = $request->request->get('menus')) { + foreach ($menus as $menu) { + $available_menus[$menu] = $menu; + } + } + $options = _menu_get_options(menu_get_menus(), $available_menus, array('mlid' => 0)); + + return new JsonResponse($options); + } + + /** + * Provides the menu link submission form. + * + * @param \Drupal\system\Plugin\Core\Entity\Menu $menu + * An entity representing a custom menu. + * + * @return array + * Returns the menu link submission form. + */ + public function addLink(Menu $menu) { + drupal_set_title(t('Add menu link')); + $menu_link = $this->entityManager->getStorageController('menu_link')->create(array( + 'mlid' => 0, + 'plid' => 0, + 'menu_name' => $menu->id(), + )); + return entity_get_form($menu_link); + } + +} diff --git a/core/modules/menu/lib/Drupal/menu/MenuFormController.php b/core/modules/menu/lib/Drupal/menu/MenuFormController.php index 4eeab27..5fd91c5 100644 --- a/core/modules/menu/lib/Drupal/menu/MenuFormController.php +++ b/core/modules/menu/lib/Drupal/menu/MenuFormController.php @@ -8,6 +8,7 @@ namespace Drupal\menu; use Drupal\Core\Entity\EntityFormController; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Base form controller for menu edit forms. @@ -15,10 +16,15 @@ class MenuFormController extends EntityFormController { /** - * Overrides Drupal\Core\Entity\EntityFormController::form(). + * {@inheritdoc} */ public function form(array $form, array &$form_state) { $form = parent::form($form, $form_state); + + if ($this->operation == 'edit') { + drupal_set_title(t('Edit menu %label', array('%label' => $this->entity->label())), PASS_THROUGH); + } + $menu = $this->entity; $system_menus = menu_list_system_menus(); $form_state['menu'] = &$menu; @@ -36,7 +42,7 @@ public function form(array $form, array &$form_state) { '#maxlength' => MENU_MAX_MENU_NAME_LENGTH_UI, '#description' => t('A unique name to construct the URL for the menu. It must only contain lowercase letters, numbers and hyphens.'), '#machine_name' => array( - 'exists' => 'menu_edit_menu_name_exists', + 'exists' => array($this, 'menuNameExists'), 'source' => array('label'), 'replace_pattern' => '[^a-z0-9-]+', 'replace' => '-', @@ -53,6 +59,7 @@ public function form(array $form, array &$form_state) { // Add menu links administration form for existing menus. if (!$menu->isNew() || isset($system_menus[$menu->id()])) { + form_load_include($form_state, 'admin.inc', 'menu'); // Form API supports constructing and validating self-contained sections // within forms, but does not allow to handle the form section's submission // equally separated yet. Therefore, we use a $form_state key to point to @@ -67,7 +74,27 @@ public function form(array $form, array &$form_state) { } /** - * Overrides Drupal\Core\Entity\EntityFormController::actions(). + * Returns whether a menu name already exists. + * + * @param string $value + * The name of the menu. + * + * @return bool + * Returns TRUE if the menu already exists. + * + * @see form_validate_machine_name() + */ + public function menuNameExists($value) { + $custom_exists = entity_load('menu', $value); + // 'menu-' is added to the menu name to avoid name-space conflicts. + $value = 'menu-' . $value; + $link_exists = \Drupal::entityQuery('menu_link')->condition('menu_name', $value)->range(0,1)->count()->execute(); + + return $custom_exists || $link_exists; + } + + /** + * {@inheritdoc} */ protected function actions(array $form, array &$form_state) { $actions = parent::actions($form, $form_state); @@ -80,7 +107,7 @@ protected function actions(array $form, array &$form_state) { } /** - * Overrides Drupal\Core\Entity\EntityFormController::save(). + * {@inheritdoc} */ public function save(array $form, array &$form_state) { $menu = $this->entity; @@ -111,7 +138,7 @@ public function save(array $form, array &$form_state) { } /** - * Overrides Drupal\Core\Entity\EntityFormController::delete(). + * {@inheritdoc} */ public function delete(array $form, array &$form_state) { $menu = $this->entity; diff --git a/core/modules/menu/lib/Drupal/menu/MenuListController.php b/core/modules/menu/lib/Drupal/menu/MenuListController.php index e557d92..448f729 100644 --- a/core/modules/menu/lib/Drupal/menu/MenuListController.php +++ b/core/modules/menu/lib/Drupal/menu/MenuListController.php @@ -48,7 +48,7 @@ public function getOperations(EntityInterface $entity) { $uri = $entity->uri(); $operations['edit']['title'] = t('Edit menu'); - $operatuins['edit']['href'] = $uri['path']; + $operations['edit']['href'] = $uri['path']; $operations['add'] = array( 'title' => t('Add link'), 'href' => $uri['path'] . '/add', diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php index 106ac64..69c288c 100644 --- a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php +++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php @@ -187,7 +187,7 @@ function deleteCustomMenu($menu) { $this->assertFalse($result, 'All menu links associated to the custom menu were deleted.'); // Make sure there's no delete button on system menus. - $this->drupalGet('admin/structure/menu/manage/main/edit'); + $this->drupalGet('admin/structure/menu/manage/main'); $this->assertNoRaw('edit-delete', 'The delete button was not found'); // Try to delete the main menu. @@ -294,7 +294,7 @@ function testSystemMenuRename() { $edit = array( 'label' => $this->randomName(16), ); - $this->drupalPost('admin/structure/menu/manage/main/edit', $edit, t('Save')); + $this->drupalPost('admin/structure/menu/manage/main', $edit, t('Save')); // Make sure menu shows up with new name in block addition. $default_theme = variable_get('theme_default', 'stark'); @@ -329,7 +329,7 @@ public function testBlockContextualLinks() { )); $this->assertResponse(200); $json = drupal_json_decode($response); - $this->assertIdentical($json[$id], ''); + $this->assertIdentical($json[$id], ''); } /** diff --git a/core/modules/menu/menu.admin.inc b/core/modules/menu/menu.admin.inc index 4150b99..5752eb2 100644 --- a/core/modules/menu/menu.admin.inc +++ b/core/modules/menu/menu.admin.inc @@ -6,47 +6,7 @@ */ use Drupal\menu_link\Plugin\Core\Entity\MenuLink; -use Drupal\system\Plugin\Core\Entity\Menu; use Drupal\Component\Utility\NestedArray; -use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; - -/** - * Menu callback which shows an overview page of all the custom menus and their descriptions. - */ -function menu_overview_page() { - return Drupal::entityManager() - ->getListController('menu') - ->render(); -} - -/** - * Page callback: Presents the menu creation form. - * - * @return array - * A form array as expected by drupal_render(). - * - * @see menu_menu() - */ -function menu_menu_add() { - $menu = entity_create('menu', array()); - return entity_get_form($menu); -} - -/** - * Page callback: Presents the menu edit form. - * - * @param \Drupal\system\Plugin\Core\Entity\Menu $menu - * The menu to edit. - * - * @return array - * A form array as expected by drupal_render(). - * - * @see menu_menu() - */ -function menu_menu_edit(Menu $menu) { - drupal_set_title(t('Edit menu %label', array('%label' => $menu->label())), PASS_THROUGH); - return entity_get_form($menu); -} /** * Form constructor to edit an entire menu tree at once. @@ -94,20 +54,6 @@ function menu_overview_form($form, &$form_state) { menu_tree_check_access($tree, $node_links); $menu_admin = FALSE; - // Inline the "Add link" action so it displays right above the table of - // links. No access check needed, since this form has the same access - // restriction as adding menu items to the menu. - $form['inline_actions'] = array( - '#prefix' => '', - ); - $form['inline_actions']['add'] = array( - '#theme' => 'menu_local_action', - '#link' => array( - 'href' => 'admin/structure/menu/manage/' . $form_state['menu']->id() . '/add', - 'title' => t('Add link'), - ), - ); $form = array_merge($form, _menu_overview_tree_form($tree, $delta)); $form['#empty_text'] = t('There are no menu links yet. Add link.', array('@link' => url('admin/structure/menu/manage/' . $form_state['menu']->id() .'/add'))); @@ -310,21 +256,6 @@ function theme_menu_overview_form($variables) { } /** - * Returns whether a menu name already exists. - * - * @see menu_edit_menu() - * @see form_validate_machine_name() - */ -function menu_edit_menu_name_exists($value) { - $custom_exists = entity_load('menu', $value); - // 'menu-' is added to the menu name to avoid name-space conflicts. - $value = 'menu-' . $value; - $link_exists = Drupal::entityQuery('menu_link')->condition('menu_name', $value)->range(0,1)->count()->execute(); - - return $custom_exists || $link_exists; -} - -/** * Submit function for adding or editing a custom menu. */ function menu_edit_menu_submit($form, &$form_state) { @@ -355,22 +286,3 @@ function menu_edit_menu_submit($form, &$form_state) { drupal_set_message(t('Your configuration has been saved.')); $form_state['redirect'] = $path . $menu['id']; } - -/** - * Menu callback: Provides the menu link submission form. - * - * @param \Drupal\system\Plugin\Core\Entity\Menu $menu - * An entity representing a custom menu. - * - * @return - * Returns the menu link submission form. - */ -function menu_link_add(Menu $menu) { - $menu_link = entity_create('menu_link', array( - 'mlid' => 0, - 'plid' => 0, - 'menu_name' => $menu->id(), - )); - drupal_set_title(t('Add menu link')); - return entity_get_form($menu_link); -} diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module index 14c41b0..d5c28d8 100644 --- a/core/modules/menu/menu.module +++ b/core/modules/menu/menu.module @@ -67,16 +67,7 @@ function menu_menu() { $items['admin/structure/menu'] = array( 'title' => 'Menus', 'description' => 'Add new menus to your site, edit existing menus, and rename and reorganize menu links.', - 'page callback' => 'menu_overview_page', - 'access callback' => 'user_access', - 'access arguments' => array('administer menu'), - 'file' => 'menu.admin.inc', - ); - $items['admin/structure/menu/parents'] = array( - 'title' => 'Parent menu items', - 'page callback' => 'menu_parent_options_js', - 'type' => MENU_CALLBACK, - 'access arguments' => array(TRUE), + 'route_name' => 'menu_overview_page', ); $items['admin/structure/menu/list'] = array( 'title' => 'List menus', @@ -84,35 +75,25 @@ function menu_menu() { ); $items['admin/structure/menu/add'] = array( 'title' => 'Add menu', - 'page callback' => 'menu_menu_add', - 'access arguments' => array('administer menu'), + 'route_name' => 'menu_add_menu', 'type' => MENU_LOCAL_ACTION, - 'file' => 'menu.admin.inc', ); $items['admin/structure/menu/settings'] = array( 'title' => 'Settings', 'route_name' => 'menu_settings', - 'access arguments' => array('administer menu'), 'type' => MENU_LOCAL_TASK, 'weight' => 100, ); $items['admin/structure/menu/manage/%menu'] = array( 'title' => 'Edit menu', - 'page callback' => 'menu_menu_edit', - 'page arguments' => array(4), - 'title callback' => 'entity_page_label', + 'title callback' => 'menu_page_label', 'title arguments' => array(4), - 'access arguments' => array('administer menu'), - 'file' => 'menu.admin.inc', + 'route_name' => 'menu_edit_menu', ); - // Not officially a local action, but displayed as such in - // menu_overview_form(). $items['admin/structure/menu/manage/%menu/add'] = array( - 'title' => 'Add menu link', - 'page callback' => 'menu_link_add', - 'page arguments' => array(4), - 'access arguments' => array('administer menu'), - 'file' => 'menu.admin.inc', + 'title' => 'Add link', + 'type' => MENU_LOCAL_ACTION, + 'route_name' => 'menu_link_add', ); $items['admin/structure/menu/manage/%menu/edit'] = array( 'title' => 'Edit menu', @@ -126,9 +107,7 @@ function menu_menu() { ); $items['admin/structure/menu/item/%menu_link/edit'] = array( 'title' => 'Edit menu link', - 'page callback' => 'entity_get_form', - 'page arguments' => array(4), - 'access arguments' => array('administer menu'), + 'route_name' => 'menu_link_edit', ); $items['admin/structure/menu/item/%menu_link/reset'] = array( 'title' => 'Reset menu link', @@ -142,13 +121,30 @@ function menu_menu() { } /** + * Title callback: Returns the label of the menu. + * + * @todo http://drupal.org/node/1981644 + * + * @param int $menu_id + * The entity ID of the menu. + * + * @return string + * The menu's label. + */ +function menu_page_label($menu_id) { + $menu = entity_load('menu', $menu_id); + return $menu->label(); +} + +/** * Implements hook_entity_info_alter(). */ function menu_entity_info_alter(&$entity_info) { $entity_info['menu']['controllers']['list'] = 'Drupal\menu\MenuListController'; $entity_info['menu']['uri_callback'] = 'menu_uri'; $entity_info['menu']['controllers']['form'] = array( - 'default' => 'Drupal\menu\MenuFormController', + 'add' => 'Drupal\menu\MenuFormController', + 'edit' => 'Drupal\menu\MenuFormController', ); } @@ -205,7 +201,7 @@ function menu_enable() { $base_link = entity_create('menu_link', array( 'menu_name' => $system_link->menu_name, - 'router_path' => 'admin/structure/menu/manage/%', + 'router_path' => 'admin/structure/menu/manage/%menu', 'module' => 'menu', )); @@ -353,22 +349,6 @@ function menu_parent_options(array $menus, MenuLink $menu_link = NULL, $type = N } /** - * Page callback. - * Get all the available menus and menu items as a JavaScript array. - */ -function menu_parent_options_js() { - $available_menus = array(); - if (isset($_POST['menus']) && count($_POST['menus'])) { - foreach ($_POST['menus'] as $menu) { - $available_menus[$menu] = $menu; - } - } - $options = _menu_get_options(menu_get_menus(), $available_menus, array('mlid' => 0)); - - return new JsonResponse($options); -} - -/** * Helper function to get the items of the given menu. */ function _menu_get_options($menus, $available_menus, $item) { diff --git a/core/modules/menu/menu.routing.yml b/core/modules/menu/menu.routing.yml index aafe5c3..2d2c47f 100644 --- a/core/modules/menu/menu.routing.yml +++ b/core/modules/menu/menu.routing.yml @@ -5,6 +5,34 @@ menu_settings: requirements: _permission: 'administer menu' +menu_overview_page: + pattern: '/admin/structure/menu' + defaults: + _content: '\Drupal\menu\Controller\MenuController::overview' + requirements: + _permission: 'administer menu' + +menu_parent_options_js: + pattern: '/admin/structure/menu/parents' + defaults: + _controller: '\Drupal\menu\Controller\MenuController::getParentOptions' + requirements: + _access: 'TRUE' + +menu_link_add: + pattern: '/admin/structure/menu/manage/{menu}/add' + defaults: + _content: '\Drupal\menu\Controller\MenuController::addLink' + requirements: + _permission: 'administer menu' + +menu_link_edit: + pattern: '/admin/structure/menu/item/{menu_link}/edit' + defaults: + _entity_form: 'menu_link' + requirements: + _permission: 'administer menu' + menu_link_reset: pattern: 'admin/structure/menu/item/{menu_link}/reset' defaults: @@ -19,6 +47,20 @@ menu_link_delete: requirements: _access_menu_delete_link: 'TRUE' +menu_add_menu: + pattern: '/admin/structure/menu/add' + defaults: + _entity_form: 'menu.add' + requirements: + _permission: 'administer menu' + +menu_edit_menu: + pattern: '/admin/structure/menu/manage/{menu}' + defaults: + _entity_form: 'menu.edit' + requirements: + _permission: 'administer menu' + menu_delete_menu: pattern: 'admin/structure/menu/manage/{menu}/delete' defaults: diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php index c2d6593..3c38883 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php @@ -114,7 +114,6 @@ function testBreadCrumbs() { 'admin/structure/menu' => t('Menus'), ); $this->assertBreadcrumb('admin/structure/menu/manage/tools', $trail); - $this->assertBreadcrumb('admin/structure/menu/manage/tools/edit', $trail); $mlid_node_add = db_query('SELECT mlid FROM {menu_links} WHERE link_path = :href AND module = :module', array( ':href' => 'node/add',