From 6a54223ca6be48bb2376ed103610b1beed4ea8b3 Mon Sep 17 00:00:00 2001
From: Jake Bell <jake@theunraveler.com>
Date: Fri, 10 Jun 2011 15:34:59 -0500
Subject: [PATCH] Initial pass at upgrading to D7.

---
 ur_autocomplete.info    |   11 ++-
 ur_autocomplete.install |   46 -----------
 ur_autocomplete.module  |  203 +++++++++--------------------------------------
 3 files changed, 47 insertions(+), 213 deletions(-)
 delete mode 100644 ur_autocomplete.install

diff --git a/ur_autocomplete.info b/ur_autocomplete.info
index 00dd2c7..b1923d1 100644
--- a/ur_autocomplete.info
+++ b/ur_autocomplete.info
@@ -1,5 +1,12 @@
 name=Userreference Autocomplete Widget
 description=Adds an autocomplete widget for userreference that works like taxonomy free-tagging
-dependencies[]=userreference
+dependencies[]=user_reference
 package=CCK
-core=6.x
+core=7.x
+
+; Information added by drupal.org packaging script on 2011-02-25
+version = "7.x-1.x-dev"
+core = "7.x"
+project = "ur_autocomplete"
+datestamp = "1298620568"
+
diff --git a/ur_autocomplete.install b/ur_autocomplete.install
deleted file mode 100644
index bcf7dad..0000000
--- a/ur_autocomplete.install
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Module installation/uninstallation hooks.
- */
-
-/**
- * Implementation of hook_install().
- */
-function ur_autocomplete_install() {
-  // Make sure this module is loaded after CCK Text/Number fields.
-  // See autocomplete_widgets_form_alter().
-  db_query("UPDATE {system} SET weight = 1 WHERE name = 'ur_autocomplete'");
-
-  // Notify content module when this module is installed.
-  drupal_load('module', 'content');
-  content_notify('install', 'ur_autocomplete');
-}
-
-/**
- * Implementation of hook_uninstall().
- */
-function ur_autocomplete_uninstall() {
-  // Notify content module when this module is uninstalled.
-  drupal_load('module', 'content');
-  content_notify('uninstall', 'ur_autocomplete');
-}
-
-/**
- * Implementation of hook_enable().
- */
-function ur_autocomplete_enable() {
-  // Notify content module when this module is enabled.
-  drupal_load('module', 'content');
-  content_notify('enable', 'ur_autocomplete');
-}
-
-/**
- * Implementation of hook_disable().
- */
-function ur_autocomplete_disable() {
-  // Notify content module when this module is disabled.
-  drupal_load('module', 'content');
-  content_notify('disable', 'ur_autocomplete');
-}
diff --git a/ur_autocomplete.module b/ur_autocomplete.module
index 84e6d25..ae40cb9 100644
--- a/ur_autocomplete.module
+++ b/ur_autocomplete.module
@@ -29,85 +29,32 @@ function ur_autocomplete_theme() {
 }
 
 /**
- * Implementation of hook_widget_info().
+ * Implementation of hook_field_widget_info().
  */
-function ur_autocomplete_widget_info() {
+function ur_autocomplete_field_widget_info() {
   return array(
     'ur_autocomplete' => array(
       'label' => t('Enhanced Userreference Autocomplete'),
-      'field types' => array('userreference'),
-      'multiple values' => CONTENT_HANDLE_MODULE,
-      'callbacks' => array(
-        'default value' => CONTENT_CALLBACK_DEFAULT,
+      'field types' => array('user_reference'),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
       ),
     ),
   );
 }
 
 /**
- * Implementation of FAPI hook_elements().
- *
- * Any FAPI callbacks needed for individual widgets can be declared here,
- * and the element will be passed to those callbacks for processing.
- *
- * Drupal will automatically theme the element using a theme with
- * the same name as the hook_elements key.
- *
- * Autocomplete_path is not used by text_widget but other widgets can use it
- * (see nodereference and userreference).
- */
-function ur_autocomplete_elements() {
-  return array(
-    'ur_autocomplete' => array(
-      '#input' => TRUE,
-      '#columns' => array('name'),
-      '#delta' => 0,
-      '#process' => array('ur_autocomplete_process'),
-      '#autocomplete_path' => FALSE,
-    ),
-  );
-}
-
-/**
- * Implementation of hook_widget_settings().
- */
-function ur_autocomplete_widget_settings($op, $widget) {
-  switch ($op) {
-    case 'form':
-      $form = array();
-      $match = isset($widget['autocomplete_match']) ? $widget['autocomplete_match'] : 'contains';
-      if ($widget['type'] == 'ur_autocomplete') {
-        $form['autocomplete_match'] = array(
-          '#type' => 'select',
-          '#title' => t('Autocomplete matching'),
-          '#default_value' => $match,
-          '#options' => array(
-            'starts_with' => t('Starts with'),
-            'contains' => t('Contains'),
-          ),
-          '#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users.'),
-        );
-      }
-      else {
-        $form['autocomplete_match'] = array('#type' => 'hidden', '#value' => $match);
-      }
-      return $form;
-
-    case 'save':
-      return array('autocomplete_match');
-  }
-}
-
-/**
- * Implementation of hook_widget().
+ * Implementation of hook_field_widget_form().
  */
