Index: modules/menu/menu.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v retrieving revision 1.4 diff -u -r1.4 menu.admin.inc --- modules/menu/menu.admin.inc 21 Oct 2007 18:59:02 -0000 1.4 +++ modules/menu/menu.admin.inc 24 Oct 2007 19:03:13 -0000 @@ -21,11 +21,10 @@ } /** - * Shows for one menu the menu items accessible to the current user and relevant operations. + * Form for editing an entire menu tree at once. Shows for one menu the menu + * items accessible to the current user and relevant operations. */ -function menu_overview($menu) { - - $header = array(t('Menu item'), t('Expanded'), array('data' => t('Operations'), 'colspan' => '3')); +function menu_overview_form(&$form_state, $menu) { $sql =" SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, ml.* FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path @@ -37,63 +36,130 @@ $node_links = array(); menu_tree_collect_node_links($tree, $node_links); menu_tree_check_access($tree, $node_links); - $rows = _menu_overview_tree($tree); - $output = theme('table', $header, $rows); - $output .= theme('pager', NULL, 200, 0); - return $output; + + $form = _menu_overview_tree_form($form_state, $tree); + return $form; } /** - * Recursive helper function for menu_overview(). + * Recursive helper function for menu_overview_form(). */ -function _menu_overview_tree($tree) { - static $rows = array(); +function _menu_overview_tree_form(&$form_state, $tree) { + static $form = array('#tree' => TRUE); foreach ($tree as $data) { $title = ''; $item = $data['link']; // Don't show callbacks; these have $item['hidden'] < 0. if ($item && $item['hidden'] >= 0) { - $title = str_repeat('  ', $item['depth'] - 1) . ($item['depth'] > 1 ? '- ' : ''); - $title .= l($item['title'], $item['href'], $item['options']); - // Populate the operations field. + $mlid = $item['mlid']; + $form[$mlid] = array(); + $form[$mlid]['title'] = array( + '#value' => l($item['title'], $item['href'], $item['options']), + ); + $form[$mlid]['expanded'] = array( + '#value' => $item['has_children'] ? (($item['expanded']) ? t('Yes') : t('No')) : '', + ); + $form[$mlid]['weight'] = array( + '#type' => 'weight', + '#default_value' => isset($form_state[$mlid]['weight']) ? $form_state[$mlid]['weight'] : $item['weight'], + ); + $form[$mlid]['depth'] = array( + '#type' => 'hidden', + '#value' => $item['depth'], + ); + $form[$mlid]['mlid'] = array( + '#type' => 'hidden', + '#value' => $item['mlid'], + ); + $form[$mlid]['plid'] = array( + '#type' => 'textfield', + '#default_value' => isset($form_state[$mlid]['plid']) ? $form_state[$mlid]['plid'] : $item['plid'], + '#size' => 6, + ); + + // Build a list of operations. $operations = array(); - // Set the edit column. - $operations[] = array('data' => l(t('edit'), 'admin/build/menu/item/'. $item['mlid'] .'/edit')); + $operations['edit'] = l(t('edit'), 'admin/build/menu/item/'. $item['mlid'] .'/edit'); if ($item['hidden']) { - $title .= ' ('. t('disabled') .')'; - $class = 'menu-disabled'; - $operations[] = array('data' => l(t('enable'), 'admin/build/menu/item/'. $item['mlid'] .'/enable')); + $form[$mlid]['title']['#value'] .= ' ('. t('disabled') .')'; + $form[$mlid]['#attributes']['class'] = 'menu-disabled'; + $operations['enable'] = l(t('enable'), 'admin/build/menu/item/'. $item['mlid'] .'/enable'); } else { - $class = 'menu-enabled'; - $operations[] = array('data' => l(t('disable'), 'admin/build/menu/item/'. $item['mlid'] .'/disable')); + $form[$mlid]['#attributes']['class'] = 'menu-enabled'; + $operations['disable'] = l(t('disable'), 'admin/build/menu/item/'. $item['mlid'] .'/disable'); } // Only items created by the menu module can be deleted. if ($item['module'] == 'menu') { - $operations[] = array('data' => l(t('delete'), 'admin/build/menu/item/'. $item['mlid'] .'/delete')); + $operations['delete'] = l(t('delete'), 'admin/build/menu/item/'. $item['mlid'] .'/delete'); } // Set the reset column. elseif ($item['module'] == 'system' && $item['customized']) { - $operations[] = array('data' => l(t('reset'), 'admin/build/menu/item/'. $item['mlid'] .'/reset')); - } - else { - $operations[] = array('data' => ''); + $operations['reset'] = l(t('reset'), 'admin/build/menu/item/'. $item['mlid'] .'/reset'); } - $row = array( - array('data' => $title, 'class' => $class), - array('data' => ($item['has_children'] ? (($item['expanded']) ? t('Yes') : t('No')) : ''), 'class' => $class), - ); - foreach ($operations as $operation) { - $operation['class'] = $class; - $row[] = $operation; + + $form[$mlid]['operations'] = array(); + foreach ($operations as $op => $value) { + $form[$mlid]['operations'][$op] = array('#value' => $value); } - $rows[] = $row; } + if ($data['below']) { - _menu_overview_tree($data['below']); + _menu_overview_tree_form($form_state, $data['below']); + } + } + return $form; +} + +/** + * Theme the menu overview form into a sortable drag and drop table. + */ +function theme_menu_overview_form($form) { + $header = array(t('Menu item'), t('Expanded'), t('Parent'), t('Weight'), array('data' => t('Operations'), 'colspan' => '3')); + $rows = array(); + foreach (element_children($form) as $mlid) { + if (isset($form[$mlid]['mlid'])) { + $plid = $form[$mlid]['plid']['#value']; + + // Add the draggable table javascript. + drupal_add_tabledrag('menu-overview', 'menu-plid', 'match', 'parent', 'menu-plid-'. $plid, 'menu-mlid-'. $plid, TRUE); + drupal_add_tabledrag('menu-overview', 'menu-weight', 'order', 'sibling', 'menu-weight-'. $plid, NULL, TRUE); + + // Build a list of operations. + $operations = array(); + foreach (element_children($form[$mlid]['operations']) as $op) { + $operations[] = drupal_render($form[$mlid]['operations'][$op]); + } + while (count($operations) <= 3) { + $operations[] = ''; + } + + // Add special classes to be used for tabledrag.js. + $form[$mlid]['plid']['#attributes']['class'] = 'menu-plid menu-plid-'. $plid; + $form[$mlid]['mlid']['#attributes']['class'] = 'menu-mlid menu-mlid-'. $plid; + $form[$mlid]['weight']['#attributes']['class'] = 'menu-weight menu-weight-'. $plid; + + // Make indentations. + $indentation = ''; + for ($n = 0; $n < $form[$mlid]['depth']['#value']; $n++) { + $indentation .= '
 
'; + } + + $row = array(); + $row[] = $indentation . drupal_render($form[$mlid]['depth']) . drupal_render($form[$mlid]['title']); + $row[] = drupal_render($form[$mlid]['expanded']); + $row[] = drupal_render($form[$mlid]['plid']) . drupal_render($form[$mlid]['mlid']); + $row[] = drupal_render($form[$mlid]['weight']); + $row = array_merge($row, $operations); + + foreach ($row as $n => $data) { + $row[$n] = array('data' => $data); + $row[$n] = array_merge($row[$n], $form[$mlid]['#attributes']); + } + $rows[] = array('data' => $row, 'class' => 'draggable'); } } - return $rows; + return theme('table', $header, $rows, array('id' => 'menu-overview')); } /** Index: modules/menu/menu.module =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v retrieving revision 1.146 diff -u -r1.146 menu.module --- modules/menu/menu.module 21 Oct 2007 18:59:02 -0000 1.146 +++ modules/menu/menu.module 24 Oct 2007 19:03:13 -0000 @@ -80,8 +80,8 @@ ); $items['admin/build/menu-customize/%menu'] = array( 'title' => 'Customize menu', - 'page callback' => 'menu_overview', - 'page arguments' => array(3), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('menu_overview_form', 3), 'title callback' => 'menu_overview_title', 'title arguments' => array(3), 'access arguments' => array('administer menu'), @@ -155,6 +155,18 @@ } /** + * Implemenation of hook_theme(). + */ +function menu_theme() { + return array( + 'menu_overview_form' => array( + 'file' => 'menu.admin.inc', + 'arguments' => array('form' => NULL), + ), + ); +} + +/** * Implementation of hook_enable() * * Add a link for each custom menu.