Synchronising drupal users information with civicrm

José's picture
José
09 Jan 2012

Recently we have been working in a civicrm project and we thought it could be very useful to develop a module which helps us to reflect automatically any change made in an user account, in his related civicrm contact.

Civicrm offers an user's synchronisation functionality out of the box but it only checks drupal users without existing related civicrm contact and it creates the respective civicrm contacts. But we wanted something else: if for example we change the email address in an user account, the email address will have to change inmediately in the civicrm contact related to that drupal user.

For this purpose we need to use hook_user and hook_nodeapi because we don't wish to control changes in the basic account information, we want to control changes in some profile fields. . In our example we will show code inside a hook_user and we will do active use of the v3 civicrm API

 

The first step is to initialize civicrm to include the api:
<?php
if ( ! civicrm_initialize( ) ) {
            return;
}

global

$civicrm_root;
require_once
$civicrm_root . '/api/api.php';
?>

 

The second step is check if the drupal user (whose information we are trying to change) has a related civicrm contact, we use the civicrm api in relation with the UFMatch table, which stores the correspondence between drupal users uids and their related civicrm contacts ids:
 
<?php
$uf_params
= array(
       
'uf_id' => $account->uid,
       
'version' => 3,
       
'sequential' => 1,
        );

$UFMatch = civicrm_api( 'UFMatch','Get',$uf_params );

$contact_id = $UFMatch['values'][0]['contact_id'];

if(

$contact_id != NULL){ ...
?>

 

The way to use civicrm api calling to the civicrm_api function where the first argument is the table we can use for our query, the second argument is the kind of operation we wish (Get, Create, Delete...) and the third argument is an array containing information about the query (in our case, the user uid whose related civi contact id we want to get, the version of the api we are using and a flag to indicate we have the results in sequential format). More useful information about using the civicrm api can be found here: http://wiki.civicrm.org/confluence/display/CRMDOC40/CiviCRM+Public+APIs

After calling the civicrm api, we will have the results in the variable $UFMatch which structure will be:

 

<?php
array( ["values"] => array( [0] => array_with_row_1_info
                                      
[1] => array_with_row_2_info...
                                    )
        )
?>
 
 
In our case we will have only one row returned so we can find the civi contact id related to the drupal user in  $UFMatch['values'][0]['contact_id']. If the drupal user doesn't exist $UFMatch['values'][0]['contact_id'] will be NULL.
 
 
 
The third step, if the drupal user has a related contact in civicrm, is compare the account info which changes we want to control. We are going to use for example, the user's email.

So first we see what's the email value in the related civicrm contact. For that we use again the civicrm api to make a query against the contacts table:

 

<?php
$contact_params
= array(
'contact_id' => $contact_id,
'version' => 3,
'sequential' => 1,
);

$contact = civicrm_api( 'contact','Get',$contact_params );

$civi_email = $contact['values'][0]['email'];
?>

 

And after that we compare it with the drupal user's email to check for any possible change:

 

<?php
$drupal_email
= $account -> mail;

if (

$civi_email != $drupal_email) {...
?>

 

If they are different then this information was updated in the user's account info so it will have to be changed in his related contact info, using again the civicrm api:

<?php
$update_params
= array(
'contact_id' => $contact_id,
'email' => $drupal_email,
'version' => 3,
);

civicrm_api('contact', 'create', $update_params);

civicrm_api('UFMatch', 'create', $update_params);
?>

In civicrm api v3 some tables don't have defined the "update" operation, in that case we can use the operation "create" so if we provide a row id in our query array and that id exists, then the information will be updated for the row with that id.

If we check our query array ($update_params), we can see we are saying to the drupal api that we want to change the email of the civi contact with id $contact_id to the email of the related drupal user ($drupal_email).

 

As you can see, civicrm api is a very powerful tool, very easy to use inside any of your drupal modules to cross information between the cms and the crm.

tags: 

Find out how Cameron & Wilding can help your business on the webContact us