Index: database/database.4.0.mysql =================================================================== RCS file: /cvs/drupal/drupal/database/database.4.0.mysql,v retrieving revision 1.3 diff -u -r1.3 database.4.0.mysql --- database/database.4.0.mysql 12 May 2006 08:50:22 -0000 1.3 +++ database/database.4.0.mysql 22 May 2006 12:54:33 -0000 @@ -412,6 +412,7 @@ promote int(2) NOT NULL default '0', moderate int(2) NOT NULL default '0', sticky int(2) NOT NULL default '0', + path varchar(255) NOT NULL default '', PRIMARY KEY (nid, vid), UNIQUE KEY vid (vid), KEY node_type (type(4)), Index: database/database.4.1.mysql =================================================================== RCS file: /cvs/drupal/drupal/database/database.4.1.mysql,v retrieving revision 1.3 diff -u -r1.3 database.4.1.mysql --- database/database.4.1.mysql 12 May 2006 08:50:22 -0000 1.3 +++ database/database.4.1.mysql 22 May 2006 12:54:53 -0000 @@ -440,6 +440,7 @@ promote int(2) NOT NULL default '0', moderate int(2) NOT NULL default '0', sticky int(2) NOT NULL default '0', + path varchar(255) NOT NULL default '', PRIMARY KEY (nid, vid), UNIQUE KEY vid (vid), KEY node_type (type(4)), Index: database/database.pgsql =================================================================== RCS file: /cvs/drupal/drupal/database/database.pgsql,v retrieving revision 1.175 diff -u -r1.175 database.pgsql --- database/database.pgsql 16 May 2006 09:22:36 -0000 1.175 +++ database/database.pgsql 22 May 2006 12:55:01 -0000 @@ -419,6 +423,7 @@ promote integer NOT NULL default '0', moderate integer NOT NULL default '0', sticky integer NOT NULL default '0', + path varchar(255) NOT NULL default '', PRIMARY KEY (nid) ); CREATE INDEX node_type_idx ON node(type); Index: database/updates.inc =================================================================== RCS file: /cvs/drupal/drupal/database/updates.inc,v retrieving revision 1.230 diff -u -r1.230 updates.inc --- database/updates.inc 16 May 2006 09:22:36 -0000 1.230 +++ database/updates.inc 22 May 2006 12:55:25 -0000 @@ -2007,3 +2007,27 @@ return $ret; } + +function system_update_183() { + $ret = array(); + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("ALTER TABLE {node} ADD path varchar(255) NOT NULL DEFAULT '' AFTER sticky;"); + // update the default values in the node, default values are 'node/nid' + $ret[] = update_sql("UPDATE {node} SET path = CONCAT('node/', nid) WHERE path = ''"); + break; + case 'pgsql': + db_add_column($ret, 'node', 'path', 'varchar(255)', array('not null' => TRUE, 'default' => "''")); + // update the default values in the node, default values are 'node/nid' + $ret[] = update_sql("UPDATE {node} SET path = 'node/' || nid WHERE path = ''"); + } + + // PostgreSQL needs CREATE TABLE foobar _AS_ SELECT ... + $AS = ($GLOBALS['db_type'] == 'pgsql') ? 'AS' : ''; + $ret[] = update_sql("CREATE TABLE {tmp_node_path} $AS SELECT n.nid, n.path, u.dst FROM node n, url_alias u WHERE n.path = u.src"); + $ret[] = update_sql('UPDATE {node} n, {tmp_node_path} t SET n.path = t.dst WHERE n.nid = t.nid'); + $ret[] = update_sql('DROP TABLE {tmp_node_path}'); + + return $ret; +} Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.540 diff -u -r1.540 common.inc --- includes/common.inc 15 May 2006 20:52:47 -0000 1.540 +++ includes/common.inc 22 May 2006 12:55:38 -0000 @@ -1052,14 +1052,14 @@ * * @param $text * The text to be enclosed with the anchor tag. - * @param $path - * The Drupal path being linked to, such as "admin/node". Can be an external - * or internal URL. - * - If you provide the full URL, it will be considered an - * external URL. + * @param $pathsrc + * Either a Drupal node or a string containing the Drupal path being linked to, + * such as "admin/node". If a string, the path be an external or internal URL. + * - If you provide the full URL, it will be considered an external URL. * - If you provide only the path (e.g. "admin/node"), it is considered an * internal link. In this case, it must be a system URL as the url() function * will generate the alias. + * If a node, the path member variable will be used for the path string * @param $attributes * An associative array of HTML attributes to apply to the anchor tag. * @param $query @@ -1077,7 +1077,11 @@ * @return * an HTML string containing a link to the given path. */ -function l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE) { +function l($text, $pathsrc, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE) { + + // if path is an object, assume node object and use the path + $path = (is_object($pathsrc)) ? $pathsrc->path : $pathsrc; + if ($path == $_GET['q']) { if (isset($attributes['class'])) { $attributes['class'] .= ' active'; @@ -1086,6 +1090,7 @@ $attributes['class'] = 'active'; } } + return ''. ($html ? $text : check_plain($text)) .''; } Index: includes/path.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/path.inc,v retrieving revision 1.4 diff -u -r1.4 path.inc --- includes/path.inc 24 Apr 2006 19:25:37 -0000 1.4 +++ includes/path.inc 22 May 2006 12:55:40 -0000 @@ -67,6 +67,11 @@ return $alias; } if (!isset($map[$path])) { + if ($nid = db_result(db_query("SELECT nid FROM {node} WHERE path = '%s'", $path))) { + $map['node/' . $nid] = $path; + return 'node/' . $nid; + } + if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s'", $path))) { $map[$src] = $path; return $src; Index: modules/blog.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blog.module,v retrieving revision 1.249 diff -u -r1.249 blog.module --- modules/blog.module 18 May 2006 14:58:56 -0000 1.249 +++ modules/blog.module 22 May 2006 12:55:48 -0000 @@ -235,7 +235,7 @@ // Breadcrumb navigation $breadcrumb[] = array('path' => 'blog', 'title' => t('blogs')); $breadcrumb[] = array('path' => 'blog/'. $node->uid, 'title' => t("%name's blog", array('%name' => $node->name))); - $breadcrumb[] = array('path' => 'node/'. $node->nid); + $breadcrumb[] = array('path' => $node->path); menu_set_location($breadcrumb); } $node = node_prepare($node, $teaser); Index: modules/blogapi.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blogapi.module,v retrieving revision 1.83 diff -u -r1.83 blogapi.module --- modules/blogapi.module 7 May 2006 00:08:36 -0000 1.83 +++ modules/blogapi.module 22 May 2006 12:55:58 -0000 @@ -230,7 +230,7 @@ $node = node_submit($edit); 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")); + 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->path)); // blogger.newPost returns a string so we cast the nid to a string by putting it in double quotes: return "$node->nid"; } @@ -284,7 +284,7 @@ $node = node_submit($node); 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")); + 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->path)); return true; } @@ -693,8 +693,8 @@ 'dateCreated' => xmlrpc_date($node->created), 'title' => $node->title, 'postid' => $node->nid, - 'link' => url('node/'.$node->nid, NULL, NULL, true), - 'permaLink' => url('node/'.$node->nid, NULL, NULL, true), + 'link' => url($node->path, NULL, NULL, true), + 'permaLink' => url($node->path, NULL, NULL, true), ); if ($bodies) { if ($node->comment = 1) { Index: modules/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book.module,v retrieving revision 1.365 diff -u -r1.365 book.module --- modules/book.module 18 May 2006 14:58:56 -0000 1.365 +++ modules/book.module 22 May 2006 12:56:18 -0000 @@ -153,7 +153,7 @@ else if ($op == 'view') { // Only display this block when the user is browsing a book: if (arg(0) == 'node' && is_numeric(arg(1))) { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d'), arg(1)); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.path, 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); @@ -374,7 +374,7 @@ * */ 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, n.path, 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); $nodes[] = $parent; @@ -386,7 +386,7 @@ * 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.nid = b.nid 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, n.path, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid 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); @@ -404,7 +404,7 @@ } // Previous on the same level: - $direct_above = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight < %d OR (b.weight = %d AND n.title < '%s')) ORDER BY b.weight DESC, n.title DESC"), $node->parent, $node->weight, $node->weight, $node->title)); + $direct_above = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, n.path, 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); @@ -413,7 +413,7 @@ } else { // Direct parent: - $prev = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d AND n.status = 1 AND n.moderate = 0'), $node->parent)); + $prev = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, n.path 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; } } @@ -423,7 +423,7 @@ */ function book_next($node) { // get first direct child - $child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight ASC, n.title ASC'), $node->nid)); + $child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, n.path, 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; } @@ -433,7 +433,7 @@ $path[] = $node; while (($leaf = array_pop($path)) && count($path)) { - $next = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight > %d OR (b.weight = %d AND n.title > '%s')) ORDER BY b.weight ASC, n.title ASC"), $leaf->parent, $leaf->weight, $leaf->weight, $leaf->title)); + $next = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, n.path, 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; } @@ -486,7 +486,7 @@ foreach ($path as $level) { $node->breadcrumb[] = array('path' => 'node/'. $level->nid, 'title' => $level->title); } - $node->breadcrumb[] = array('path' => 'node/'. $node->nid); + $node->breadcrumb[] = array('path' => $node->path); $node->body .= theme('book_navigation', $node); @@ -518,16 +518,16 @@ $tree = book_tree($node->nid); if ($prev = book_prev($node)) { - drupal_add_link(array('rel' => 'prev', 'href' => url('node/'. $prev->nid))); - $links .= l(t('‹ ') . $prev->title, 'node/'. $prev->nid, array('class' => 'page-previous', 'title' => t('Go to previous page'))); + drupal_add_link(array('rel' => 'prev', 'href' => url($prev->path))); + $links .= l(t('‹ ') . $prev->title, $prev->path, array('class' => 'page-previous', 'title' => t('Go to previous page'))); } if ($node->parent) { drupal_add_link(array('rel' => 'index', 'href' => url('node/'. $node->parent))); $links .= l(t('up'), 'node/'. $node->parent, array('class' => 'page-up', 'title' => t('Go to parent page'))); } 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'))); + drupal_add_link(array('rel' => 'next', 'href' => url($next->path))); + $links .= l($next->title . t(' ›'), $next->path, array('class' => 'page-next', 'title' => t('Go to next page'))); } if (isset($tree) || isset($links)) { @@ -565,7 +565,7 @@ * 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')); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.path, 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]) { @@ -595,20 +595,20 @@ if (in_array($node->nid, $unfold)) { if ($tree = book_tree_recurse($node->nid, $depth - 1, $children, $unfold)) { $output .= '
'. filter_xss($revision->log) .'
' : ''), 'class' => 'revision-current'); $operations[] = array('data' => theme('placeholder', t('current revision')), 'class' => 'revision-current', 'colspan' => 2); @@ -1422,7 +1431,7 @@ while ($node = db_fetch_object($nodes)) { // Load the specified node: $item = node_load($node->nid); - $link = url("node/$node->nid", NULL, NULL, 1); + $link = url($node->path, NULL, NULL, 1); if ($item_length != 'title') { $teaser = ($item_length == 'teaser') ? TRUE : FALSE; @@ -1447,7 +1456,7 @@ case 'teaser': $item_text = $item->teaser; if ($item->readmore) { - $item_text .= ''. l(t('read more'), 'node/'. $item->nid, NULL, NULL, NULL, TRUE) .'
'; + $item_text .= ''. l(t('read more'), $item, NULL, NULL, NULL, TRUE) .'
'; } break; case 'title': @@ -1559,7 +1568,10 @@ form_set_error('date', t('You have to specify a valid date.')); } } - + $node->path = trim($node->path); + if ($node->path && !valid_url($node->path)) { + form_set_error('path', t('The path is invalid.')); + } // Do node-type-specific validation checks. node_invoke($node, 'validate', $form); node_invoke_nodeapi($node, 'validate', $form); @@ -1844,7 +1856,7 @@ // perform this operation: if (node_access('update', $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)); + watchdog('content', t('%type: updated %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), $node)); drupal_set_message(t('The %post was updated.', array ('%post' => node_get_name($node)))); } } @@ -1853,13 +1865,13 @@ // perform this operation: if (node_access('create', $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")); + watchdog('content', t('%type: added %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), $node)); drupal_set_message(t('Your %post was created.', array ('%post' => node_get_name($node)))); } } if ($node->nid) { if (node_access('view', $node)) { - return 'node/'. $node->nid; + return $node->path; } else { return ''; Index: modules/path.module =================================================================== RCS file: /cvs/drupal/drupal/modules/path.module,v retrieving revision 1.84 diff -u -r1.84 path.module --- modules/path.module 7 May 2006 00:08:36 -0000 1.84 +++ modules/path.module 22 May 2006 12:58:22 -0000 @@ -196,57 +196,6 @@ } /** - * Implementation of hook_nodeapi(). - * - * Allows URL aliases for nodes to be specified at node edit time rather - * than through the administrative interface. - */ -function path_nodeapi(&$node, $op, $arg) { - if (user_access('create url aliases') || user_access('administer url aliases')) { - switch ($op) { - case 'validate': - $node->path = trim($node->path); - if ($node->path && !valid_url($node->path)) { - form_set_error('path', t('The path is invalid.')); - } - else if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE dst = '%s' AND src != '%s'", $node->path, "node/$node->nid"))) { - form_set_error('path', t('The path is already in use.')); - } - break; - - case 'load': - $path = "node/$node->nid"; - // We don't use drupal_get_path_alias() to avoid custom rewrite functions. - // We only care about exact aliases. - $result = db_query("SELECT dst FROM {url_alias} WHERE src = '%s'", $path); - if (db_num_rows($result)) { - $node->path = db_result($result); - } - break; - - case 'insert': - // Don't try to insert if path is NULL. We may have already set - // the alias ahead of time. - if ($node->path) { - path_set_alias("node/$node->nid", $node->path); - } - break; - - case 'update': - path_set_alias("node/$node->nid", $node->path, $node->pid); - break; - - case 'delete': - $path = "node/$node->nid"; - if (drupal_get_path_alias($path) != $path) { - path_set_alias($path); - } - break; - } - } -} - -/** * Implementation of hook_form_alter(). */ function path_form_alter($form_id, &$form) { Index: modules/poll.module =================================================================== RCS file: /cvs/drupal/drupal/modules/poll.module,v retrieving revision 1.196 diff -u -r1.196 poll.module --- modules/poll.module 7 May 2006 00:08:36 -0000 1.196 +++ modules/poll.module 22 May 2006 12:58:39 -0000 @@ -261,7 +261,7 @@ $result = pager_query($sql, 15); $output = '