Drupal/CiviCRM Integration - CiviCRM Entity and Webform CiviCRM

Published
2013-09-19 16:11
Written by

Example Use Case

This example is a one event page which has tabs of many types of content and views attached which allows a anonymous user to view the info, see registered participants, register for the CiviCRM event via one webform which also automatically creates a contact, membership, active drupal user, and participant event registration to the event, logs in the user, and sets his user entered password via text field on the webform. Skvare has developed similar solutions for clients using these methods.

Using this method you can create easily customizable membership join, and event registration pages which leverage the full gauntlet of advanced Drupal 7 modules, and the ease of customizing the layout and style with css in the Drupal theme.

Original blog posted at Skvare.com.

 

Views

Wiki instructions,http://wiki.civicrm.org/confluence/display/CRMDOC42/Views3+Integration, to give Drupal Views access to CiviCRM tables.

Entities

Drupal entities are data structures returned as objects and accessed and manipulated with object methods. Full blown Object-oriented approach

Excerpts from Intro to Drupal Entities Book Page - http://drupal.org/node/1261744

The Drupal community often compares site building through configuration to a favorite childhood toy: LEGO bricks. We can build Entity types, which can make Bundles, to which we can add Fields and then create Entities. This article explains the relationships between Entity types > Bundles > Fields > Entities. This was one of the most important changes of Drupal 7, and brought components from some well-loved contributed modules -- such as CCK -- into the core system.

Entity types

In earlier versions of Drupal, the field system was only used on content types. Now, thanks to the Entity API, we can add fields to other things, like comments. Fieldable entities make Drupal eminently flexible. An entity type is a useful abstraction to group together fields. Let’s consider some examples of entity types:

  • Nodes (content)
  • Comments
  • Taxonomy terms
  • User profiles

You can also build new kinds of entity types where the options above don't suit your needs.

Eileen's CiviCRM Entity Module

Core CiviCRM drupal module exposes a few entities, mainly contacts, groups, and mailings. Exposes 11 CiviCRM data entities such as memberships, groups, participants, mailings, activities, pledges, events to views, rules, and entity reference modules as Drupal entities. Actually allows druaplized interaction with many more civicrm data structures including the tags,relationships, and custom data field sets via Relationships in views. http://drupal.org/sandbox/eileen/1923028

I hacked civicrm core views handling to add group relationships to views (For Civi 4.2, unnecessary in 4.3). See issue page for instructions.

Webform CiviCRM Module

From Project Page - http://drupal.org/project/webform_civicrm
This project brings the power and flexibility of Drupal Webforms to the CiviCRM community, allowing for tighter integration of your Website and CRM database. This module can link any webform with CiviCRM, creating and updating contacts, group subscriptions, tags, relationships, cases, activities and event participants. Includes support for custom data set fields attached to contacts

How its done

This document describes how to setup a Drupal content type of "Event' which will be used as a container to provide an extended interface for an CiviCRM event. Using fieldgroups, EVA, and Entity Reference among those modules listed below one can setup using site-building techniques only a set of tabs each with different associated information that a user may find interesting to have at their fingertips.

I create tabs for:

  1. The event information
  2. Travel Information (additional Drupal CT)
  3. Participant list
  4. Embedded Webform that allows for contact creation and event registration
  5. Map (via Openlayers) Registration via the webform will trigger php code with rules to create a synced drupal user, set the user to active, log the user in, set the password based on a webform field, create a free membership and sync the user's roles.

Modules Used

  1. core PHP Filter
  2. Views
  3. Entity Reference
  4. Enity Views Attachment(EVA)
  5. Field Group
  6. Rules
  7. Openlayers (for mapping)
  8. Webform
  9. Webform CiviCRM
  10. CiviCRM Entity Use Git to get latest version

