CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Creating contacts from custom fields on company membership
Pages: [1]

Author Topic: Creating contacts from custom fields on company membership  (Read 2757 times)

herb

  • I’m new here
  • *
  • Posts: 27
  • Karma: 2
Creating contacts from custom fields on company membership
September 13, 2010, 09:26:27 am
We have a client with a complex membership setup. They have individual memberships and company memberships. For the company memberships we created custom fields to capture the names/emails of contacts which acquire membership by association with the company. The first iteration just focused on creating contact records for each custom field, and ensuring that the "On Behalf of organization" is checked when the submitter chooses a company membership on the contribution page.

Syncing the "on behalf of organization with company membership"
In a custom template of CRM/Contribute/Form/Contribution/Main.tpl I added this jquery:

Code: [Select]
   <script language="JavaScript" type="text/javascript">
    {literal}
             $("input[name='selectMembership']").click(function () {
                        var select = $("input[name='selectMembership']:checked").val();
                var behalf = $("#is_for_organization").is(':checked');

                if (behalf == false && (select == 12 || select == 15 || select == 13)) {
                        $("#is_for_organization").click();
                }
                else if (behalf == true && select < 12) {
                        $("#is_for_organization").click();
                }
                });
    {/literal}
    </script>

It ensured that if the submitter chose a company membership they would trigger the "on behalf of organization" checkbox, but also ensure that they couldn't then uncheck it by clicking on the membership again. You may find you need to change the logic for your own situation - in this case the client's company membership IDs were all above 12.

Creating contacts from custom fields

The client had contribution forms with custom fields attached to the membership. Someone joining or renewing would choose a Company membership type, check off On Behalf of Organization, and then fill in fields for the second and third members to be associated with that membership. The On Behalf of Org will put the membership on the organization and add an "Employee of" relationship to the contact of the user filling out the form.

We wanted to add custom actions when the user submits the form, so this called for a hook in a custom Drupal module - in this case, civicrm_postProcess() worked the best. (civicrm_post() might have worked as well but it wasn't readily apparent to me how. The $objectRef depends on the $objectName and it doesn't look like it can all be available at the same time. It meant that I could get the custom fields but not the contact id or the org information all at the same time.)

