From 919fa75a13790a8f9a53447860b3399b2ae04a0c Mon Sep 17 00:00:00 2001
From: Amitaibu <none>
Date: Sun, 30 Aug 2009 10:38:14 +0300
Subject: [PATCH] Custom menu API.

---
 includes/menu.inc               |    8 +++++++-
 modules/menu/menu.admin.inc     |   25 +++++--------------------
 modules/menu/menu.install       |    7 +++++--
 modules/menu/menu.module        |   35 +++++++++++++++++++++++++++++++++++
 modules/menu/menu.test          |   38 ++++++++++++++++++++++++++++++++++++++
 modules/toolbar/toolbar.install |   13 +++++--------
 6 files changed, 95 insertions(+), 31 deletions(-)

diff --git includes/menu.inc includes/menu.inc
index 07c1a5f..1467cd1 100644
--- includes/menu.inc
+++ includes/menu.inc
@@ -1384,7 +1384,13 @@ function menu_get_names() {
  * Return an array containing the names of system-defined (default) menus.
  */
 function menu_list_system_menus() {
-  return array('navigation' => 'Navigation', 'management' => 'Management', 'user-menu' => 'User menu', 'main-menu' => 'Main menu', 'secondary-menu' => 'Secondary menu');
+  return array(
+    'navigation' => 'Navigation',
+    'management' => 'Management',
+    'user-menu' => 'User menu',
+    'main-menu' => 'Main menu',
+    'secondary-menu' => 'Secondary menu'
+  );
 }
 
 /**
diff --git modules/menu/menu.admin.inc modules/menu/menu.admin.inc
index aaf1458..d093006 100644
--- modules/menu/menu.admin.inc
+++ modules/menu/menu.admin.inc
@@ -527,13 +527,10 @@ function menu_delete_menu_confirm_submit($form, &$form_state) {
   foreach ($result as $m) {
     menu_link_delete($m['mlid']);
   }
+
   // Delete all the links in the menu and the menu from the list of custom menus.
-  db_delete('menu_links')
-    ->condition('menu_name', $menu['menu_name'])
-    ->execute();
-  db_delete('menu_custom')
-    ->condition('menu_name', $menu['menu_name'])
-    ->execute();
+  menu_custom_delete($menu['menu_name']);
+
   // Delete all the blocks for this menu.
   if (module_exists('block')) {
     db_delete('block')
@@ -595,22 +592,10 @@ function menu_edit_menu_submit($form, &$form_state) {
     ->fetchField();
 
     menu_link_save($link);
-    db_insert('menu_custom')
-      ->fields(array(
-        'menu_name' => $menu['menu_name'],
-        'title' => $menu['title'],
-        'description' => $menu['description'],
-      ))
-      ->execute();
+    menu_custom_save($menu);
   }
   else {
-    db_update('menu_custom')
-      ->fields(array(
-        'title' => $menu['title'],
-        'description' => $menu['description'],
-      ))
-      ->condition('menu_name', $menu['menu_name'])
-      ->execute();
+    menu_custom_save($menu);
     $result = db_query("SELECT mlid FROM {menu_links} WHERE link_path = :path", array(':path' => $path . $menu['menu_name']), array('fetch' => PDO::FETCH_ASSOC));
     foreach ($result as $m) {
       $link = menu_link_load($m['mlid']);
diff --git modules/menu/menu.install modules/menu/menu.install
index adbecb2..83266f3 100644
--- modules/menu/menu.install
+++ modules/menu/menu.install
@@ -21,9 +21,12 @@ function menu_install() {
     'secondary-menu' => 'The <em>Secondary menu</em> is the default source for the Secondary links which are often used for legal notices, contact details, and other navigation items that play a lesser role than the Main links.',
   );
   $t = get_t();
-  $query = db_insert('menu_custom')->fields(array('menu_name', 'title', 'description'));
   foreach ($system_menus as $menu_name => $title) {
-    $query->values(array('menu_name' => $menu_name, 'title' => $t($title), 'description' => $t($descriptions[$menu_name])))->execute();
+    menu_custom_save(array(
+      'menu_name' => $menu_name,
+      'title' => $t($title),
+      'description' => $t($descriptions[$menu_name]),
+    ));
   }
 }
 
diff --git modules/menu/menu.module modules/menu/menu.module
index 41d33b4..80b14a8 100644
--- modules/menu/menu.module
+++ modules/menu/menu.module
@@ -496,3 +496,38 @@ function menu_get_menus($all = TRUE) {
 
   return $query->execute()->fetchAllKeyed();
 }
+
+/**
+ * Save a custom menu.
+ *
+ * @param $custom_menu
+ *   The custom menu array. Keys are:
+ *   - menu_name    Unique key for menu.
+ *   - title        Menu title; displayed at top of block.
+ *   - description  Menu description.
+ */
+function menu_custom_save(array $custom_menu) {
+  db_merge('menu_custom')
+    ->key(array('menu_name' => $custom_menu['menu_name']))
+    ->fields(array(
+        'title' => $custom_menu['title'],
+        'description' => $custom_menu['description'],
+    ))
+    ->execute();
+}
+
+/**
+ * Delete custom menu from the database
+ *
+ * @param $menu_name
+ *   The name of the custom menu to be deleted.
+ */
+function menu_custom_delete($menu_name) {
+  // Delete all the links in the menu and the menu from the list of custom menus.
+  db_delete('menu_custom')
+    ->condition('menu_name', $menu_name)
+    ->execute();
+  db_delete('menu_links')
+    ->condition('menu_name', $menu_name)
+    ->execute();
+}
diff --git modules/menu/menu.test modules/menu/menu.test
index bb0dc1f..314cdad 100644
--- modules/menu/menu.test
+++ modules/menu/menu.test
@@ -87,6 +87,41 @@ class MenuTestCase extends DrupalWebTestCase {
     $this->menu = $this->addCustomMenu();
     $this->doMenuTests($this->menu['menu_name']);
     $this->addInvalidMenuLink($this->menu['menu_name']);
+    $this->customMenuApi();
+  }
+
+  /**
+   * Add and delete custom menu using API.
+   */
+  function customMenuApi() {
+    // Add a new custom menu.
+    $menu_name = substr(md5($this->randomName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI);
+    $title = $this->randomName(16);
+
+    $menu = array(
+      'menu_name' => $menu_name,
+      'title' => $title,
+      'description' => 'Description text',
+    );
+    menu_custom_save($menu);
+
+    // Assert the menu.
+    $this->drupalGet('admin/structure/menu-customize/' . $menu_name . '/edit');
+    $this->assertText($title, t('Custom menu was added.'));
+
+    // Edit the menu.
+    $new_title = $this->randomName(16);
+    $menu['title'] = $new_title;
+    menu_custom_save($menu);
+    $this->drupalGet('admin/structure/menu-customize/' . $menu_name . '/edit');
+    $this->assertText($new_title, t('Custom menu was edited.'));
+
+    // Delete the menu.
+    menu_custom_delete($menu_name);
+
+    // Assert custom menu was removed from database.
+    $result = db_query("SELECT menu_name FROM {menu_custom} WHERE menu_name = :menu_name", array('menu_name' => $menu_name))->fetchField();
+    $this->assertFalse($result, t('Custom menu was deleted.'));
   }
 
   /**
@@ -147,6 +182,9 @@ class MenuTestCase extends DrupalWebTestCase {
     $this->assertResponse(200);
     $this->assertRaw(t('The custom menu %title has been deleted.', array('%title' => $title)), t('Custom menu was deleted'));
     $this->assertFalse(menu_load($menu_name), 'Custom menu was deleted');
+    // Test if all menu links associated to the menu were removed from database.
+    $result = db_query("SELECT menu_name FROM {menu_links} WHERE menu_name = :menu_name", array('menu_name' => $menu_name))->fetchField();
+    $this->assertFalse($result, t('All menu links associated to the custom menu were deleted.'));
   }
 
   /**
diff --git modules/toolbar/toolbar.install modules/toolbar/toolbar.install
index 42dadd2..fb80a45 100644
--- modules/toolbar/toolbar.install
+++ modules/toolbar/toolbar.install
@@ -14,14 +14,11 @@
  */
 function toolbar_install() {
   $t = get_t();
-  $query = db_insert('menu_custom')
-    ->fields(array(
-      'menu_name' => 'admin_shortcuts',
-      'title' => $t('Administration shortcuts'),
-      'description' => $t('The <em>Admininstration shortcuts</em> menu contains commonly used links for administrative tasks.')
-    ))
-    ->execute();
-
+  menu_custom_save(array(
+    'menu_name' => 'admin_shortcuts',
+    'title' => $t('Administration shortcuts'),
+    'description' => $t('The <em>Admininstration shortcuts</em> menu contains commonly used links for administrative tasks.')
+  ));
   // Add starter convenience shortcuts.
   menu_rebuild();
   $items = array(
-- 
1.6.0.4

