Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.80 diff -u -F^f -r1.80 menu.inc --- includes/menu.inc 24 Apr 2005 16:34:32 -0000 1.80 +++ includes/menu.inc 3 May 2005 14:57:36 -0000 @@ -82,6 +82,8 @@ define('MENU_IS_LOCAL_TASK', 0x0080); define('MENU_EXPANDED', 0x0100); define('MENU_LINKS_TO_PARENT', 0x0200); +define('MENU_MODIFIED_BY_MODULE', 0x0400); +define('MENU_CREATED_BY_MODULE', 0x0800); /** * @} End of "Menu flags". @@ -152,6 +154,21 @@ define('MENU_CUSTOM_MENU', MENU_IS_ROOT | MENU_VISIBLE_IN_TREE | MENU_CREATED_BY_ADMIN | MENU_MODIFIABLE_BY_ADMIN); /** + * Module menus are similar to custom menus but are defined by modules. Reserved for + * modules that create menus automatically for the node types they support. An example + * would be the book.module automatically creating a menu for each book in a site. + * Do not return from hook_menu() implementations. + */ +define('MENU_MODULE_MENU', MENU_IS_ROOT | MENU_VISIBLE_IN_TREE | MENU_CREATED_BY_MODULE); + +/** + * Module items are similar to custom items but are defined by modules. Module items are + * children of module menus. Reserved for modules that create menus automatically for the + * node types they support. Do not return from hook_menu() implementations. + */ +define('MENU_MODULE_ITEM', MENU_VISIBLE_IN_TREE | MENU_VISIBLE_IN_BREADCRUMB | MENU_CREATED_BY_MODULE); + +/** * @} End of "Menu item types". */ @@ -571,8 +588,8 @@ function menu_tree($pid = 1) { if (isset($menu['visible'][$pid]) && $menu['visible'][$pid]['children']) { foreach ($menu['visible'][$pid]['children'] as $mid) { $output .= theme('menu_item', $mid, menu_in_active_trail($mid) || ($menu['visible'][$mid]['type'] & MENU_EXPANDED) ? theme('menu_tree', $mid) : '', count($menu['visible'][$mid]['children']) == 0); + } } - } return $output; } @@ -813,7 +830,7 @@ function _menu_build() { } else { // The path was not declared, so this is a custom item or an orphaned one. - if ($item->type & MENU_CREATED_BY_ADMIN) { + if ($item->type & MENU_CREATED_BY_ADMIN || $item->type & MENU_CREATED_BY_MODULE) { $_menu['items'][$item->mid] = array('path' => $item->path, 'access' => TRUE, 'callback' => ''); if (!empty($item->path)) { $_menu['path index'][$item->path] = $item->mid; @@ -822,7 +839,7 @@ function _menu_build() { } // If the administrator has changed the item, reflect the change. - if ($item->type & MENU_MODIFIED_BY_ADMIN) { + if ($item->type & MENU_MODIFIED_BY_ADMIN || $item->type & MENU_MODIFIED_BY_MODULE) { $_menu['items'][$item->mid]['title'] = $item->title; $_menu['items'][$item->mid]['description'] = $item->description; $_menu['items'][$item->mid]['pid'] = $item->pid; cvs diff: Diffing misc cvs diff: Diffing modules Index: modules/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book.module,v retrieving revision 1.294 diff -u -F^f -r1.294 book.module --- modules/book.module 30 Apr 2005 21:34:41 -0000 1.294 +++ modules/book.module 4 May 2005 15:40:31 -0000 @@ -122,42 +122,6 @@ function book_menu($may_cache) { } /** - * Implementation of hook_block(). - * - * Displays the book table of contents in a block when the current page is a - * single-node view of a book node. - */ -function book_block($op = 'list', $delta = 0) { - $block = array(); - if ($op == 'list') { - $block[0]['info'] = t('Book navigation'); - return $block; - } - else if ($op == 'view') { - // Only display this block when the user is browsing a book: - if (arg(0) == 'node' && is_numeric(arg(1))) { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d'), arg(1)); - if (db_num_rows($result) > 0) { - $node = db_fetch_object($result); - - $path = book_location($node); - $path[] = $node; - - $expand = array(); - foreach ($path as $key => $node) { - $expand[] = $node->nid; - } - - $block['subject'] = check_plain($path[0]->title); - $block['content'] = book_tree($expand[0], 5, $expand); - } - } - - return $block; - } -} - -/** * Implementation of hook_load(). */ function book_load($node) { @@ -186,6 +150,7 @@ function book_load($node) { */ function book_insert($node) { db_query("INSERT INTO {book} (nid, parent, weight, log) VALUES (%d, %d, %d, '%s')", $node->nid, $node->parent, $node->weight, $node->log); + book_build_menu_module_menu(); } /** @@ -193,6 +158,7 @@ function book_insert($node) { */ function book_update($node) { db_query("UPDATE {book} SET parent = %d, weight = %d, log = '%s' WHERE nid = %d", $node->parent, $node->weight, $node->log, $node->nid); + book_build_menu_module_menu(); } /** @@ -200,6 +166,7 @@ function book_update($node) { */ function book_delete(&$node) { db_query('DELETE FROM {book} WHERE nid = %d', $node->nid); + book_build_menu_module_menu(); } /** @@ -257,18 +224,21 @@ function book_outline() { switch ($op) { case t('Add to book outline'): db_query('INSERT INTO {book} (nid, parent, weight) VALUES (%d, %d, %d)', $node->nid, $edit['parent'], $edit['weight']); + book_build_menu_module_menu(); drupal_set_message(t('Added the post to the book.')); drupal_goto("node/$node->nid"); break; case t('Update book outline'): db_query('UPDATE {book} SET parent = %d, weight = %d WHERE nid = %d', $edit['parent'], $edit['weight'], $node->nid); + book_build_menu_module_menu(); drupal_set_message(t('Updated the book outline.')); drupal_goto("node/$node->nid"); break; case t('Remove from book outline'): db_query('DELETE FROM {book} WHERE nid = %d', $node->nid); + book_build_menu_module_menu(); drupal_set_message(t('Removed the post from the book.')); drupal_goto("node/$node->nid"); break; @@ -731,12 +701,14 @@ function book_admin_save($nid, $edit = a $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid)); if ($title != $value['title']) { db_query("UPDATE {node} SET title = '%s' WHERE nid = %d", $value['title'], $nid); + book_build_menu_module_menu(); } // Check to see whether the weight needs updating: $weight = db_result(db_query('SELECT weight FROM {book} WHERE nid = %d', $nid)); if ($weight != $value['weight']) { db_query('UPDATE {book} SET weight = %d WHERE nid = %d', $value['weight'], $nid); + book_build_menu_module_menu(); } } @@ -822,4 +794,72 @@ function book_help($section) { } } +/** +* Create menus for books in the menu system and update their associated blocks +*/ +function book_build_menu_module_menu() { + //remember menu_module_menu block settings + $results = db_query('SELECT m.path, b.status, b.weight, b.region, b.throttle, b.visibility, b.pages, b.custom FROM {menu} m INNER JOIN {blocks} b ON m.mid = b.delta WHERE m.type = %d', MENU_MODULE_MENU | MENU_MODIFIED_BY_MODULE); + while ($result = db_fetch_object($results)) { + $menu_block_settings[$result->path] = array('status' => $result->status, 'weight' => $result->weight, 'region' => $result->region, 'throttle' => $result->throttle, 'visibility' => $result->visibility, 'pages' => $result->pages, 'custom' => $result->custom); + } + //Remove existing module menus + db_query('DELETE FROM {menu} WHERE type = %d OR type = %d', MENU_MODULE_MENU | MENU_MODIFIED_BY_MODULE, MENU_MODULE_ITEM | MENU_MODIFIED_BY_MODULE); + //Get book hierarchies + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND n.moderate = 0 ORDER BY b.parent, b.weight, n.title')); + while ($node = db_fetch_object($result)) { + $list = $children[$node->parent] ? $children[$node->parent] : array(); + array_push($list, $node); + $children[$node->parent] = $list; + } + + //Build and execute insert of new module menu - rebuild menu system array - rehash blocks - restore block settings + if ($tree = book_menu_tree_recurse(0, $children, 0, 0, MENU_MODULE_MENU | MENU_MODIFIED_BY_MODULE, MENU_MODULE_ITEM | MENU_MODIFIED_BY_MODULE)) { + $q = rtrim($tree, ', '); + db_query('INSERT INTO {menu} (mid, pid, path, title, weight, type) VALUES ' . $q); + menu_rebuild(); + _block_rehash(); + //restore menu_module_menu block settings + if ($menu_block_settings) { + $result = db_query('SELECT m.path, b.delta FROM {menu} m INNER JOIN {blocks} b ON m.mid = b.delta WHERE m.type = %d', MENU_MODULE_MENU | MENU_MODIFIED_BY_MODULE); + while ($menu_block = db_fetch_object($result)) { + if (array_key_exists($menu_block->path, $menu_block_settings)) { + db_query("UPDATE {blocks} SET status = %d, weight = %d, region = %d, throttle = %d, visibility = %d, pages = '%s', custom = '%s' WHERE delta = %d", + $menu_block_settings[$menu_block->path]['status'], $menu_block_settings[$menu_block->path]['weight'], $menu_block_settings[$menu_block->path]['region'], $menu_block_settings[$menu_block->path]['throttle'], $menu_block_settings[$menu_block->path]['visibility'], $menu_block_settings[$menu_block->path]['pages'], $menu_block_settings[$menu_block->path]['custom'], $menu_block->delta); + } + } + } + } +} + +/** +* Recursively traverse books' hiearchies and return SQL insert parameters +*/ +function book_menu_tree_recurse($pid, $children, $pmid, $mid, $menu, $item) { + + if ($children[$pid]) { + foreach ($children[$pid] as $foo => $node) { + $node->mid = db_next_id('{menu}_mid'); + $node->pmid = $pmid; + if ($output .= book_menu_tree_recurse($node->nid, $children, $node->mid, db_next_id('{menu}_mid'), $menu, $item)) { + if ($pmid==0) { + $output .= "($node->mid, $node->pmid, 'node/$node->nid', '". addslashes($node->title) ."', $node->weight, $menu), "; + } + else { + $output .= "($node->mid, $node->pmid, 'node/$node->nid', '". addslashes($node->title) ."', $node->weight, $item), "; + } + } + else { + if ($pid==0) { + $output .= "($node->mid, $node->pmid, 'node/$node->nid', '". addslashes($node->title) ."', $node->weight, $menu), "; + } + else { + $output .= "($node->mid, $node->pmid, 'node/$node->nid', '". addslashes($node->title) ."', $node->weight, $item), "; + } + } + } + } + +return $output; +} ?> Index: modules/menu.module =================================================================== RCS file: /cvs/drupal/drupal/modules/menu.module,v retrieving revision 1.30 diff -u -F^f -r1.30 menu.module --- modules/menu.module 24 Apr 2005 16:34:34 -0000 1.30 +++ modules/menu.module 3 May 2005 19:44:42 -0000 @@ -114,7 +114,7 @@ function menu_reset() { $op = $_POST['op']; switch ($op) { case t('Reset all'): - db_query('DELETE FROM {menu}'); + db_query('DELETE FROM {menu} WHERE type < %d', MENU_MODULE_MENU | MENU_MODIFIED_BY_MODULE); drupal_set_message(t('All menu items reset.')); drupal_goto('admin/menu'); break; @@ -484,7 +484,7 @@ function menu_parent_options($mid, $pid usort($menu['items'][$pid]['children'], '_menu_sort'); foreach ($menu['items'][$pid]['children'] as $child) { if ($child != $mid) { - if ($child > 0 && ($menu['items'][$child]['type'] & (MENU_MODIFIABLE_BY_ADMIN | MENU_IS_ROOT))) { + if ($child > 0 && ($menu['items'][$child]['type'] & (MENU_MODIFIABLE_BY_ADMIN | MENU_IS_ROOT)) && ($menu['items'][$child]['type'] != (MENU_MODULE_MENU | MENU_MODIFIED_BY_MODULE))) { $title = ' '. $menu['items'][$child]['title']; for ($i = 0; $i < $depth; $i++) { $title = '--'. $title; cvs diff: Diffing scripts cvs diff: Diffing sites cvs diff: Diffing sites/default cvs diff: Diffing themes cvs diff: Diffing themes/bluemarine cvs diff: Diffing themes/chameleon cvs diff: Diffing themes/chameleon/marvin cvs diff: Diffing themes/engines cvs diff: Diffing themes/engines/xtemplate cvs diff: Diffing themes/pushbutton ***** CVS exited normally with code 1 *****