I've created a CiviCRM 3.0 data provider for RealName.

It works by getting the list of data fields from CiviCRM (the same ones shown on the profile create and view pages, configured from within CiviCRM), and making them available as fields for RealName.

I haven't done extensive testing (yet), but i seems to Work For Me(tm). :)

I can't attach just the .inc file, so attached is a patch against RealName-1.3...

Comments

Slovak’s picture

This appears to do exactly what I need, however I don't have any experience with applying patches. I searched Google and drupal.org for clues, but no matter what I tried, no luck. My web server is hosted with PHP 5.2.12 and I do have SSH access. I tried the patch command (patch -b < realname_civicrm.patch as well as just patch < realname_civicrm.patch) within the realname directory, but I continue to get error "can't find file to patch at input line 2". Can someone please clue me in?

coderintherye’s picture

Assigned: Unassigned » coderintherye
Status: Active » Needs work

First of all, good work =)

Patch is going to need some work. Just FYI to 2nd poster, you will need to manually create the realname_civicrm.inc I'm going to paste the code below. Focus on the last piece of the patch which adds the civicrm option to realname. I'd imagine it is fine to see if we can add the realname_civicrm.inc file with the realname distribution and thus allow a user to add it as a default. I'd think we would want to do a basic check to see if CiviCRM is enabled before providing it as an option.

The current code for the .inc seems to work although produces a number of errors. It also needs to be cleaned up for coding standards. I did some cleanup. I'm also not sure if realname is respecting the FALSE choice on the type setting, get_types seems to throw an error. Hopefully some time to clean this up. Anyone have any reason why we would not want to support CiviCRM by default?

<?php
/**
 * @file
 * Realname module support for CiviCRM.
 */
 
/**
 * Implementation of hook_profile_load().
 * Loads the CiviCRM profile information
 */
function civicrm_load_profile(&$account, $type=NULL) {
  civicrm_initialize();
  require_once 'CRM/Core/BAO/UFMatch.php';
  $userID = CRM_Core_BAO_UFMatch::getContactId( $account->uid );
  if ($userID) {
    require_once 'CRM/Core/BAO/UFGroup.php';
    require_once 'CRM/Core/BAO/UFField.php';
    require_once 'CRM/Core/Action.php';
 
    $ctype = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $userID, 'contact_type');
 
    $ufGroups =& CRM_Core_BAO_UFGroup::getModuleUFGroup('User Account', 0, false);
    $weight   = 100;
    foreach ($ufGroups as $id => $title) {
      $fieldType = CRM_Core_BAO_UFField::getProfileType($id);
      if (($fieldType != 'Contact') && ($fieldType != $ctype)) {
        continue;
      }
      $fields = CRM_Core_BAO_UFGroup::getFields($id, false, CRM_Core_Action::VIEW, null, null, false, null, true);
      $values = array();
      CRM_Core_BAO_UFGroup::getValues($userID, $fields, $values);
 
      foreach($fields as $field_name => $field) {
        $value = $values[$field['title']];
        $account->{$field_name} = strip_tags($value);
      }
 
    }
 
  }
  return;
}
 
function realname_civicrm_get_fields($current) {
  civicrm_initialize();
  $fields = $links = array();
  require_once 'CRM/Core/BAO/UFField.php';
  require_once 'CRM/Core/BAO/UFGroup.php';
  require_once 'CRM/Core/Action.php';
 
  $ctype = 'Individual';
  $ufGroups =& CRM_Core_BAO_UFGroup::getModuleUFGroup('User Account', 0, false);
  foreach ($ufGroups as $id => $title) {
    $fieldType = CRM_Core_BAO_UFField::getProfileType($id);
    if (($fieldType != 'Contact' ) && ($fieldType != $ctype)) {
      continue;
    }
 
    $civi_fields = CRM_Core_BAO_UFGroup::getFields($id, false, CRM_Core_Action::VIEW, null, null, false, null, true);
 
    foreach($civi_fields as $field_name => $f) {
      $selected = array_key_exists($field_name, $current);
      $fields[$field_name] = array(
        'title' => $f['title'],
        'weight' => $selected ? $current[$field_name] : 0,
        'selected' => $selected,
      );
    }
 
  }
 
 return array('fields' => $fields, 'links' => $links);
}
colemanw’s picture

