Index: database/database.mysql =================================================================== RCS file: /cvs/drupal/drupal/database/database.mysql,v retrieving revision 1.170 diff -u -F^f -r1.170 database.mysql --- database/database.mysql 21 Feb 2005 19:47:44 -0000 1.170 +++ database/database.mysql 5 Mar 2005 19:16:28 -0000 @@ -135,11 +135,12 @@ -- CREATE TABLE book ( + vid int(10) unsigned NOT NULL default '0', nid int(10) unsigned NOT NULL default '0', parent int(10) NOT NULL default '0', weight tinyint(3) NOT NULL default '0', - log longtext, - PRIMARY KEY (nid), + PRIMARY KEY (vid), + KEY nid (nid), KEY parent (parent) ) TYPE=MyISAM; @@ -232,6 +233,7 @@ CREATE TABLE files ( fid int(10) unsigned NOT NULL default '0', nid int(10) unsigned NOT NULL default '0', + vid int(10) unsigned NOT NULL default '0', filename varchar(255) NOT NULL default '', filepath varchar(255) NOT NULL default '', filemime varchar(255) NOT NULL default '', @@ -279,9 +281,11 @@ -- CREATE TABLE forum ( + vid int(10) unsigned NOT NULL default '0', nid int(10) unsigned NOT NULL default '0', tid int(10) unsigned NOT NULL default '0', - PRIMARY KEY (nid), + PRIMARY KEY (vid), + KEY nid (nid), KEY tid (tid) ) TYPE=MyISAM; @@ -392,8 +396,8 @@ CREATE TABLE node ( nid int(10) unsigned NOT NULL auto_increment, + vid int(10) unsigned NOT NULL default '1', type varchar(16) NOT NULL default '', - title varchar(128) NOT NULL default '', uid int(10) NOT NULL default '0', status int(4) NOT NULL default '1', created int(11) NOT NULL default '0', @@ -401,16 +405,12 @@ comment int(2) NOT NULL default '0', promote int(2) NOT NULL default '0', moderate int(2) NOT NULL default '0', - teaser longtext NOT NULL, - body longtext NOT NULL, - revisions longtext NOT NULL, sticky int(2) NOT NULL default '0', - format int(4) NOT NULL default '0', PRIMARY KEY (nid), KEY node_type (type(4)), - KEY node_title_type (title,type(4)), KEY status (status), KEY uid (uid), + KEY vid (vid), KEY node_moderate (moderate), KEY node_promote_status (promote, status), KEY node_created (created), @@ -431,6 +431,24 @@ grant_delete tinyint(1) unsigned NOT NULL default '0', PRIMARY KEY (nid,gid,realm) ) TYPE=MyISAM; + +-- +-- Table structure for table 'node_revisions' +-- + +CREATE TABLE node_revisions ( + nid int(10) unsigned NOT NULL, + vid int(10) unsigned NOT NULL, + uid int(10) NOT NULL default '0', + title varchar(128) NOT NULL default '', + body longtext NOT NULL default '', + teaser longtext NOT NULL default '', + log longtext NOT NULL default '', + timestamp int(11) NOT NULL default '0', + format int(4) NOT NULL default '0', + PRIMARY KEY (nid,vid), + KEY uid (uid) +) TYPE=MyISAM; -- -- Table structure for table 'profile_fields' Index: database/database.pgsql =================================================================== RCS file: /cvs/drupal/drupal/database/database.pgsql,v retrieving revision 1.106 diff -u -F^f -r1.106 database.pgsql --- database/database.pgsql 27 Feb 2005 15:40:35 -0000 1.106 +++ database/database.pgsql 5 Mar 2005 19:16:32 -0000 @@ -133,10 +133,10 @@ -- CREATE TABLE book ( + vid integer NOT NULL default '0', nid integer NOT NULL default '0', parent integer NOT NULL default '0', weight smallint NOT NULL default '0', - log text default '', PRIMARY KEY (nid) ); CREATE INDEX book_nid_idx ON book(nid); @@ -231,6 +231,7 @@ CREATE TABLE files ( fid SERIAL, nid integer NOT NULL default '0', + vid integer NOT NULL default '0', filename varchar(255) NOT NULL default '', filepath varchar(255) NOT NULL default '', filemime varchar(255) NOT NULL default '', @@ -279,11 +280,13 @@ -- CREATE TABLE forum ( + vid integer NOT NULL default '0', nid integer NOT NULL default '0', tid integer NOT NULL default '0', - shadow integer NOT NULL default '0', - PRIMARY KEY (nid) + PRIMARY KEY (vid) ); +CREATE INDEX forum_vid_idx ON forum(vid); +CREATE INDEX forum_nid_idx ON forum(nid); CREATE INDEX forum_tid_idx ON forum(tid); -- @@ -434,6 +437,26 @@ PRIMARY KEY (nid,gid,realm) ); +-- +-- Table structure for table 'node_revisions' +-- + +CREATE TABLE node_revisions ( + vid integer NOT NULL default '0', + nid integer NOT NULL default '0', + uid integer NOT NULL default '0', + title varchar(128) NOT NULL default '', + body text NOT NULL default '', + teaser text NOT NULL default '', + log text NOT NULL default '', + format smallint NOT NULL default '0', + timestamp integer NOT NULL default '0', + data text NOT NULL default '', + PRIMARY KEY (vid) +); + +CREATE INDEX node_revisions_nid_idx ON node_revisions(nid); +CREATE INDEX node_revisions_uid_idx ON node_revisions(uid); -- -- Table structure for table 'node_counter' Index: database/updates.inc =================================================================== RCS file: /cvs/drupal/drupal/database/updates.inc,v retrieving revision 1.98 diff -u -F^f -r1.98 updates.inc --- database/updates.inc 3 Mar 2005 20:21:51 -0000 1.98 +++ database/updates.inc 5 Mar 2005 19:16:53 -0000 @@ -102,7 +102,9 @@ "2005-01-28" => "update_123", "2005-02-11" => "update_124", "2005-02-23" => "update_125", - "2005-03-03" => "update_126" + "2005-03-03" => "update_126", + "2005-03-04" => "update_127", + "2005-03-05" => "update_128" ); function update_32() { @@ -2313,6 +2315,154 @@ function update_126() { return array(); } +function update_127() { + $ret = array(); + + if ($GLOBALS['db_type'] == 'mysql') { + $ret[] = update_sql("CREATE TABLE {node_revisions} ( + nid int(10) unsigned NOT NULL, + vid int(10) unsigned NOT NULL, + uid int(10) NOT NULL default '0', + title varchar(128) NOT NULL default '', + body longtext NOT NULL default '', + teaser longtext NOT NULL default '', + log longtext NOT NULL default '', + timestamp int(11) NOT NULL default '0', + format int(4) NOT NULL default '0', + PRIMARY KEY (vid), + KEY nid (nid), + KEY uid (uid) + )"); + $ret[] = update_sql("ALTER TABLE {node} ADD vid int(10) unsigned NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {files} ADD vid int(10) unsigned NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {book} ADD vid int(10) unsigned NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {forum} ADD vid int(10) unsigned NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {book} DROP PRIMARY KEY"); + $ret[] = update_sql("ALTER TABLE {forum} DROP PRIMARY KEY"); + $ret[] = update_sql("ALTER TABLE {book} ADD KEY nid (nid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD KEY nid (nid)"); + } + else { + $ret[] = update_sql("CREATE TABLE {node_revisions} ( + vid integer NOT NULL default '0', + nid integer NOT NULL default '0', + uid integer NOT NULL default '0', + title varchar(128) NOT NULL default '', + body text NOT NULL default '', + teaser text NOT NULL default '', + log text NOT NULL default '', + timestamp integer NOT NULL default '0', + format smallint NOT NULL default '0', + PRIMARY KEY (vid) + )"); + $ret[] = update_sql("ALTER TABLE {node} ADD vid integer NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {files} ADD vid integer NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {book} ADD vid integer NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {forum} ADD vid integer NOT NULL default '0'"); + $ret[] = update_sql("CREATE INDEX node_revisions_uid_idx ON node_revisions(uid)"); + $ret[] = update_sql("CREATE INDEX node_revisions_nid_idx ON node_revisions(nid)"); + $ret[] = update_sql("ALTER TABLE {book} DROP INDEX nid"); + $ret[] = update_sql("ALTER TABLE {forum} DROP INDEX nid"); +/* This needs to be ported to pgsql + $ret[] = update_sql("ALTER TABLE {book} ADD PRIMARY KEY vid (vid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD PRIMARY KEY vid (vid)"); + $ret[] = update_sql("ALTER TABLE {book} ADD KEY nid (nid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD KEY nid (nid)"); +*/ + } + + return $ret; +} + +function update_128() { + $ret = array(); + + $vid = 0; + $result = db_query("SELECT nid, uid, type, title, body, teaser, changed, format, revisions FROM {node}"); + while ($row = db_fetch_array($result)) { + $nid = $row['nid']; + $vid++; + db_query("INSERT INTO {node_revisions} (nid, vid, uid, title, body, teaser, timestamp, format) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)", $nid, $vid, $row['uid'], $row['title'], $row['body'], $row['teaser'], $row['changed'], $row['format']); + switch ($row['type']) { + case 'forum': + db_query("UPDATE {forum} SET vid = %d WHERE nid = %d", $vid, $nid); + break; + case 'book': + db_query("UPDATE {book} SET vid = %d WHERE nid = %d", $vid, $nid); + break; + } + + db_query("UPDATE {node} SET vid = %d WHERE nid = %d", $vid, $nid); + + $revisions = unserialize($row['revisions']); + if (is_array($revisions) && count($revisions) > 0) { + foreach ($revisions as $version) { + $revision = array(); + foreach ($version['node'] as $node_field => $node_value) { + $revision[$node_field] = $node_value; + } + $revision['uid'] = $version['uid']; + $revision['timestamp'] = $version['timestamp']; + + $vid++; + db_query("INSERT INTO {node_revisions} (nid, vid, uid, title, body, teaser, log, timestamp, format) VALUES (%d, %d, %d, '%s', '%s', '%s', '%s', %d, %d)", $nid, $vid, $revision['uid'], $revision['title'], $revision['body'], $revision['teaser'], $revision['log'], $revision['timestamp'], $revision['format']); + switch ($row['type']) { + case 'forum': + db_query("INSERT INTO {forum} (vid, nid, tid) VALUES (%d, %d, %d)", $vid, $nid, $revision['tid']); + break; + case 'book': + db_query("INSERT INTO {book} (vid, nid, parent, weight) VALUES (%d, %d, %d, %d, '%s')", $vid, $nid, $revision['parent'], $revision['weight']); + break; + } + } + } + } + + // Other node types might be added to the book. Move logs too. + $result = db_query("SELECT n.nid, n.vid, n.type, b.log FROM {book} b INNER JOIN {node} n ON b.nid = n.nid"); + while ($row = db_fetch_object($result)) { + if ($row->type != 'book') { + db_query("UPDATE {book} SET vid = %d WHERE nid = %d", $row->vid, $row->nid); + } + if ($row->log != '') { + db_query("UPDATE {node_revisions} SET log = '%s' WHERE vid = %d", $row->log, $row->vid); + } + } + + // Assign existing files to current vid + $result = db_query("SELECT n.nid, n.vid FROM {node} INNER JOIN {files} f ON n.nid = f.nid"); + while ($row = db_fetch_object($result)) { + db_query("UPDATE {files} SET vid = %d WHERE nid = %d", $row->vid, $row->nid); + } + + if ($GLOBALS['db_type'] == 'mysql') { + $ret[] = update_sql("ALTER TABLE {book} ADD PRIMARY KEY vid (vid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD PRIMARY KEY vid (vid)"); + $ret[] = update_sql("CREATE TABLE {old_revisions} ( + nid integer NOT NULL default '0', + revisions text NOT NULL default '', + PRIMARY KEY (nid) + )"); + } + else { // pgsql update + } + + // Move old revisions to old_revisions table. + $result = db_query("SELECT nid, revisions FROM {node} WHERE revisions != ''"); + while ($row = db_fetch_object($result)) { + db_query("INSERT INTO {old_revisions} (nid, revisions) VALUES (%d, '%s')", $row->nid, $row->revisions); + } + + $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{node_revisions}_vid', $vid)"); + $ret[] = update_sql("ALTER TABLE {book} DROP log"); + $ret[] = update_sql("ALTER TABLE {node} DROP teaser"); + $ret[] = update_sql("ALTER TABLE {node} DROP body"); + $ret[] = update_sql("ALTER TABLE {node} DROP format"); + $ret[] = update_sql("ALTER TABLE {node} DROP revisions"); + + return $ret; +} + function update_sql($sql) { $edit = $_POST["edit"]; $result = db_query($sql); Index: includes/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.inc,v retrieving revision 1.39 diff -u -F^f -r1.39 database.inc --- includes/database.inc 19 Feb 2005 22:24:23 -0000 1.39 +++ includes/database.inc 5 Mar 2005 19:16:56 -0000 @@ -129,8 +129,13 @@ function db_set_active($name = 'default' * A string containing an SQL query. * @param ... * A variable number of arguments which are substituted into the query using - * printf() syntax. Instead of a variable number of query arguments, you may - * also pass a single array containing the query arguments. + * printf() syntax. The query arguments can be enclosed in one array instead. + * For INSERT and UPDATE queries the arguments should be present in an + * array in which the keys name the database columns. For UPDATE queries + * additional parameters can be passed as single arguments after the array. + * Examples: + * db_query('INSERT INTO {node} %a', array('nid' => 42, 'title' => 'foo bar', ...)); + * db_query('UPDATE {node} SET %a WHERE nid = %d', array('uid' => 42, 'title' => 'foo bar'), $node->nid); * @return * A database query result resource, or FALSE if the query was not executed * correctly. @@ -139,8 +144,20 @@ function db_query($query) { $args = func_get_args(); $query = db_prefix_tables($query); if (count($args) > 1) { + if (strpos($query, '%a') !== FALSE) { + if (strpos($query, 'INSERT') !== FALSE) { + $keys = array_keys($args[1]); + $insert = '('. implode(', ', $keys) .') VALUES ('. implode(', ', array_pad(array(), count($keys), "'%s'")) .')'; + $query = str_replace('%a', $insert, $query); + } + else if (strpos($query, 'UPDATE') !== FALSE) { + $keys = array_keys($args[1]); + $update = implode(" = '%s', ", $keys) ." = '%s'"; + $query = str_replace('%a', $update, $query); + } + } if (is_array($args[1])) { - $args = array_merge(array($query), $args[1]); + $args = array_merge(array($query), $args[1], array_slice($args, 2)); } $args = array_map('db_escape_string', $args); $args[0] = $query; Index: includes/database.mysql.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.mysql.inc,v retrieving revision 1.27 diff -u -F^f -r1.27 database.mysql.inc --- includes/database.mysql.inc 29 Nov 2004 13:10:43 -0000 1.27 +++ includes/database.mysql.inc 5 Mar 2005 19:16:59 -0000 @@ -236,6 +236,92 @@ function db_escape_string($text) { } /** + * Begins a transaction/lock + * + * Use this when you need to update multiple tables in such a way that + * either all of the updates go through or none do at all. This is + * especially useful for the improved revisions system. + * + * In order to accomodate older versions of MySQL that don't support + * table types that have transactions, rollback is not used, and we + * must specify which tables are going to be + * + * So, your code will look something like this: + * db_begin_transaction(array('table1', 'table2')); + * // Check if conditions are okay for this update + * if ($conditions_ok) { + * // run queries + * } + * db_commit_transaction(); + * + * You code should ALWAYS call both db_begin_transaction() and + * db_commit_transaction() and ALWAYS call them in the same order + * + * @param $tables array of tables to lock + * @return a DB_Result object or a DB_Error + */ +function db_begin_transaction($tables) { + foreach ($tables as $num => $table) { + $tables[$num]= $table .' WRITE'; + } + return db_query('LOCK TABLES '. implode(', ', $tables)); +} + +/** + * Commits a transaction/lock + * + * See db_begin_transaction() for usage details + * + * @return a DB_Result object or a DB_Error + */ +function db_commit_transaction() { + return db_query('UNLOCK TABLES'); +} + +/** + * Begins a transaction/lock + * + * Use this when you need to update multiple tables in such a way that + * either all of the updates go through or none do at all. This is + * especially useful for the improved revisions system. + * + * In order to accomodate older versions of MySQL that don't support + * table types that have transactions, rollback is not used, and we + * must specify which tables are going to be + * + * So, your code will look something like this: + * db_begin_transaction(array('table1', 'table2')); + * // Check if conditions are okay for this update + * if ($conditions_ok) { + * // run queries + * } + * db_commit_transaction(); + * + * You code should ALWAYS call both db_begin_transaction() and + * db_commit_transaction() and ALWAYS call them in the same order + * + * @param $tables array of tables to lock + * @return a DB_Result object or a DB_Error + */ +function db_begin_transaction($tables) { + foreach ($tables as $num => $table) { + $tables[$num]= '{'. $table .'} WRITE'; + } + return db_query('LOCK TABLES '. implode(', ', $tables)); +} + +/** + * Commits a transaction/lock + * + * See db_begin_transaction() for usage details + * + * @return a DB_Result object or a DB_Error + */ +function db_commit_transaction() { + return db_query('UNLOCK TABLES'); +} + +/** * @} End of "ingroup database". */ Index: includes/database.pgsql.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.pgsql.inc,v retrieving revision 1.6 diff -u -F^f -r1.6 database.pgsql.inc --- includes/database.pgsql.inc 7 Jan 2005 19:18:05 -0000 1.6 +++ includes/database.pgsql.inc 5 Mar 2005 19:17:01 -0000 @@ -231,6 +231,45 @@ function db_escape_string($text) { } /** + * Begins a transaction/lock + * + * Use this when you need to update multiple tables in such a way that + * either all of the updates go through or none do at all. This is + * especially useful for the improved revisions system. + * + * In order to accomodate older versions of MySQL that don't support + * table types that have transactions, rollback is not used, and we + * must specify which tables are going to be + * + * So, your code will look something like this: + * db_begin_transaction(array('table1', 'table2')); + * // Check if conditions are okay for this update + * if ($conditions_ok) { + * // run queries + * } + * db_commit_transaction(); + * + * You code should ALWAYS call both db_begin_transaction() and + * db_commit_transaction() and ALWAYS call them in the same order + * + * @param $tables array of tables to lock + * @return a DB_Result object or a DB_Error + */ +function db_begin_transaction($tables) { + return db_query('START TRANSACTION'); +} + +/** + * Commits a transaction/lock + * + * See db_begin_transaction() for usage details + * + * @return a DB_Result object or a DB_Error + */ +function db_commit_transaction() { + return db_query('COMMIT'); +} +/** * @} End of "ingroup database". */ Index: modules/blogapi.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blogapi.module,v retrieving revision 1.37 diff -u -F^f -r1.37 blogapi.module --- modules/blogapi.module 31 Jan 2005 19:36:20 -0000 1.37 +++ modules/blogapi.module 5 Mar 2005 19:17:10 -0000 @@ -370,7 +370,12 @@ function blogapi_get_recent_posts($req_p } $type = _blogapi_blogid($params[0]); - $result = db_query_range('SELECT n.nid, n.title,'. ($bodies ? ' n.body,' : '') ." n.created, u.name FROM {node} n, {users} u WHERE n.uid=u.uid AND n.type = '%s' AND n.uid = %d ORDER BY n.created DESC", $type, $user->uid, 0, $params[3]); + if ($bodies) { + $result = db_query_range("SELECT n.nid, n.title, r.body, n.created, u.name FROM {node} n, {node_revisions} r, {users} u WHERE n.uid = u.uid AND n.vid = r.vid AND n.type = '%s' AND n.uid = %d ORDER BY n.created DESC", $type, $user->uid, 0, $params[3]); + } + else { + $result = db_query_range("SELECT n.nid, n.title, n.created, u.name FROM {node} n, {users} u WHERE n.uid = u.uid AND n.type = '%s' AND n.uid = %d ORDER BY n.created DESC", $type, $user->uid, 0, $params[3]); + } while ($blog = db_fetch_object($result)) { $xmlrpcval = _blogapi_get_post($blog, $bodies); $blogs[] = $xmlrpcval; Index: modules/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book.module,v retrieving revision 1.285 diff -u -F^f -r1.285 book.module --- modules/book.module 12 Feb 2005 07:51:14 -0000 1.285 +++ modules/book.module 5 Mar 2005 19:17:20 -0000 @@ -111,7 +111,7 @@ function book_menu($may_cache) { // We don't want to cache these menu items because they could change whenever // a book page or outline node is edited. if (arg(0) == 'admin' && arg(1) == 'node' && arg(2) == 'book') { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 ORDER BY b.weight, n.title')); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = 0 ORDER BY b.weight, n.title')); while ($book = db_fetch_object($result)) { $items[] = array('path' => 'admin/node/book/'. $book->nid, 'title' => t('"%title" book', array('%title' => $book->title))); } @@ -136,7 +136,7 @@ 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.nid = b.nid 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} b ON n.vid = b.vid WHERE n.nid = %d'), arg(1)); if (db_num_rows($result) > 0) { $node = db_fetch_object($result); @@ -163,7 +163,7 @@ function book_block($op = 'list', $delta function book_load($node) { global $user; - $book = db_fetch_object(db_query('SELECT parent, weight, log FROM {book} WHERE nid = %d', $node->nid)); + $book = db_fetch_object(db_query('SELECT parent, weight FROM {book} WHERE vid = %d', $node->vid)); if (arg(2) == 'edit' && !user_access('administer nodes')) { // If a user is about to update a book page, we overload some @@ -185,14 +185,19 @@ function book_load($node) { * Implementation of hook_insert(). */ 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); + db_query("INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $node->parent, $node->weight); } /** * Implementation of hook_update(). */ 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); + if ($node->is_new || $node->revision) { + db_query("INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d, '%s')", $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); + } } /** @@ -229,6 +234,7 @@ function book_form(&$node) { $output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, '', NULL, TRUE); $output .= filter_form('format', $node->format); + $output .= form_textarea(t('Log message'), 'log', $node->log, 60, 5, t('An explanation of the additions or updates being made to help other authors understand your motivations.')); if (user_access('administer nodes')) { @@ -256,13 +262,15 @@ function book_outline() { if ($node->nid) { 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']); + db_query('INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)', $node->nid, $node->vid, $edit['parent'], $edit['weight']); + db_query("UPDATE {node_revisions} SET log = '%s' WHERE vid = %d", $edit['log'], $node->vid); 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); + db_query('UPDATE {book} SET parent = %d, weight = %d WHERE vid = %d', $edit['parent'], $edit['weight'], $node->vid); + db_query("UPDATE {node_revisions} SET log = '%s' WHERE vid = %d", $edit['log'], $node->vid); drupal_set_message(t('Updated the book outline.')); drupal_goto("node/$node->nid"); break; @@ -274,10 +282,11 @@ function book_outline() { break; default: - $page = db_fetch_object(db_query('SELECT * FROM {book} WHERE nid = %d', $node->nid)); + $page = db_fetch_object(db_query('SELECT * FROM {book} WHERE vid = %d', $node->vid)); $output = form_select(t('Parent'), 'parent', $page->parent, book_toc($node->nid), t('The parent page in the book.')); - $output .= form_weight(t('Weight'), 'weight', $node->weight, 15, t('Pages at a given level are ordered first by weight and then by title.')); + $output .= form_weight(t('Weight'), 'weight', $page->weight, 15, t('Pages at a given level are ordered first by weight and then by title.')); + $output .= form_textarea(t('Log message'), 'log', $node->log, 60, 5, t('An explanation of the additions or updates being made to help other authors understand your motivations.')); if ($page->nid) { $output .= form_submit(t('Update book outline')); @@ -325,7 +334,7 @@ function book_revision_load($page, $cond * Return the path (call stack) to a certain book page. */ 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.nid = b.nid 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} b ON n.vid = b.vid WHERE n.nid = %d'), $node->parent)); if ($parent->title) { $nodes = book_location($parent, $nodes); array_push($nodes, $parent); @@ -334,7 +343,7 @@ function book_location($node, $nodes = a } 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.nid = b.nid WHERE 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} b ON n.vid = b.vid WHERE b.parent = %d ORDER BY b.weight DESC, n.title DESC'), $node->nid)); if ($last_direct_child) { array_push($nodes, $last_direct_child); $nodes = book_location_down($last_direct_child, $nodes); @@ -352,7 +361,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 FROM {node} n INNER JOIN {book} b ON n.nid = b.nid 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 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)); if ($direct_above) { // Get last leaf of $above. $path = book_location_down($direct_above); @@ -361,7 +370,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.nid = b.nid 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} b ON n.vid = b.vid WHERE n.nid = %d AND n.status = 1 AND n.moderate = 0'), $node->parent)); return $prev; } } @@ -371,7 +380,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.nid = b.nid 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} 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; } @@ -380,7 +389,7 @@ function book_next($node) { array_push($path = book_location($node), $node); // Path to top-level node including this one. 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.nid = b.nid 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} 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; } @@ -415,10 +424,6 @@ function book_content($node, $teaser = F */ function book_view(&$node, $teaser = FALSE, $page = FALSE) { $node = book_content($node, $teaser); - - if (!$teaser && $node->moderate) { - $node->body .= '