Index: modules/cck/nodereference.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/cck/nodereference.module,v
retrieving revision 1.25.2.14
diff -u -r1.25.2.14 nodereference.module
--- modules/cck/nodereference.module	7 Nov 2006 10:45:47 -0000	1.25.2.14
+++ modules/cck/nodereference.module	7 Nov 2006 23:45:00 -0000
@@ -219,7 +219,10 @@
     switch ($op) {
       case 'prepare form values':
         foreach ($node_field as $delta => $item) {
-          $node_field[$delta]['default node_name'] = db_result(db_query(db_rewrite_sql('SELECT n.title FROM {node} n WHERE n.nid = %d'), $node_field[$delta]['nid']));
+          if (!empty($node_field[$delta]['nid'])) {
+            $node_field[$delta]['default node_name'] = db_result(db_query(db_rewrite_sql('SELECT n.title FROM {node} n WHERE n.nid = %d'), $node_field[$delta]['nid']));
+            $node_field[$delta]['default node_name'] .= ' [nid:'. $node_field[$delta]['nid'] .']';
+          }
         }
         break;
 
@@ -268,10 +271,26 @@
 
       case 'validate':
         foreach ($node_field as $delta => $item) {
+          $error_field = $field['field_name'].']['.$delta.'][node_name';
           if (!empty($item['node_name'])) {
-            $refs = _nodereference_potential_references($field, false, $item['node_name'], true);
-            if (empty($refs)) {
-              form_set_error($field['field_name'], t('No post with that title exists.'));
+            preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $item['node_name'], $matches);
+            if (!empty($matches)) {
+              // explicit nid
+              list(, $title, $nid) = $matches;
+              $refs = _nodereference_potential_references($field, TRUE);
+              if (!in_array($nid, array_keys($refs))) {
+                form_set_error($error_field, t('This post can\'t be referenced.'));
+              }
+              elseif (!empty($title) && ($n = $refs[$nid]) && $title != $n->node_title) {
+                form_set_error($error_field, t('Title mismatch. Please reiterate your selection.'));
+              }
+            }
+            else {
+              // no explicit nid
+              $refs = _nodereference_potential_references($field, FALSE, $item['node_name'], TRUE);
+              if (empty($refs)) {
+                form_set_error($error_field, t('No post with that title can be referenced.'));
+              }
             }
           }
         }
@@ -279,18 +298,26 @@
 
       case 'process form values':
         foreach ($node_field as $delta => $item) {
-          $nid = 0;
-          if ($node_field[$delta]['node_name']) {
-            $nid = db_result(db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.title = '%s'"), $node_field[$delta]['node_name']));
+          $nid = '';
+          if (!empty($item['node_name'])) {
+            preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $item['node_name'], $matches);
+            if (!empty($matches)) {
+              // autocomplete-added nid
+              $nid = $matches[2];
+            }
+            else {
+              // no autocomplete-added nid (JS disabled, or the user bypassed the autocompletion list)
+              // TODO :
+              // the best thing would be to present the user with an additional form,
+              // allowing the user to choose between valid candidates with the same title
+              // ATM, we pick the first matching candidate...
+              $nids = _nodereference_potential_references($field, false, $item['node_name'], true);
+              $nid = array_shift(array_keys($nids));
+            }
           }
+          $node_field[$delta]['nid'] = $nid;
           // Remove the widget's data representation so it isn't saved.
           unset($node_field[$delta]['node_name']);
-          if ($nid) {
-            $node_field[$delta]['nid'] = $nid;
-          }
-          else {
-            unset($node_field[$delta]);
-          }
         }
         break;
     }
@@ -383,7 +410,7 @@
   $matches = array();
 
   foreach (_nodereference_potential_references($field, TRUE, $string) as $row) {
-    $matches[$row->node_title] = _nodereference_item($field, $row, TRUE);
+    $matches[$row->node_title .' [nid:'. $row->nid .']'] = _nodereference_item($field, $row, TRUE);
   }
   print drupal_to_js($matches);
   exit();
