Index: modules/cck/nodereference.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/cck/nodereference.module,v
retrieving revision 1.25.2.11
diff -u -r1.25.2.11 nodereference.module
--- modules/cck/nodereference.module	21 Aug 2006 03:06:45 -0000	1.25.2.11
+++ modules/cck/nodereference.module	21 Aug 2006 16:35:48 -0000
@@ -53,10 +53,29 @@
         '#default_value' => isset($field['referenceable_types']) ? $field['referenceable_types'] : array(),
         '#options' => node_get_types(),
       );
+      if (module_exist('views')) {
+        $form['advanced_view'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Advanced : view name'),
+          '#default_value' => isset($field['advanced_view']) ? $field['advanced_view'] : '',
+          '#description' => t('Enter the name of a view')
+        );
+      }
       return $form;
 
+    case 'validate':
+      $form = $field;
+      if (!empty($form['advanced_view']) && !views_get_view($form['advanced_view'])) {
+        form_set_error($form['advanced_view'], t('The "%view" view does not exist.', array('%view' => $form['advanced_view'])));
+      }
+      return;
+
     case 'save':
-      return array('referenceable_types');
+      $settings = array('referenceable_types');
+      if (module_exist('views')) {
+        $settings[] = 'advanced_view';
+      }
+      return $settings;
 
     case 'database columns':
       $columns = array(
@@ -147,12 +166,16 @@
         $form = array();
 
         $form[$field['field_name']] = array('#tree' => TRUE);
+        $options = _nodereference_potential_references($field, true);
+        foreach ($options as $key => $value) {
+          $options[$key] = _nodereference_item($field, $value);
+        }
         $form[$field['field_name']]['nids'] = array(
           '#type' => 'select',
           '#title' => t($field['widget']['label']),
           '#default_value' => $node_field['default nids'],
           '#multiple' => $field['multiple'],
-          '#options' => _nodereference_potential_references($field),
+          '#options' => $options,
           '#required' => $field['required'],
           '#description' => $field['widget']['description'],
         );
@@ -249,28 +272,65 @@
   }
 }
 
+function nodereference_views_query_alter(&$query, $view, $summary, $level) {
+  if (isset($view->nodereference)) {
+    $alter_params = $view->nodereference;
+    if (isset($alter_params['string'])) {
+      $query->add_where("%s.%s LIKE '%%%s%'", array('node', 'title', $alter_params['string']));
+    }
+    // we do need title field, so add it if not present (unlikely...)
+    if (!in_array("node.title AS node_title", $query->fields)) {
+      $query->add_field('title', 'node', 'node_title');
+    }
+  }
+}
 
 /**
  * Fetch an array of all candidate referenced nodes, for use in presenting the selection form to the user.
  */
-function _nodereference_potential_references($field, $return_full_nodes = FALSE) {
-  $related_types = array();
+function _nodereference_potential_references($field, $return_full_nodes = FALSE, $string = '') {
+  if (module_exist('views') && ($view = views_get_view($field['advanced_view']))) {
+    // advanced field : referenceable nodes defined by a view
+    // let views.module build the query
+
+    // prepare useful params for the nodereference_views_query_alter function
+    $alter_params = array('field' => $field);
+    if (isset($string)) {
+      $alter_params['string'] = $string;
+    }
+    $view->nodereference = $alter_params;
 
-  if (isset($field['referenceable_types'])) {
-    foreach ($field['referenceable_types'] as $related_type) {
-      if ($related_type) {
-        $related_types[] = " type = '". $related_type ."'";
+    $view_result = views_build_view('result', $view);
+    $result = $view_result['result'];
+  }
+  else {
+    // standard field : referenceable nodes defined by content types
+    // build the appropriate query
+    $related_types = array();
+    $args = array();
+
+    if (isset($field['referenceable_types'])) {
+      foreach ($field['referenceable_types'] as $related_type) {
+        if ($related_type) {
+          $related_types[] = " type = '%s'";
+          $args[] = $related_type;
+        }
       }
     }
-  }
 
-  $related_clause = implode(' OR ', $related_types);
+    $related_clause = implode(' OR ', $related_types);
 
-  if (!count($related_types)) {
-    return array();
-  }
+    if (!count($related_types)) {
+      return array();
+    }
 
-  $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, n.type FROM {node} n WHERE ". $related_clause ." ORDER BY n.title, n.type"));
+    if (isset($string)) {
+      $related_clause = "(". $related_clause .") AND title LIKE '%%%s%'";
+      $args[] = $string;
+    }
+
+    $result = db_query(db_rewrite_sql("SELECT n.nid, n.title AS node_title, n.type AS node_type FROM {node} n WHERE ". $related_clause ." ORDER BY n.title, n.type"), $args);
+  }
 
   if (db_num_rows($result) == 0) {
     return array();
@@ -283,7 +343,7 @@
       $rows[$node->nid] = $node;
     }
     else {
-      $rows[$node->nid] = $node->title;
+      $rows[$node->nid] = $node->node_title;
     }
   }
 
@@ -298,12 +358,42 @@
   $field = $fields[$field_name];
   $matches = array();
 
-  foreach (_nodereference_potential_references($field, TRUE) as $key => $value) {
-    if (stristr($value->title, $string)) {
-      $matches[$value->title] = check_plain('('. str_replace('content_', '', $value->type) .') '. $value->title);
-    }
+  foreach (_nodereference_potential_references($field, TRUE, $string) as $row) {
+    $matches[$row->node_title] = _nodereference_item($field, $row, TRUE);
   }
-
   print drupal_to_js($matches);
   exit();
-}
\ No newline at end of file
+}
+
+function _nodereference_item($field, $item, $html = false) {
+  if (module_exist('views') && ($view = views_get_view($field['advanced_view']))) {
+    $output = theme('nodereference_item_advanced', $item, $view);
+    if (!$html) {
+      $output = strip_tags($output);
+    }
+  }
+  else {
+    $output = theme('nodereference_item_simple', $item);
+  }
+  return $output;
+}
+
+function theme_nodereference_item_advanced($item, $view) {
+  $fields = _views_get_fields();
+  $item_fields = array();
+  foreach ($view->field as $field) {
+    $value = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $item);
+    // remove possible tags (ex : <a> for node titles)
+    $value = strip_tags($value);
+    if (!empty($value)) {
+      $item_fields[] = "<span class='view-field view-data-$field[queryname]'>$value</span>";;
+    }
+  }
+  $output = implode(' - ', $item_fields);
+  $output = "<span class='view-item view-item-$view->name'>$output</span>";
+  return $output;
+}
+
+function theme_nodereference_item_simple($item) {
+  return $item->node_title;
+}
