=== modified file 'sites/all/modules/cck/includes/views/handlers/content_handler_filter_many_to_one.inc'
--- sites/all/modules/cck/includes/views/handlers/content_handler_filter_many_to_one.inc	2009-11-06 21:55:24 +0000
+++ sites/all/modules/cck/includes/views/handlers/content_handler_filter_many_to_one.inc	2010-04-25 00:33:19 +0000
@@ -8,6 +8,7 @@
  */
 class content_handler_filter_many_to_one extends views_handler_filter_many_to_one {
   var $content_field;
+  var $can_autocomplete = FALSE;
 
   function construct() {
     parent::construct();
@@ -15,10 +16,16 @@
     $this->additional_fields = $this->definition['additional fields'];
     $field = $this->content_field;
     $this->value_title = $field['widget']['label'];
+    $this->can_autocomplete = in_array($field['module'], array('nodereference', 'userreference'));
   }
 
   function get_value_options() {
-    $this->value_options = $this->allowed_values();
+    if (empty($this->can_autocomplete) || $this->options['type'] == 'select') {
+      $this->value_options = $this->allowed_values();
+    }
+    else {
+      /* don't overwrite the value options */
+    }
   }
 
   // Get allowed values from hook_allowed_values(), if any,
@@ -39,4 +46,129 @@
     return (array) $options;
   }
 
-}
\ No newline at end of file
+  function has_extra_options() { return $this->can_autocomplete; }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['type'] = array('default' => 'select');
+
+    return $options;
+  }
+
+  function extra_options_form(&$form, &$form_state) {
+    $form['type'] = array(
+      '#type' => 'radios',
+      '#title' => t('Selection type'),
+      '#options' => array('select' => t('Dropdown'), 'textfield' => t('Autocomplete')),
+      '#default_value' => $this->options['type'],
+    );
+  }
+
+  function value_form(&$form, &$form_state) {
+    if ($this->options['type'] == 'textfield') {
+      $form['value'] = array(
+        '#tree' => TRUE,
+        '#title' => t('@widget-label', array('@widget-label' => $this->value_title)),
+        '#type' => 'nodereference_autocomplete',
+        '#views' => TRUE,
+        '#views_single' => $this->options['expose']['single'],
+        '#default_value' => $this->value ? array('name' => $this->value) : array(),
+        '#field_name' => $this->content_field['field_name'],
+        '#type_name' => $this->content_field['type_name'],
+        '#value_callback' => 'nodereference_autocomplete_value',
+      );
+
+      if (empty($form_state['exposed'])) {
+        // Retain the helper option
+        $this->helper->options_form($form, $form_state);
+      }
+    }
+    else {
+      parent::value_form($form, $form_state);
+    }
+  }
+
+  function value_validate(&$form, &$form_state) {
+    // We only validate if they've chosen the text field style.
+    if ($this->options['type'] != 'textfield') {
+      return;
+    }
+
+    $form_state['values']['options']['value'] = $form_state['values']['options']['value']['name'];
+  }
+
+  function accept_exposed_input($input) {
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+    // If it's optional and there's no value don't bother filtering.
+    if ($this->options['expose']['optional'] && empty($this->validated_exposed_input)) {
+      return FALSE;
+    }
+
+    $rc = parent::accept_exposed_input($input);
+    if ($rc) {
+      // If we have previously validated input, override.
+      if (isset($this->validated_exposed_input)) {
+        $this->value = $this->validated_exposed_input;
+      }
+    }
+
+    return $rc;
+  }
+
+  function exposed_validate(&$form, &$form_state) {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    $identifier = $this->options['expose']['identifier'];
+
+    // We only validate if they've chosen the text field style.
+    if ($this->options['type'] != 'textfield') {
+      if ($form_state['values'][$identifier] != 'All')  {
+        $this->validated_exposed_input = (array) $form_state['values'][$identifier];
+      }
+      return;
+    }
+
+    if (empty($this->options['expose']['identifier'])) {
+      return;
+    }
+
+    $this->validated_exposed_input = $form_state['values'][$identifier]['name'];
+  }
+
+  function value_submit($form, &$form_state) {
+    // prevent array_filter from messing up our arrays in parent submit.
+  }
+
+  function expose_form_right(&$form, &$form_state) {
+    parent::expose_form_right($form, $form_state);
+    if ($this->options['type'] != 'select') {
+      unset($form['expose']['reduce']);
+    }
+  }
+
+  function admin_summary() {
+    // set up $this->value_options for the parent summary
+    $this->value_options = array();
+
+    if ($this->value) {
+      if ($this->content_field['module'] == 'nodereference') {
+        $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n WHERE n.nid IN (' . implode(', ', $this->value) . ')'));
+      }
+      elseif ($this->content_field['module'] == 'userreference') {
+        $result = db_query('SELECT u.uid, u.name FROM {user} u WHERE u.uid IN (' . implode(', ', $this->value) . ')');
+      }
+
+      while ($node = db_fetch_object($result)) {
+        $this->value_options[$node->nid] = $node->title .'[nid:'. $node->nid .']';
+      }
+    }
+    return parent::admin_summary();
+  }
+
+}

