diff --git a/core/modules/menu/lib/Drupal/menu/MenuFormController.php b/core/modules/menu/lib/Drupal/menu/MenuFormController.php
new file mode 100644
index 0000000..ba994b7
--- /dev/null
+++ b/core/modules/menu/lib/Drupal/menu/MenuFormController.php
@@ -0,0 +1,103 @@
+ 'textfield',
+ '#title' => t('Title'),
+ '#default_value' => $menu->label(),
+ '#required' => TRUE,
+ // The title of a system menu cannot be altered.
+ '#access' => !isset($system_menus[$menu->id()]),
+ );
+ $form['id'] = array(
+ '#type' => 'machine_name',
+ '#title' => t('Menu name'),
+ '#default_value' => $menu->id(),
+ '#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',
+ 'source' => array('label'),
+ 'replace_pattern' => '[^a-z0-9-]+',
+ 'replace' => '-',
+ ),
+ // A menu's machine name cannot be changed.
+ '#disabled' => !$menu->isNew() || isset($system_menus[$menu->id()]),
+ );
+ $form['description'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Description'),
+ '#default_value' => $menu->description,
+ );
+ $form['actions'] = array('#type' => 'actions');
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ '#button_type' => 'primary',
+ );
+ // Only custom menus may be deleted.
+ $form['actions']['delete'] = array(
+ '#type' => 'submit',
+ '#value' => t('Delete'),
+ '#access' => $menu->isNew() && !isset($system_menus[$menu->id()]),
+ );
+
+ return $form;
+ }
+
+ /**
+ * Overrides Drupal\Core\Entity\EntityFormController::save().
+ */
+ public function save(array $form, array &$form_state) {
+ $menu = $this->getEntity($form_state);
+
+ if ($menu->isNew()) {
+ // Add 'menu-' to the menu name to help avoid name-space conflicts.
+ $menu->set('id', 'menu-' . $menu->id());
+ }
+
+ $status = $menu->save();
+
+ $uri = $menu->uri();
+ if ($status == SAVED_UPDATED) {
+ drupal_set_message(t('Menu %label has been updated.', array('%label' => $menu->label())));
+ watchdog('contact', 'Menu %label has been updated.', array('%label' => $menu->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit'));
+ }
+ else {
+ drupal_set_message(t('Menu %label has been added.', array('%label' => $menu->label())));
+ watchdog('contact', 'Menu %label has been added.', array('%label' => $menu->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit'));
+ }
+
+ $form_state['redirect'] = 'admin/structure/menu/manage/' . $menu->id();
+ }
+
+ /**
+ * Overrides Drupal\Core\Entity\EntityFormController::delete().
+ */
+ public function delete(array $form, array &$form_state) {
+ $menu = $this->getEntity($form_state);
+ $form_state['redirect'] = 'admin/structure/menu/manage/' . $menu->id() . '/delete';
+ }
+
+}
diff --git a/core/modules/menu/lib/Drupal/menu/MenuListController.php b/core/modules/menu/lib/Drupal/menu/MenuListController.php
index 1ccf212..f20708e 100644
--- a/core/modules/menu/lib/Drupal/menu/MenuListController.php
+++ b/core/modules/menu/lib/Drupal/menu/MenuListController.php
@@ -19,6 +19,7 @@ class MenuListController extends ConfigEntityListController {
*/
public function buildHeader() {
$row['title'] = t('Title');
+ $row['description'] = t('Description');
$row['operations'] = t('Operations');
return $row;
}
@@ -27,14 +28,8 @@ public function buildHeader() {
* Overrides \Drupal\Core\Entity\EntityListController::buildRow().
*/
public function buildRow(EntityInterface $entity) {
- $row['title'] = array(
- 'data' => array(
- '#theme' => 'menu_admin_overview',
- '#label' => $entity->label(),
- '#id' => $entity->id(),
- '#description' => $entity->description,
- ),
- );
+ $row['title'] = check_plain($entity->label());
+ $row['description'] = filter_xss_admin($entity->description);
$row['operations']['data'] = $this->buildOperations($entity);
return $row;
}
diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
index 01242c0..b5d4c5d 100644
--- a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
+++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
@@ -115,12 +115,12 @@ function addCustomMenuCRUD() {
$menu_name = substr(hash('sha256', $this->randomName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI);
$label = $this->randomName(16);
- $menu = array(
+ $menu = entity_create('menu', array(
'id' => $menu_name,
'label' => $label,
'description' => 'Description text',
- );
- menu_save($menu);
+ ));
+ $menu->save();
// Assert the new menu.
$this->drupalGet('admin/structure/menu/manage/' . $menu_name . '/edit');
@@ -128,8 +128,8 @@ function addCustomMenuCRUD() {
// Edit the menu.
$new_label = $this->randomName(16);
- $menu['label'] = $new_label;
- menu_save($menu);
+ $menu->set('label', $new_label);
+ $menu->save();
$this->drupalGet('admin/structure/menu/manage/' . $menu_name . '/edit');
$this->assertRaw($new_label, 'Custom menu was edited.');
}
diff --git a/core/modules/menu/menu.admin.inc b/core/modules/menu/menu.admin.inc
index 961be26..1962ce3 100644
--- a/core/modules/menu/menu.admin.inc
+++ b/core/modules/menu/menu.admin.inc
@@ -16,19 +16,32 @@ function menu_overview_page() {
}
/**
- * Returns HTML for a menu title and description for the menu overview page.
+ * Page callback: Presents the menu creation form.
*
- * @param $variables
- * An associative array containing:
- * - id: The menu's machine name.
- * - label: The menu's label.
- * - description: The menu's description.
+ * @return array
+ * A form array as expected by drupal_render().
*
- * @ingroup themeable
+ * @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 theme_menu_admin_overview($variables) {
- return check_plain($variables['label']) .
- '
' . filter_xss_admin($variables['description']) . '
';
+function menu_menu_edit(Menu $menu) {
+ drupal_set_title(t('Edit menu %label', array('%label' => $menu->label())), PASS_THROUGH);
+ return entity_get_form($menu);
}
/**
@@ -450,76 +463,6 @@ function menu_edit_item_submit($form, &$form_state) {
}
/**
- * Menu callback; Build the form that handles the adding/editing of a custom menu.
- */
-function menu_edit_menu($form, &$form_state, $type, $menu = NULL) {
- $system_menus = menu_list_system_menus();
- if (!isset($menu)) {
- $menu = entity_create('menu', array());
- }
- // Allow menu_edit_menu_submit() and other form submit handlers to determine
- // whether the menu already exists.
- $form['#insert'] = $menu->isNew();
- $form['old_name'] = array(
- '#type' => 'value',
- '#value' => $menu->getOriginalID(),
- );
-
- $form['label'] = array(
- '#type' => 'textfield',
- '#title' => t('Title'),
- '#default_value' => $menu->label(),
- '#required' => TRUE,
- // The title of a system menu cannot be altered.
- '#access' => !isset($system_menus[$menu->id()]),
- );
-
- $form['id'] = array(
- '#type' => 'machine_name',
- '#title' => t('Menu name'),
- '#default_value' => $menu->id(),
- '#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',
- 'source' => array('label'),
- 'replace_pattern' => '[^a-z0-9-]+',
- 'replace' => '-',
- ),
- // A menu's machine name cannot be changed.
- '#disabled' => !$menu->isNew() || isset($system_menus[$menu->id()]),
- );
-
- $form['description'] = array(
- '#type' => 'textarea',
- '#title' => t('Description'),
- '#default_value' => $menu->description,
- );
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save'),
- '#button_type' => 'primary',
- );
- // Only custom menus may be deleted.
- $form['actions']['delete'] = array(
- '#type' => 'submit',
- '#value' => t('Delete'),
- '#access' => $type == 'edit' && !isset($system_menus[$menu->id()]),
- '#submit' => array('menu_custom_delete_submit'),
- );
-
- return $form;
-}
-
-/**
- * Submit function for the 'Delete' button on the menu editing form.
- */
-function menu_custom_delete_submit($form, &$form_state) {
- $form_state['redirect'] = 'admin/structure/menu/manage/' . $form_state['values']['id'] . '/delete';
-}
-
-/**
* Menu callback; check access and get a confirm form for deletion of a custom menu.
*/
function menu_delete_menu_page($menu) {
@@ -571,7 +514,7 @@ function menu_delete_menu_confirm_submit($form, &$form_state) {
}
// Delete the custom menu and all its menu links.
- menu_delete($menu);
+ $menu->delete();
$t_args = array('%title' => $menu->label());
drupal_set_message(t('The custom menu %title has been deleted.', $t_args));
diff --git a/core/modules/menu/menu.api.php b/core/modules/menu/menu.api.php
index 3f3818e..95926a6 100644
--- a/core/modules/menu/menu.api.php
+++ b/core/modules/menu/menu.api.php
@@ -17,11 +17,8 @@
* Contributed modules may use the information to perform actions based on the
* information entered into the menu system.
*
- * @param $menu
- * An array representing a custom menu:
- * - menu_name: The unique name of the custom menu.
- * - title: The human readable menu title.
- * - description: The custom menu description.
+ * @param \Drupal\system\Plugin\Core\Entity\Menu $menu
+ * A menu entity.
*
* @see hook_menu_update()
* @see hook_menu_delete()
@@ -29,7 +26,7 @@
function hook_menu_insert($menu) {
// For example, we track available menus in a variable.
$my_menus = variable_get('my_module_menus', array());
- $my_menus[$menu['menu_name']] = $menu['menu_name'];
+ $my_menus[$menu->id()] = $menu->id();
variable_set('my_module_menus', $my_menus);
}
@@ -40,13 +37,8 @@ function hook_menu_insert($menu) {
* Contributed modules may use the information to perform actions based on the
* information entered into the menu system.
*
- * @param $menu
- * An array representing a custom menu:
- * - menu_name: The unique name of the custom menu.
- * - title: The human readable menu title.
- * - description: The custom menu description.
- * - old_name: The current 'menu_name'. Note that internal menu names cannot
- * be changed after initial creation.
+ * @param \Drupal\system\Plugin\Core\Entity\Menu $menu
+ * A menu entity.
*
* @see hook_menu_insert()
* @see hook_menu_delete()
@@ -54,7 +46,7 @@ function hook_menu_insert($menu) {
function hook_menu_update($menu) {
// For example, we track available menus in a variable.
$my_menus = variable_get('my_module_menus', array());
- $my_menus[$menu['menu_name']] = $menu['menu_name'];
+ $my_menus[$menu->id()] = $menu->id();
variable_set('my_module_menus', $my_menus);
}
@@ -66,11 +58,8 @@ function hook_menu_update($menu) {
* information to perform actions based on the information entered into the menu
* system.
*
- * @param $link
- * An array representing a custom menu:
- * - menu_name: The unique name of the custom menu.
- * - title: The human readable menu title.
- * - description: The custom menu description.
+ * @param \Drupal\system\Plugin\Core\Entity\Menu $menu
+ * A menu entity.
*
* @see hook_menu_insert()
* @see hook_menu_update()
@@ -78,7 +67,7 @@ function hook_menu_update($menu) {
function hook_menu_delete($menu) {
// Delete the record from our variable.
$my_menus = variable_get('my_module_menus', array());
- unset($my_menus[$menu['menu_name']]);
+ unset($my_menus[$menu->id()]);
variable_set('my_module_menus', $my_menus);
}
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 154f3b1..3d4a360 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -83,8 +83,7 @@ function menu_menu() {
);
$items['admin/structure/menu/add'] = array(
'title' => 'Add menu',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('menu_edit_menu', 'add'),
+ 'page callback' => 'menu_menu_add',
'access arguments' => array('administer menu'),
'type' => MENU_LOCAL_ACTION,
'file' => 'menu.admin.inc',
@@ -123,8 +122,8 @@ function menu_menu() {
);
$items['admin/structure/menu/manage/%menu/edit'] = array(
'title' => 'Edit menu',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('menu_edit_menu', 'edit', 4),
+ 'page callback' => 'menu_menu_edit',
+ 'page arguments' => array(4),
'access arguments' => array('administer menu'),
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
@@ -167,6 +166,9 @@ function menu_menu() {
function menu_entity_info_alter(&$entity_info) {
$entity_info['menu']['list_controller_class'] = 'Drupal\menu\MenuListController';
$entity_info['menu']['uri_callback'] = 'menu_uri';
+ $entity_info['menu']['form_controller_class'] = array(
+ 'default' => 'Drupal\menu\MenuFormController',
+ );
}
/**
@@ -190,10 +192,6 @@ function menu_theme() {
'file' => 'menu.admin.inc',
'render element' => 'form',
),
- 'menu_admin_overview' => array(
- 'file' => 'menu.admin.inc',
- 'variables' => array('label' => NULL, 'id' => NULL, 'description' => NULL),
- ),
);
}
@@ -239,76 +237,43 @@ function menu_load($menu_name) {
}
/**
- * Save a custom menu.
- *
- * @param \Drupal\system\Plugin\Core\Entity\Menu $menu
- * An array representing a custom menu:
- * - menu_name: The unique name of the custom menu (composed of lowercase
- * letters, numbers, and hyphens).
- * - title: The human readable menu title.
- * - description: The custom menu description.
- *
- * Modules should always pass a fully populated $menu when saving a custom
- * menu, so other modules are able to output proper status or watchdog messages.
- *
- * @see menu_load()
+ * Implements hook_menu_insert()
*/
-function menu_save($menu_array) {
- $menu = entity_create('menu', $menu_array);
- $status = $menu->save();
+function menu_menu_insert(Menu $menu) {
menu_cache_clear_all();
// Invalidate the block cache to update menu-based derivatives.
if (module_exists('block')) {
drupal_container()->get('plugin.manager.block')->clearCachedDefinitions();
}
+ // Make sure the menu is present in the active menus variable so that its
+ // items may appear in the menu active trail.
+ // See menu_set_active_menu_names().
+ $config = config('system.menu');
+
+ $active_menus = $config->get('active_menus_default') ?: array_keys(menu_get_menus());
+ if (!in_array($menu->id(), $active_menus)) {
+ $active_menus[] = $menu->id();
+ $config
+ ->set('active_menus_default', $active_menus)
+ ->save();
+ }
+}
- switch ($status) {
- case SAVED_NEW:
- // Make sure the menu is present in the active menus variable so that its
- // items may appear in the menu active trail.
- // See menu_set_active_menu_names().
- $config = config('system.menu');
-
- $active_menus = $config->get('active_menus_default') ?: array_keys(menu_get_menus());
- if (!in_array($menu->id(), $active_menus)) {
- $active_menus[] = $menu->id();
- $config->set('active_menus_default', $active_menus);
- }
-
- module_invoke_all('menu_insert', $menu);
- break;
-
- case SAVED_UPDATED:
- module_invoke_all('menu_update', $menu);
- break;
+/**
+ * Implements hook_menu_update().
+ */
+function menu_menu_update(Menu $menu) {
+ menu_cache_clear_all();
+ // Invalidate the block cache to update menu-based derivatives.
+ if (module_exists('block')) {
+ drupal_container()->get('plugin.manager.block')->clearCachedDefinitions();
}
}
/**
- * Delete a custom menu and all contained links.
- *
- * Note that this function deletes all menu links in a custom menu. While menu
- * links derived from router paths may be restored by rebuilding the menu, all
- * customized and custom links will be irreversibly gone. Therefore, this
- * function should usually be called from a user interface (form submit) handler
- * only, which allows the user to confirm the action.
- *
- * @param \Drupal\system\Plugin\Core\Entity\Menu $menu
- * An array representing a custom menu:
- * - menu_name: The unique name of the custom menu.
- * - title: The human readable menu title.
- * - description: The custom menu description.
- *
- * Modules should always pass a fully populated $menu when deleting a custom
- * menu, so other modules are able to output proper status or watchdog messages.
- *
- * @see menu_load()
- *
- * menu_delete_links() will take care of clearing the page cache. Other modules
- * should take care of their menu-related data by implementing
- * hook_menu_delete().
+ * Implements hook_menu_predelete().
*/
-function menu_delete($menu) {
+function menu_menu_predelete(Menu $menu) {
// Delete all links from the menu.
menu_delete_links($menu->id());
@@ -320,16 +285,17 @@ function menu_delete($menu) {
variable_set('menu_default_active_menus', $active_menus);
}
}
+}
- // Delete the custom menu.
- $menu->delete();
-
+/**
+ * Implements hook_menu_delete().
+ */
+function menu_menu_delete(Menu $menu) {
menu_cache_clear_all();
// Invalidate the block cache to update menu-based derivatives.
if (module_exists('block')) {
drupal_container()->get('plugin.manager.block')->clearCachedDefinitions();
}
- module_invoke_all('menu_delete', $menu);
}
/**