Create the CiviCRM Event

  1. Create Event via CiviCRM admin interface
  2. Set Title, Description, Event Type: Exhibition, Free, Online Registration, Start and End Dates, Event Capacity, enter address, enter longitude and latitude coordinates in appropriate fields
  • Setting up content data structures and content

  1. Create view with References views display that lists all CiviCRM events (How to create Entity Reference view)
  2. Create Drupal Content Type Event
  3. Add entity reference field called Event Reference, choose to use view created first to give options to select list
  4. Create Drupal Content Type Travel Information
  5. Add exisiting entity reference field called Event Reference, choose to use view created first to give options to select list, as well as other fields as desired
  6. Add exisiting entity reference field called Event Reference to Webform content type
  7. Create Drupal content Event node and set entity reference field to newly created CiviCRM event
  8. Create Drupal content Travel information node and set entity reference field to newly created CiviCRM event
  9. Create Membership Type in CiviCRM titled "Free Member"
  • Creating CiviCRM Webform

  1. Create Webform node, title appropriately, enter body text, SET Event Reference field to the newly created CiviCRM event, save
  2. Click webform tab and add a regular webform text field for a password
  3. Click CiviCRM tab on Webform node view page
  4. Check checkbox labeled "Enable CiviCRM Processing "
  • Contact 1 Vertical Tab Settings

    1. Select Contact Type for Webform fields
    2. Leave "Exisiting Contact" checkbox checked if you want the webform to autopopulate with logged in user's CiviCRM contact data
    3. Check checkboxes for CiviCRM contact data fields to include in Webform
    4. Include any Email, Phone, Tags, Relationships, Groups, Websites, or ANY CUSTOM DATA FIELD SETS THAT HAVE BEEN CREATED,,,, COOOL!!
    5. In this case try checking the first and last name boxes under Contact Fields
  • Event Registration Vertical Tab Settings

    1. Select Register all contacts for same event
    2. Select show events of type the same as the event that was created earlier
    3. Select "Always" for Show Remaining Space in Events
    4. Under Registration, Select 1 for Number of Event Sets (yes you can register for multiple events in one webform)
    5. Select the Event, Participant Role, and Registration status fields appropriately

Create Views (The basics ignoring styling)

Create CiviCRM Event info EVA View

  1. Create new view, list of CiviCRM events entities
  2. Add EVA views display
  3. In the Entity content settings category
    1. Set Entity to Node
    2. Set Bundle to Event
    3. Set Arguments to token with the value of [node:field-event-reference:id]
  4. Add Relationship: Entity Reference: Referencing entity
  5. Add fields as you see fit
  6. Add Contextual Filter: Content: Event Reference (field_event_reference)
    1. Relationship to use should be set automatically but make sure that the Content: Event Reference is used
    2. Under When the filter value is NOT available set hide view
    3. Add filter criteria Content: Type = Event
    4. Save

Create Participant Info EVA View (Create view of CiviCRM Participant Entities)

  1. Add EVA views display
  2. In the Entity content settings category
    1. Set Entity to Node
    2. Set Bundle to Event
    3. Set Arguments to token with the value of [node:field-event-reference:id]
  3. Add Relationships
    1. CiviCRM Participants: Event ID
    2. CiviCRM Participants: Participant's Contact ID
  4. Add Contextual Filter: CiviCRM Events: Event ID
    1. Relationship to use should be set automatically but make sure that the CiviCRM Participants: Event ID Relationship is used
    2. Under When the filter value is NOT available set hide view
    3. Add fields as you see appropriate
    4. Save

Create Registration Webform EVA

  1. Create view, list of Content of Type Webform
  2. Add EVA views display
  3. In the Entity content settings category
    1. Set Entity to Node
    2. Set Bundle to Event
    3. Set Arguments to token with the value of [node:field-event-reference:id]
  4. Add Relationship Entity Reference: Event Reference
  5. Add Contextual Filter: CiviCRM Events: Event ID
    1. Relationship to use should be set automatically but make sure that the Entity Reference: Event Reference Relationship is used
    2. Under When the filter value is NOT available set hide view
    3. Under Format: set to Rendered Entity, Full Content
    4. Make sure you have a Filter Criteria: Type=Webform
    5. Save
    6. View for Travel Information is the same except the Filter Criteria should be Type=Travel Information

Create Openlayers Map Custom Map

  1. goto admin/structure/openlayers/maps/add
  2. Set title to 'Event Map'
  3. Save.....to be continued

Create Event Map EVA

  1. Create new view, list of CiviCRM events entities
  2. Add EVA views display
  3. In the Entity content settings category
    1. Set Entity to Node
    2. Set Bundle to Event
    3. Leave Arguments set to id
  4. Set Format to Openlayers Map, set Map setting to Event Map
  5. Add Contextual Filter: CiviCRM Events: Event ID
    1. Under When the filter value is NOT available set hide view
    2. Add Openlayers Data Overlay views display to view
    3. Set Display name: Event Location Point
    4. Set Format:Show to Fields MAKE SURE AND SET THE FOR SELECT OPTION ABOVE TO "This openlayers (override)"
    5. Add fields
      1. CiviCRM Address: Latitude
      2. CiviCRM Address: Longitude
      3. CiviCRM Events: Title
    6. Set Format to Openlayers Data Overlay MAKE SURE AND SET THE FOR SELECT OPTION ABOVE TO "This openlayers (override)"
    7. Set settings to Format: OpenLayers Data Overlay | Settings
      1. Set Map Data Sources to Lat/Lon Pair
      2. Set latitude setting to CiviCRM Address: Latitude
      3. Set longitude setting to CiviCRM Address: Longitude
      4. Set Title setting to CiviCRM Events: Title
      5. Apply settings and save view

