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
<?php
if ( ! civicrm_initialize( ) ) {
return;
}
global
$civicrm_root;
require_once $civicrm_root . '/api/api.php';
?>
<?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...
)
)
?>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.

