? vcard/cvs
? vcard/hcard.png
Index: vcard/INSTALL.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/vcard/INSTALL.txt,v
retrieving revision 1.3
diff -u -u -p -r1.3 INSTALL.txt
--- vcard/INSTALL.txt	15 Jan 2008 13:19:08 -0000	1.3
+++ vcard/INSTALL.txt	1 Feb 2008 03:37:21 -0000
@@ -18,12 +18,26 @@ Installation instructions for vcard modu
     */
    function yourtheme_user_profile($account, $fields) {
      if (module_exists("vcard")) {
-       return theme("vcard", $account);
+       return theme("vcard", $account, $fields);
      }
      else {
        return theme_user_profile($account, $fields);
      }
    }
-   ?>
+
+   /**
+    * Override of theme_profile_block()
+    * Adds microformats to the 'Author information' block
+    */
+    function yourtheme_profile_block($account, $fields = array()) {
+      if (function_exists('theme_vcard')) {
+        return theme('vcard', $account, $fields);
+      }
+      else {
+        return theme_profile_listing($account, $fields);
+      }
+    }
+    
+    ?>
 
    For additional information on themeing read the handbook pages http://drupal.org/theme-guide.
\ No newline at end of file
Index: vcard/vcard.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/vcard/vcard.module,v
retrieving revision 1.16
diff -u -u -p -r1.16 vcard.module
--- vcard/vcard.module	26 Jan 2008 20:47:53 -0000	1.16
+++ vcard/vcard.module	1 Feb 2008 03:37:22 -0000
@@ -44,7 +44,7 @@ function vcard_help($section) {
         </p>
         <p>
         Web browsers and !aggregation_tools can also extract and use vCard-like information when it is displayed on the page using !hcard - an embedded !microformat.
-        Read the module's documentation for more information on how to add hCard support to your theme.
+        Read the vCard module's INSTALL.txt documentation for more information on how to add hCard support to your theme.
         </p>
         <pre>",
         array(
@@ -53,6 +53,30 @@ function vcard_help($section) {
           '!microformat' => l('microformat', 'http://microformats.org'),
         )
       );
+      break;
+    case 'admin/user/profile':
+      return t("<p>
+        For assistance setting up a default profile with common fields, visit
+        <a href='!vcard_settings_link'>the VCard settings</a> which can preset an automatic profile definition.
+      </p><p>
+        To enable machine-readable <a href='!microformat_link'>microformats</a>
+        for your profiles, see the <a href='!vcard_help_link'>vCard help</a> and README. 
+      </p>",
+      array(
+        '!vcard_settings_link' => url('admin/settings/vcard'),
+        '!vcard_help_link' => url('admin/help/vcard'),
+        '!microformat_link' => url('http://microformats.org'),
+      )
+    );
+    case 'admin/settings/vcard':
+      return t("
+        Profile fields are added and administered on
+        <a href='!profile_settings_link'>the Profile Configuration page</a>.
+      ",
+      array(
+        '!profile_settings_link' => url('admin/user/profile'),
+      )
+    );
   }
 }
 
@@ -100,6 +124,13 @@ function vcard_admin_settings() {
     '#title' => t('Field Mappings'),
     '#description' => t('This section is only enabled if the "profiles" module is enabled. When enabled it will provide a dropdown selection box for each defined profile item of type textfield, textarea, or url.'),
   );
