menu.module 20 KB
Newer Older
1 2 3
<?php
// $Id$

Dries's avatar
 
Dries committed
4 5 6 7 8
/**
 * @file
 * Allows administrators to customize the site navigation menu.
 */

9
/**
Dries's avatar
 
Dries committed
10
 * Implementation of hook_menu().
11
 */
Dries's avatar
 
Dries committed
12
function menu_menu($may_cache) {
Dries's avatar
 
Dries committed
13
  $items = array();
Dries's avatar
 
Dries committed
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

  if ($may_cache) {
    $items[] = array('path' => 'admin/menu', 'title' => t('menus'),
      'callback' => 'menu_overview',
      'access' => user_access('administer menu'));
    $items[] = array('path' => 'admin/menu/item/edit', 'title' => t('edit menu item'),
      'callback' => 'menu_edit_item',
      'access' => user_access('administer menu'),
      'type' => MENU_CALLBACK);
    $items[] = array('path' => 'admin/menu/item/reset', 'title' => t('reset menu item'),
      'callback' => 'menu_reset_item',
      'access' => user_access('administer menu'),
      'type' => MENU_CALLBACK);
    $items[] = array('path' => 'admin/menu/item/disable', 'title' => t('disable menu item'),
      'callback' => 'menu_disable_item',
      'access' => user_access('administer menu'),
      'type' => MENU_CALLBACK);
    $items[] = array('path' => 'admin/menu/item/delete', 'title' => t('delete menu item'),
      'callback' => 'menu_delete_item',
      'access' => user_access('administer menu'),
      'type' => MENU_CALLBACK);

    $items[] = array('path' => 'admin/menu/list', 'title' => t('list'),
      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
    $items[] = array('path' => 'admin/menu/menu/add', 'title' => t('add menu'),
      'callback' => 'menu_add_menu',
      'access' => user_access('administer menu'),
      'type' => MENU_LOCAL_TASK);
    $items[] = array('path' => 'admin/menu/item/add', 'title' => t('add menu item'),
      'callback' => 'menu_edit_item',
      'access' => user_access('administer menu'),
      'type' => MENU_LOCAL_TASK);
    $items[] = array('path' => 'admin/menu/reset', 'title' => t('reset menus'),
      'callback' => 'menu_reset',
      'access' => user_access('administer menu'),
      'type' => MENU_LOCAL_TASK);
  }
Dries's avatar
 
Dries committed
51 52

  return $items;
53 54 55 56 57 58 59
}

/**
 * Implementation of hook_help().
 */
function menu_help($section) {
  switch ($section) {
Dries's avatar
 
Dries committed
60
    case 'admin/modules#description':
61 62
      return t('Allows administrators to customize the site navigation menu.');
    case 'admin/menu':
63
      return t('<p>Select an operation from the list to move, change, or delete a menu item.</p>');
64
    case 'admin/menu/menu/add':
65
      return t('<p>Enter the name for your new menu. Remember to enable the newly created block in the %blocks administration page.</p>', array('%blocks' => l(t('blocks'), 'admin/block')));
66
    case 'admin/menu/item/add':
67
      return t('<p>Enter the title, path, position and the weight for your new menu item.</p>');
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  }
}

/**
 * Implementation of hook_block().
 */
function menu_block($op = 'list', $delta = 0) {
  $menu = menu_get_menu();

  if ($op == 'list') {
    $blocks = array();
    foreach ($menu['items'][0]['children'] as $mid) {
      // Default "Navigation" block is handled by user.module.
      if ($mid != 1) {
        $blocks[$mid]['info'] = $menu['items'][$mid]['title'];
      }
    }
    return $blocks;
  }
87
  else if ($op == 'view') {
88
    $data['subject'] = $menu['items'][$delta]['title'];
89
    $data['content'] = '<div class="menu">'. theme('menu_tree', $delta) .'</div>' ;
90 91 92 93
    return $data;
  }
}

94 95 96 97 98 99 100
/**
 * Implementation of hook_nodeapi().
 */
function menu_nodeapi(&$node, $op) {

  if (user_access('administer menu')) {
    switch ($op) {
101
      case 'form':
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
        $edit = $_POST['edit'];
        $edit['nid'] = $node->nid;
        return menu_node_form($edit);
        break;

      case 'insert':
      case 'update':
        if ($node->menu['delete']) {
          menu_node_form_delete($node);
          menu_rebuild();
        }
        elseif ($node->menu['title']) {
          $node->menu['path'] = ($node->menu['path']) ? $node->menu['path'] : "node/$node->nid";
          menu_edit_item_save($node->menu);
          menu_rebuild();
        }
        break;

      case 'delete':
        menu_node_form_delete($node);
        menu_rebuild();
        break;
    }
  }
}

128 129 130 131 132 133 134 135
/**
 * Implementation of hook_perm().
 */
function menu_perm() {
  return array('administer menu');
}

/**
136
 * Menu callback; present the main menu management page.
137 138 139 140
 */
function menu_overview() {
  menu_rebuild();

Dries's avatar
 
Dries committed
141
  return menu_overview_tree();
142 143 144
}

/**
145
 * Menu callback; clear the database, resetting the menu to factory defaults.
146 147 148 149
 */
function menu_reset() {
  $op = $_POST['op'];
  switch ($op) {
150
    case t('Reset all'):
151
      db_query('DELETE FROM {menu}');
152
      drupal_set_message(t('The menu items have been reset to their default settings.'));
Dries's avatar
 
Dries committed
153
      drupal_goto('admin/menu');
154 155
      break;
    default:
156 157 158 159
      return confirm_form('menu_confirm_reset', array(),
        t('Are you sure you want to reset all menu items to their default settings?'),
        'admin/menu', t('Any custom additions or changes to the menu will be lost.'),
        t('Reset all'));
160 161 162 163
  }
}

/**
164
 * Menu callback; handle the adding of a new menu.
165 166 167 168 169 170 171 172
 */
function menu_add_menu() {
  $op = $_POST['op'];
  $edit = $_POST['edit'];
  $output = '';

  switch ($op) {
    case t('Submit'):
Dries's avatar
 
Dries committed
173 174 175 176 177 178
      menu_edit_item_validate($edit);
      if (!form_get_errors()) {
        menu_edit_item_save($edit);
        drupal_goto('admin/menu');
      }
      // Fall through.
179 180
    default:
      $edit['pid'] = 0;
Dries's avatar
 
Dries committed
181
      $edit['type'] = MENU_CUSTOM_MENU;
182 183 184
      $output .= menu_edit_item_form($edit);
  }

Dries's avatar
 
Dries committed
185
  return $output;
186 187 188
}

/**
189
 * Menu callback; reset a single modified item.
190 191 192 193 194 195
 */
function menu_reset_item($mid) {
  $op = $_POST['op'];
  switch ($op) {
    case t('Reset'):
      db_query('DELETE FROM {menu} WHERE mid = %d', $mid);
196
      drupal_set_message(t("The menu item was reset to its default settings."));
Dries's avatar
 
Dries committed
197
      drupal_goto('admin/menu');
198 199
      break;
    default:
200
      $title = db_result(db_query('SELECT title FROM {menu} WHERE mid = %d', $mid));
201 202 203 204
      return confirm_form('menu_item_confirm_reset', array(),
        t('Are you sure you want to reset the item %item to its default values?', array('%item' => theme('placeholder', $title))),
        'admin/menu', t('Any customizations will be lost. This action cannot be undone.'),
        t('Reset'));
205 206 207 208
  }
}

/**
209
 * Menu callback; delete a single custom item.
210 211 212
 */
function menu_delete_item($mid) {
  $op = $_POST['op'];
213 214 215 216 217
  $result = db_query('SELECT type, title FROM {menu} WHERE mid = %d', $mid);
  $menu = db_fetch_object($result);
  if (!$menu) {
    drupal_goto('admin/menu');
  }
218 219 220
  switch ($op) {
    case t('Delete'):
      db_query('DELETE FROM {menu} WHERE mid = %d', $mid);
221
      if ($menu->type & MENU_IS_ROOT) {
222
        drupal_set_message(t('The menu has been removed.'));
223 224
      }
      else {
225
        drupal_set_message(t('The menu item has been removed.'));
226
      }
Dries's avatar
 
Dries committed
227
      drupal_goto('admin/menu');
228 229
      break;
    default:
230
      if ($menu->type & MENU_IS_ROOT) {
231
        $message = t('Are you sure you want to delete the menu %item?', array('%item' => theme('placeholder', $menu->title)));
232 233
      }
      else {
234
        $message = t('Are you sure you want to delete the custom menu item %item?', array('%item' => theme('placeholder', $menu->title)));
235
      }
236
      return confirm_form('menu_confirm_delete', $form, $message, 'admin/menu', t('This action cannot be undone.'), t('Delete'));
237 238 239 240
  }
}

/**
241
 * Menu callback; hide a menu item.
242 243
 */
function menu_disable_item($mid) {
Dries's avatar
 
Dries committed
244 245 246 247
  $menu = menu_get_menu();
  $type = $menu['items'][$mid]['type'];
  $type &= ~MENU_VISIBLE_IN_TREE;
  $type &= ~MENU_VISIBLE_IN_BREADCRUMB;
Dries's avatar
 
Dries committed
248
  $type |= MENU_MODIFIED_BY_ADMIN;
Dries's avatar
 
Dries committed
249
  db_query('UPDATE {menu} SET type = %d WHERE mid = %d', $type, $mid);
250
  drupal_set_message(t('The menu item has been disabled.'));
Dries's avatar
 
Dries committed
251
  drupal_goto('admin/menu');
252 253 254
}

/**
255
 * Menu callback; dispatch to the appropriate menu item edit function.
256
 */
Dries's avatar
Dries committed
257
function menu_edit_item($mid = 0) {
258 259
  $op = $_POST['op'];
  $edit = $_POST['edit'];
Dries's avatar
 
Dries committed
260

261 262 263 264
  $output = '';

  switch ($op) {
    case t('Submit'):
Dries's avatar
 
Dries committed
265 266 267 268 269
      menu_edit_item_validate($edit);
      if (!form_get_errors()) {
        menu_edit_item_save($edit);
        drupal_goto('admin/menu');
      }
270 271
      $output .= menu_edit_item_form($edit);
      break;
272 273 274 275 276 277 278 279
    default:
      if ($mid > 0) {
        $item = db_fetch_object(db_query('SELECT * FROM {menu} WHERE mid = %d', $mid));

        $edit['mid'] = $item->mid;
        $edit['pid'] = $item->pid;
        $edit['path'] = $item->path;
        $edit['title'] = $item->title;
Dries's avatar
 
Dries committed
280
        $edit['description'] = $item->description;
281
        $edit['weight'] = $item->weight;
Dries's avatar
 
Dries committed
282
        $edit['type'] = $item->type;
283 284 285 286
      }
      else {
        $edit['mid'] = 0; // In case a negative ID was passed in.
        $edit['pid'] = 1; // default to "Navigation" menu.
Dries's avatar
 
Dries committed
287
        $edit['type'] = MENU_CUSTOM_ITEM;
288 289 290 291
      }
      $output .= menu_edit_item_form($edit);
  }

Dries's avatar
 
Dries committed
292
  return $output;
293 294 295 296 297 298 299 300
}

/**
 * Present the menu item editing form.
 */
function menu_edit_item_form($edit) {
  $menu = menu_get_menu();

301
  $form['title'] = array(type => 'textfield', title => t('Title'), default_value => $edit['title'], size => 60, maxlength => 128, description => t('The name of the menu.'), required => TRUE);
302 303 304

  if ($edit['pid'] == 0) {
    // Display a limited set of fields for menus (not items).
305 306 307
    $form['path'] = array(type => 'hidden', value => '');
    $form['pid'] = array(type => 'hidden', value => 0);
    $form['weight'] = array(type => 'hidden', value => 0);
308 309
  }
  else {
310
    $form['description'] = array(type => textfield, title => t('Description'), default_value => $edit['description'], size => 60, maxlength => 128, description => t('The description displayed when hovering over a menu item.'));
Dries's avatar
 
Dries committed
311

Dries's avatar
 
Dries committed
312
    $path_description = t('The Drupal path this menu item links to.');
Dries's avatar
 
Dries committed
313
    if (isset($edit['path']) && array_key_exists($edit['path'], $menu['path index']) && $menu['path index'][$edit['path']] != $edit['mid']) {
Dries's avatar
 
Dries committed
314 315 316 317 318
      $old_mid = $menu['path index'][$edit['path']];
      $old_item = $menu['items'][$old_mid];
      $path_description .= "\n". t('Since a menu item "%old" already exists for "%path", this menu item is shortcut to that location.', array('%old' => l($old_item['title'], 'admin/menu/item/edit/'. $old_mid), '%path' => $edit['path']));
    }

Dries's avatar
 
Dries committed
319
    if ($edit['type'] & MENU_CREATED_BY_ADMIN) {
320
      $form['path'] = array(type => 'textfield', title => t('Path'), default_value => $edit['path'], size => 60, maxlength => 128, description => $path_description, required => TRUE);
321 322
    }
    else {
323 324
      $form['_path'] = array(type => 'item', title => t('Path'), title => l($edit['path'], $edit['path']));
      $form['path'] = array(type => 'hidden', value => $edit['path']);
325
    }
326 327
    $expanded = $edit['type'] & MENU_EXPANDED ? 1 : 0;
    $form['expanded'] = array(type => 'checkbox', title => t('Expanded'), default_value => $expanded, description => t('If selected and this menu item has children, the menu will always appear expanded.'));
Dries's avatar
 
Dries committed
328

329 330
    // Generate a list of possible parents (not including this item or descendants).
    $options = menu_parent_options($edit['mid']);
331
    $form['pid'] = array(type => 'select', title => t('Parent item'), default_value =>  $edit['pid'], options => $options);
332

333
    $form['weight'] = array(type => 'weight', title => t('Weight'), default_value => $edit['weight'], delta => 10, description => t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'));
334 335
  }

336
  $form['submit'] = array(type => 'submit', value => t('Submit'));
337

338
  $form['mid'] = array(type => 'hidden', value => $edit['mid']);
Dries's avatar
 
Dries committed
339 340 341 342 343 344

  // Always enable menu items (but not menus) when editing them.
  if (!($edit['type'] & MENU_IS_ROOT)) {
    $edit['type'] |= MENU_VISIBLE_IN_TREE | MENU_VISIBLE_IN_BREADCRUMB;
  }

345
  $form['type'] = array(type => 'hidden', value => $edit['type']);
346

347
  return drupal_get_form('menu_edit_item_form', $form);
348 349
}

Dries's avatar
 
Dries committed
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
/**
 * Confirm that an edited menu item has fields properly filled in.
 */
function menu_edit_item_validate($edit) {
  if (empty($edit['title'])) {
    form_set_error('title', t('You must specify a title.'));
  }

  if ($edit['pid'] != 0) {
    if (empty($edit['path'])) {
      form_set_error('path', t('You must specify a path.'));
    }
  }
}

365 366 367 368
/**
 * Save changes to a menu item into the database.
 */
function menu_edit_item_save($edit) {
Dries's avatar
 
Dries committed
369 370
  $menu = menu_get_menu();

Dries's avatar
 
Dries committed
371 372 373 374 375 376 377
  if ($edit['expanded']) {
    $edit['type'] |= MENU_EXPANDED;
  }
  else {
    $edit['type'] &= ~MENU_EXPANDED;
  }

378
  if ($edit['mid']) {
Dries's avatar
 
Dries committed
379
    db_query("UPDATE {menu} SET pid = %d, path = '%s', title = '%s', description = '%s', weight = %d, type = %d WHERE mid = %d", $edit['pid'], $edit['path'], $edit['title'], $edit['description'], $edit['weight'], $edit['type'] | MENU_MODIFIED_BY_ADMIN, $edit['mid']);
380
    drupal_set_message(t('The menu item %title has been updated.', array('%title' => theme('placeholder', $edit['title']))));
381 382
  }
  else {
Dries's avatar
 
Dries committed
383
    $mid = db_next_id('{menu}_mid');
Dries's avatar
 
Dries committed
384
    db_query("INSERT INTO {menu} (mid, pid, path, title, description, weight, type) VALUES (%d, %d, '%s', '%s', '%s', %d, %d)", $mid, $edit['pid'], $edit['path'], $edit['title'], $edit['description'], $edit['weight'], $edit['type'] | MENU_MODIFIED_BY_ADMIN);
385
    drupal_set_message(t('The menu item %title has been created.', array('%title' => theme('placeholder', $edit['title']))));
Dries's avatar
 
Dries committed
386 387 388
    if (array_key_exists($edit['path'], $menu['path index'])) {
      $old_mid = $menu['path index'][$edit['path']];
      $old_item = $menu['items'][$old_mid];
389
      drupal_set_message(t('Since a menu item %old already exists for %path, this new menu item was created as a shortcut to that location.', array('%old' => l(theme('placeholder', $old_item['title']), 'admin/menu/item/edit/'. $old_mid, array(), NULL, NULL, FALSE, TRUE), '%path' => theme('placeholder', $edit['path']))));
Dries's avatar
 
Dries committed
390
    }
391 392 393 394 395 396 397 398
  }
}

/**
 * Present the menu tree, rendered along with links to edit menu items.
 */
function menu_overview_tree() {
  $menu = menu_get_menu();
Dries's avatar
 
Dries committed
399
  $header = array(t('Menu item'), t('Expanded'), array('data' => t('Operations'), 'colspan' => '3'));
400 401 402 403
  $output = '';

  foreach ($menu['items'][0]['children'] as $mid) {
    $operations = array();
Dries's avatar
 
Dries committed
404
    if ($menu['items'][$mid]['type'] & MENU_MODIFIABLE_BY_ADMIN) {
405 406
      $operations[] = l(t('edit'), 'admin/menu/item/edit/'. $mid);
    }
Dries's avatar
 
Dries committed
407
    if ($menu['items'][$mid]['type'] & MENU_CREATED_BY_ADMIN) {
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
      $operations[] = l(t('delete'), 'admin/menu/item/delete/'. $mid);
    }
    $table = theme('item_list', $operations);
    $table .= theme('table', $header, menu_overview_tree_rows($mid));
    $output .= theme('box', $menu['items'][$mid]['title'], $table);
  }
  return $output;
}

function menu_overview_tree_rows($pid = 0, $depth = 0) {
  $menu = menu_get_menu();

  $rows = array();

  if (isset($menu['items'][$pid]) && $menu['items'][$pid]['children']) {

    usort($menu['items'][$pid]['children'], '_menu_sort');
    foreach ($menu['items'][$pid]['children'] as $mid) {
      // Populate the title field.
      $title = '';
      if ($pid == 0) {
        // Top-level items are menu names, and don't have an associated path.
430
        $title .= $menu['items'][$mid]['title'];
431 432
      }
      else {
433
        $title .= l($menu['items'][$mid]['title'], $menu['items'][$mid]['path']);
434 435 436 437 438 439 440 441 442 443
      }
      if ($depth > 0) {
        $title = '-&nbsp;'. $title;
      }
      for ($i = 1; $i < $depth; $i++) {
        $title = '&nbsp;&nbsp;'. $title;
      }

      // Populate the operations field.
      $operations = array();
Dries's avatar
 
Dries committed
444
      if (!($menu['items'][$mid]['type'] & MENU_MODIFIABLE_BY_ADMIN)) {
Dries's avatar
 
Dries committed
445
        $operations[] = array('data' => t('locked'), 'colspan' => '3', 'align' => 'center');
446 447
      }
      else {
Dries's avatar
 
Dries committed
448
        if ($menu['items'][$mid]['type'] & MENU_VISIBLE_IN_TREE) {
449
          $operations[] = array('data' => l(t('edit'), 'admin/menu/item/edit/'. $mid));
Dries's avatar
 
Dries committed
450
          if ($menu['items'][$mid]['type'] & MENU_IS_ROOT) {
451 452 453 454 455 456 457
            // Disabling entire menus is done from block admin page.
            $operations[] = array('data' => '');
          }
          else {
            $operations[] = array('data' => l(t('disable'), 'admin/menu/item/disable/'. $mid));
          }
        }
Dries's avatar
 
Dries committed
458 459 460
        else {
          $operations[] = array('data' => '');
          $operations[] = array('data' => l(t('enable'), 'admin/menu/item/edit/'. $mid));
461
        }
Dries's avatar
 
Dries committed
462 463

        if ($menu['items'][$mid]['type'] & MENU_CREATED_BY_ADMIN) {
464 465
          $operations[] = array('data' => l(t('delete'), 'admin/menu/item/delete/'. $mid));
        }
Dries's avatar
 
Dries committed
466 467 468
        else if ($menu['items'][$mid]['type'] & MENU_MODIFIED_BY_ADMIN) {
          $operations[] = array('data' => l(t('reset'), 'admin/menu/item/reset/'. $mid));
        }
469 470 471 472 473 474
        else {
          $operations[] = array('data' => '');
        }
      }

      // Call out disabled items.
Dries's avatar
 
Dries committed
475 476
      if ($menu['items'][$mid]['type'] & MENU_VISIBLE_IN_TREE) {
        $class = 'menu-enabled';
477 478
      }
      else {
Dries's avatar
 
Dries committed
479 480
        $title .= ' ('. t('disabled') .')';
        $class = 'menu-disabled';
481 482
      }

Dries's avatar
 
Dries committed
483
      if ($menu['items'][$mid]['type'] & (MENU_MODIFIABLE_BY_ADMIN | MENU_VISIBLE_IN_TREE)) {
Dries's avatar
 
Dries committed
484
        $row = array(array('data' => $title, 'class' => $class), array('data' => ($menu['items'][$mid]['children'] ? (($menu['items'][$mid]['type'] & MENU_EXPANDED) ? t('Yes') : t('No')) : ''), 'class' => $class));
485 486 487 488 489 490 491
        foreach ($operations as $operation) {
          $operation['class'] = $class;
          $row[] = $operation;
        }
        $rows[] = $row;
        $rows = array_merge($rows, menu_overview_tree_rows($mid, $depth + 1));
      }
Dries's avatar
 
Dries committed
492 493 494 495
      else {
        // Skip items that are hidden and locked; admins will never care about them.
        $rows = array_merge($rows, menu_overview_tree_rows($mid, $depth));
      }
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
    }

  }

  return $rows;
}

/**
 * Return a list of menu items that are valid possible parents for the
 * given menu item.
 */
function menu_parent_options($mid, $pid = 0, $depth = 0) {
  $menu = menu_get_menu();

  $options = array();

  if (isset($menu['items'][$pid]) && $menu['items'][$pid]['children']) {
    usort($menu['items'][$pid]['children'], '_menu_sort');
    foreach ($menu['items'][$pid]['children'] as $child) {
      if ($child != $mid) {
Dries's avatar
 
Dries committed
516
        if ($child > 0 && ($menu['items'][$child]['type'] & (MENU_MODIFIABLE_BY_ADMIN | MENU_IS_ROOT))) {
517 518 519 520
          $title = ' '. $menu['items'][$child]['title'];
          for ($i = 0; $i < $depth; $i++) {
            $title = '--'. $title;
          }
Dries's avatar
 
Dries committed
521
          if (!($menu['items'][$child]['type'] & MENU_VISIBLE_IN_TREE)) {
522 523 524 525 526 527 528 529 530 531 532 533
            $title .= ' ('. t('disabled') .')';
          }
          $options[$child] = $title;
        }
        $options += menu_parent_options($mid, $child, $depth + 1);
      }
    }
  }

  return $options;
}

534 535 536 537 538 539 540 541
/**
 * Add menu item fields to the node form.
 */
function menu_node_form($edit = array()) {
  $item = array();
  if ($edit['nid'] > 0) {
    $item = db_fetch_array(db_query("SELECT * FROM {menu} WHERE path = 'node/%d'", $edit['nid']));
    if (is_array($edit['menu'])) {
542
      $item = !is_array($item) ? $edit['menu'] : (($_POST['op'] == t('Preview')) ? array_merge($item, $edit['menu']) : array_merge($edit['menu'], $item));
543 544 545
    }
  }

546 547 548 549
  $form['menu'] = array(type => 'fieldset', title => t('Menu item settings'), collapsible => TRUE, collapsed => TRUE, tree => TRUE);

  $form['menu']['title'] = array(type => 'textfield', title => t('Title'), default_value => $item['title'], size => 60, maxlength => 128, description => t('The name to display for this link.'));

550 551
  // Generate a list of possible parents (not including this item or descendants).
  $options = menu_parent_options($edit['mid']);
552 553 554 555 556 557 558
  $form['menu']['pid'] = array(type => select, title => t('Parent item'), default_value => $item['pid'], options => $options);
  $form['menu']['description'] = array(type => 'hidden', value => $item['description']);
  $form['menu']['path'] = array(type => 'hidden', value => $item['path']);
  $form['menu']['weight'] = array(type => 'hidden', value => $item['weight'] ? $item['weight'] : 0);

  $form['menu']['mid'] = array(type => 'hidden', value => $item['mid'] ? $item['mid'] : 0);
  $form['menu']['type'] = array(type => 'hidden', value => $item['type'] ? $item['type'] : MENU_CUSTOM_ITEM);
559 560

  if ($item['mid'] > 0) {
561
    $form['menu']['delete'] = array(type => 'checkbox', title => t('Check to delete this menu item.'), default_value => $item['delete']);
562 563 564 565 566 567 568 569 570
  }

  return $form;
}

/**
 * Remove the menu item.
 */
function menu_node_form_delete($node) {
571
  db_query("DELETE FROM {menu} WHERE path = 'node/%s'", $node->nid);
572
}
573