(By the way, I found it very useful (though it's not readily documented) to use this function to have a nicely formatted view of the variables submitted: CRM_Core_Error::debug( $form );)

The $form variable of the hook - associated_members_civicrm_postProcess ( $class, &$form ) - contained the custom fields, the org name, org email and the related contact (of the submitter).

Creating the contacts is straightforward:

Code: [Select]
$contactParams = array(
                    'first_name'    => $form->_params['custom_1'],
                    'last_name'     => $form->_params['custom_2'],
                    'email'         => $form->_params['custom_3'],
                    'contact_type'  => 'Individual',
                    'dupe_check'    => True,
                    );
$contact = &civicrm_contact_create( $contactParams );

To create the relationships takes an extra step. For some reason it doesn't set the org ID or at least doesn't show it in every case. This may be because a new organization won't have an ID set yet. That means we have to get the org ID by looking for related orgs for matching email.

With the related_contact variable we are able to retrieve all the relationships of that contact with:
$result = & civicrm_relationship_get( $params );

It returns an multi-dimensional array so a couple foreach loops were needed to get at the org emails. If the org email matched that of the submitted form I assumed we had the right one. Armed with the org ID I could now create new contacts from the custom fields and then create relationships based on that.

Code: [Select]
$relationshipParams = array(
                   'contact_id_a'         => $contact['contact_id'],
                   'contact_id_b'         => $orgID,
                   'relationship_type_id' => 4, // Employee of
                   'is_active'            => 1
                   );
$relationshipCreate = & civicrm_relationship_create( $relationshipParams );


This is what the hook looks like (look at the CiviCRM wiki for how to make a basic Drupal module):

Code: [Select]
<?php

/*
 * When Contribution Confirm form is submitted
 * 
 * When the contribution page is submitted we want to check for 2nd and 3rd members 
 * and create contacts for them. 
 * Then we create a relationship with the organization identified.
 */

function associated_members_civicrm_postProcess ( $class, &$form ) {

if ( ! 
is_a($form, 'CRM_Contribute_Form_Contribution_Confirm') ) {
return;
}

//CRM_Core_Error::debug( $form );

civicrm_initialize( true );
require_once 
'CRM/Core/Config.php';
$config =& CRM_Core_Config::singleton( );

require_once 
"api/v2/Contact.php";
require_once 
"api/v2/Relationship.php";
require_once 
"api/v2/GroupContact.php";

// if selected "on behalf of organization" then get that org ID
if ($form->_params['is_for_organization'] == 1) { 

//get the Organization id that was submitted with this form - have to do it in a roundabout way
// get contacts related to contact submitting form (assumes the contact id is always set)
$relationParams = array( 'contact_id' => $form->_values['related_contact'] );

$relatedContacts = & civicrm_relationship_get( $relationParams );
if ( civicrm_error ( $relatedContacts )) { return $relatedContacts['error_message']; }
//CRM_Core_Error::debug( $relatedContacts );

//use this email to ensure related org is the right one
$orgEmail = $form->_params['onbehalf_location']['email']['1']['email'];

// loop through multi-dimensional array and look for email that 
// matches the org's email from the form
foreach ($relatedContacts['result'] as $related) {
foreach ($related as $relate) {
if ($relate == $orgEmail) { // it's probably the right org
$relatedOrgID = $related['cid'];
}
}
}
} 
// endif "on behalf of org" is selected

// get contact of the submitter - it doesn't show up in the $form if it's an anon user
$indivParams = array ( 
'email' => $form->_params['email-5'],
'contact_type' => 'Individual',
);
$indivResult = civicrm_contact_search( $indivParams );

if ( 
civicrm_error ($indivResult )) { return $indivResult['error_message']; } 
else {

foreach ($indivResult as $indiv) {
foreach ($indiv as $ind) {
$submitterID = $indiv['contact_id'];
}
}
}

// create contacts for the 2nd member
$contactParams2 = array(
                    
'first_name'    => $form->_params['custom_69'],
                    
'last_name'     => $form->_params['custom_70'],
                    
'email'         => $form->_params['custom_71'],
                    
'contact_type'  => 'Individual',
                    
'dupe_check'    => True,
                    );
$contact2 = &civicrm_contact_create( $contactParams2 ); // returns contact id, is_error
if ( civicrm_error ( $contact2)) { return $contact2['error_message']; }

// create contacts for the 3rd member
$contactParams3 = array(
                    
'first_name'    => $form->_params['custom_72'],
                    
'last_name'     => $form->_params['custom_73'],
                    
'email'         => $form->_params['custom_74'],
                    
'contact_type'  => 'Individual',
                    
'dupe_check'    => True,
                    );
$contact3 = &civicrm_contact_create( $contactParams3 ); // returns contact id, is_error
if ( civicrm_error ( $contact3)) { return $contact3['error_message']; }


//CRM_Core_Error::debug($form);

if ($form->_params['is_for_organization'] == 1) {
$contactbID = $relatedOrgID;
$reltype = 11; // DOC company membership
} else {
// if no org was set we still want to create a relationship
$contactbID = $submitterID;
$reltype = 12; // colleague of 
}

// we still want to make "employee of" relationships for each contact if org is set
if ($form->_params['is_for_organization'] == 1) {
add_relationship($contact2['contact_id'],$contactbID,4);

add_relationship($contact3['contact_id'],$contactbID,4);

} 
// end of making employee relationships for 2nd/3rd contacts

// we want to set the default relationships for each contact as set above
add_relationship($contact2['contact_id'],$contactbID,$reltype);

add_relationship($contact3['contact_id'],$contactbID,$reltype);


// add submitter to the member group
add_to_group(33,$submitterID);

// add 2nd member to member group
add_to_group(33,$contact2['contact_id']);

// add 3nd member to member group
add_to_group(33,$contact3['contact_id']);


} 
//end associated_members_civicrm_postProcess()

function add_to_group($groupID, $contactID) {

$groupParams = array(
                    
'contact_id' => $contactID,
                    
'group_id'     => $groupID
                    
);
$groupResult = civicrm_group_contact_add( $groupParams );
}

function 
add_relationship($contactaID,$contactbID,$relationshipType) {

$relationshipParams = array(
                    
'contact_id_a'         => $contactaID,
                    
'contact_id_b'         => $contactbID,
                    
'relationship_type_id' => $relationshipType,
                    
'is_active'            => 1
                    
);
$relationshipCreate = & civicrm_relationship_create( $relationshipParams );
if ( civicrm_error ( $relationshipCreate )) { 
return $relationshipCreate['error_message']; 
}
}

I hope this helps. I'm new to creating custom actions for CiviCRM and it's been tough to find some information on what does what.
« Last Edit: October 14, 2010, 04:58:58 pm by herb@freeform »
Web Developer
Freeform Solutions

Michał Mach

  • Ask me questions
  • ****
  • Posts: 748
  • Karma: 59
    • CiviCRM site
  • CiviCRM version: latest
  • CMS version: Drupal and Joomla latest
  • MySQL version: numerous
  • PHP version: 5.3 and 5.2
Re: Creating contacts from custom fields on company membership
September 14, 2010, 04:51:52 am
Thanks for sharing the recipe! :-)

m
Found this reply helpful? Contribute NOW and help us improve CiviCRM with the Make it Happen! initiative.

My absolute favourite: Wordpress Integration!.

Donate Now!

zesgar

  • I post occasionally
  • **
  • Posts: 107
  • Karma: 2
  • CiviCRM version: 4.3.4
  • CMS version: Joomla 2.5
Re: Creating contacts from custom fields on company membership
February 09, 2011, 08:42:27 am
Thanks for the code!!!

herb

  • I’m new here
  • *
  • Posts: 27
  • Karma: 2
Re: Creating contacts from custom fields on company membership
February 24, 2011, 07:18:54 am
I thought I'd just post my reply to Zack regarding the code:

Hi Zack,

The approach I took was to first get the form id. So in a postProcess hook, I used the civicrm debug function to just output all arrays to the screen:

Code: [Select]
function example_civicrm_postProcess ( $class, &$form ) {
   require_once "CRM/Core/Error.php";
    CRM_Core_Error::debug( 'form', $form );
}

I haven't tried it with event registration. Once you can see the whole array you can find out what is the contact id. Then if you create some custom fields to capture the parent info, you'll then need to insert those custom fields into a civicrm_conctact_create() API function and then use the result from that as the second contact id in the civicrm_relationship_create() API function (along with the original camper contact id).

You can read more up on the APIs here http://wiki.civicrm.org/confluence/display/CRMDOC33/CiviCRM+Public+APIs and hooks here: http://wiki.civicrm.org/confluence/display/CRMDOC33/CiviCRM+hook+specification.

Quote
I have been reading and playing with your code that you wrote for tying individuals to organizations.  I am trying to translate this into an event registration form.  I am trying to get a camper sign up at the top and then ask for parent information at the bottom and create a simple relationship for them.  Is there a way to post the profiles first then get the contact and household ids?

Thanks,

Zack
Web Developer
Freeform Solutions

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Creating contacts from custom fields on company membership

This forum was archived on 2017-11-26.