=== modified file 'sites/all/modules/cck/modules/nodereference/nodereference.module'
--- sites/all/modules/cck/modules/nodereference/nodereference.module	2009-11-06 21:55:24 +0000
+++ sites/all/modules/cck/modules/nodereference/nodereference.module	2010-04-25 00:33:19 +0000
@@ -519,10 +519,21 @@
 function nodereference_autocomplete_value($element, $edit = FALSE) {
   $field_key  = $element['#columns'][0];
   if (!empty($element['#default_value'][$field_key])) {
-    $nid = $element['#default_value'][$field_key];
-    $value = db_result(db_query(db_rewrite_sql('SELECT n.title FROM {node} n WHERE n.nid = %d'), $nid));
-    $value .= ' [nid:'. $nid .']';
-    return array($field_key => $value);
+    $nids = array();
+    $values = array();
+    if (!empty($element['#views'])) {
+      $nids = $element['#default_value'][$field_key];
+    }
+    else {
+      $nids = array($element['#default_value'][$field_key]);
+    }
+
+    $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n WHERE n.nid IN ('. db_placeholders($nids) .')'), $nids);
+    while ($data = db_fetch_object($result)) {
+      $values[] = $data->title .' [nid:'. $data->nid .']';
+    }
+
+    return array($field_key => implode(', ', $values));
   }
   return array($field_key => NULL);
 }
@@ -609,11 +620,15 @@
   // path and some extra processing to it.
   // Add a validation step where the value can be unwrapped.
   $field_key  = $element['#columns'][0];