-function ur_autocomplete_widget(&$form, &$form_state, $field, $items, $delta = 0) {
-  $element = array(
-    '#type' => $field['widget']['type'],
+function ur_autocomplete_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+  $element += array(
+    '#type' => 'textfield',
     '#default_value' => $items,
+    '#autocomplete_path' => 'ur_autocomplete/autocomplete/' . $field['field_name'],
     '#value_callback' => 'ur_autocomplete_value',
+    '#element_validate' => array('_ur_validate_element'),
   );
-  return $element;
+  return array('uid' => $element);
 }
 
 /**
@@ -120,7 +67,7 @@ function ur_autocomplete_value($element, $edit = FALSE) {
   $field_key  = $element['#columns'][0];
   foreach ($element['#default_value'] as $delta => $item) {
     if (!empty($item['uid'])) {
-      $n = db_result(db_query(db_rewrite_sql('SELECT u.name FROM {users} u WHERE u.uid = %d'), $item['uid']));
+      $n = db_query('SELECT u.name FROM {users} u WHERE u.uid = ?', array($item['uid']))->fetchField();
       $names[] = ur_autocomplete_encode($n);
     }
   }
@@ -128,83 +75,31 @@ function ur_autocomplete_value($element, $edit = FALSE) {
 }
 
 /**
- * Process an individual element.
- *
- * Build the form element. When creating a form using FAPI #process,
- * note that $element['#value'] is already set.
- *
- */
-function ur_autocomplete_process($element, $edit, $form_state, $form) {
-  // The userreference autocomplete widget doesn't need to create its own
-  // element, it can wrap around the text_textfield element and add an autocomplete
-  // path and some extra processing to it.
-  // Add a validation step where the value can be unwrapped.
-  $field_name = $element['#field_name'];
-  $field = $form['#field_info'][$field_name];
-
-  if (!$field['multiple']) {
-    $autocomplete = 'userreference/autocomplete/';
-  }
-  else {
-    $autocomplete = 'ur_autocomplete/autocomplete/';
-  }
-  $field_key  = $element['#columns'][0];
-
-  $element[$field_key] = array(
-    '#type' => 'text_textfield',
-    '#default_value' => isset($element['#value']) ? $element['#value'] : '',
-    '#autocomplete_path' => $autocomplete . $element['#field_name'],
-    // The following values were set by the content module and need
-    // to be passed down to the nested element.
-    '#title' => $element['#title'],
-    '#required' => $element['#required'],
-    '#description' => $element['#description'],
-    '#field_name' => $element['#field_name'],
-    '#type_name' => $element['#type_name'],
-    '#delta' => $element['#delta'],
-    '#columns' => $element['#columns'],
-  );
-  if (empty($element[$field_key]['#element_validate'])) {
-    $element[$field_key]['#element_validate'] = array();
-  }
-  array_unshift($element[$field_key]['#element_validate'], 'ur_autocomplete_validate');
-
-  // Used so that hook_field('validate') knows where to flag an error.
-  $element['_error_element'] = array(
-    '#type' => 'value',
-    // Wrapping the element around a text_textfield element creates a
-    // nested element, so the final id will look like 'field-name-0-nid-nid'.
-    '#value' => implode('][', array_merge($element['#parents'], array($field_key, $field_key))),
-  );
-  return $element;
-}
-
-/**
  * Validate an autocomplete element.
  *
  * Remove the wrapper layer and set the right element's value.
- * This will move the nested value at 'field-name-0-nid-nid'
- * back to its original location, 'field-name-0-nid'.
  */
-function ur_autocomplete_validate($element, &$form_state) {
+function _ur_validate_element($element, &$form_state) {
   $field_name = $element['#field_name'];
-  $type_name = $element['#type_name'];
-  $field = content_fields($field_name, $type_name);
   $field_key = $element['#columns'][0];
-  $value = $element['#value'][$field_key];
+  // TODO: Why is $element['#value'] not set?!
+  $value = $form_state['input'][$field_name]['und'][$field_key];
+
+  // Loop through all of the comma-separated values.
   $values = array();
-  $uid = NULL;
-  $typed_names = ur_autocomplete_parse_input($value);
-  foreach ($typed_names as $delta => $name) {
+  $usernames = ur_autocomplete_parse_input($value);
+  foreach ($usernames as $delta => $name) {
     if (!empty($name)) {
-      if (($u = user_load(array('name' => $name))) && ur_autocomplete_encode($name) != $u->name && $name != $u->name) {
-        form_error($element[$field_key], t('%name: name mismatch. Please check your selection.', array('%name' => t($field['widget']['label']))));
-      }
-      else {
+      $uid = db_query('SELECT uid FROM {users} WHERE name = ?', array($name))->fetchField();
+      if (!($u = user_load($uid)) || (ur_autocomplete_encode($name) != $u->name && $name != $u->name)) {
+        form_set_error($field_name, t('%name is not a registered user.', array('%name' => $name)));
+      } else {
         $values[] = array('uid' => $u->uid);
       }
     }
   }
+
+  // Reassign the field's values.
   $new_parents = array();
   foreach ($element['#parents'] as $parent) {
     $value = $value[$parent];
@@ -219,62 +114,45 @@ function ur_autocomplete_validate($element, &$form_state) {
 }
 
 /**
- * Implementation of hook_allowed_values().
- */
-function ur_autocomplete_allowed_values($field) {
-  $references = _userreference_potential_references($field);
-
-  $options = array();
-  foreach ($references as $key => $value) {
-    $options[$key] = $value['rendered'];
-  }
-  return $options;
-}
-
-/**
  * Retrieve a pipe delimited string of autocomplete suggestions
  *
  * Unholy union of taxonomy.module's taxonomy_autocomplete() and
- * userreference.module's userreference_autocomplete().
+ * user_reference.module's user_reference_autocomplete().
  */
 function ur_autocomplete_autocomplete($field_name, $string = '') {
   // The user enters a comma-separated list of users. We only autocomplete the last user.
-  $array = drupal_explode_tags($string);
+  $array = explode(', ', $string);
+
   // Fetch last user.
   $last_string = trim(array_pop($array));
 
   if ($last_string != '') {
-    $fields = content_fields();
-    $field = $fields[$field_name];
+    $field = field_info_field($field_name);
+    
     $count = count($array);
-    if ($count && empty($field['multiple'])) {
-      drupal_json(array());
-      return;
+    if ($field['cardinality'] !== '-1' && $count >= $field['cardinality']) {
+      drupal_json_output(array()); exit;
     }
     $match = isset($field['widget']['autocomplete_match']) ? $field['widget']['autocomplete_match'] : 'contains';
     $matches = array();
 
     $prefix = $count ? implode(', ', $array) . ', ' : '';
+    $suffix = $count ? '' : ', ';
 
-    $references = _userreference_potential_references($field, $last_string, $match, array(), 10);
+    $references = _user_reference_potential_references($field, $last_string, $match, array(), 10);
     foreach ($references as $id => $row) {
       $u = ur_autocomplete_encode($row['title']);
       // Add a class wrapper for a few required CSS overrides.
-      $matches[$prefix . $u] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';
+      $matches[$prefix . $u . $suffix] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';
     }
-    drupal_json($matches);
+    drupal_json_output($matches); exit;
   }
 }
 
 /**
  * Escapes commas and quotes in user names.
- * 
- * Based on code found in taxonomy.module
  *
- * @param string $string
- *  String to encode
- * @return string
- *  Encoded string
+ * Based on code found in taxonomy.module
  */
 function ur_autocomplete_encode($string) {
   $n = $string;
@@ -286,11 +164,6 @@ function ur_autocomplete_encode($string) {
 
 /**
  * Returns array containing all of the typed user names.
- *
- * @param string $typed_input
- *  What the user put into the autocomplete field
- * @return array
- *  Array containing each user name
  */
 function ur_autocomplete_parse_input($typed_input) {
   // This regexp allows the following types of user input:
-- 
1.7.5.4

