Index: install.php
===================================================================
RCS file: /cvs/drupal/drupal/install.php,v
retrieving revision 1.1
diff -u -p -r1.1 install.php
--- install.php 13 Jul 2006 13:11:36 -0000 1.1
+++ install.php 24 Jul 2006 02:29:01 -0000
@@ -114,6 +114,9 @@ function install_verify_settings() {
*/
function install_change_settings() {
global $profile, $db_url, $db_type, $db_prefix;
+ // see http://drupal.org/node/74992
+ // temporary fix.
+ $profile = 'default';
$url = parse_url($db_url);
$db_user = urldecode($url['user']);
Index: modules/book/book.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.install,v
retrieving revision 1.2
diff -u -p -r1.2 book.install
--- modules/book/book.install 14 Jul 2006 01:05:09 -0000 1.2
+++ modules/book/book.install 24 Jul 2006 02:29:02 -0000
@@ -5,14 +5,62 @@ function book_install() {
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
- db_query("CREATE TABLE {book} (
+ db_query("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)
) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+ db_query("CREATE TABLE {book} (
+ bid INT( 10 ) UNSIGNED NOT NULL default '0' PRIMARY KEY ,
+ nid INT( 10 ) UNSIGNED NOT NULL default '0' ,
+ book_author VARCHAR(255) NOT NULL default '' ,
+ book_license LONGTEXT NOT NULL default '' ,
+ weight TINYINT( 3 ) NOT NULL default '0',
+ KEY nid (nid)
+ ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+ }
+}
+
+/**
+ * Update book table definitions.
+ */
+function book_update_1() {
+ $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 ,
+ `nid` INT( 10 ) UNSIGNED NOT NULL default '0' ,
+ `book_author` VARCHAR(255) NOT NULL default '' ,
+ `book_license` LONGTEXT NOT NULL default '' ,
+ `weight` TINYINT( 3 ) NOT NULL default '0',
+ KEY nid (nid)
+ ) 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' ,
+ nid integer NOT NULL default '0' ,
+ book_author varchar(255) NOT NULL default '' ,
+ book_license text 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;
}
-}
\ No newline at end of file
+ return $ret;
+}
Index: modules/book/book.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.module,v
retrieving revision 1.375
diff -u -p -r1.375 book.module
--- modules/book/book.module 19 Jul 2006 07:15:34 -0000 1.375
+++ modules/book/book.module 24 Jul 2006 02:29:04 -0000
@@ -10,7 +10,10 @@
* Implementation of hook_node_info().
*/
function book_node_info() {
- return array('book' => array('name' => t('book page'), 'base' => 'book'));
+ return array(
+ 'book' => array('name' => t('book page'), 'base' => 'book'),
+ 'book_cover' => array('name' => t('book cover'), 'base' => 'book_cover')
+ );
}
/**
@@ -20,8 +23,38 @@ function book_perm() {
return array('outline posts in books', 'create book pages', 'create new books', 'edit book pages', 'edit own book pages', 'see printer-friendly version');
}
+
+/**
+ * Implementation of hook_access() for a book cover.
+ */
+function book_cover_access($op, $node) {
+ global $user;
+
+ if ($op == 'create') {
+ // Only registered users can create books. Given the nature
+ // of the book module this is considered to be a good/safe idea.
+ return user_access('create new books');
+ }
+
+ if ($op == 'update') {
+ // Only registered users can update book pages. Given the nature
+ // of the book module this is considered to be a good/safe idea.
+ // One can only update a book page if there are no suggested updates
+ // of that page waiting for approval. That is, only updates that
+ // don't overwrite the current or pending information are allowed.
+
+ if ($node->uid == $user->uid && user_access('edit own book pages')) {
+ return TRUE;
+ }
+ else {
+ // do nothing. node-access() will determine further access
+ }
+ }
+}
+
+
/**
- * Implementation of hook_access().
+ * Implementation of hook_access() for a book page.
*/
function book_access($op, $node) {
global $user;
@@ -55,6 +88,16 @@ function book_link($type, $node = NULL,
$links = array();
+ if ($type == 'node' && $node->type == 'book_cover') {
+ if (user_access('create new books', $node)) {
+ $links['book_add_child'] = array(
+ 'title' => t('add child page'),
+ 'href' => "node/add/book/bid/$node->bid"
+ );
+ }
+ return $links;
+ }
+
if ($type == 'node' && isset($node->parent)) {
if (!$teaser) {
if (book_access('create', $node)) {
@@ -88,6 +131,10 @@ function book_menu($may_cache) {
'title' => t('book page'),
'access' => user_access('create book pages'));
$items[] = array(
+ 'path' => 'node/add/book_cover',
+ 'title' => t('book cover'),
+ 'access' => user_access('create book pages'));
+ $items[] = array(
'path' => 'admin/node/book',
'title' => t('books'),
'callback' => 'book_admin',
@@ -106,10 +153,10 @@ function book_menu($may_cache) {
'weight' => 8);
$items[] = array(
'path' => 'book',
- 'title' => t('books'),
- 'callback' => 'book_render',
- 'access' => user_access('access content'),
- 'type' => MENU_SUGGESTED_ITEM);
+ 'title' => t('book shelf'),
+ 'callback' => 'book_shelf',
+ 'type' => MENU_NORMAL_ITEM,
+ 'access' => user_access('access content'));
$items[] = array(
'path' => 'book/export',
'callback' => 'book_export',
@@ -117,12 +164,30 @@ function book_menu($may_cache) {
'type' => MENU_CALLBACK);
}
else {
+ $items[] = array(
+ 'path' => 'book/select',
+ 'title' => t('New page'),
+ 'callback' => '_add_page_select_book',
+ 'access' => user_access('create book pages'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2);
// 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')) {
// Only add the outline-tab for non-book pages:
- $result = db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.nid = %d AND n.type != 'book'"), arg(1));
- if (db_num_rows($result) > 0) {
+ $result = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.type FROM {node} n WHERE n.nid = %d'), arg(1)));
+ if ($result->type == 'book') {
+ // If it's a book page, add the 'book' tab.
+ $items[] = array(
+ 'path' => 'node/'.arg(1).'/movetobook',
+ 'title' => t('book'),
+ 'callback' => 'move_page_to_book',
+ 'access' => user_access('outline posts in books'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 8);
+ }
+ elseif ($result->type != 'book_cover') {
+ // add outline tab
$items[] = array(
'path' => 'node/'. arg(1) .'/outline',
'title' => t('outline'),
@@ -139,6 +204,108 @@ function book_menu($may_cache) {
}
/**
+ * Menu call back: Select a book to move a page to.
+ * @param:
+ * outline: TRUE if it is a non-book page.
+ */
+function move_page_to_book($outline = FALSE) {
+ $result = db_query('SELECT b.bid, n.title FROM {book} b JOIN {node} n ON n.nid = b.nid ORDER BY b.weight, n.title');
+ $books = array();
+ $books[0] = 'Independant, top-level book page';
+ 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.'),
+ );
+ /*
+ // It is better and simpler if we do not include this function.
+ $form['children'] = array(
+ '#type' => 'checkbox',
+ '#title' => 'Move all the page\'s children to the other book, too',
+ '#default_value' => 1,
+ );
+ $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['outline'] = array(
+ '#type' => 'value',
+ '#value' => FALSE,
+ );
+ $form['nid'] = array(
+ '#type' => 'value',
+ '#value' => $nid,
+ );
+ $form['children_note'] = array(
+ '#value' => t('Note: All of this pages\'s children will be moved together to the new book. If you do not wish that, please update the outline of the children pages first.
'),
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Submit'),
+ );
+
+ //override some of the above defaults if it is not a book_page node
+ if ($outline) {
+ $form['outline']['#value'] = TRUE;
+ $form['children_note'] = NULL;
+ }
+
+ $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) {
+
+ if($form['outline']) {
+ $node = node_load($form['nid']);
+ db_query('INSERT INTO {book_pages} (nid, vid, bid, parent, weight) VALUES (%d, %d, %d, %d, %d)', $node->nid, $node->vid, $form['bid'], $form['parent'], $form['weight']);
+ db_query("UPDATE {node_revisions} SET log = '%s' WHERE vid = %d", $form['log'], $node->vid);
+ drupal_set_message(t('The post has been added to the book. Now update where in the book you want to add the post.'));
+ drupal_goto('node/'. $form['nid'].'/outline');
+ }
+
+ $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.
You can now edit the page\'s location within the new book.'));
+ drupal_goto('node/'. $form['nid'].'/edit');
+}
+
+/**
+ * Helper function to recursively update $bid for each children
+ * when moving the parent to a new book.
+ */
+function book_update_children_bid($parent, $bid, $i=1) {
+ $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);
+ book_update_children_bid($page->nid, $bid, $i+2);
+ }
+ }
+}
+
+/**
* Implementation of hook_block().
*
* Displays the book table of contents in a block when the current page is a
@@ -147,13 +314,31 @@ function book_menu($may_cache) {
function book_block($op = 'list', $delta = 0) {
$block = array();
if ($op == 'list') {
- $block[0]['info'] = t('Book navigation');
+ $block['navigation']['info'] = t('Book navigation');
+ $block['license']['info'] = t('Book license');
return $block;
}
else if ($op == 'view') {
+ // Book license block
+ // Only display this block when the user is browsing a book page:
+ // (the block will not appear on the book cover. Maybe it should but it's not implemented yet.
+ // being able to call global $node and check on $node->bid would be much more convenient.)
+ if ($delta == 'license') {
+ if (arg(0) == 'node' && is_numeric(arg(1))) {
+ $result = db_query(db_rewrite_sql('SELECT b.book_license, n.title, nr.format FROM {book} b JOIN {book_pages} bp ON bp.bid = b.bid JOIN {node} n ON n.nid = b.nid JOIN {node_revisions} nr ON nr.vid = n.vid WHERE bp.nid = %d'), arg(1));
+ if (db_num_rows($result) > 0) {
+ $book = db_fetch_object($result);
+ $block['subject'] = check_plain($book->title). ' license';
+ $block['content'] = check_markup($book->book_license, $book->format, FALSE);
+ }
+ }
+ return $block;
+ }
+
+ // Book navigation block
// 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));
+ $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);
@@ -175,17 +360,40 @@ function book_block($op = 'list', $delta
}
/**
+ * Implementation of hook_load() for a book cover.
+ */
+function book_cover_load($node) {
+ return db_fetch_object(db_query('SELECT * FROM {book} WHERE nid = %d', $node->nid));
+}
+
+
+/**
* 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));
}
/**
- * Implementation of hook_insert().
+ * Implementation of hook_insert() for book pages.
+ */
+function book_cover_insert($node) {
+ $bid = db_next_id('book_bid');
+ db_query('INSERT INTO {book} (bid, nid, book_author, book_license, weight) VALUES (%d, %d, "%s", "%s", %d)', $bid, $node->nid, $node->book_author, $node->book_license, $node->weight);
+}
+
+/**
+ * Implementation of hook_insert() for book pages.
*/
function book_insert($node) {
- db_query("INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $node->parent, $node->weight);
+ db_query("INSERT INTO {book_pages} (nid, bid, vid, parent, weight) VALUES (%d, %d, %d, %d, %d)", $node->nid, $node->bid, $node->vid, $node->parent, $node->weight);
+}
+
+/**
+ * Implementation of hook_update() for book covers.
+ */
+function book_cover_update($node) {
+ db_query('UPDATE {book} SET book_author = "%s", weight = %d, book_license = "%s" WHERE bid = %d', $node->book_author, $node->weight, $node->book_license, $node->bid);
}
/**
@@ -193,22 +401,36 @@ function book_insert($node) {
*/
function book_update($node) {
if ($node->revision) {
- db_query("INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $node->parent, $node->weight);
+ db_query("INSERT INTO {book_pages} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $node->parent, $node->weight);
}
else {
- db_query("UPDATE {book} SET parent = %d, weight = %d WHERE vid = %d", $node->parent, $node->weight, $node->vid);
+ db_query("UPDATE {book_pages} SET parent = %d, weight = %d WHERE vid = %d", $node->parent, $node->weight, $node->vid);
}
}
/**
+ * Implementation of hook_delete() for book covers.
+ */
+function book_cover_delete(&$node) {
+ db_query('DELETE FROM {book} WHERE nid = %d', $node->nid);
+}
+
+/**
* Implementation of hook_delete().
*/
function book_delete(&$node) {
- db_query('DELETE FROM {book} WHERE nid = %d', $node->nid);
+ db_query('DELETE FROM {book_pages} WHERE nid = %d', $node->nid);
}
/**
- * Implementation of hook_submit().
+ * Implementation of hook_submit() for book covers.
+ */
+function book_cover_submit(&$node) {
+ global $form;
+
+}
+/**
+ * Implementation of hook_submit() for book pages.
*/
function book_submit(&$node) {
global $user;
@@ -222,22 +444,88 @@ function book_submit(&$node) {
}
/**
- * Implementation of hook_form().
+ * Implementation of hook_form() for a book.
+ */
+function book_cover_form(&$node) {
+
+ $form['title'] = array('#type' => 'textfield',
+ '#title' => t('Title'),
+ '#required' => TRUE,
+ '#default_value' => $node->title,
+ '#weight' => -5,
+ );
+ $form['body_filter']['body'] = array('#type' => 'textarea',
+ '#title' => t('Body'),
+ '#default_value' => $node->body,
+ '#rows' => 20,
+ '#required' => TRUE,
+ );
+ $form['body_filter']['format'] = filter_form($node->format);
+ $form['book_author'] = array('#type' => 'textfield',
+ '#title' => t('Author'),
+ '#required' => FALSE,
+ '#default_value' => $node->book_author,
+ );
+ $form['book_license'] = array('#type' => 'textarea',
+ '#title' => t('License'),
+ '#default_value' => $node->book_license,
+ '#rows' => 8,
+ '#required' => FALSE,
+ );
+
+ return $form;
+}
+
+
+/**
+ * Implementation of hook_form() for a book page.
*/
function book_form(&$node) {
- if ($node->nid && !$node->parent && !user_access('create new books')) {
- $form['parent'] = array('#type' => 'value', '#value' => $node->parent);
+
+ // looking for url like node/add/book/bid/$bid
+ if (arg(3) == 'bid') {
+ if (is_numeric(arg(4))) {
+ $node->bid = arg(4);
+ $node->parent = 0;
+ }
}
- else {
- $form['parent'] = array('#type' => 'select',
- '#title' => t('Parent'),
- '#default_value' => ($node->parent ? $node->parent : arg(4)),
- '#options' => book_toc($node->nid),
- '#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.'),
+
+ // url like node/add/book/parent/$nid
+ if (arg(3) == 'parent') {
+ $node->parent = arg(4);
+ $sql = "SELECT bid FROM {book_pages} where nid = %d";
+ $result = db_query($sql, $node->parent);
+ $node->bid = db_result($result);
+ }
+
+ // check that the book exists.
+ if (!$result = db_result(db_query('SELECT bid FROM {book} WHERE bid = %d', $node->bid))) {
+ $node->bid = 0;
+ }
+ //else {
+ $form['bid'] = array ('#type' => 'hidden',
+ '#value' => $node->bid,
);
+
+ if ($node->nid && !$node->parent && !user_access('create new books')) {
+ $form['parent'] = array('#type' => 'value', '#value' => $node->parent);
+ }
+ else {
+ $form['parent'] = array('#type' => 'select',
+ '#title' => t('Parent'),
+ '#default_value' => ($node->parent ? $node->parent : arg(4)),
+ '#options' => book_toc($node->nid, $node->bid),
+ '#weight' => -4,
+ '#description' => t('The parent that this page belongs in. "Top level" means the highest level within this book.'),
+ );
+ }
+ //}
+
+ if (!isset($node->parent)) {
+ $node->parent = 0;
}
+
$form['title'] = array('#type' => 'textfield',
'#title' => t('Title'),
'#required' => TRUE,
@@ -285,11 +573,22 @@ function book_form(&$node) {
function book_outline($nid) {
$node = node_load($nid);
$page = book_load($node);
+ /*
+ echo "";
+ print_r($node);
+ print_r($page);
+ echo "
";
+ */
+
+ if (!$page) {
+ return move_page_to_book(TRUE);
+ }
+
$form['parent'] = array('#type' => 'select',
'#title' => t('Parent'),
'#default_value' => $page->parent,
- '#options' => book_toc($node->nid),
+ '#options' => book_toc($node->nid, $page->bid),
'#description' => t('The parent page in the book.'),
);
$form['weight'] = array('#type' => 'weight',
@@ -330,17 +629,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 +659,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 (isset($parent->title)) {
$nodes = book_location($parent, $nodes);
$nodes[] = $parent;
@@ -372,7 +671,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);
@@ -390,7 +689,7 @@ function book_prev($node) {
}
// 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 (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 +698,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'), $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 +708,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 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 +718,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 (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;
}
@@ -440,6 +739,58 @@ function book_content($node, $teaser = F
/**
* Implementation of hook_view().
*
+ */
+function book_cover_view(&$node, $teaser = FALSE, $page = FALSE) {
+ $node = node_prepare($node, $teaser);
+ $node->book_license = check_markup($node->book_license, $node->format, FALSE);
+ //$book_author = theme('book_cover_book_author', $node);
+ $node->body .= ''.$node->book_author.'
';
+ $node->teaser .= ''.$node->book_author.'
';
+ //$book_license = theme('book_cover_book_license', $node);
+ $node->body .= ''.$node->book_license.'
';
+ $node->body .= _book_cover_toc($node->bid);
+}
+
+/**
+ * Creates the Table of Content printed on book cover $bid.
+ * Returns formatted html.
+ */
+function _book_cover_toc($bid) {
+ $toc = '
Table of Content
';
+ $result = db_query('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 AND bp.bid = %d ORDER BY bp.weight, n.title', $bid);
+
+ while ($node = db_fetch_object($result)) {
+ if (!$children[$node->parent]) {
+ $children[$node->parent] = array();
+ }
+ $children[$node->parent][] = $node;
+ }
+
+ $toc .= _book_cover_toc_recurse(0, $children);
+
+ $toc .= '
';
+ return $toc;
+}
+
+/**
+ * This is a helper function for _book_cover_toc().
+ */
+function _book_cover_toc_recurse($nid, $children) {
+ if ($children[$nid]) {
+ $toc = '';
+ foreach ($children[$nid] as $foo => $node) {
+ $toc .= '- '. l($node->title , 'node/'.$node->nid). '
';
+ $toc .= _book_cover_toc_recurse($node->nid, $children);
+ }
+ $toc .= '
';
+ }
+
+ return $toc;
+}
+
+/**
+ * Implementation of hook_view().
+ *
* If not displayed on the main page, we render the node as a page in the
* book with extra links to the previous and next pages.
*/
@@ -456,37 +807,54 @@ 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));
- if ($book) {
+ if ($node->type == 'book_cover') {
+ $node->breadcrumb = array(); // Overwrite the trail with a book trail.
+ $node->breadcrumb[] = array ('path' => 'book', 'title' => 'books');
+ $node->breadcrumb[] = array ('path' => 'node/'. $node->nid, 'title' => $node->title);
+ menu_set_location($node->breadcrumb);
+ }
+ else {
+ // check if it is a node added in the outline:
+ $book = db_fetch_array(db_query('SELECT * FROM {book_pages} WHERE vid = %d', $node->vid));
+ if ($book) {
+ /* // the moderate bit has been removed recently in core. This piece of code is a leftover that should be DEBUGed.
if (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."));
}
+ */
- foreach ($book as $key => $value) {
- $node->$key = $value;
- }
-
- $path = book_location($node);
- // Construct the breadcrumb:
- $node->breadcrumb = array(); // Overwrite the trail with a book trail.
- foreach ($path as $level) {
- $node->breadcrumb[] = array('path' => 'node/'. $level->nid, 'title' => $level->title);
- }
- $node->breadcrumb[] = array('path' => 'node/'. $node->nid);
-
- $node->body .= theme('book_navigation', $node);
-
- if ($page) {
- menu_set_location($node->breadcrumb);
+ foreach ($book as $key => $value) {
+ $node->$key = $value;
+ }
+
+ $path = book_location($node);
+ // Construct the breadcrumb:
+ $node->breadcrumb = array(); // Overwrite the trail with a book trail.
+ $node->breadcrumb[] = array ('path' => 'book', 'title' => 'books');
+ if (!empty($node->bid)) {
+ $cover = db_fetch_object(db_query('SELECT n.title, n.nid FROM {book} AS b JOIN {node} AS n ON n.nid = b.nid WHERE b.bid = %d', $node->bid));
+ $node->breadcrumb[] = array ('path' => 'node/'. $cover->nid, 'title' => $cover->title);
+ }
+
+ foreach ($path as $level) {
+ $node->breadcrumb[] = array('path' => 'node/'. $level->nid, 'title' => $level->title);
+ }
+ $node->breadcrumb[] = array('path' => 'node/'. $node->nid);
+
+ $node->body .= theme('book_navigation', $node);
+
+ if ($page) {
+ menu_set_location($node->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;
}
}
@@ -512,6 +880,10 @@ function theme_book_navigation($node) {
drupal_add_link(array('rel' => 'up', 'href' => url('node/'. $node->parent)));
$links .= l(t('up'), 'node/'. $node->parent, array('class' => 'page-up', 'title' => t('Go to parent page')));
}
+ else {
+ $cover_nid = db_result(db_query('SELECT nid FROM {book} WHERE bid = %d', $node->bid));
+ $links .= l(t('up'), 'node/'. $cover_nid, 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)));
$links .= l($next->title . t(' ›'), 'node/'. $next->nid, array('class' => 'page-next', 'title' => t('Go to next page')));
@@ -551,8 +923,9 @@ 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) {
+ $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 AND bp.bid = %d ORDER BY bp.weight, n.title'), $bid);
+
while ($node = db_fetch_object($result)) {
if (!$children[$node->parent]) {
@@ -562,10 +935,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);
@@ -611,7 +981,7 @@ function book_tree_recurse($nid, $depth,
* as a tree.
*/
function book_tree($parent = 0, $depth = 3, $unfold = array()) {
- $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'));
+ $result = 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 n.moderate = 0 ORDER BY b.weight, n.title'));
while ($node = db_fetch_object($result)) {
$list = isset($children[$node->parent]) ? $children[$node->parent] : array();
@@ -627,13 +997,21 @@ function book_tree($parent = 0, $depth =
/**
* 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 ORDER BY b.weight, n.title'));
+function book_shelf() {
+ $result = db_query('SELECT b.bid, b.nid , n.title FROM {book} b JOIN {node} n ON n.nid = b.nid 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);
}
+ // Add to those the top-level book pages without a book_cover.
+ // Do we need to make two lists separated with a heading
?
+ $result = db_query('SELECT b.nid , n.title FROM {book_pages} b JOIN {node} n ON n.nid = b.nid WHERE parent = 0 AND bid = 0 ORDER BY weight, title');
+ while ($node = db_fetch_object($result)) {
+ $books[] = l($node->title, 'node/'. $node->nid);
+ }
return theme('item_list', $books);
}
@@ -658,7 +1036,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);
}
@@ -748,7 +1126,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 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);
@@ -761,7 +1139,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 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) {
@@ -853,7 +1231,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));
}
@@ -906,7 +1284,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)) {
@@ -978,7 +1356,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"));
}
@@ -1015,7 +1393,11 @@ function book_help($section) {
case 'admin/node/book/orphan':
return t('Pages in a book are like a tree. As pages are edited, reorganized and removed, child pages might be left with no link to the rest of the book. Such pages are referred to as "orphan pages". On this page, administrators can review their books for orphans and reattach those pages as desired.
');
case 'node/add#book':
- return t("A book is a collaborative writing effort: users can collaborate writing the pages of the book, positioning the pages in the right order, and reviewing or modifying pages previously written. So when you have some information to share or when you read a page of the book and you didn't like it, or if you think a certain page could have been written better, you can do something about it.");
+ $link = l(t('select a book to add a page to'), 'book/select');
+ return t("A book is a collaborative writing effort: users can collaborate writing the pages of the book, positioning the pages in the right order, and reviewing or modifying pages previously written. So when you have some information to share or when you read a page of the book and you didn't like it, or if you think a certain page could have been written better, you can do something about it.
+ Use this link to $link, otherwise your book page will be created independently of any existing book.");
+ case 'node/add#book_cover':
+ return t("Add a new book.");
}
if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'outline') {
@@ -1024,3 +1406,20 @@ function book_help($section) {
}
+
+/**
+ * Prints a list of books in which the user can add pages.
+ */
+function _add_page_select_book() {
+ $breadcrumb = array (l( t('Home'),''));
+ drupal_set_breadcrumb($breadcrumb);
+
+ $result = db_query('SELECT b.bid, b.nid , n.title FROM {book} b JOIN {node} n ON n.nid = b.nid ORDER BY weight, title');
+ while($book = db_fetch_object($result)) {
+ $books[] = l($book->title, 'node/add/book/bid/'.$book->bid);
+ }
+ $output = t('Select the book you wish to add a page to.
');
+ $output .= theme('item_list', $books);
+ return $output;
+}
+