Index: modules/profile.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile.module,v
retrieving revision 1.132
diff -u -F^f -r1.132 profile.module
--- modules/profile.module	30 Jan 2006 18:32:24 -0000	1.132
+++ modules/profile.module	13 Feb 2006 12:05:04 -0000
@@ -30,6 +30,7 @@ function profile_help($section) {
 <li>freeform list</li>
 <li>URL</li>
 <li>date</li>
+<li>taxonomy</li>
 </ul>
 ');
       $output .= t('<p>You can</p>
@@ -162,6 +163,7 @@ function profile_browse() {
 
     // Determine what query to use:
     $arguments = array($field->fid);
+    $table = '{profile_values}';
     switch ($field->type) {
       case 'checkbox':
         $query = 'v.value = 1';
@@ -174,13 +176,19 @@ function profile_browse() {
         $query = "v.value LIKE '%%%s%%'";
         $arguments[] = $value;
         break;
+      case 'taxonomy':
+        $table = '{profile_values_term}';
+        $query = "v.tid = '%s'";
+        $terms = taxonomy_get_term_by_name($value);
+        $arguments[] = $terms[0]->tid;
+        break;
       default:
         drupal_not_found();
         return;
     }
 
     // Extract the affected users:
-    $result = pager_query("SELECT u.uid, u.access FROM {users} u INNER JOIN {profile_values} v ON u.uid = v.uid WHERE v.fid = %d AND $query ORDER BY u.access DESC", 20, 0, NULL, $arguments);
+    $result = pager_query("SELECT u.uid, u.access FROM {users} u INNER JOIN $table v ON u.uid = v.uid WHERE v.fid = %d AND $query ORDER BY u.access DESC", 20, 0, NULL, $arguments);
 
     $output = '<div id="profile">';
     while ($account = db_fetch_object($result)) {
@@ -190,7 +198,7 @@ function profile_browse() {
     }
     $output .= theme('pager', NULL, 20);
 
-    if ($field->type == 'selection' || $field->type == 'list') {
+    if ($field->type == 'selection' || $field->type == 'list' || $field->type == 'taxonomy') {
       $title = strtr($field->page, array('%value' => theme('placeholder', $value)));
     }
     else {
@@ -247,6 +255,21 @@ function profile_save_profile(&$edit, &$
     // We use LOWER('%s') instead of PHP's strtolower() to avoid UTF-8 conversion issues.
   }
   while ($field = db_fetch_object($result)) {
+    if ($field->type == 'taxonomy') {
+      /* Do this before serialize.  Also, remove the term "0" if exists
+       * (corresponds to <none>) */
+      db_query("DELETE FROM {profile_values_term} WHERE fid = %d AND uid = %d", $field->fid, $user->uid);
+
+      foreach ((array)$edit[$field->name] as $index => $term_id) {
+        if ($term_id) {
+          db_query("INSERT INTO {profile_values_term} (fid, uid, tid) VALUES (%d, %d, %d)", $field->fid, $user->uid, $term_id);
+        }
+        else {
+          unset($edit[$field->name][$index]);
+        }
+      }
+    }
+
     if (_profile_field_serialize($field->type)) {
        $edit[$field->name] = serialize($edit[$field->name]);
     }
@@ -295,6 +318,13 @@ function profile_view_field($user, $fiel
           }
         }
         return implode(', ', $fields);
+      case 'taxonomy':
+        $fields = array();
+        foreach((array)$value as $tid) {
+            $term = taxonomy_get_term($tid);
+            $fields[] = $browse ? l($term->name, "profile/". drupal_urlencode($field->name) ."/". drupal_urlencode($term->name)) : check_plain($term->name);
+        }
+        return implode(', ', $fields);
     }
   }
 }
@@ -381,6 +411,10 @@ function profile_form_profile($edit, $us
       case 'date':
         $fields[$category][$field->name] = array('#type' => 'date', '#title' => check_plain($field->title), '#default_value' => $edit[$field->name], '#description' => _profile_form_explanation($field), '#required' => $field->required);
         break;
+      case 'taxonomy':
+        $vid = $field->options;
+        $fields[$category][$field->name] = taxonomy_form($vid, $edit[$field->name], _profile_form_explanation($field));
+        break;
     }
   }
   return $fields;
@@ -552,6 +586,7 @@ function profile_admin_delete($fid) {
   if ($_POST['edit']['confirm']) {
     db_query('DELETE FROM {profile_fields} WHERE fid = %d', $fid);
     db_query('DELETE FROM {profile_values} WHERE fid = %d', $fid);
+    db_query('DELETE FROM {profile_values_term} WHERE fid = %d', $fid);
     cache_clear_all();
     drupal_set_message(t('The field %field has been deleted.', array('%field' => theme('placeholder', $field->title))));
     drupal_goto('admin/settings/profile');
@@ -602,6 +637,20 @@ function _profile_field_form($type, $edi
       '#description' => t('A list of all options. Put each option on a separate line. Example options are "red", "blue", "green", etc.'),
     );
   }
+  if ($type == 'taxonomy') {
+    $tax_options = taxonomy_get_vocabularies();
+    $taxopt = array();
+    foreach ($tax_options as $key => $value) {
+      $taxopt[$key] = $value->name; 
+    }
+    $form['fields']['options'] = array(
+      '#type' => 'select',
+      '#title' => t('Vocabulary'),
+      '#description' => t('Select the vocabulary you want to use'),
+      '#default_value' => $edit['options'],
+      '#options' => $taxopt
+    );
+  }
   $form['fields']['weight'] = array('#type' => 'weight',
     '#title' => t('Weight'),
     '#default_value' => $edit['weight'],
@@ -613,7 +662,7 @@ function _profile_field_form($type, $edi
     '#default_value' => isset($edit['visibility']) ? $edit['visibility'] : PROFILE_PUBLIC,
     '#options' => array(PROFILE_HIDDEN => t('Hidden profile field, only accessible by administrators, modules and themes.'), PROFILE_PRIVATE => t('Private field, content only available to privileged users.'), PROFILE_PUBLIC => t('Public field, content shown on profile page but not used on member list pages.'), PROFILE_PUBLIC_LISTINGS => t('Public field, content shown on profile page and on member list pages.')),
   );
-  if ($type == 'selection' || $type == 'list') {
+  if ($type == 'selection' || $type == 'list' || $type == 'taxonomy') {
     $form['fields']['page'] = array('#type' => 'textfield',
       '#title' => t('Page title'),
       '#default_value' => $edit['page'],
@@ -706,10 +755,12 @@ function _profile_field_types($type = NU
                  'selection' => t('list selection'),
                  'list' => t('freeform list'),
                  'url' => t('URL'),
-                 'date' => t('date'));
+                 'date' => t('date'),
+                 'taxonomy' => t('taxonomy'),
+                 );
   return isset($type) ? $types[$type] : $types;
 }
 
 function _profile_field_serialize($type = NULL) {
-  return $type == 'date';
+  return $type == 'date' || $type == 'taxonomy';
 }
