--- /build/drupal-cvs/database/database.mysql	2005-02-21 22:00:01.000000000 +0100
+++ database/database.mysql	2005-03-17 07:44:54.000000000 +0100
@@ -466,6 +466,16 @@
   KEY fid (fid)
 );
 
+--
+-- Table structure for table 'profile_values_term'
+--
+
+CREATE TABLE profile_values_term (
+  fid int(11) NOT NULL default '0',
+  uid int(11) NOT NULL default '0',
+  tid int(11) NOT NULL default '0',
+  KEY fidtid (fid, tid)
+);
 
 --
 -- Table structure for table 'url_alias'
--- /build/drupal-cvs/database/database.pgsql	2005-02-27 22:00:01.000000000 +0100
+++ database/database.pgsql	2005-03-17 07:44:42.000000000 +0100
@@ -491,6 +491,18 @@
   PRIMARY KEY  (pid)
 );
 CREATE INDEX url_alias_dst_idx ON url_alias(dst);
+
+--
+-- Table structure for table 'profile_values_term'
+--
+
+CREATE TABLE profile_values_term (
+  fid int(11) NOT NULL default '0',
+  uid int(11) NOT NULL default '0',
+  tid int(11) NOT NULL default '0'
+);
+CREATE INDEX fidtid ON profile_values_term(fid, tid);
+
 --
 -- Table structure for permission
 --
--- /build/drupal-cvs/modules/profile.module	2005-01-28 22:00:01.000000000 +0100
+++ modules/profile.module	2005-03-17 07:49:00.000000000 +0100
@@ -161,6 +161,17 @@
     // 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 ($edit[$field->name] as $index => $term_id) {
+      	if ($term_id[0])
+          db_query("INSERT INTO {profile_values_term} (fid, uid, tid) VALUES (%d, %d, %d)", $field->fid, $user->uid, $term_id[0]);
+	else
+          unset($edit[$field->name][$index]);
+      }
+    }
     if (_profile_field_serialize($field->type)) {
        $edit[$field->name] = serialize($edit[$field->name]);
     }
@@ -289,6 +300,9 @@
       case 'date':
         $fields[$category] .= _profile_date_field($field, $edit);
         break;
+      case 'taxonomy':
+      	$fields[$category] .= _profile_taxonomy_field($field, $edit);
+	break;
     }
   }
 
@@ -348,6 +362,23 @@
   return format_date(gmmktime(0, 0, 0, $month, 2, 1970), 'custom', 'M', 0);
 }
 
+
+/**
+ * Helper function to select one or more types of taxonomy.
+ * This is basically the function taxonomy_form() with vocabulary->multiple
+ * forced to true.
+ */ 
+function _profile_taxonomy_field($field, $edit) {
+  $vid = $field->options;
+  $vocabulary = taxonomy_get_vocabulary($vid);
+  $data = array();
+  foreach ($edit[$field->name] as $index => $termid) {
+    $data[] = $termid[0];
+  }
+  return _taxonomy_term_select($vocabulary->name, $field->name,
+    $data, $vid, $vocabulary->help, 1, '<' . t('none') . '>');
+}
+
 function profile_validate_profile($edit, $category) {
 
   if (($_GET['q'] == 'user/register') ? 1 : 0) {
@@ -514,6 +545,13 @@
   if ($type == 'selection') {
     $group .= form_textarea(t('Selection options'), 'options', $edit['options'], 70, 8, 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;
+    $group .= form_select(t('Vocabulary'), 'options', $edit['options'], $taxopt, t('Select the vocabulary you want to use'), '', FALSE, TRUE);
+  }
   $group .= form_weight(t('Weight'), 'weight', $edit['weight'], 5, t('The weights define the order in which the form fields are shown.  Lighter fields "float up" towards the top of the category.'));
   $group .= form_radios(t('Visibility'), 'visibility', $edit['visibility'], array(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') {
@@ -582,12 +620,13 @@
                  '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' or $type == 'taxonomy';
 }
 
 ?>
