Introductory Tips on Hacking CiviCRM

Recently, I built a website for the International Peace Tiles Project. My goals were pretty straight forward:

  1. Develop an interface that would allow users to upload photos of their peace tiles.
  2. If users wished to swap their tiles with other users, have a system in place that would track the status of the tile.
  3. Have tiles be searchable by location.
  4. Gather user’s location and status of involvement

A good golden rule to follow is never make users enter data twice, and if certain functions (i.e. filing the tile under the user’s country) can be automated, automate them. So with that rule in mind, I decided to use CiviCRM to store user data.

However, there was a problem: I had no clue how to get to the user data, or connect it to their drupal account options. Obviously, I succeeded, however. In this tutorial, I will explain how to get a user’s country from CiviCRM, and auto-generate a taxonomy term within the context of the user posting a new content item.

Step One: Activate the CiviCRM dataset

I developed a custom module built off of the story module for this project. In order to get the user’s data, we must first declare the global user variable:

<?php global $user; ?>

This declaration makes the CURRENT user’s info available. Next, we will make all functions from all modules available [module_invoke_all()] (because we’re lazy, and it wouldn’t work otherwise). In addition, we will call function that basically wakes CiviCRM up[civicrm_initialize(TRUE)].

<?php global $user; module_invoke_all(); civicrm_initialize(TRUE); ?>

The above three lines have given us all we need to hack into CiviCRM.

Step Two: Get the correct contact record from the current user’s drupal uid

In the last step, we declared the global $user variable. That crucial step allows us to get the user’s unique id from the $user->uid variable. However, CiviCRM uses an entirely different unique ID for users, so we have to call a special function to get our dirty little hands on their records. Using the function below, we are given access to that lovely little number:

$userID = crm_uf_get_match_id( $user->uid );

Next we define a variable (in this case $contact) for an object that contains all information associated with that unique CiviCRM contact id (which is contained within the $userID variable).

$contact = crm_get_contact(array('contact_id' =>$userID));

As you can see, we use the crm_get_contact() function. The function will return our record along whatever lines we specify in the array, however in this case to keep it simple, we’re merely going to get it using CiviCRM’s unique contact_id. Now, there are hundreds of different fields we could return. You can take a look at all of them by using the EXTREMELY USEFUL YOU CAN’T LIVE WITHOUT IT function get_object_vars(). If you’d like to take a look at all of the data you have at your finger tips, include the following code at this point:

print_r(get_object_vars($contact));

Otherwise, continue on, and take a look at how we got our hands on the CiviCRM country field:

$userCountry = $contact->location[1]->address->country;

Step Three: Automatically Generate a Taxonomy Term Using $userCountry

Just for kicks, I’m leaving you the code I used to automatically generate a taxonomy term. It is called within the hook_nodeapi of the module:

switch($op) { case 'insert': case 'update': $node->taxonomy = array(); $new = taxonomy_node_get_terms(42); $results = module_invoke('taxonomy', 'get_term_by_name', $userCountry); // Create a new category term if (count($results) == 0) { $term = array(); $term['name'] = $userCountry; $term['description'] = t(‘’); $term['vid'] = 5; $term['weight'] = 0; $term = taxonomy_save_term($term); $node->taxonomy[] = $term['tid']; } else { // Use the existing category term in the database if (!in_array($results[0]->tid, $new)) { $node->taxonomy[] = $results[0]->tid; } break; }