Good work indeed. I was just sitting down this morning to write something like this, and lo, you've already gotten us off to a great start. Thanks for doing this work.
My first observation is that you don't seem to be making use of the CiviCRM API; doing so would increase the longevity of this code and hopefully cut down on error messages. I would try to keep calls to non-public civi functions to a minimum. I know that using CRM_Core_BAO_UFMatch::getContactId is necessary because there is no api for that. But getting at the actual data should be achievable by using the API function civicrm_contact_search, and it would look something like this:


require_once 'CRM/Core/BAO/UFMatch.php';
require_once 'api/v2/Contact.php';
  
$cid = CRM_Core_BAO_UFMatch::getContactId($user->uid);
    
$search = array(
        'contact_id'          => $cid,
        'sort'                => 'contact_id',
        'return_display_name' => TRUE,
        'return_email' => TRUE,
        'return some other stuff' => TRUE,
        );
$result = civicrm_contact_search($search);

@nowarninglabel, please let me know how I can help.

colemanw’s picture

Title: CiviCRM 3.0 data provider module » CiviCRM 3.0 data provider patch

nudge

coderintherye’s picture

Sorry for my delays on this. I go work on a ship during the months of July and August and don't get back to coding until September usually (I'm currently in the Bering Sea west of Attu island, Alaska). Though I may get some time to look at this tomorrow since due to crossing the International Date line, I get the enviable bonus of having two Saturdays.

If you want to help in the meantime, can clean up the provided patch and resubmit it so I can apply it against a dev build and run it through coder. If all looks good then we can set to RTBC and apply the patch to dev.

voxpelli’s picture

I would suggest supporting #517844: Add hooks to have modules define support in themselves instead so that not support for all modules needs to be added directly to RealName.

coderintherye’s picture

#517844 may definitely be the better long term strategy, though I will have to review your patch and see how things go then talk to Nancy about it.

I'll report back here once I have some consensus.

colemanw’s picture

Sorry for my long-delayed response. After looking at the options, I have dropped this module in favor of a much lighter-weight theme function. In addition to avoiding whatever overhead Realname requires, this function also avoids bootstrapping CiviCRM, which is a huge performance drag.
If anyone else is interested in using CiviCRM name fields (or other contact data) instead of the default drupal username, here is my theme function for you to mess with: (place in your theme's template.php file and rename mytheme to the actual name of your theme)

/**
 * Implementation of HOOK_username().
 */
function mytheme_username($object) {

  if ($object->uid && $object->name) {

    $db = db_query('SELECT con.first_name, con.nick_name, con.last_name FROM {civicrm_uf_match} uf, {civicrm_contact} con
								    WHERE uf.uf_id = %d AND uf.contact_id = con.id', $object->uid );

    $contact = db_fetch_array( $db );
    
    if( $contact['nick_name'] )
	    $name = $contact['nick_name'].' '.$contact['last_name'];
    elseif( $contact['first_name'] )
	    $name = $contact['first_name'].' '.$contact['last_name'];
    else
	    $name = $object->name;

    // 20 characters is too short, let's set it to 30.
    if (drupal_strlen($name) > 30)
      $name = drupal_substr($name, 0, 28) .'...';

    if (user_access('access user profiles')) {
      $output = l($name, 'user/'. $object->uid, array('attributes' => array('title' => 'View user profile.')));
    }
    else {
      $output = check_plain($name);
    }
  }
  elseif ($object->name) {
  
    if (!empty($object->homepage)) {
      $output = l($object->name, $object->homepage, array('attributes' => array('rel' => 'nofollow')));
    }
    else {
      $output = check_plain($object->name);
    }

  }
  else {
    $output = 'Visitor';
  }

  return $output;
}

Sorry if it's off-topic to post that here, but it might help somebody out.

coderintherye’s picture

Status: Needs work » Closed (won't fix)

I'm going to mark this as closed in favor of #517844

It was obvious from the approach here that even when an API is available for a module it is still not going to get us there completely. We should allow simply for other modules to provide real name service as easily as possible through RealName and leave the onus on the other modules developers on whether or not they want to implement it.