Index: database/database.4.0.mysql =================================================================== RCS file: /cvs/drupal/drupal/database/database.4.0.mysql,v retrieving revision 1.5 diff -u -p -r1.5 database.4.0.mysql --- database/database.4.0.mysql 29 May 2006 16:04:41 -0000 1.5 +++ database/database.4.0.mysql 7 Jun 2006 07:23:36 -0000 @@ -133,12 +133,26 @@ CREATE TABLE blocks ( -- CREATE TABLE book ( + bid INT( 10 ) UNSIGNED NOT NULL default '0' PRIMARY KEY , + uid INT( 10 ) UNSIGNED NOT NULL default '0' , + title VARCHAR(255) NOT NULL default '' , + weight TINYINT( 3 ) NOT NULL default '0', + KEY uid (uid) +); + +-- +-- Table structure for table 'book_pages' +-- + +CREATE TABLE book_pages ( vid int(10) unsigned NOT NULL default '0', nid int(10) unsigned NOT NULL default '0', + bid int(10) unsigned NOT NULL default '0', parent int(10) NOT NULL default '0', weight tinyint(3) NOT NULL default '0', PRIMARY KEY (vid), KEY nid (nid), + KEY bid (bid), KEY parent (parent) ); Index: database/database.4.1.mysql =================================================================== RCS file: /cvs/drupal/drupal/database/database.4.1.mysql,v retrieving revision 1.5 diff -u -p -r1.5 database.4.1.mysql --- database/database.4.1.mysql 29 May 2006 16:04:41 -0000 1.5 +++ database/database.4.1.mysql 7 Jun 2006 07:23:37 -0000 @@ -142,12 +142,27 @@ DEFAULT CHARACTER SET utf8; -- CREATE TABLE book ( + bid INT( 10 ) UNSIGNED NOT NULL default '0' PRIMARY KEY , + uid INT( 10 ) UNSIGNED NOT NULL default '0' , + title VARCHAR(255) NOT NULL default '' , + weight TINYINT( 3 ) NOT NULL default '0', + KEY uid (uid) +); +DEFAULT CHARACTER SET utf8; + +-- +-- Table structure for table 'book_pages' +-- + +CREATE TABLE book_pages ( vid int(10) unsigned NOT NULL default '0', nid int(10) unsigned NOT NULL default '0', + bid int(10) unsigned NOT NULL default '0', parent int(10) NOT NULL default '0', weight tinyint(3) NOT NULL default '0', PRIMARY KEY (vid), KEY nid (nid), + KEY bid (bid), KEY parent (parent) ) DEFAULT CHARACTER SET utf8; Index: database/database.pgsql =================================================================== RCS file: /cvs/drupal/drupal/database/database.pgsql,v retrieving revision 1.178 diff -u -p -r1.178 database.pgsql --- database/database.pgsql 29 May 2006 16:04:41 -0000 1.178 +++ database/database.pgsql 7 Jun 2006 07:23:38 -0000 @@ -137,14 +137,30 @@ CREATE TABLE blocks ( -- CREATE TABLE book ( + bid integer NOT NULL default '0', + uid integer NOT NULL default '0', + title varchar(255) NOT NULL default '', + weight smallint NOT NULL default '0' +); +CREATE INDEX book_bid_idx ON book(bid); +CREATE INDEX book_uid_idx ON book(uid); + + +-- +-- Table structure for book_pages +-- + +CREATE TABLE book_pages ( vid integer NOT NULL default '0', nid integer NOT NULL default '0', + bid integer NOT NULL default '0', parent integer NOT NULL default '0', weight smallint NOT NULL default '0', PRIMARY KEY (vid) ); -CREATE INDEX book_nid_idx ON book(nid); -CREATE INDEX book_parent_idx ON book(parent); +CREATE INDEX book_pages_nid_idx ON book_pages(nid); +CREATE INDEX book_pages_bid_idx ON book_pages(bid); +CREATE INDEX book_pages_parent_idx ON book_pages(parent); -- -- Table structure for boxes Index: database/updates.inc =================================================================== RCS file: /cvs/drupal/drupal/database/updates.inc,v retrieving revision 1.236 diff -u -p -r1.236 updates.inc --- database/updates.inc 6 Jun 2006 20:23:03 -0000 1.236 +++ database/updates.inc 7 Jun 2006 07:23:41 -0000 @@ -2071,3 +2071,81 @@ function system_update_185() { return $ret; } + +/** + * Update book table definitions. + */ +function system_update_186() { + $ret = array(); + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("ALTER TABLE `{book}` RENAME `{book_pages}`;"); + $ret[] = update_sql("CREATE TABLE `{book}` ( + `bid` INT( 10 ) UNSIGNED NOT NULL default '0' PRIMARY KEY , + `uid` INT( 10 ) UNSIGNED NOT NULL default '0' , + `title` VARCHAR(255) NOT NULL default '' , + `weight` TINYINT( 3 ) NOT NULL default '0', + KEY uid (uid) + ) TYPE = MYISAM"); + $ret[] = update_sql("ALTER TABLE `{book_pages}` ADD `bid` INT( 10 ) UNSIGNED NOT NULL AFTER `nid` ;"); + $ret[] = update_sql("ALTER TABLE `{book_pages}` ADD INDEX ( `bid` );"); + break; + case 'pgsql': + $ret[] = update_sql("ALTER TABLE {book} RENAME {book_pages};"); + $ret[] = update_sql("CREATE TABLE {book} ( + bid integer NOT NULL default '0' , + uid integer NOT NULL default '0' , + title varchar(255) NOT NULL default '' , + weight smallint NOT NULL default '0' + "); + $ret[] = update_sql("CREATE INDEX {book}_bid_idx ON {book}(bid);"); + $ret[] = update_sql("CREATE INDEX {book}_uid_idx ON {book}(uid);"); + db_add_column($ret, 'book_pages', 'bid', 'int', array('not null' => TRUE, 'default' => 0)); + $ret[] = update_sql("CREATE INDEX {book_pages}_bid_idx ON {book_pages}(bid);"); + break; + } + return $ret; +} + +/** + * Create books definition and update book pages with their respective $bid. + */ +function system_update_187() { + $ret = array(); + + // Function to recursively update $bid for each book page. + function update_bid ($parent, $bid, $i) { + $sql = "SELECT DISTINCT(nid) FROM {book_pages} WHERE parent = %d"; + $result[$i] = db_query($sql,$parent); + if (db_num_rows($result[$i]) > 0) { + while ($page = db_fetch_object($result[$i])) { + $sql = "UPDATE {book_pages} SET bid = %d WHERE nid = %d"; + $result[$i+1] = db_query($sql, $bid, $page->nid); + update_bid($page->nid, $bid, $i+2); + } + } + } + + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + case 'pgsql': + // Create the book 'covers' + $sql_books = "SELECT n.title, n.uid, n.vid, n.nid + FROM {book_pages} AS bp + JOIN {node} AS n ON bp.nid = n.nid AND bp.vid = n.vid + WHERE parent =0"; + $books = db_query($sql_books); + while ($row = db_fetch_object($books)) { + $bid = db_next_id('book_bid'); + $sql = 'INSERT INTO {book} (bid, uid, title) VALUES (%d, %d, "%s")'; + $result_a = db_query($sql, $bid, $row->uid, $row->title); + $sql = 'UPDATE {book_pages} SET bid = %d WHERE nid = %d'; + $result_b = db_query($sql, $bid, $row->nid); + update_bid ($row->nid, $bid, 1); + } + break; + } + return $ret; +} Index: modules/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book.module,v retrieving revision 1.368 diff -u -p -r1.368 book.module --- modules/book.module 5 Jun 2006 09:00:22 -0000 1.368 +++ modules/book.module 7 Jun 2006 07:23:43 -0000 @@ -107,9 +107,9 @@ function book_menu($may_cache) { $items[] = array( 'path' => 'book', 'title' => t('books'), - 'callback' => 'book_render', + 'callback' => 'book_shelf', 'access' => user_access('access content'), - 'type' => MENU_SUGGESTED_ITEM); + 'type' => MENU_NORMAL_ITEM); $items[] = array( 'path' => 'book/export', 'callback' => 'book_export', @@ -117,6 +117,36 @@ function book_menu($may_cache) { 'type' => MENU_CALLBACK); } else { + global $user; + $items[] = array( + 'path' => 'book/list', + 'title' => t('List'), + 'callback' => 'book_shelf', + 'access' => user_access('access content'), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => 0); + $items[] = array( + 'path' => 'book/addpage', + 'title' => t('New page'), + 'callback' => 'select_book', + 'access' => user_access('create book pages'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 2); + $items[] = array( + 'path' => 'book/addbook', + 'title' => t('New book'), + 'callback' => 'setup_book_cover', + 'access' => user_access('create new books'), + 'callback arguments' => array('create'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 1); + $items[] = array( + 'path' => 'node/'.arg(1).'/movetobook', + 'title' => t('Move to book'), + 'callback' => 'move_page_to_book', + 'access' => user_access('outline posts in books'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 8); // To avoid SQL overhead, check whether we are on a node page and whether the // user is allowed to outline posts in books. if (arg(0) == 'node' && is_numeric(arg(1)) && user_access('outline posts in books')) { @@ -132,9 +162,51 @@ function book_menu($may_cache) { 'type' => MENU_LOCAL_TASK, 'weight' => 2); } + } + elseif (arg(0) == 'book' && is_numeric(arg(1))) { + $result = db_query('SELECT uid, title FROM {book} WHERE bid = %d', arg(1)); + if ($book = db_fetch_object($result)) { + $items[] = array ( + 'path' => 'book/'. arg(1) , + 'title' => $book->title, + 'callback' => 'book_cover', + 'callback arguments' => array(arg(1)), + 'access' => user_access('access content'), + 'type' => MENU_CALLBACK); + $items[] = array ( + 'path' => 'book/'. arg(1) .'/addpage', + 'title' => t('Add page'), + 'callback' => 'book_addpage_redirect', + 'callback arguments' => array(arg(1)), + 'access' => user_access('create book pages'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 3); + $items[] = array ( + 'path' => 'book/'. arg(1) .'/view', + 'title' => t('View'), + 'callback' => 'book_cover', + 'callback arguments' => array(arg(1)), + 'access' => user_access('access content'), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => 0); + if ($user->uid == $book->uid || $user->uid == 1) { + $access = TRUE; + } + else { + $access = FALSE; + } + $items[] = array ( + 'path' => 'book/'. arg(1) . '/edit', + 'title' => t('Edit Book Cover'), + 'callback' => 'setup_book_cover', + 'callback arguments' => array('edit', arg(1)), + 'access' => $access, + 'type' => MENU_LOCAL_TASK, + 'weight' => 1); + } } } - + return $items; } @@ -152,8 +224,8 @@ function book_block($op = 'list', $delta } 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.vid = b.vid WHERE n.nid = %d'), arg(1)); + if ((arg(0) == 'node' || arg(0) == 'book') && is_numeric(arg(1))) { + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE n.nid = %d'), arg(1)); if (db_num_rows($result) > 0) { $node = db_fetch_object($result); @@ -178,14 +250,97 @@ function book_block($op = 'list', $delta * Implementation of hook_load(). */ function book_load($node) { - return db_fetch_object(db_query('SELECT * FROM {book} WHERE vid = %d', $node->vid)); + return db_fetch_object(db_query('SELECT * FROM {book_pages} WHERE vid = %d', $node->vid)); +} + +/** + * Menu call back: Select a book to move a page to. + */ +function move_page_to_book() { + $result = db_query('SELECT bid, title FROM {book} ORDER BY weight, title'); + $books = array(); + while ($book = db_fetch_object($result)) { + $books[$book->bid] = $book->title; + } + $nid = arg(1); + $bid = db_result(db_query('SELECT bid FROM {book_pages} WHERE nid = %d', $nid)); + $form = array(); + $form['bid'] = array( + '#type' => 'select', + '#title' => t('Select a book'), + '#default_value' => $bid, + '#options' => $books, + '#description' => t('Select the book you wish to move your page to.'), + ); + $form['children'] = array( + '#type' => 'checkbox', + '#title' => 'Move all the page\'s children to the other book, too', + '#default_value' => 1, + ); + $form['nid'] = array( + '#type' => 'value', + '#value' => $nid, + ); + $form[] = array( + '#value' => t('
Note: if you don\'t want to move the page\'s children, those will be attached to the current page\'s own parent.
'), + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Submit'), + ); + $output = drupal_get_form('move_page_to_book', $form); + return $output; +} + +/** + * Menu call back: Select a book to move a page to. + */ +function move_page_to_book_submit($form_id, $form) { + $result = db_query('UPDATE {book_pages} SET bid = %d, parent = 0 WHERE nid = %d', $form['bid'], $form['nid']); + if ($form['children']) { + book_update_children_bid($form['nid'], $form['bid']); + } + else { + $parent = db_result(db_query('SELECT parent FROM {book_pages} WHERE nid / %d', $form['nid'])); + $result = db_query('UPDATE {book_pages} SET parent = %d WHERE parent = %d', $parent, $form['nid']); + } + drupal_set_message(t('The page and its children have been relocated.Select the book you wish to add a page to.
'); + $output .= theme('item_list', $books); + return $output; +} + +/** * Implementation of hook_form(). */ function book_form(&$node) { + + // I am not sure what's the best way to retrieve bid. + // looking for url like node/add/book/bid + if (arg(2) == 'book') { + if (is_numeric(arg(3))) { + $node->bid = arg(3); + // check the book exists. + if (!$result = db_result(db_query('SELECT bid FROM {book} WHERE bid = %d', $node->bid))) { + drupal_goto('book/addpage'); + } + } + elseif (arg(3) != 'parent') { + // No bid: we print a list where the user can add a book page. + $form = array(); + drupal_goto('book/addpage'); + } + } + + $node->parent = $node->parent ? $node->parent : arg(4); + if (!$node->bid && $node->parent) { + $sql = "SELECT bid FROM {book_pages} where nid = %d"; + $result = db_query($sql, $node->parent); + $node->bid = db_result($result); + } + + if ($node->nid && !$node->parent && !user_access('create new books')) { $form['parent'] = array('#type' => 'value', '#value' => $node->parent); } @@ -232,12 +429,16 @@ function book_form(&$node) { $form['parent'] = array('#type' => 'select', '#title' => t('Parent'), '#default_value' => ($node->parent ? $node->parent : arg(4)), - '#options' => book_toc($node->nid), + '#options' => book_toc($node->nid, $node->bid), '#weight' => -4, - '#description' => user_access('create new books') ? t('The parent section in which to place this page. Note that each page whose parent is <top-level> is an independent, top-level book.') : t('The parent that this page belongs in.'), + '#description' => t('The parent that this page belongs in.'), ); } + $form['bid'] = array ('#type' => 'hidden', + '#value' => $node->bid, + ); + $form['title'] = array('#type' => 'textfield', '#title' => t('Title'), '#required' => TRUE, @@ -289,7 +490,7 @@ function book_outline($nid) { $form['parent'] = array('#type' => 'select', '#title' => t('Parent'), '#default_value' => $page->parent, - '#options' => book_toc($node->nid), + '#options' => book_toc($node->nid, $node->bid), '#description' => t('The parent page in the book.'), ); $form['weight'] = array('#type' => 'weight', @@ -330,17 +531,17 @@ function book_outline_submit($form_id, $ switch ($op) { case t('Add to book outline'): - db_query('INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)', $node->nid, $node->vid, $form_values['parent'], $form_values['weight']); + db_query('INSERT INTO {book_pages} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)', $node->nid, $node->vid, $form_values['parent'], $form_values['weight']); db_query("UPDATE {node_revisions} SET log = '%s' WHERE vid = %d", $form_values['log'], $node->vid); drupal_set_message(t('The post has been added to the book.')); break; case t('Update book outline'): - db_query('UPDATE {book} SET parent = %d, weight = %d WHERE vid = %d', $form_values['parent'], $form_values['weight'], $node->vid); + db_query('UPDATE {book_pages} SET parent = %d, weight = %d WHERE vid = %d', $form_values['parent'], $form_values['weight'], $node->vid); db_query("UPDATE {node_revisions} SET log = '%s' WHERE vid = %d", $form_values['log'], $node->vid); drupal_set_message(t('The book outline has been updated.')); break; case t('Remove from book outline'): - db_query('DELETE FROM {book} WHERE nid = %d', $node->nid); + db_query('DELETE FROM {book_pages} WHERE nid = %d', $node->nid); drupal_set_message(t('The post has been removed from the book.')); break; } @@ -360,7 +561,7 @@ function book_outline_submit($form_id, $ * */ function book_location($node, $nodes = array()) { - $parent = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d'), $node->parent)); + $parent = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE n.nid = %d'), $node->parent)); if ($parent->title) { $nodes = book_location($parent, $nodes); $nodes[] = $parent; @@ -372,7 +573,7 @@ function book_location($node, $nodes = a * Accumulates the nodes up to the root of the book from the given node in the $nodes array. */ function book_location_down($node, $nodes = array()) { - $last_direct_child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 AND b.parent = %d ORDER BY b.weight DESC, n.title DESC'), $node->nid)); + $last_direct_child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE n.status = 1 AND b.parent = %d ORDER BY b.weight DESC, n.title DESC'), $node->nid)); if ($last_direct_child) { $nodes[] = $last_direct_child; $nodes = book_location_down($last_direct_child, $nodes); @@ -385,12 +586,12 @@ function book_location_down($node, $node */ function book_prev($node) { // If the parent is zero, we are at the start of a book so there is no previous. - if ($node->parent == 0) { + if ($node->parent == 'aoeu0') { return NULL; } // Previous on the same level: - $direct_above = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight < %d OR (b.weight = %d AND n.title < '%s')) ORDER BY b.weight DESC, n.title DESC"), $node->parent, $node->weight, $node->weight, $node->title)); + $direct_above = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight < %d OR (b.weight = %d AND n.title < '%s')) ORDER BY b.weight DESC, n.title DESC"), $node->parent, $node->weight, $node->weight, $node->title)); if ($direct_above) { // Get last leaf of $above. $path = book_location_down($direct_above); @@ -399,7 +600,7 @@ function book_prev($node) { } else { // Direct parent: - $prev = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d AND n.status = 1 AND n.moderate = 0'), $node->parent)); + $prev = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE n.nid = %d AND n.status = 1 AND n.moderate = 0'), $node->parent)); return $prev; } } @@ -409,7 +610,7 @@ function book_prev($node) { */ function book_next($node) { // get first direct child - $child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight ASC, n.title ASC'), $node->nid)); + $child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight ASC, n.title ASC'), $node->nid)); if ($child) { return $child; } @@ -419,7 +620,7 @@ function book_next($node) { $path[] = $node; while (($leaf = array_pop($path)) && count($path)) { - $next = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight > %d OR (b.weight = %d AND n.title > '%s')) ORDER BY b.weight ASC, n.title ASC"), $leaf->parent, $leaf->weight, $leaf->weight, $leaf->title)); + $next = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight > %d OR (b.weight = %d AND n.title > '%s')) ORDER BY b.weight ASC, n.title ASC"), $leaf->parent, $leaf->weight, $leaf->weight, $leaf->title)); if ($next) { return $next; } @@ -456,7 +657,7 @@ function book_nodeapi(&$node, $op, $teas switch ($op) { case 'view': if (!$teaser) { - $book = db_fetch_array(db_query('SELECT * FROM {book} WHERE vid = %d', $node->vid)); + $book = db_fetch_array(db_query('SELECT bp.*, b.title AS book_title FROM {book_pages} bp JOIN {book} b ON b.bid = bp.bid WHERE vid = %d', $node->vid)); if ($book) { if ($node->moderate && user_access('administer nodes')) { drupal_set_message(t("The post has been submitted for moderation and won't be accessible until it has been approved.")); @@ -469,24 +670,40 @@ function book_nodeapi(&$node, $op, $teas $path = book_location($node); // Construct the breadcrumb: $node->breadcrumb = array(); // Overwrite the trail with a book trail. + $breadcrumb = array (l( t('Home'),''),l( t('books'), 'book')); + $breadcrumb[] = l( $book['book_title'], 'book/'.$node->bid ); + + //for some reason, the two paths below are not included in the breadcrumb. + //actually, the whole $node->breadcrumb variable seems to be ignored. + $node->breadcrumb[] = array ('path' => 'book', 'title' => 'books'); + $node->breadcrumb[] = array ('path' => 'book/'. $node->bid, 'title' => $book['book_title']); foreach ($path as $level) { $node->breadcrumb[] = array('path' => 'node/'. $level->nid, 'title' => $level->title); + $breadcrumb[] = l( $level->title, 'node/'. $level->nid ); } $node->breadcrumb[] = array('path' => 'node/'. $node->nid); $node->body .= theme('book_navigation', $node); + /* + echo ""; + print_r ($node->breadcrumb); + echo ""; + /**/ if ($page) { menu_set_location($node->breadcrumb); + // the breadcrumb created by $node->breadcrumb[] doesn't show the two top levels after home (books -> $book_title). + // I override it here with my own so that you can see what I am trying to achieve, but there must be a better way. + drupal_set_breadcrumb($breadcrumb); } } } break; case 'delete revision': - db_query('DELETE FROM {book} WHERE vid = %d', $node->vid); + db_query('DELETE FROM {book_pages} WHERE vid = %d', $node->vid); break; case 'delete': - db_query('DELETE FROM {book} WHERE nid = %d', $node->nid); + db_query('DELETE FROM {book_pages} WHERE nid = %d', $node->nid); break; } } @@ -510,6 +727,9 @@ function theme_book_navigation($node) { if ($node->parent) { drupal_add_link(array('rel' => 'index', 'href' => url('node/'. $node->parent))); $links .= l(t('up'), 'node/'. $node->parent, array('class' => 'page-up', 'title' => t('Go to parent page'))); + } + else { + $links .= l(t('up'), 'book/'. $node->bid, array('class' => 'page-up', 'title' => t('Go to book cover'))); } if ($next = book_next($node)) { drupal_add_link(array('rel' => 'next', 'href' => url('node/'. $next->nid))); @@ -550,8 +770,12 @@ function book_toc_recurse($nid, $indent, /** * Returns an array of titles and nid entries of book pages in table of contents order. */ -function book_toc($exclude = 0) { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 ORDER BY b.weight, n.title')); +function book_toc($exclude = 0, $bid = FALSE) { + $one_book = ''; + if ($bid) { + $one_book = 'AND bp.bid = ' . $bid ; + } + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, bp.parent, bp.weight FROM {node} n INNER JOIN {book_pages} bp ON n.vid = bp.vid WHERE n.status = 1 '.$one_book.' ORDER BY bp.weight, n.title')); while ($node = db_fetch_object($result)) { if (!$children[$node->parent]) { @@ -561,10 +785,7 @@ function book_toc($exclude = 0) { } $toc = array(); - // If the user has permission to create new books, add the top-level book page to the menu; - if (user_access('create new books')) { - $toc[0] = '<'. t('top-level') .'>'; - } + $toc[0] = '<'. t('top-level') .'>'; $toc = book_toc_recurse(0, '', $toc, $children, $exclude); @@ -605,11 +826,48 @@ function book_tree_recurse($nid, $depth, } /** + * This is a helper function for book_tree() + */ +function book_tree_recurse_original($nid, $depth, $children, $unfold = array()) { + if ($depth > 0) { + if ($children[$nid]) { + foreach ($children[$nid] as $foo => $node) { + if (in_array($node->nid, $unfold)) { + if ($tree = book_tree_recurse($node->nid, $depth - 1, $children, $unfold)) { + $output .= '
Authored/maintained by %name.
', array('%name' => $author->name)); + + $output .= "DEV NOTE: Here, I am trying to get the whole book's TOC expanded in a nested table,but I don't know how to achieve this best
"; + $result = db_queryd('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE b.bid = %d', $bid); + 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; + } + + $ouput .= book_tree($expand[0], 5, $expand); + } + $output .= book_tree(0, 5, array(), $book->bid); + return $output; +} + + + +/** * Menu callback; prints a listing of all books. */ -function book_render() { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = 0 AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title')); +function book_shelf() { + $result = db_query('SELECT bid, title FROM {book} ORDER BY weight, title'); + $breadcrumb = array (l( t('Home'),'')); + drupal_set_breadcrumb($breadcrumb); $books = array(); - while ($node = db_fetch_object($result)) { - $books[] = l($node->title, 'node/'. $node->nid); + while ($book = db_fetch_object($result)) { + $books[] = l($book->title, 'book/'. $book->bid); } return theme('item_list', $books); } + + +/** + * Menu callback: create a new book / update book cover. + * @param:$op + * either create or edit + */ +function setup_book_cover($op, $bid = 0) { + global $user; + $breadcrumb = array (l( t('Home'),'')); + drupal_set_breadcrumb($breadcrumb); + + if ($bid) { + $result = db_query('SELECT * FROM {book} WHERE bid = %d ORDER BY weight, title', $bid); + $book = db_fetch_array($result); + $book['submit'] = t('Update book'); + } + else { + $book = array('bid' => 0, 'uid' => $user->uid, 'title' => '', 'weight' => 0, 'submit' => t('Create new book')); + } + + $form['title'] = array ( + '#type' => 'textfield', + '#title' => t('Book title'), + '#size' => 60, + '#default_value' => $book['title'], + '#maxlength' => 255, + '#description' => t('Enter the title of your book.'), + ); + $form['weight'] = array ( + '#type' => 'weight', + '#default_value' => $book['weight'], + '#delta' => 15, + ); + $form['submit'] = array ( + '#type' => 'submit', + '#value' => $book['submit'], + ); + $form['uid'] = array ( + '#type' => 'value', + '#value' => $book['uid'], + ); + $form['op'] = array ( + '#type' => 'value', + '#value' => $op, + ); + $form['bid'] = array ( + '#type' => 'value', + '#value' => $book['bid'], + ); + + $output = drupal_get_form('book_create', $form); + return $output; +} + +/** + * Validates the form 'create new book / update book' + */ +function book_create_validate() { +} + +/** + * Saves the new book / update book. + */ +function book_create_submit($form_id, $form) { + if ($form['op'] == 'create') { + $bid = db_next_id('book_bid'); + db_query("INSERT INTO {book} (bid, uid, title, weight) VALUES (%d, %d, '%s', %d) ", $bid, $form['uid'], $form['title'], $form['weight']); + drupal_set_message(t('Your new book has been created.')); + drupal_goto('book/'. $bid); + } + + if ($form['op'] == 'edit') { + db_query('UPDATE {book} SET uid = %d, title = "%s", weight = %d WHERE bid = %d', $form['uid'], $form['title'], $form['weight'], $form['bid']); + drupal_set_message(t('The book has been updated.')); + drupal_goto('book/'. $form['bid']); + } + + +} + + /** * Menu callback; Generates various representation of a book page with * all descendants and prints the requested representation to output. @@ -656,7 +1037,7 @@ function book_render() { */ function book_export($type = 'html', $nid = 0) { $type = drupal_strtolower($type); - $node_result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d'), $nid); + $node_result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE n.nid = %d'), $nid); if (db_num_rows($node_result) > 0) { $node = db_fetch_object($node_result); } @@ -753,7 +1134,7 @@ function theme_book_export_html($title, * - the output generated in visiting each node */ function book_recurse($nid = 0, $depth = 1, $visit_pre, $visit_post) { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 AND n.nid = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $nid); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE n.status = 1 AND n.nid = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $nid); while ($page = db_fetch_object($result)) { // Load the node: $node = node_load($page->nid); @@ -766,7 +1147,7 @@ function book_recurse($nid = 0, $depth = $output .= book_node_visitor_html_pre($node, $depth, $nid); } - $children = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 AND b.parent = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $node->nid); + $children = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE n.status = 1 AND b.parent = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $node->nid); while ($childpage = db_fetch_object($children)) { $childnode = node_load($childpage->nid); if ($childnode->nid != $node->nid) { @@ -858,7 +1239,7 @@ function _book_admin_table_tree($node, $ ), ); - $children = db_query(db_rewrite_sql('SELECT n.nid, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d ORDER BY b.weight, n.title'), $node->nid); + $children = db_query(db_rewrite_sql('SELECT n.nid, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE b.parent = %d ORDER BY b.weight, n.title'), $node->nid); while ($child = db_fetch_object($children)) { $form = array_merge($form, _book_admin_table_tree(node_load($child->nid), $depth + 1)); } @@ -911,7 +1292,7 @@ function book_admin_edit($nid) { * Menu callback; displays a listing of all orphaned book pages. */ function book_admin_orphan() { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.status, b.parent FROM {node} n INNER JOIN {book} b ON n.vid = b.vid')); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.status, b.parent FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid')); $pages = array(); while ($page = db_fetch_object($result)) { @@ -983,7 +1364,7 @@ function book_admin($nid = 0) { * Returns an administrative overview of all books. */ function book_admin_overview() { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = 0 ORDER BY b.weight, n.title')); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book_pages} b ON n.vid = b.vid WHERE b.parent = 0 ORDER BY b.weight, n.title')); while ($book = db_fetch_object($result)) { $rows[] = array(l($book->title, "node/$book->nid"), l(t('outline'), "admin/node/book/$book->nid")); }