Index: database/database.mysql =================================================================== RCS file: /cvs/drupal/drupal/database/database.mysql,v retrieving revision 1.194 diff -u -p -r1.194 database.mysql --- database/database.mysql 16 Aug 2005 18:06:18 -0000 1.194 +++ database/database.mysql 28 Aug 2005 18:25:00 -0000 @@ -136,11 +136,12 @@ CREATE TABLE blocks ( -- 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; @@ -243,12 +244,14 @@ CREATE TABLE directory ( 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 '', filesize int(10) unsigned NOT NULL default '0', list tinyint(1) unsigned NOT NULL default '0', - PRIMARY KEY (fid) + KEY vid (vid), + KEY fid (fid) ) TYPE=MyISAM; -- @@ -403,6 +406,7 @@ CREATE TABLE moderation_votes ( CREATE TABLE node ( nid int(10) unsigned NOT NULL auto_increment, + vid int(10) unsigned NOT NULL default '0', type varchar(32) NOT NULL default '', title varchar(128) NOT NULL default '', uid int(10) NOT NULL default '0', @@ -412,16 +416,13 @@ CREATE TABLE node ( 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), @@ -442,6 +443,24 @@ CREATE TABLE node_access ( 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.133 diff -u -p -r1.133 database.pgsql --- database/database.pgsql 16 Aug 2005 18:06:18 -0000 1.133 +++ database/database.pgsql 28 Aug 2005 18:25:00 -0000 @@ -131,12 +131,13 @@ CREATE TABLE blocks ( -- 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) + PRIMARY KEY (vid) ); +CREATE INDEX book_vid_idx ON book(vid); CREATE INDEX book_nid_idx ON book(nid); CREATE INDEX book_parent ON book(parent); @@ -239,13 +240,15 @@ CREATE TABLE directory ( 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 '', filesize integer NOT NULL default '0', - list smallint NOT NULL default '0', - PRIMARY KEY (fid) + list smallint NOT NULL default '0' ); +CREATE INDEX files_fid_idx ON files(fid); +CREATE INDEX files_vid_idx ON files(vid); -- -- Table structure for table 'filter_formats' @@ -403,6 +406,7 @@ CREATE TABLE moderation_votes ( CREATE TABLE node ( nid SERIAL, + vid integer NOT NULL default '0', type varchar(32) NOT NULL default '', title varchar(128) NOT NULL default '', uid integer NOT NULL default '0', @@ -412,11 +416,7 @@ CREATE TABLE node ( comment integer NOT NULL default '0', promote integer NOT NULL default '0', moderate integer NOT NULL default '0', - teaser text NOT NULL default '', - body text NOT NULL default '', - revisions text NOT NULL default '', sticky integer NOT NULL default '0', - format smallint NOT NULL default '0', PRIMARY KEY (nid) ); CREATE INDEX node_type_idx ON node(type); @@ -427,6 +427,7 @@ CREATE INDEX node_moderate_idx ON node ( CREATE INDEX node_promote_status_idx ON node (promote, status); CREATE INDEX node_created ON node(created); CREATE INDEX node_changed ON node(changed); +CREATE INDEX node_vid_idx ON node(vid); -- -- Table structure for table `node_access` @@ -442,6 +443,24 @@ CREATE TABLE node_access ( PRIMARY KEY (nid,gid,realm) ); +-- +-- Table structure for table 'node_revisions' +-- + +CREATE TABLE node_revisions ( + nid integer NOT NULL default '0', + vid 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 int NOT NULL default '0', + PRIMARY KEY (nid,vid) +); +CREATE INDEX node_revisions_uid_idx ON node_revisions(uid); +CREATE SEQUENCE node_revisions_vid_seq INCREMENT 1 START 1; -- -- Table structure for table 'node_counter' Index: database/updates.inc =================================================================== RCS file: /cvs/drupal/drupal/database/updates.inc,v retrieving revision 1.128 diff -u -p -r1.128 updates.inc --- database/updates.inc 16 Aug 2005 20:17:54 -0000 1.128 +++ database/updates.inc 28 Aug 2005 18:25:00 -0000 @@ -43,7 +43,8 @@ $sql_updates = array( "2005-07-29" => "update_142", "2005-07-30" => "update_143", "2005-08-08" => "update_144", - "2005-08-15" => "update_145" + "2005-08-15" => "update_145", + "2005-08-25" => "update_146" ); function update_110() { @@ -705,6 +706,66 @@ function update_145() { return $ret; } +function update_146() { + $ret = array(); + + if ($GLOBALS['db_type'] == 'mysql') { + $ret[] = update_sql("CREATE TABLE {node_revisions} + SELECT nid, nid as vid, uid, type, title, body, teaser, changed, format + FROM {node}"); + + $ret[] = update_sql("ALTER TABLE {node_revisions} CHANGE nid nid int(10) unsigned NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {node_revisions} ADD log longtext"); + $ret[] = update_sql("ALTER TABLE {node_revisions} CHANGE changed timestamp int(11) NOT NULL default '0'"); + + $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 {node_revisions} DROP PRIMARY KEY"); + $ret[] = update_sql("ALTER TABLE {book} DROP PRIMARY KEY"); + $ret[] = update_sql("ALTER TABLE {forum} DROP PRIMARY KEY"); + $ret[] = update_sql("ALTER TABLE {files} DROP PRIMARY KEY"); + + $ret[] = update_sql("UPDATE {node} SET vid = nid"); + $ret[] = update_sql("UPDATE {forum} SET vid = nid"); + $ret[] = update_sql("UPDATE {book} SET vid = nid"); + $ret[] = update_sql("UPDATE {files} SET vid = nid"); + + $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 {node_revisions} ADD PRIMARY KEY vid (vid)"); + $ret[] = update_sql("ALTER TABLE {node_revisions} ADD KEY nid (nid)"); + $ret[] = update_sql("ALTER TABLE {node_revisions} ADD KEY uid (uid)"); + + $ret[] = update_sql("CREATE TABLE {old_revisions} SELECT nid, revisions FROM {node} WHERE revisions != ''"); + + $ret[] = update_sql("ALTER TABLE {book} ADD KEY nid (nid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD KEY nid (nid)"); + $ret[] = update_sql("ALTER TABLE {files} ADD KEY fid (fid)"); + $ret[] = update_sql("ALTER TABLE {files} ADD KEY vid (vid)"); + $vid = db_next_id('{node}_nid'); + $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{node_revisions}_vid', $vid)"); + } + else { // pgsql + } + + // Move logs too. + $result = db_query("SELECT nid, log FROM {book} WHERE log != ''"); + while ($row = db_fetch_object($result)) { + db_query("UPDATE {node_revisions} SET log = '%s' WHERE vid = %d", $row->log, $row->nid); + } + + $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: modules/blogapi.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blogapi.module,v retrieving revision 1.54 diff -u -p -r1.54 blogapi.module --- modules/blogapi.module 28 Aug 2005 15:29:34 -0000 1.54 +++ modules/blogapi.module 28 Aug 2005 18:25:00 -0000 @@ -218,9 +218,9 @@ function blogapi_blogger_new_post($appke return blogapi_error(t('You do not have permission to create the type of post you wanted to create.')); } - $nid = node_save($node); - if ($nid) { - watchdog('content', t('%type: added %title using blog API.', array('%type' => ''. t($node->type) .'', '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$nid")); + node_save(&$node); + if ($node->nid) { + watchdog('content', t('%type: added %title using blog API.', array('%type' => ''. t($node->type) .'', '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid")); return $nid; } @@ -276,9 +276,9 @@ function blogapi_blogger_edit_post($appk foreach ($terms as $term) { $node->taxonomy[] = $term->tid; } - $nid = node_save($node); - if ($nid) { - watchdog('content', t('%type: updated %title using blog API.', array('%type' => ''. t($node->type) .'', '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$nid")); + node_save(&$node); + if ($node->nid) { + watchdog('content', t('%type: updated %title using blog API.', array('%type' => ''. t($node->type) .'', '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid")); return true; } @@ -325,7 +325,12 @@ function blogapi_blogger_get_recent_post } $type = _blogapi_blogid($blogid); - $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, $number_of_posts); + 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, $number_of_posts); + } + 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, $number_of_posts); + } while ($blog = db_fetch_object($result)) { $blogs[] = _blogapi_get_post($blog, $bodies); } Index: modules/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book.module,v retrieving revision 1.312 diff -u -p -r1.312 book.module --- modules/book.module 28 Aug 2005 15:29:34 -0000 1.312 +++ modules/book.module 28 Aug 2005 18:25:00 -0000 @@ -145,7 +145,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); @@ -172,7 +172,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 @@ -194,14 +194,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->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); + } } /** @@ -234,6 +239,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')) { @@ -261,13 +267,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('The post has been added 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('The book outline has been updated.')); drupal_goto("node/$node->nid"); break; @@ -279,10 +287,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', $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 to help other authors understand your motivations to put this post into the book.')); if ($page->nid) { $output .= form_submit(t('Update book outline')); @@ -330,7 +339,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); @@ -360,7 +369,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.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, 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)); if ($direct_above) { // Get last leaf of $above. $path = book_location_down($direct_above); @@ -369,7 +378,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; } } @@ -379,7 +388,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; } @@ -388,7 +397,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; } @@ -429,10 +438,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 .= '
'. t('Log') .':
'. $node->log .'
'; - } } /** @@ -444,7 +449,7 @@ function book_nodeapi(&$node, $op, $teas switch ($op) { case 'view': if (!$teaser) { - $book = db_fetch_array(db_query('SELECT * FROM {book} WHERE nid = %d', $node->nid)); + $book = db_fetch_array(db_query('SELECT * FROM {book} 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.")); @@ -543,7 +548,7 @@ 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.nid = b.nid 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} b ON n.vid = b.vid WHERE n.status = 1 ORDER BY b.weight, n.title')); while ($node = db_fetch_object($result)) { if (!$children[$node->parent]) { @@ -603,7 +608,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.nid = b.nid WHERE n.status = 1 AND n.moderate = 0 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} 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 = $children[$node->parent] ? $children[$node->parent] : array(); @@ -620,7 +625,7 @@ 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.nid = b.nid WHERE b.parent = 0 AND n.status = 1 AND n.moderate = 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} b ON n.vid = b.vid WHERE b.parent = 0 AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title')); $books = array(); while ($node = db_fetch_object($result)) { @@ -757,7 +762,7 @@ function _book_get_depth($nid) { * - 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.nid = b.nid 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} 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); @@ -775,7 +780,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.nid = b.nid 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} 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) { @@ -965,7 +970,7 @@ function book_admin_edit_line($node, $de } function book_admin_edit_book($nid, $depth = 1) { - $result = db_query(db_rewrite_sql('SELECT n.nid, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight, n.title'), $nid); + $result = 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'), $nid); $rows = array(); @@ -1008,15 +1013,16 @@ function book_admin_save($nid, $edit = a foreach ($edit as $nid => $value) { // Check to see whether the title needs updating: - $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid)); - if ($title != $value['title']) { + $node = db_fetch_object(db_query('SELECT title, vid FROM {node} WHERE nid = %d', $nid)); + if ($node->title != $value['title']) { db_query("UPDATE {node} SET title = '%s' WHERE nid = %d", $value['title'], $nid); + db_query("UPDATE {book} SET title = '%s' WHERE vid = %d", $value['title'], $node->vid); } // Check to see whether the weight needs updating: - $weight = db_result(db_query('SELECT weight FROM {book} WHERE nid = %d', $nid)); - if ($weight != $value['weight']) { - db_query('UPDATE {book} SET weight = %d WHERE nid = %d', $value['weight'], $nid); + $node = db_fetch_object(db_query('SELECT b.vid, b.weight FROM {book} b INNER JOIN {node} n ON n.vid = b.vid WHERE n.nid = %d', $nid)); + if ($node->weight != $value['weight']) { + db_query('UPDATE {book} SET weight = %d WHERE vid = %d', $value['weight'], $node->vid); } } @@ -1031,7 +1037,7 @@ function book_admin_save($nid, $edit = a * 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.nid = b.nid')); + $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')); while ($page = db_fetch_object($result)) { $pages[$page->nid] = $page; @@ -1075,7 +1081,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.nid = b.nid 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} 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")); } Index: modules/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment.module,v retrieving revision 1.367 diff -u -p -r1.367 comment.module --- modules/comment.module 28 Aug 2005 15:16:58 -0000 1.367 +++ modules/comment.module 28 Aug 2005 18:25:00 -0000 @@ -793,7 +793,7 @@ function comment_render($node, $cid = 0) $output .= '
\n"; $output .= form_hidden('nid', $nid); - $result = db_query('SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.data, c.score, c.users FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = %d GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, c.name, c.mail, u.picture, c.homepage, u.uid, u.name, u.picture, u.data, c.score, c.users', $cid, COMMENT_PUBLISHED); + $result = db_query('SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.data, c.score, c.users FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = %d GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, u.picture, c.homepage, u.uid, u.name, u.picture, u.data, c.score, c.users', $cid, COMMENT_PUBLISHED); if ($comment = db_fetch_object($result)) { $comment->name = $comment->uid ? $comment->registered_name : $comment->name; Index: modules/forum.module =================================================================== RCS file: /cvs/drupal/drupal/modules/forum.module,v retrieving revision 1.264 diff -u -p -r1.264 forum.module --- modules/forum.module 28 Aug 2005 15:58:52 -0000 1.264 +++ modules/forum.module 28 Aug 2005 18:25:00 -0000 @@ -335,7 +335,7 @@ function forum_admin_configure() { * Implementation of hook_load(). */ function forum_load($node) { - $forum = db_fetch_object(db_query('SELECT * FROM {forum} WHERE nid = %d', $node->nid)); + $forum = db_fetch_object(db_query('SELECT * FROM {forum} WHERE vid = %d', $node->vid)); return $forum; } @@ -546,7 +546,12 @@ function forum_validate(&$node) { * Implementation of hook_update(). */ function forum_update($node) { - db_query('UPDATE {forum} SET tid = %d WHERE nid = %d', $node->tid, $node->nid); + if ($node->is_new || $node->revision) { + db_query("INSERT INTO {forum} (nid, vid, tid) VALUES (%d, %d, %d)", $node->nid, $node->vid, $node->tid); + } + else { + db_query('UPDATE {forum} SET tid = %d WHERE vid = %d', $node->tid, $node->vid); + } } /** @@ -579,7 +584,7 @@ function forum_form(&$node) { * Implementation of hook_insert(). */ function forum_insert($node) { - db_query('INSERT INTO {forum} (nid, tid) VALUES (%d, %d)', $node->nid, $node->tid); + db_query('INSERT INTO {forum} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $node->tid); } /** @@ -704,7 +709,7 @@ function forum_get_topics($tid, $sortby, $term = taxonomy_get_term($tid); - $sql = db_rewrite_sql("SELECT n.nid, f.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node} n, {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {forum} f WHERE n.status = 1 AND l.last_comment_uid = cu.uid AND n.nid = l.nid AND n.nid = r.nid AND r.tid = %d AND n.uid = u.uid AND n.nid = f.nid"); + $sql = db_rewrite_sql("SELECT n.nid, f.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node} n, {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {forum} f WHERE n.status = 1 AND l.last_comment_uid = cu.uid AND n.nid = l.nid AND n.nid = r.nid AND r.tid = %d AND n.uid = u.uid AND n.vid = f.vid"); $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,'); $sql_count = db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum'"); Index: modules/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node.module,v retrieving revision 1.524 diff -u -p -r1.524 node.module --- modules/node.module 28 Aug 2005 15:29:34 -0000 1.524 +++ modules/node.module 28 Aug 2005 18:25:00 -0000 @@ -367,31 +367,27 @@ function node_load($param = array(), $re } // Retrieve the node. - $node = db_fetch_object(db_query(db_rewrite_sql('SELECT n.*, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE '. $cond))); - $node = drupal_unpack($node); - - // Unserialize the revisions and user data fields. - if ($node->revisions) { - $node->revisions = unserialize($node->revisions); + if ($revision) { + $node = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, r.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.moderate, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.nid = n.nid AND r.vid = %d WHERE '. $cond), $revision)); } - - // Call the node specific callback (if any) and piggy-back the - // results to the node or overwrite some values. - if ($extra = node_invoke($node, 'load')) { - foreach ($extra as $key => $value) { - $node->$key = $value; - } + else { + $node = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.moderate, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond))); } - if ($extra = node_invoke_nodeapi($node, 'load')) { - foreach ($extra as $key => $value) { - $node->$key = $value; + if ($node->nid) { + // Call the node specific callback (if any) and piggy-back the + // results to the node or overwrite some values. + if ($extra = node_invoke($node, 'load')) { + foreach ($extra as $key => $value) { + $node->$key = $value; + } } - } - // Return the desired revision. - if (!is_null($revision) && is_array($node->revisions[$revision])) { - $node = $node->revisions[$revision]['node']; + if ($extra = node_invoke_nodeapi($node, 'load')) { + foreach ($extra as $key => $value) { + $node->$key = $value; + } + } } if ($cachable) { @@ -405,61 +401,100 @@ function node_load($param = array(), $re * Save a node object into the database. */ function node_save($node) { - // Fetch fields to save to node table: - $fields = node_invoke_nodeapi($node, 'fields'); + global $user; - // Serialize the revisions field: - if ($node->revisions) { - $node->revisions = serialize($node->revisions); - } + $node->is_new = false; // Apply filters to some default node fields: if (empty($node->nid)) { // Insert a new node. + $node->is_new = true; // Set some required fields: if (!$node->created) { $node->created = time(); } - if (!$node->changed) { + $node->nid = db_next_id('{node}_nid'); + $node->vid = db_next_id('{node_revisions}_vid');; + } + else { + // We need to ensure that all node fields are filled. + $node_current = node_load($node->nid); + foreach ($node as $field => $data) { + $node_current->$field = $data; + } + $node = $node_current; + + if ($node->revision) { + $node->old_vid = $node->vid; + $node->vid = db_next_id('{node_revisions}_vid'); + // We always update the timestamp for new revisions. $node->changed = time(); } - $node->nid = db_next_id('{node}_nid'); + } - // Prepare the query: - foreach ($node as $key => $value) { - if (in_array((string) $key, $fields)) { - $k[] = db_escape_string($key); - $v[] = $value; - $s[] = "'%s'"; + if (!$node->changed) { + $node->changed = time(); + } + + // Split off revisions data to another structure + $revisions_table_values = array('nid' => $node->nid, 'vid' => $node->vid, + 'title' => $node->title, 'body' => $node->body, + 'teaser' => $node->teaser, 'log' => $node->log, 'timestamp' => $node->changed, + 'uid' => $user->uid, 'format' => $node->format); + $revisions_table_types = array('nid' => '%d', 'vid' => '%d', + 'title' => "'%s'", 'body' => "'%s'", + 'teaser' => "'%s'", 'log' => "'%s'", 'timestamp' => '%d', + 'uid' => '%d', 'format' => '%d'); + $node_table_values = array('nid' => $node->nid, 'vid' => $node->vid, + 'title' => $node->title, 'type' => $node->type, 'uid' => $node->uid, + 'status' => $node->status, 'created' => $node->created, + 'changed' => $node->changed, 'comment' => $node->comment, + 'promote' => $node->promote, 'moderate' => $node->moderate, + 'sticky' => $node->sticky); + $node_table_types = array('nid' => '%d', 'vid' => '%d', + 'title' => "'%s'", 'type' => "'%s'", 'uid' => '%d', + 'status' => '%d', 'created' => '%d', + 'changed' => '%d', 'comment' => '%d', + 'promote' => '%d', 'moderate' => '%d', + 'sticky' => '%d'); + + //Generate the node table query and the + //the node_revisions table query + if ($node->is_new) { + $node_query = 'INSERT INTO {node} ('. implode(', ', array_keys($node_table_types)) .') VALUES ('. implode(', ', $node_table_types) .')'; + $revisions_query = 'INSERT INTO {node_revisions} ('. implode(', ', array_keys($revisions_table_types)) .') VALUES ('. implode(', ', $revisions_table_types) .')'; + } + else { + $arr = array(); + foreach ($node_table_types as $key => $value) { + $arr[] = $key .' = '. $value; + } + $node_table_values[] = $node->nid; + $node_query = 'UPDATE {node} SET '. implode(', ', $arr) .' WHERE nid = %d'; + if ($node->revision) { + $revisions_query = 'INSERT INTO {node_revisions} ('. implode(', ', array_keys($revisions_table_types)) .') VALUES ('. implode(', ', $revisions_table_types) .')'; + } + else { + $arr = array(); + foreach ($revisions_table_types as $key => $value) { + $arr[] = $key .' = '. $value; } + $revisions_table_values[] = $node->vid; + $revisions_query = 'UPDATE {node_revisions} SET '. implode(', ', $arr) .' WHERE vid = %d'; } + } - // Insert the node into the database: - db_query("INSERT INTO {node} (". implode(", ", $k) .") VALUES(". implode(", ", $s) .")", $v); + // Insert the node into the database: + db_query($node_query, $node_table_values); + db_query($revisions_query, $revisions_table_values); - // Call the node specific callback (if any): + // Call the node specific callback (if any): + if ($node->is_new) { node_invoke($node, 'insert'); node_invoke_nodeapi($node, 'insert'); } else { - // Update an existing node. - - // Set some required fields: - $node->changed = time(); - - // Prepare the query: - foreach ($node as $key => $value) { - if (in_array($key, $fields)) { - $q[] = db_escape_string($key) ." = '%s'"; - $v[] = $value; - } - } - - // Update the node in the database: - db_query("UPDATE {node} SET ". implode(', ', $q) ." WHERE nid = '$node->nid'", $v); - - // Call the node specific callback (if any): node_invoke($node, 'update'); node_invoke_nodeapi($node, 'update'); } @@ -468,7 +503,7 @@ function node_save($node) { cache_clear_all(); // Return the node ID: - return $node->nid; + return $node; } /** @@ -493,6 +528,10 @@ function node_view($node, $teaser = FALS // TODO: this strips legitimate uses of '' also. $node->body = str_replace('', '', $node->body); + if ($node->log != '' && !$teaser && $node->moderate) { + $node->body .= '
'. t('Log') .':
'. $node->log .'
'; + } + // The 'view' hook can be implemented to overwrite the default function // to display nodes. if (node_hook($node, 'view')) { @@ -701,8 +740,7 @@ function node_menu($may_cache) { 'access' => node_access('delete', $node), 'weight' => 1, 'type' => MENU_CALLBACK); - - if ($node->revisions) { + if (user_access('administer nodes') && db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', arg(1))) > 1) { $items[] = array('path' => 'node/'. arg(1) .'/revisions', 'title' => t('revisions'), 'callback' => 'node_page', 'access' => user_access('administer nodes'), @@ -982,13 +1020,38 @@ function node_revision_overview($nid) { if (user_access('administer nodes')) { $node = node_load($nid); - drupal_set_title(check_plain($node->title)); + drupal_set_title(t('Revisions for %title', array('%title' => check_plain($node->title)))); - if ($node->revisions) { - $header = array(t('Older revisions'), array('colspan' => '3', 'data' => t('Operations'))); + if ($node->vid) { + $header = array('', t('Author'), t('Title'), t('Date'), array('colspan' => '3', 'data' => t('Operations'))); - foreach ($node->revisions as $key => $revision) { - $rows[] = array(t('revision #%r revised by %u on %d', array('%r' => $key, '%u' => theme('username', user_load(array('uid' => $revision['uid']))), '%d' => format_date($revision['timestamp'], 'small'))) . ($revision['history'] ? '
'. $revision['history'] .'' : ''), l(t('view'), "node/$node->nid", array(), "revision=$key"), l(t('rollback'), "node/$node->nid/rollback-revision/$key"), l(t('delete'), "node/$node->nid/delete-revision/$key")); + $revisions = node_revision_list($node); + + $i = 0; + foreach ($revisions as $revision) { + $row = ++$i; + if ($revision->current_vid) { + $rows[] = array( + array('data' => $row .' '. t('(current)'), 'rowspan' => ($revision->log != '') ? 2 : 1), + theme('username', $revision), + $revision->title, + format_date($revision->timestamp, 'small'), + l(t('view'), "node/$node->nid"), + '', ''); + } + else { + $rows[] = array( + array('data' => $row, 'rowspan' => ($revision->log != '') ? 2 : 1), + theme('username', $revision), + $revision->title, + format_date($revision->timestamp, 'small'), + l(t('view'), "node/$node->nid/revision/". $revision->vid), + l(t('set active'), "node/$node->nid/rollback-revision/". $revision->vid), + l(t('delete'), "node/$node->nid/delete-revision/". $revision->vid)); + } + if ($revision->log != '') { + $rows[] = array(array('data' => $revision->log, 'colspan' => 6)); + } } $output .= theme('table', $header, $rows); } @@ -997,32 +1060,6 @@ function node_revision_overview($nid) { return $output; } - -/** - * Return the revision with the specified revision number. - */ -function node_revision_load($node, $revision) { - return $node->revisions[$revision]['node']; -} - -/** - * Create and return a new revision of the given node. - */ -function node_revision_create($node) { - global $user; - - // "Revision" is the name of the field used to indicate that we have to - // create a new revision of a node. - if ($node->nid && $node->revision) { - $prev = node_load($node->nid); - $node->revisions = $prev->revisions; - unset($prev->revisions); - $node->revisions[] = array('uid' => $user->uid, 'timestamp' => time(), 'node' => $prev, 'history' => $node->history); - } - - return $node; -} - /** * Roll back to the revision with the specified revision number. */ @@ -1030,28 +1067,14 @@ function node_revision_rollback($nid, $r global $user; if (user_access('administer nodes')) { - $node = node_load($nid); - - // Extract the specified revision: - $rev = $node->revisions[$revision]['node']; + if($title = db_fetch_object(db_query('SELECT title, timestamp FROM {node_revisions} WHERE nid = %d AND vid = %d', $nid, $revision))) { + db_query('UPDATE {node} SET vid = %d, changed = %d WHERE nid = %d', $revision, $title->timestamp, $nid); - // Inherit all the past revisions: - $rev->revisions = $node->revisions; - - // Save the original/current node: - $rev->revisions[] = array('uid' => $user->uid, 'timestamp' => time(), 'node' => $node); - - // Remove the specified revision: - unset($rev->revisions[$revision]); - - // Save the node: - foreach ($node as $key => $value) { - $filter[] = $key; + drupal_set_message(t('%title has been rolled back to the revision from %revision-date', array('%revision-date' => theme('placeholder', format_date($title->timestamp)), '%title' => theme('placeholder', check_plain($title->title))))); + } + else { + drupal_set_message(t('You tried to roll back to an invalid revision.'), 'error'); } - - node_save($rev, $filter); - - drupal_set_message(t('Rolled back to revision %revision of %title', array('%revision' => "#$revision", '%title' => theme('placeholder', $node->title)))); drupal_goto('node/'. $nid .'/revisions'); } } @@ -1061,14 +1084,17 @@ function node_revision_rollback($nid, $r */ function node_revision_delete($nid, $revision) { if (user_access('administer nodes')) { - $node = node_load($nid); - - unset($node->revisions[$revision]); - - node_save($node, array('nid', 'revisions')); + $count_revisions = db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $nid)); + // Don't delete the last revision of the node or the current revision + if ($count_revisions > 1) { + db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $nid, $revision); + drupal_set_message(t('Deleted revision with the ID %revision.', array('%revision' => theme('placeholder', $revision)))); + } + else { + drupal_set_message(t('Deletion failed. You tried to delete the current revision.')); + } - drupal_set_message(t('Deleted revision %revision of %title', array('%revision' => "#$revision", '%title' => theme('placeholder', $node->title)))); - drupal_goto('node/'. $nid . (count($node->revisions) ? '/revisions' : '')); + drupal_goto("node/$nid/revisions"); } } @@ -1076,12 +1102,13 @@ function node_revision_delete($nid, $rev * Return a list of all the existing revision numbers. */ function node_revision_list($node) { - if (is_array($node->revisions)) { - return array_keys($node->revisions); - } - else { - return array(); + $revisions = array(); + $result = db_query('SELECT r.vid, r.title, r.log, r.uid, n.vid AS current_vid, r.timestamp, u.name FROM {node_revisions} r LEFT JOIN {node} n ON n.vid = r.vid INNER JOIN {users} u ON u.uid = r.uid WHERE r.nid = %d ORDER BY r.timestamp ASC', $node->nid); + while ($revision = db_fetch_object($result)) { + $revisions[] = $revision; } + + return $revisions; } /** @@ -1257,9 +1284,6 @@ function node_validate($node) { unset($node->created); } - // Create a new revision when required. - $node = node_revision_create($node); - // Do node-type-specific validation checks. node_invoke($node, 'validate'); node_invoke_nodeapi($node, 'validate'); @@ -1549,7 +1573,7 @@ function node_submit(&$node) { // Check whether the current user has the proper access rights to // perform this operation: if (node_access('update', $node)) { - $node->nid = node_save($node); + node_save(&$node); watchdog('content', t('%type: updated %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid)); $msg = t('The %post was updated.', array ('%post' => node_get_name($node))); } @@ -1558,7 +1582,7 @@ function node_submit(&$node) { // Check whether the current user has the proper access rights to // perform this operation: if (node_access('create', $node)) { - $node->nid = node_save($node); + node_save(&$node); watchdog('content', t('%type: added %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid")); $msg = t('Your %post was created.', array ('%post' => node_get_name($node))); } @@ -1578,8 +1602,8 @@ function node_delete($edit) { if (node_access('delete', $node)) { if ($edit['confirm']) { - // Delete the specified node: db_query('DELETE FROM {node} WHERE nid = %d', $node->nid); + db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid); // Call the node-specific callback (if any): node_invoke($node, 'delete'); @@ -1702,6 +1726,18 @@ function node_page() { } } break; + case 'revision': + if (is_numeric(arg(1)) && is_numeric(arg(3))) { + $node = node_load(arg(1), arg(3)); + if ($node->nid) { + drupal_set_title(t('Revision of %title', array('%title' => theme('placeholder', $node->title)))); + print theme('page', node_show($node, arg(2))); + } + else { + drupal_not_found(); + } + } + break; case t('Preview'): $edit = node_validate($edit); drupal_set_title(t('Preview')); @@ -1799,9 +1835,6 @@ function node_nodeapi(&$node, $op, $arg case 'settings': // $node contains the type name in this operation return form_checkboxes(t('Default options'), 'node_options_'. $node->type, variable_get('node_options_'. $node->type, array('status', 'promote')), array('status' => t('Published'), 'moderate' => t('In moderation queue'), 'promote' => t('Promoted to front page'), 'sticky' => t('Sticky at top of lists'), 'revision' => t('Create new revision')), t('Users with the administer nodes permission will be able to override these options.')); - - case 'fields': - return array('nid', 'uid', 'type', 'title', 'teaser', 'body', 'revisions', 'status', 'promote', 'moderate', 'sticky', 'created', 'changed', 'format'); } } Index: modules/page.module =================================================================== RCS file: /cvs/drupal/drupal/modules/page.module,v retrieving revision 1.134 diff -u -p -r1.134 page.module --- modules/page.module 28 Aug 2005 15:29:34 -0000 1.134 +++ modules/page.module 28 Aug 2005 18:25:00 -0000 @@ -74,6 +74,8 @@ function page_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.')); + return $output; } Index: modules/upload.module =================================================================== RCS file: /cvs/drupal/drupal/modules/upload.module,v retrieving revision 1.47 diff -u -p -r1.47 upload.module --- modules/upload.module 25 Aug 2005 21:14:17 -0000 1.47 +++ modules/upload.module 28 Aug 2005 18:25:00 -0000 @@ -314,7 +314,7 @@ function upload_nodeapi(&$node, $op, $ar * The ammount of disk space used by the user in bytes. */ function upload_space_used($uid) { - return db_result(db_query('SELECT SUM(f.filesize) FROM {files} f INNER JOIN {node} n ON f.nid = n.nid WHERE uid = %d', $uid)); + return db_result(db_query('SELECT SUM(f.filesize) FROM {files} f INNER JOIN {node_revisions} n ON f.vid = n.vid WHERE uid = %d', $uid)); } /** @@ -324,7 +324,7 @@ function upload_space_used($uid) { * The ammount of disk space used by uploaded files in bytes. */ function upload_total_space_used() { - return db_result(db_query('SELECT SUM(f.filesize) FROM {files} f INNER JOIN {node} n ON f.nid = n.nid')); + return db_result(db_query('SELECT SUM(f.filesize) FROM {files} f INNER JOIN {node_revisions} n ON f.vid = n.vid')); } function upload_save($node) { @@ -336,18 +336,33 @@ function upload_save($node) { // Insert new files: if ($file = file_save_upload($file, $file->filename)) { $fid = db_next_id('{files}_fid'); - db_query("INSERT INTO {files} (fid, nid, filename, filepath, filemime, filesize, list) VALUES (%d, %d, '%s', '%s', '%s', %d, %d)", - $fid, $node->nid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key]); + db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)", + $fid, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key]); } } - else { - // Remove or update existing files: - if ($node->remove[$key]) { + } + // Remove or update existing files: + foreach ((array)$node->remove as $key => $value) { + if ($node->remove[$key]) { + db_query('DELETE FROM {files} WHERE fid = %d AND vid = %d', $key, $node->vid); + // We only delete a file if it isn't used anymore by any revision. + $count = db_result(db_query('SELECT COUNT(fid) FROM {files} WHERE fid = %d', $key)); + if (!($count > 0)) { file_delete($file->filepath); - db_query("DELETE FROM {files} WHERE fid = %d", $key); } - if ($file->list != $node->list[$key]) { - db_query("UPDATE {files} SET list = %d WHERE fid = %d", $node->list[$key], $key); + } + } + foreach ((array)$node->list as $key => $value) { + if (!$node->remove[$key]) { + db_query('UPDATE {files} SET list = %d WHERE fid = %d AND vid = %d', $node->list[$key], $key, $node->vid); + } + } + if ($node->old_vid) { + foreach ((array)$node->remove as $key => $remove) { + if (!$remove) { + $file = db_fetch_object(db_query('SELECT * FROM {files} WHERE vid = %d AND fid = %d', $node->old_vid, $key)); + db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)", + $key, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $file->list); } } } @@ -392,8 +407,8 @@ function upload_form($node) { function upload_load($node) { $files = array(); - if ($node->nid) { - $result = db_query("SELECT * FROM {files} WHERE nid = %d", $node->nid); + if ($node->vid) { + $result = db_query("SELECT * FROM {files} WHERE vid = %d", $node->vid); while ($file = db_fetch_object($result)) { $files[$file->fid] = $file; }