Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1211
diff -u -p -r1.1211 common.inc
--- includes/common.inc	27 Aug 2010 11:54:32 -0000	1.1211
+++ includes/common.inc	27 Aug 2010 15:59:38 -0000
@@ -2030,15 +2030,32 @@ function format_username($account) {
  *     Drupal on a web server that cannot be configured to automatically find
  *     index.php, then hook_url_outbound_alter() can be implemented to force
  *     this value to 'index.php'.
- *   - 'entity_type': The entity type of the object that called url(). Only set if
- *     url() is invoked by entity_uri().
+ *   - 'entity_type': The entity type of the object that called url(). Only set
+ *     if url() is invoked by entity_uri(). This is usually handled internally
+ *     by looking at the root path to determine the entity type.
  *   - 'entity': The entity object (such as a node) for which the URL is being
- *     generated. Only set if url() is invoked by entity_uri().
+ *     generated. Only set if url() is invoked by entity_uri(). This is usually
+ *     handled internally by looking at the path to determine the entity id and
+ *     then load the entity object.
  *
  * @return
  *   A string containing a URL to the given path.
  */
 function url($path = NULL, array $options = array()) {
+  // Use the advanced drupal_static() pattern, since this is called very often.
+  static $drupal_static_fast;
+  if (!isset($drupal_static_fast)) {
+    $drupal_static_fast['entity_altered_root_path_list'] = &drupal_static(__FUNCTION__);
+  }
+  $entity_altered_root_path_list = &$drupal_static_fast['entity_altered_root_path_list'];
+
+  // The first time this function is called, populate a list of entity-related
+  // root paths we will need to search for, in order to properly link to
+  // entities.
+  if (!isset($entity_altered_root_path_list)) {
+    $entity_altered_root_path_list = variable_get('entity_altered_root_path_list', array());
+  }
+
   // Merge in defaults.
   $options += array(
     'fragment' => '',
@@ -2058,6 +2075,58 @@ function url($path = NULL, array $option
     $options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && drupal_strip_dangerous_protocols($path) == $path);
   }
 
+  // If there are modules enabled which alter entity URIs, we need to check
+  // this path against that list and possibly rewrite it. If no modules did
+  // this, or if the path was passed through entity_uri() already, there is no
+  // need to go any further.
+  if (!empty($entity_altered_root_path_list) && !isset($options['entity_type'])) {
+    // First do a quick check to see if the provided path is on our list; we
+    // only need to invoke the entity code if it is. We do this by stripping
+    // off the last part of the path and checking the rest. For example, if the
+    // path is 'taxonomy/term/2' we want to check if 'taxonomy/term' is on the
+    // list of altered root paths.
+    $slash_position = strrpos($path, '/');
+    if ($slash_position !== FALSE) {
+      $root_path = substr($path, 0, $slash_position);
+      if (isset($entity_altered_root_path_list[$root_path])) {
+        // Load the entity by ID. In most cases, it will already have been
+        // loaded (an exception is if it was stored as a menu link in the
+        // database), so as long as the entity allows static caching this
+        // should be fairly quick. We also make sure the last part of the path
+        // is actually a numeric ID before proceeding, since we don't want to
+        // trigger this on a hypothetical path like 'taxonomy/term/admin'.
+        $entity_id = substr($path, $slash_position + 1);
+        if (is_numeric($entity_id)) {
+          $entity_type = $entity_altered_root_path_list[$root_path];
+          // Avoid infinite recursion; do not try to load an entity if it is
+          // currently in the process of being loaded. In that case, we
+          // wouldn't be able to generate a correct altered URL anyway, since
+          // entity_uri() requires a fully-loaded entity as input. So the only
+          // thing we can do here is stick with the original, passed-in URL.
+          if (!entity_is_loading($entity_type, $entity_id)) {
+            $entities = entity_load($entity_type, array($entity_id));
+            $entity = reset($entities);
+            // Generate the entity URI and use the results of that to construct
+            // the URL in the rest of this function.
+            $entity_uri = entity_uri($entity_type, $entity);
+            if (isset($entity_uri)) {
+              $path = $entity_uri['path'];
+              // Merge in the entity URI options. These must take precedence
+              // over the passed-in options, since, for example, if the entity
+              // URI is associated with a particular fragment or query string,
+              // that must appear in the final URL in order to link to the
+              // entity correctly.
+              if (isset($entity_uri['options']['query'])) {
+                $entity_uri['options']['query'] = array_merge($options['query'], $entity_uri['options']['query']);
+              }
+              $options = array_merge($options, $entity_uri['options']);
+            }
+          }
+        }
+      }
+    }
+  }
+
   // Preserve the original path before altering or aliasing.
   $original_path = $path;
 
@@ -6647,8 +6716,43 @@ function entity_get_info($entity_type = 
           $entity_info[$name]['bundles'] = array($name => array('label' => $entity_info[$name]['label']));
         }
       }
-      // Let other modules alter the entity info.
+      // Let other modules alter the entity info. Make a copy of the original
+      // entity info beforehand so we can compare what changed below.
+      $original_entity_info = $entity_info;
       drupal_alter('entity_info', $entity_info);
+      // Search for any URI callbacks changed or added by the drupal_alter()
+      // call, and record the root path (the non-entity-specific part of the
+      // URI). For example, when the Forum module is enabled, we will use this
+      // information in url() to rewrite links like 'taxonomy/term/2' to links
+      // like 'forum/2'; in that case, 'taxonomy/term' will be recorded by the
+      // code below.
+      $entity_altered_root_path_list = array();
+      foreach ($entity_info as $name => $info) {
+        // Strip the original and altered entity info down to arrays that only
+        // contain 'uri callback' keys, and save the altered root paths if any
+        // of them changed. If there were no uri callbacks originally, then
+        // there is no need to record anything, because there is no way anyone
+        // could link to the original entity.
+        // @todo This code does not support the edge case of multiple levels
+        // of alteration; e.g., if a module implements hook_entity_info_alter()
+        // to further rewrite the Forum module's URLs, then calls such as
+        // url('taxonomy/term/2') will properly be translated to the final
+        // value, but direct calls to url('forum/2') won't. To support that, we
+        // would need to replace the drupal_alter() call above with an explicit
+        // loop, and run the code here each time through the loop.
+        _entity_info_extract_uri_callbacks($original_entity_info[$name]);
+        if (!empty($original_entity_info[$name])) {
+          _entity_info_extract_uri_callbacks($info);
+          if ($info != $original_entity_info[$name]) {
+            foreach (_entity_uri_collect_root_paths($name, $original_entity_info[$name]) as $root_path) {
+              $entity_altered_root_path_list[$root_path] = $name;
+            }
+          }
+        }
+      }
+      if ($entity_altered_root_path_list != variable_get('entity_altered_root_path_list', array())) {
+        variable_set('entity_altered_root_path_list', $entity_altered_root_path_list);
+      }
       cache_set("entity_info:$langcode", $entity_info);
     }
   }