+  $form['auto_create'] = array(
+    '#type' => 'submit',
+    '#value' => t('Auto-create profile fields'),
+    '#description' => t("Attempt to create the normal required profile fields, if you haven't already done so'"),
+  );
+  $form['#submit']['vcard_auto_create_profile_submit'] = array(); 
+  
   $options = array('' => 'Select a property');
   $options = $options + _vcard_properties();
   foreach (_vcard_profile_fields() as $fid => $title) {
@@ -209,8 +240,38 @@ function vcard_fetch() {
  * see http://microformats.org/wiki/hcard
  *
  * @param $account user object
+ * @param $fields a structured (nested) array of profile field definitions and
+ * values. Access visibility (public/private etc) has already filtered them to
+ * the ones that should be displayed. Settings are on the profile fields
+ * 'visibility' setting. If not set, all account info may be displayed!
  */
-function theme_vcard($account) {
+function theme_vcard($account, $fields = NULL) {
+  if(! $fields) { $fields = array() ; }
+  // Flatten the fields (which may have previously been grouped by category) so I can access them directly by id
+  $all_fields = array();
+  foreach ($fields as $category => $items) {
+    if(is_array($items)){
+      $all_fields = array_merge($all_fields, $items);
+    }
+    else {
+      $all_fields[$items->name] = $items;
+    }
+  }
+  #drupal_set_message('<pre>'. print_r($all_fields, 1) .'</pre>');
+
+  // For privacy, only profile fields that have an entry in 'fields' should be displayed
+  // Respect this by only accessing values listed in $fields
+  if(! empty($all_fields)){
+    foreach ($account as $var => $val) {
+      if (! $all_fields[$var]) { 
+        if (($var != 'picture') && ($var != 'name')) {
+          // Temporarily blank this info
+          unset($account->$var);
+        }
+      }
+    }
+  }
+
   // photo
   if (variable_get('user_pictures', 0)) {
     if ($account->picture && file_exists($account->picture)) {
@@ -224,13 +285,17 @@ function theme_vcard($account) {
     }
   }
 
+  $url = vcard_get_field('url', $account);
+
   // name
   $firstname = vcard_get_field('givenname', $account);
   $lastname = vcard_get_field('familyname', $account);
   if ($firstname && $lastname) {
     $name = '<div class="n">';
+    if ($url) {$name .= '<a class="url" href="'. $url .'">'; }
     $name .= '<span class="given-name">'. $firstname ."</span>\n";
     $name .= '<span class="family-name">'. $lastname ."</span>\n";
+    if ($url) {$name .= "</a>"; }
     $name .= '<span class="nickname">'. $account->name ."</span>\n";
     $name .= "</div>\n";
   }
@@ -341,3 +406,100 @@ function _vcard_get_map($account) {
 
   return $map;
 }
+
+/**
+ * Add an action to auto-create a detailed contact profile with consistant
+ * names.
+ *
+ * Capture the vcard settings submission, and act on the button if pressed.
+ *  
+ * Although I could have just over-written everything, instead I take care to
+ * absorb half-profiles that have already been made, possibly with different
+ * names, and not replace anything that already works OK. This process just adds
+ * the supplimental contact vCard fields. Thus it should be safe to run as an
+ * upgrade over anything you already have.
+ */
+function vcard_auto_create_profile_submit($form_id, $form_values) {
+  if ($form_values['op'] == t('Auto-create profile fields')) {
+    drupal_set_message(t("Creating required profile fields"));
+    $required_fields = _vcard_properties();
+
+    // Load in all currently existing fields, to see what exists and what they are matched to so far.
+    $available_fields = array();
+    $available_fields_result = db_query('SELECT * FROM {profile_fields} ORDER BY weight ');
+    while ($field = db_fetch_object($available_fields_result)) {
+      // Index these on a version of the internal id, not the text label
+      $key = preg_replace('|^profile_|', '', $field->name);
+      if ($linked = variable_get('vcard_profile_'. $field->fid, "")) {
+        // This field is already linked to a vcard tag. Add it to the index in the right place
+        $key = $linked;
+      }
+      // There may be confusion if there are more than one field named the same. Don't do that.
+      if (! $available_fields[$key]) {
+        $available_fields[$key] = $field;
+      }
+    }
+    $vcard_fields = _vcard_profile_fields();
+
+    foreach ($required_fields as $required_field_id => $required_field_label) {
+      // Check if a field with its label is already existing
+      if (in_array($required_field_id, array_keys($available_fields))) {
+        $field_def = $available_fields[$required_field_id];
+        drupal_set_message(t(
+          "<a href='!field_link'>%field_label</a> already exists as a profile field. %alt_name", 
+          array(
+            '%field_label' => $required_field_label, 
+            '!field_link'  => url('admin/user/profile/edit/'. $field_def->fid), 
+            '%alt_name'    => (($field_def->title != $required_field_label) ? " (called $field_def->title)" : "")
+          )
+        ));
+      }
+      else {
+        // need to make it
+        drupal_set_message(t("Creating profile field ") . $required_field_label);
+        // @see profile_field_form_submit()
+        $field_def = array(
+          'title'       => $required_field_label, 
+          'name'        => 'profile_'. $required_field_id, 
+          'explanation' => '', 
+          'category'    => 'Contact Information', 
+          'type'        => 'textfield', 
+          'weight'      => 0, 
+          'required'    => 0, 
+          'register'    => 1, 
+          'visibility'  => 2,
+        );
+        if ($required_field_id == 'url') {$field_def['type']='url';}
+        if ($required_field_id == 'birthday') {$field_def['type']='date';}
+        db_query("
+          INSERT INTO {profile_fields} 
+          (title, name, explanation, category, type, weight, required, register, visibility, autocomplete, options, page) 
+          VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s', '%s')", 
+          $field_def['title'], $field_def['name'], $field_def['explanation'], $field_def['category'], $field_def['type'], $field_def['weight'], $field_def['required'], $field_def['register'], $field_def['visibility'], $field_def['autocomplete'], $field_def['options'], $field_def['page']        
+          );
+        // retrieve its new ID
+        $result = db_query('SELECT * FROM {profile_fields} WHERE name = "%s"', $field_def['name']);
+        $field_def = db_fetch_object($result);
+      }
+      // Now check the right profile field is matched up with the right vcard field
+      if ($field_def && (variable_get('vcard_profile_'. $field_def->fid, '') != $required_field_id)) {
+        drupal_set_message(t(
+          "Assigning profile field %fid (<a href='!field_link'>%title</a>) to vcard key %required_field_id", 
+          array(
+            '%fid' => $field_def->fid,
+            '%title' => $field_def->title,
+            '%required_field_id' => $required_field_id,
+            '!field_link' => url('admin/user/profile/edit/'. $field_def->fid)
+          )
+        ));
+        variable_set('vcard_profile_'. $field_def->fid, $required_field_id);
+      }
+    }
+    drupal_set_message(t("
+      Created profile fields! You may want to review the profile settings
+      individually to ensure their display order and public visibility 
+      settings are right for you. 
+      By default they are all displayed on the users profile page.  
+    "));
+  }
+}