+  $field_name = $element['#field_name'];
+  if (!empty($element['#views']) && empty($element['#views_single'])) {
+    $field_name = 'views_'. $field_name;
+  }
 
   $element[$field_key] = array(
     '#type' => 'text_textfield',
     '#default_value' => isset($element['#value']) ? $element['#value'] : '',
-    '#autocomplete_path' => 'nodereference/autocomplete/'. $element['#field_name'],
+    '#autocomplete_path' => 'nodereference/autocomplete/'. $field_name,
     // The following values were set by the content module and need
     // to be passed down to the nested element.
     '#title' => $element['#title'],
@@ -623,6 +638,7 @@
     '#type_name' => $element['#type_name'],
     '#delta' => $element['#delta'],
     '#columns' => $element['#columns'],
+    '#views' => $element['#views'],
   );
   if (empty($element[$field_key]['#element_validate'])) {
     $element[$field_key]['#element_validate'] = array();
@@ -682,31 +698,46 @@
   $delta = $element['#delta'];
   $value = $element['#value'][$field_key];
   $nid = NULL;
+  $nids = array();
+
   if (!empty($value)) {
-    preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $value, $matches);
-    if (!empty($matches)) {
-      // Explicit [nid:n].
-      list(, $title, $nid) = $matches;
-      if (!empty($title) && ($n = node_load($nid)) && trim($title) != trim($n->title)) {
-        form_error($element[$field_key], t('%name: title mismatch. Please check your selection.', array('%name' => t($field['widget']['label']))));
-      }
+    if (!empty($element['#views'])) {
+      $value = drupal_explode_tags($value);
     }
     else {
-      // No explicit nid.
-      $reference = _nodereference_potential_references($field, $value, 'equals', NULL, 1);
-      if (empty($reference)) {
-        form_error($element[$field_key], t('%name: found no valid post with that title.', array('%name' => t($field['widget']['label']))));
+      $value = array($value);
+    }
+
+    foreach ($value as $v) {
+      $nid = NULL;
+      preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $v, $matches);
+      if (!empty($matches)) {
+        // Explicit [nid:n].
+        list(, $title, $nid) = $matches;
+        if (!empty($title) && ($n = node_load($nid)) && trim($title) != trim($n->title)) {
+          form_error($element[$field_key], t('%name: title mismatch. Please check your selection.', array('%name' => t($field['widget']['label']))));
+        }
       }
       else {
-        // 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...
-        $nid = key($reference);
+        // No explicit nid.
+        $reference = _nodereference_potential_references($field, $v, 'equals', NULL, 1);
+        if (empty($reference)) {
+          form_error($element[$field_key], t('%name: found no valid post with that title.', array('%name' => t($field['widget']['label']))));
+        }
+        else {
+          // 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...
+          $nid = key($reference);
+        }
+      }
+      if (!empty($nid)) {
+        $nids[] = $nid;
       }
     }
   }
-  form_set_value($element, $nid, $form_state);
+  form_set_value($element, (empty($element['#views']) ? $nid : $nids), $form_state);
 }
 
 /**
@@ -910,6 +941,16 @@
  */
 function nodereference_autocomplete($field_name, $string = '') {
   $fields = content_fields();
+  $prefix = '';
+
+  // Check for a views field.
+  if (0 === substr_compare($field_name, 'views_', 0, 6)) {
+    $field_name = str_replace('views_', '', $field_name);
+    $array = drupal_explode_tags($string);
+    $string = trim(array_pop($array));
+    $prefix = count($array) ? implode(', ', $array) .', ' : '';
+  }
+
   $field = $fields[$field_name];
   $match = isset($field['widget']['autocomplete_match']) ? $field['widget']['autocomplete_match'] : 'contains';
   $matches = array();
@@ -917,7 +958,7 @@
   $references = _nodereference_potential_references($field, $string, $match, array(), 10);
   foreach ($references as $id => $row) {
     // Add a class wrapper for a few required CSS overrides.
-    $matches[$row['title'] ." [nid:$id]"] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';
+    $matches[$prefix . $row['title'] ." [nid:$id]"] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';
   }
   drupal_json($matches);
 }

=== modified file 'sites/all/modules/cck/modules/userreference/userreference.module'
--- sites/all/modules/cck/modules/userreference/userreference.module	2009-11-06 21:55:24 +0000
+++ sites/all/modules/cck/modules/userreference/userreference.module	2010-04-25 00:53:10 +0000
@@ -451,8 +451,20 @@
 function userreference_autocomplete_value($element, $edit = FALSE) {
   $field_key  = $element['#columns'][0];
   if (!empty($element['#default_value'][$field_key])) {
-    $value = db_result(db_query("SELECT name FROM {users} WHERE uid = '%d'", $element['#default_value'][$field_key]));
-    return array($field_key => $value);
+    $values = array();
+    $uids = array();
+    if (!empty($element['#views'])) {
+      $uids = $element['#default_value'][$field_key];
+    }
+    else {
+      $uids = array($element['#default_value'][$field_key]);
+    }
+
+    $result = db_query(db_rewrite_sql('SELECT name FROM {users} n WHERE n.uid IN ('. db_placeholders($uids) .')'), $uids);
+    while ($data = db_fetch_object($result)) {
+      $values[] = $data->name;
+    }
+    return array($field_key => implode(', ', $values));
   }
   return array($field_key => NULL);
 }