@@ -6662,6 +6766,78 @@ function entity_get_info($entity_type = 
 }
 
 /**
+ * Helper function that modifies the entity info array to only include
+ * 'uri callback' keys.
+ */
+function _entity_info_extract_uri_callbacks(&$info) {
+  foreach ($info as $key => &$data) {
+    if ($key != 'uri callback' && $key != 'bundles') {
+      unset($info[$key]);
+    }
+    elseif ($key == 'bundles') {
+      foreach ($data as $bundle_name => $bundle_data) {
+        if (isset($bundle_data['uri callback'])) {
+          $data[$bundle_name] = array('uri callback' => $bundle_data['uri callback']);
+        }
+        else {
+          unset($data[$bundle_name]);
+        }
+      }
+    }
+  }
+  if (empty($info['bundles'])) {
+    unset($info['bundles']);
+  }
+}
+
+/**
+ * Helper function that collects root paths from the $info array.
+ *
+ * @param $entity_type
+ *   The entity type we shall collect root paths for.
+ * @param $info
+ *   Array only containing URI callback values.
+ * @return
+ *   Array of root paths.
+ */
+function _entity_uri_collect_root_paths($entity_type, $info) {
+  $root_paths = array();
+  foreach ($info as $value) {
+    if (is_array($value)) {
+      $root_paths = array_merge($root_paths, _entity_uri_collect_root_paths($entity_type, $value));
+    }
+    else {
+      $root_path = entity_uri_root_path($entity_type, $value);
+      if (isset($root_path)) {
+        $root_paths[] = $root_path;
+      }
+    }
+  }
+  return $root_paths;
+}
+
+/**
+ * Determines the root path for an entity.
+ *
+ * @param $entity_type
+ *   The entity type name.
+ * @param $uri_callback
+ *   The callback that will return the complete URI to the entity.
+ * @return
+ *   The root path.
+ */
+function entity_uri_root_path($entity_type, $uri_callback) {
+  if (function_exists($uri_callback)) {
+    $entity = entity_create_stub_entity($entity_type, array(1, NULL, NULL));
+    $uri = $uri_callback($entity);
+    $slash_position = strrpos($uri['path'], '/');
+    if ($slash_position !== FALSE) {
+      return substr($uri['path'], 0, $slash_position);
+    }
+  }
+}
+
+/**
  * Resets the cached information about entity types.
  */
 function entity_info_cache_clear() {
@@ -6763,6 +6939,14 @@ function entity_load($entity_type, $ids 
 }
 
 /**
+ * Determines if an entity is loading. Use this to avoid race conditions or
+ * infinite recursions.
+ */
+function entity_is_loading($entity_type, $entity_id) {
+  return entity_get_controller($entity_type)->isLoading($entity_type, $entity_id);
+}
+
+/**
  * Get the entity controller class for an entity type.
  */
 function entity_get_controller($entity_type) {
@@ -6816,7 +7000,14 @@ function entity_prepare_view($entity_typ
 }
 
 /**
- * Returns the uri elements of an entity.
+ * Returns the URI elements of an entity.
+ *
+ * Only use this if you are dealing with
+ * generic enteties that you don't know the URI pattern for. When you do know
+ * the URI pattern, url() should be used. Eventual alteration of the URI pattern
+ * will be handled by url().
+ *
+ * @see url()
  *
  * @param $entity_type
  *   The entity type; e.g. 'node' or 'user'.
Index: includes/entity.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/entity.inc,v
retrieving revision 1.13
diff -u -p -r1.13 entity.inc
--- includes/entity.inc	22 Aug 2010 16:11:12 -0000	1.13
+++ includes/entity.inc	27 Aug 2010 15:59:38 -0000
@@ -39,6 +39,12 @@ interface DrupalEntityControllerInterfac
    *   An array of entity objects indexed by their ids.
    */
   public function load($ids = array(), $conditions = array());
+
+  /**
+   * Determines if an entity is loading. Use this to avoid race conditions or
+   * infinite recursions.
+   */
+  public function isLoading($entity_type, $entity_id);
 }
 
 /**
@@ -114,6 +120,13 @@ class DrupalDefaultEntityController impl
   protected $cache;
 
   /**
+   * Stores a record of which entities are currently being loaded.
+   *
+   * @var array
+   */
+  protected $isLoadingCache;
+
+  /**
    * Constructor: sets basic variables.
    */
   public function __construct($entityType) {
@@ -121,6 +134,7 @@ class DrupalDefaultEntityController impl
     $this->entityInfo = entity_get_info($entityType);
     $this->entityCache = array();
     $this->hookLoadArguments = array();
+    $this->isLoadingCache = array();
     $this->idKey = $this->entityInfo['entity keys']['id'];
 
     // Check if the entity type supports revisions.
@@ -190,8 +204,14 @@ class DrupalDefaultEntityController impl
     // which attaches fields (if supported by the entity type) and calls the
     // entity type specific load callback, for example hook_node_load().
     if (!empty($queried_entities)) {
+      foreach (array_keys($queried_entities) as $entity_id) {
+        $this->isLoadingCache[$this->entityType][$entity_id] = TRUE;
+      }
       $this->attachLoad($queried_entities, $revision_id);
       $entities += $queried_entities;
+      foreach (array_keys($queried_entities) as $entity_id) {
+        unset($this->isLoadingCache[$this->entityType][$entity_id]);
+      }
     }
 
     if ($this->cache) {
@@ -216,6 +236,13 @@ class DrupalDefaultEntityController impl
   }
 
   /**
+   * Implements DrupalEntityControllerInterface::isLoading().
+   */
+  public function isLoading($entity_type, $entity_id) {
+    return isset($this->isLoadingCache[$entity_type][$entity_id]);
+  }
+
+  /**
    * Builds the query to load the entity.
    *
    * This has full revision support. For entities requiring special queries,
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.892
diff -u -p -r1.892 comment.module
--- modules/comment/comment.module	23 Aug 2010 14:53:50 -0000	1.892
+++ modules/comment/comment.module	27 Aug 2010 15:59:39 -0000
@@ -2198,9 +2198,8 @@ function template_preprocess_comment(&$v
   $variables['picture']   = theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', array('account' => $comment)) : '';
   $variables['signature'] = $comment->signature;
 
-  $uri = entity_uri('comment', $comment);
-  $variables['title']     = l($comment->subject, $uri['path'], $uri['options']);
-  $variables['permalink'] = l('#', $uri['path'], $uri['options']);
+  $variables['title']     = l($comment->subject, 'comment/' . $comment->cid, array('fragment' => 'comment-' . $comment->cid));
+  $variables['permalink'] = l('#', 'comment/' . $comment->cid, array('fragment' => 'comment-' . $comment->cid));
 
   // Preprocess fields.
   field_attach_preprocess('comment', $comment, $variables['elements'], $variables);
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1293
diff -u -p -r1.1293 node.module
--- modules/node/node.module	23 Aug 2010 22:15:34 -0000	1.1293
+++ modules/node/node.module	27 Aug 2010 15:59:39 -0000
@@ -1353,8 +1353,7 @@ function template_preprocess_node(&$vari
   $variables['date']      = format_date($node->created);
   $variables['name']      = theme('username', array('account' => $node));
 
-  $uri = entity_uri('node', $node);
-  $variables['node_url']  = url($uri['path'], $uri['options']);
+  $variables['node_url']  = url('node/' . $node->nid);
   $variables['title']     = check_plain($node->title);
   $variables['page']      = $variables['view_mode'] == 'full' && node_is_page($node);
 
@@ -1580,9 +1579,8 @@ function node_search_execute($keys = NUL
 
     $extra = module_invoke_all('node_search_result', $node);
 
-    $uri = entity_uri('node', $node);
     $results[] = array(
-      'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE))),
+      'link' => url('node/' . $node->nid, array('absolute' => TRUE)),
       'type' => check_plain(node_type_get_name($node)),
       'title' => $node->title,
       'user' => theme('username', array('account' => $node)),
@@ -2515,11 +2513,10 @@ function node_page_view($node) {
   // of the active trail, and the link name becomes the page title.
   // Thus, we must explicitly set the page title to be the node title.
   drupal_set_title($node->title);
-  $uri = entity_uri('node', $node);
   // Set the node path as the canonical URL to prevent duplicate content.
-  drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url($uri['path'], $uri['options'])), TRUE);
+  drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url('node/' . $node->nid)), TRUE);
   // Set the non-aliased path as a default shortlink.
-  drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url($uri['path'], array_merge($uri['options'], array('alias' => TRUE)))), TRUE);
+  drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url('node/' . $node->nid, array('alias' => TRUE))), TRUE);
   return node_show($node);
 }
 
Index: modules/rdf/rdf.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/rdf/rdf.module,v
retrieving revision 1.43
diff -u -p -r1.43 rdf.module
--- modules/rdf/rdf.module	23 Jul 2010 04:39:32 -0000	1.43
+++ modules/rdf/rdf.module	27 Aug 2010 15:59:39 -0000
@@ -565,30 +565,30 @@ function rdf_preprocess_field(&$variable
  */
 function rdf_preprocess_user_profile(&$variables) {
   $account = $variables['elements']['#account'];
-  $uri = entity_uri('user', $account);
+  $account_url = url('user/' . $account->uid);
 
   // Adds RDFa markup to the user profile page. Fields displayed in this page
   // will automatically describe the user.  
   if (!empty($account->rdf_mapping['rdftype'])) {
     $variables['attributes_array']['typeof'] = $account->rdf_mapping['rdftype'];
-    $variables['attributes_array']['about'] = url($uri['path'], $uri['options']);
+    $variables['attributes_array']['about'] = $account_url;
   }
   // Adds the relationship between the sioc:UserAccount and the foaf:Person who
   // holds the account.
   $account_holder_meta = array(
     '#tag' => 'meta',
     '#attributes' => array(
-      'about' => url($uri['path'], array_merge($uri['options'], array('fragment' => 'me'))),
+      'about' => url('user/' . $account->uid, array('fragment' => 'me')),
       'typeof' => array('foaf:Person'),
       'rel' => array('foaf:account'),
-      'resource' => url($uri['path'], $uri['options']),
+      'resource' => $account_url,
     ),
   );
   // Adds the markup for username.
   $username_meta = array(
     '#tag' => 'meta',
     '#attributes' => array(
-      'about' => url($uri['path'], $uri['options']),
+      'about' => $account_url,
       'property' => $account->rdf_mapping['name']['predicates'],
       'content' => $account->name,
     )
@@ -661,8 +661,7 @@ function rdf_preprocess_comment(&$variab
     // Adds RDFa markup to the comment container. The about attribute specifies
     // the URI of the resource described within the HTML element, while the
     // typeof attribute indicates its RDF type (e.g. sioc:Post, etc.).
-    $uri = entity_uri('comment', $comment);
-    $variables['attributes_array']['about'] = url($uri['path'], $uri['options']);
+    $variables['attributes_array']['about'] = url('comment/' . $comment->cid, array('fragment' => 'comment-' . $comment->cid));
     $variables['attributes_array']['typeof'] = $comment->rdf_mapping['rdftype'];
   }
 
Index: modules/simpletest/tests/entity_uri_test.info
===================================================================
RCS file: modules/simpletest/tests/entity_uri_test.info
diff -N modules/simpletest/tests/entity_uri_test.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/entity_uri_test.info	27 Aug 2010 15:59:39 -0000
@@ -0,0 +1,8 @@
+; $Id$
+name = "Entity URI test"
+description = "Support module for testing entity URIs."
+package = Testing
+version = VERSION
+core = 7.x
+files[] = entity_uri_test.module
+hidden = TRUE
Index: modules/simpletest/tests/entity_uri_test.module
===================================================================
RCS file: modules/simpletest/tests/entity_uri_test.module
diff -N modules/simpletest/tests/entity_uri_test.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/entity_uri_test.module	27 Aug 2010 15:59:39 -0000
@@ -0,0 +1,37 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Helper module for entity URI tests.
+ */
+
+/**
+ * Implements hook_entity_info_alter().
+ */
+function entity_uri_test_entity_info_alter(&$entity_info) {
+  foreach ($entity_info as $type => &$info) {
+    if (isset($info['uri callback'])) {
+      $info['uri callback'] = "entity_uri_test_{$type}_uri";
+    }
+  }
+}
+
+function entity_uri_test_comment_uri($comment) {
+  return array(
+    'path' => "comment/{$comment->cid}/{$comment->name}",
+    'options' => array('fragment' => 'comment-' . $comment->cid),
+  );
+}
+
+function entity_uri_test_node_uri($node) {
+  return array('path' => "node/{$node->nid}/{$node->type}");
+}
+
+function entity_uri_test_taxonomy_term_uri($term) {
+  return array('path' => "taxonomy/term/{$term->tid}/{$term->vocabulary_machine_name}");
+}
+
+function entity_uri_test_user_uri($account) {
+  return array('path' => "user/{$account->uid}/{$account->name}");
+}
Index: modules/system/system.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.api.php,v
retrieving revision 1.187
diff -u -p -r1.187 system.api.php
--- modules/system/system.api.php	22 Aug 2010 13:55:53 -0000	1.187
+++ modules/system/system.api.php	27 Aug 2010 15:59:39 -0000
@@ -85,8 +85,16 @@ function hook_hook_info_alter(&$hooks) {
  *   - load hook: The name of the hook which should be invoked by
  *     DrupalDefaultEntityController:attachLoad(), for example 'node_load'.
  *   - uri callback: A function taking an entity as argument and returning the
- *     uri elements of the entity, e.g. 'path' and 'options'. The actual entity
- *     uri can be constructed by passing these elements to url().
+ *     URI elements of the entity, e.g. 'path' and 'options'. The actual entity
+ *     URI can be constructed by passing these elements to url(). To give other
+ *     modules the possibility to properly alter the the uri for an entity the
+ *     original pattern must follow these rules:
+ *       - The unique identifier used to construct the URI must only be the
+ *         entity ID.
+ *       - The entity ID must be the last part of the path.
+ *       - Query strings and fragments are optionally allowed, but should also
+ *         only use the entity ID as the unique identifier.
+ *     As an example is 'some/random/path/{$entity_id}'.
  *   - fieldable: Set to TRUE if you want your entity type to be fieldable.
  *   - entity keys: An array describing how the Field API can extract the
  *     information it needs from the objects of the type. Elements:
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.603
diff -u -p -r1.603 taxonomy.module
--- modules/taxonomy/taxonomy.module	22 Aug 2010 15:45:03 -0000	1.603
+++ modules/taxonomy/taxonomy.module	27 Aug 2010 15:59:39 -0000
@@ -634,8 +634,7 @@ function template_preprocess_taxonomy_te
   $variables['term'] = $variables['elements']['#term'];
   $term = $variables['term'];
 
-  $uri = entity_uri('taxonomy_term', $term);
-  $variables['term_url']  = url($uri['path'], $uri['options']);
+  $variables['term_url']  = url('taxonomy/term/' . $term->tid);
   $variables['term_name'] = check_plain($term->name);
   $variables['page']      = $variables['view_mode'] == 'full' && taxonomy_term_is_page($term);
 
@@ -1240,12 +1239,10 @@ function taxonomy_field_formatter_view($
         }
         else {
           $term = $item['taxonomy_term'];
-          $uri = entity_uri('taxonomy_term', $term);
           $element[$delta] = array(
             '#type' => 'link',
             '#title' => $term->name,
-            '#href' => $uri['path'],
-            '#options' => $uri['options'],
+            '#href' => 'taxonomy/term/' . $term->tid,
           );
         }
       }
Index: modules/taxonomy/taxonomy.tokens.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.tokens.inc,v
retrieving revision 1.9
diff -u -p -r1.9 taxonomy.tokens.inc
--- modules/taxonomy/taxonomy.tokens.inc	8 Aug 2010 02:06:56 -0000	1.9
+++ modules/taxonomy/taxonomy.tokens.inc	27 Aug 2010 15:59:39 -0000
@@ -111,8 +111,7 @@ function taxonomy_tokens($type, $tokens,
           break;
 
         case 'url':
-          $uri = entity_uri('taxonomy_term', $term);
-          $replacements[$original] = url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE)));
+          $replacements[$original] = url('taxonomy/term/' . $term->tid, array('absolute' => TRUE));
           break;
 
         case 'node-count':
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.1196
diff -u -p -r1.1196 user.module
--- modules/user/user.module	26 Aug 2010 09:14:33 -0000	1.1196
+++ modules/user/user.module	27 Aug 2010 15:59:39 -0000
@@ -3556,9 +3556,9 @@ function user_register_submit($form, &$f
   $account->password = $pass;
 
   // New administrative account without notification.
-  $uri = entity_uri('user', $account);
+  $account_url = url('user/' . $account->uid);
   if ($admin && !$notify) {
-    drupal_set_message(t('Created a new user account for <a href="@url">%name</a>. No e-mail has been sent.', array('@url' => url($uri['path'], $uri['options']), '%name' => $account->name)));
+    drupal_set_message(t('Created a new user account for <a href="@url">%name</a>. No e-mail has been sent.', array('@url' => $account_url, '%name' => $account->name)));
   }
   // No e-mail verification required; log in user immediately.
   elseif (!$admin && !variable_get('user_email_verification', TRUE) && $account->status) {
@@ -3573,7 +3573,7 @@ function user_register_submit($form, &$f
     $op = $notify ? 'register_admin_created' : 'register_no_approval_required';
     _user_mail_notify($op, $account);
     if ($notify) {
-      drupal_set_message(t('A welcome message with further instructions has been e-mailed to the new user <a href="@url">%name</a>.', array('@url' => url($uri['path'], $uri['options']), '%name' => $account->name)));
+      drupal_set_message(t('A welcome message with further instructions has been e-mailed to the new user <a href="@url">%name</a>.', array('@url' => $account_url, '%name' => $account->name)));
     }
     else {
       drupal_set_message(t('A welcome message with further instructions has been sent to your e-mail address.'));