Create Openlayers Map Custom Map Continued

  1. Edit Event Map settings
  2. Layers and Styles tab

    1. Choose base layer maps and choose a default
    2. At the bottom of the list is a section called Openlayers layers. Find the one with Event Location Point in it. Check the Enabled and Activated checkboxes
    3. Set pointers in Style and Select Style options
    4. Click save and then edit again
  3. Behaviors Tab

    1. Under Tooltip for Features check the Tooltip for Features checkbox. Also check the checkbox for the overlay view that we had just created
    2. Under Zoom to Layer check the Zoom to Layer checkbox. Also check the checkbox for the overlay view that we had just created.
    3. Save

Manage Drupal Event content type Display

  1. Manage Display for event content type default display
  2. Create horizontal tab group
  3. Create 5 groups, Event Info, Travel Info, Participants, Register, Map
  4. Nest the groups in the horizontal tab group
  5. You will see EVA fields have appeared since we created several EVA Views
  6. Nest the Event EVA into Event Info, Participants EVA under Participant group, etc....

Rules, now we get jiggy

The Webform civicrm module always creates a contact from the webform submission

Create rule Create Membership after contact creation

  1. Create free membership for webform, and CiviCRM event registration pages
    1. Add rule
    2. React to "CiviCRM Contact has been created"
    3. Add action Execute PHP code
    4. Automagic member create code
    5. Membership type id of 1 is for the Free Member type created in the beginning, check the id for your membership type and change in code
    6. Also change the join, start, and end dates. Generally you want the join and start dates to be whatever today is...or write some date code yourself. 
    7. Code: I know its Civi API2 and not the best but it works for this example (Use API version 3)

      require_once 'api/v2/Membership.php'; //require_once 'api/api.php'; $params = array( 'contact_id' => $civicrm_contact->id, 'membership_type_id' => '1', 'join_date' => '2013-06-13', 'start_date' => '2013-06-13', 'end_date' => '2014-12-21', 'is_override' => 1, 'status_id' => 1, ); $result = civicrm_contact_membership_create( $params );

  2. Create rule Create Drupal user after webform submission

    1. React to "Webform was submitted"
    2. Switch to "data selection" and leave form_id as the value in the "Data selector" field
    3. Condition "Webform has name" select appropriate name
    4. Add action execute php code
    5. Add Code:

      $email = $data['components']['civicrm_1_contact_1_email_email']['value'][0]; $password = $data['components']['desired_password']['value'][0]; $params2 = array( 'name' => $email, 'mail' => $email, 'email' => $email, ); $errors = array(); $config = CRM_Core_Config::singleton(); $config->userSystem->checkUserNameEmailExists($params, $errors); if (! empty($errors)) { drupal_set_message(" could not create user record " . $errors['email']); return FALSE; } $params2['cms_name'] = $params2['name'] = $newuser['name'] = $params2['mail']; $params2['cms_pass'] = $newuser['pass'] = $password ; //substr(str_shuffle("abcefghijklmnopqrstuvwxyz"), 0, 8); $params2['status'] = 1; $params2['notify'] = TRUE; $newuser['uid'] = $config->userSystem->createUser($params2, 'email'); $newuser['mail'] = $params2['mail']; $user_object = (object) $newuser; CRM_Core_BAO_UFMatch::synchronizeUFMatch($user_object, $user_object->uid, $email, 'drupal', NULL, NULL, TRUE); $user_updated = db_update('users') ->fields(array( 'status' => 1, )) ->condition('uid', $user_object->uid, '=') ->execute(); global $user; $user = user_load( array('uid'=>$user_object->uid ) ); $pass = user_hash_password($password); db_query("UPDATE {users} SET pass = :pwd WHERE uid = :uid", array('pwd'=>$pass,':uid' =>$user->uid)); _civicrm_member_roles_sync($user->uid);

    6. creates user with username as email address, password set by webform textfield, sets user to active, logs them in and syncs roles

This example is really the tip of the iceberg to what is now possible using the CiviCRM Entity and Webform CiviCRM modules in combination with the many powerful Drupal modules available.  Site building with Drupal and CiviCRM has become much easier and powerful now that these two modules have become available.

Comments

Just thought I'd point out that the 4.x version of Webform-CiviCRM Integration makes this sort of thing even easier, it comes with built-in support for memberships so you won't need custom code for that, and it also supports paid events :)

Although I used the 3.x version of Webform-CiviCRM for this example, the new features of the 4.x version round out the versatility of this module.  It is now possible to build complete, fully functional interfaces for users that are totally Drupally.  In a word -- Awesome!