@@ -536,11 +548,15 @@
   // path and some extra processing to it.
   // Add a validation step where the value can be unwrapped.
   $field_key  = $element['#columns'][0];
+  $field_name = $element['#field_name'];
+  if (!empty($element['#views']) && empty($element['#views_single'])) {
+    $field_name = 'views_'. $field_name;
+  }
 
   $element[$field_key] = array(
     '#type' => 'text_textfield',
     '#default_value' => isset($element['#value']) ? $element['#value'] : '',
-    '#autocomplete_path' => 'userreference/autocomplete/'. $element['#field_name'],
+    '#autocomplete_path' => 'userreference/autocomplete/'. $field_name,
     // The following values were set by the content module and need
     // to be passed down to the nested element.
     '#title' => $element['#title'],
@@ -550,6 +566,7 @@
     '#type_name' => $element['#type_name'],
     '#delta' => $element['#delta'],
     '#columns' => $element['#columns'],
+    '#views' => $element['#views'],
   );
   if (empty($element[$field_key]['#element_validate'])) {
     $element[$field_key]['#element_validate'] = array();
@@ -608,16 +625,30 @@
   $field_key = $element['#columns'][0];
   $value = $element['#value'][$field_key];
   $uid = NULL;
+  $uids = array();
   if (!empty($value)) {
-    $reference = _userreference_potential_references($field, $value, 'equals', NULL, 1);
-    if (empty($reference)) {
-      form_error($element[$field_key], t('%name: found no valid user with that name.', array('%name' => t($field['widget']['label']))));
+    if (!empty($element['#views'])) {
+      $value = drupal_explode_tags($value);
     }
     else {
-      $uid = key($reference);
+      $value = array($value);
+    }
+
+    foreach ($value as $v) {
+      $uid = NULL;
+      $reference = _userreference_potential_references($field, $v, 'equals', NULL, 1);
+      if (empty($reference)) {
+        form_error($element[$field_key], t('%name: found no valid user with that name.', array('%name' => t($field['widget']['label']))));
+      }
+      else {
+        $uid = key($reference);
+      }
+      if (!empty($uid)) {
+        $uids[] = $uid;
+      }
     }
   }
-  form_set_value($element, $uid, $form_state);
+  form_set_value($element, (empty($element['#views']) ? $uid : $uids), $form_state);
 }
 
 /**
@@ -826,6 +857,16 @@
  */
 function userreference_autocomplete($field_name, $string = '') {
   $fields = content_fields();
+  $prefix = '';
+
+  // Check for a views field.
+  if (0 === substr_compare($field_name, 'views_', 0, 6)) {
+    $field_name = str_replace('views_', '', $field_name);
+    $array = drupal_explode_tags($string);
+    $string = trim(array_pop($array));
+    $prefix = count($array) ? implode(', ', $array) .', ' : '';
+  }
+
   $field = $fields[$field_name];
   $match = isset($field['widget']['autocomplete_match']) ? $field['widget']['autocomplete_match'] : 'contains';
   $matches = array();
@@ -833,7 +874,7 @@
   $references = _userreference_potential_references($field, $string, $match, array(), 10);
   foreach ($references as $id => $row) {
     // Add a class wrapper for a few required CSS overrides.
-    $matches[$row['title']] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';
+    $matches[$prefix . $row['title']] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';
   }
   drupal_json($matches);
 }
@@ -928,4 +969,4 @@
 
 function theme_userreference_autocomplete($element) {
   return $element['#children'];
-}
\ No newline at end of file
+}

