civicrm_entity_price_set_field.event_registration.inc in CiviCRM Entity 7.2
CiviCRM Entity Price Set Field, Form display formatter, event registration
File
modules/civicrm_entity_price_set_field/includes/civicrm_entity_price_set_field.event_registration.incView source
<?php
/**
* @file
* CiviCRM Entity Price Set Field, Form display formatter, event registration
*/
/**
* CiviCRM Entity Price Set Field Get Registration Access Callback Info
*
* Sets up info hook to gather registration access callbacks
*
* @param null $id
* @return array
*/
function civicrm_entity_price_set_field_get_registration_access_callbacks_info($id = NULL) {
$results = array();
foreach (module_implements('civicrm_entity_price_set_field_registration_access_callback_info') as $module) {
// Calling all modules implementing hook_hook_name and
// Returning results than pushing them into the $result array:
$result = module_invoke($module, 'civicrm_entity_price_set_field_registration_access_callback_info');
foreach ($result as $id => $r) {
if (!empty($r['callback'])) {
$results[$id] = $result;
}
}
}
if (empty($id)) {
return $results;
}
else {
return $results[$id];
}
}
/**
* Utility function to find modules with custom event registration access callbacks
*
* Designed to make exceptions to access, user still required to have 'register for events' permission that comes with CiviCRM
*
* @param $entity_type
* @param $entity
* @param $field
* @param $instance
* @param null $account
* @return bool
*/
function civicrm_entity_price_set_field_allow_registration($entity_type, $entity, $field, $instance, $account = NULL) {
if (is_null($account)) {
global $user;
$account = $user;
}
$callbacks = civicrm_entity_price_set_field_get_registration_access_callbacks_info();
if (!empty($callbacks)) {
foreach ($callbacks as $key => $info) {
if (!empty($info['callback'])) {
$result = call_user_func($info['callback'], $entity_type, $entity, $field, $instance, $account);
if ($result === FALSE) {
return FALSE;
}
}
}
}
return TRUE;
}
/**
* Form callback for event registration form
*
* @param $form
* @param $form_state
* @return mixed
*/
function civicrm_entity_price_set_field_display_form_event($form, &$form_state) {
$form = array();
$price_set_id = $form_state['build_info']['args'][0];
$host_entity_type = $form_state['build_info']['args'][1];
$event = $form_state['event'] = $form_state['build_info']['args'][2];
$form_state['field'] = $form_state['build_info']['args'][3];
$form_state['instance'] = $form_state['build_info']['args'][4];
$form_state['display_settings'] = $form_state['build_info']['args'][5];
// online registration
if (!empty($event->is_online_registration)) {
if (user_access('register for events') && civicrm_entity_price_set_field_allow_registration($host_entity_type, $event, $form_state['field'], $form_state['instance'])) {
// check if registration date is set and passed yet
if (!empty($event->registration_start_date)) {
if (time() < strtotime($event->registration_start_date)) {
$form['message'] = array(
'#type' => 'markup',
'#message' => 'registration_state_date',
'#markup' => 'Registration opens ' . $event->registration_start_date,
);
return $form;
}
}
// check if registration end date is set and passed yet
if (!empty($event->registration_end_date)) {
if (time() > strtotime($event->registration_end_date)) {
$form['message'] = array(
'#type' => 'markup',
'#message' => 'registration_end_date',
'#markup' => 'Registration closed on ' . $event->registration_end_date,
);
return $form;
}
}
// check if max_participants has been reached, and if so, close the form down, good messaging
if (isset($event->max_participants)) {
$registered_count = _civicrm_entity_price_set_field_get_participant_count_for_event($event->id);
if ($registered_count >= $event->max_participants) {
$form['message'] = array(
'#type' => 'markup',
'#message' => 'max_participants',
'#markup' => !empty($event->event_full_text) ? $event->event_full_text : 'The event is currently full',
);
return $form;
}
}
// paid event
if (!empty($event->is_monetary)) {
if ($price_set_id) {
if (empty($form_state['contacts'])) {
$form_state['price_set_data'][0] = _civicrm_entity_price_set_field_get_relevant_entities_clone($price_set_id);
}
else {
foreach ($form_state['contacts'] as $count => $contact) {
$form_state['price_set_data'][$count] = _civicrm_entity_price_set_field_get_relevant_entities_clone($price_set_id);
}
}
foreach ($form_state['price_set_data'] as $count => $ps_data) {
$context = array(
'participant_count' => $count,
'entity_type' => $host_entity_type,
'entity' => $event,
'field' => $form_state['field'],
'instance' => $form_state['instance'],
'display_settings' => $form_state['display_settings'],
);
drupal_alter('civicrm_entity_price_set_field_registration_form_price_set_data', $form_state['price_set_data'][$count], $context);
}
}
else {
$form['price_set']['message'] = array(
'#type' => 'markup',
'#message' => 'no_price_set',
'#markup' => 'No price options for event.',
);
return $form;
}
}
else {
// free event
if (empty($form_state['contacts'])) {
$form_state['price_set_data'][0] = array();
}
else {
foreach ($form_state['contacts'] as $count => $contact) {
$form_state['price_set_data'][$count] = array();
}
}
}
// setup ajax multi step
// If $form_state['step'] is not set, we set it to 1
$form_state['step'] = isset($form_state['step']) ? $form_state['step'] : 1;
// Add a wrapper div that will be used by the Form API to update the form using AJAX
$form['#prefix'] = '<div id="civicrm-price-set-field-event-registration">';
$form['#suffix'] = '</div>';
$form['#attached']['js'][] = drupal_get_path('module', 'civicrm_entity_price_set_field') . '/js/civicrm_entity_price_set_field_display_form.js';
// Depending on which step of the form we are on, we output different form fields
switch ($form_state['step']) {
// Registration Form
case 1:
$default_values = array();
if (isset($form_state['input']['registration_form'])) {
$default_values = $form_state['input']['registration_form'];
}
elseif (isset($form_state['values']['registration_form'])) {
$default_values = $form_state['values']['registration_form'];
}
elseif (isset($form_state['storage']['registration_form'])) {
$default_values = $form_state['storage']['registration_form'];
}
global $user;
if ($user->uid && empty($default_values['register_as_another'])) {
$contact = civicrm_entity_user_contact_get($user, array(), '', '', '');
if ($contact) {
$already_registered = _civicrm_entity_price_set_field_get_participant_count_for_event($event->id, $contact->id);
if (empty($event->allow_same_participant_emails) && !empty($already_registered)) {
drupal_set_message(t('You have already registered for this event.'), 'status', FALSE);
$form_state['main_registrant_already_registered'] = TRUE;
}
}
}
// setup registration form
_civicrm_entity_price_set_field_setup_event_registration_form_fapi($form, $form_state, $default_values);
break;
// Confirmation Page
case 2:
_civicrm_entity_price_set_field_setup_event_confirmation_page_fapi($form, $form_state);
break;
// Thank you page
case 3:
_civicrm_entity_price_set_field_setup_event_thank_you_page_fapi($form, $form_state);
break;
}
// Create a container for our buttons
$form['buttons'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'civicrm-entity-price-set-registration-buttons',
),
),
);
switch ($form_state['step']) {
case 1:
$form['buttons']['register'] = array(
'#type' => 'submit',
'#value' => t('Register'),
'#ajax' => array(
'wrapper' => 'civicrm-price-set-field-event-registration',
'callback' => 'civicrm_entity_price_set_field_event_registration_form_ajax_callback',
),
);
break;
case 2:
$form['buttons']['confirm'] = array(
'#type' => 'submit',
'#value' => t('Confirm'),
'#ajax' => array(
'wrapper' => 'civicrm-price-set-field-event-registration',
'callback' => 'civicrm_entity_price_set_field_event_registration_form_ajax_callback',
),
);
$form['buttons']['back'] = array(
'#type' => 'submit',
'#value' => t('Back'),
'#limit_validation_errors' => array(),
'#submit' => array(
'_civicrm_entity_price_set_field_event_confirmation_page_back_submit',
),
'#ajax' => array(
'wrapper' => 'civicrm-price-set-field-event-registration',
'callback' => 'civicrm_entity_price_set_field_event_registration_form_ajax_callback',
),
);
break;
case 3:
break;
}
}
else {
$form['message'] = array(
'#type' => 'markup',
'#message' => 'online_registration_access_denied',
'#markup' => 'You are not authorized to register for the event.',
);
}
}
else {
$form['message'] = array(
'#type' => 'markup',
'#message' => 'online_registration_disabled',
'#markup' => 'Online registration disabled.',
);
return $form;
}
return $form;
}
/**
* Helper function to setup event registration form FAPI
*
* @param $form
* @param $form_state
* @param $default_values
*/
function _civicrm_entity_price_set_field_setup_event_registration_form_fapi(&$form, &$form_state, $default_values) {
$event = $form_state['event'];
$form['registration_form'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'civicrm-entity-price-set-field-registration-form',
),
),
'#tree' => TRUE,
);
// get contacts and set form state with contacts
global $user;
if (empty($default_values['register_as_another'])) {
if ($user->uid && empty($form_state['main_registrant_already_registered'])) {
$contact = civicrm_entity_user_contact_get($user, array(), '', '', '');
if ($contact) {
$form_state['contacts'][0] = $contact;
$form_state['contacts'][0]->uid = $user->uid;
}
}
else {
$form_state['contacts'][0] = new CivicrmEntity(array(
'is_new' => 1,
), 'civicrm_contact');
}
}
else {
if (empty($form_state['contacts'][0]->id)) {
$form_state['contacts'][0] = new CivicrmEntity(array(
'is_new' => 1,
), 'civicrm_contact');
if ($user->uid && empty($form_state['main_registrant_already_registered'])) {
$form_state['contacts'][0]->uid = $user->uid;
}
}
}
$form['registration_form']['register_as_another'] = array(
'#type' => 'checkbox',
'#title' => t('Register as new contact.'),
'#return_value' => 1,
'#ajax' => array(
'wrapper' => 'civicrm-price-set-field-event-registration',
'callback' => 'civicrm_entity_price_set_field_event_registration_form_register_as_another_ajax_callback',
'event' => 'click',
'method' => 'replace',
),
);
if (!empty($form_state['contacts'][0]->uid)) {
$form['registration_form']['register_as_another']['#default_value'] = !empty($default_values['register_as_another']) ? $default_values['register_as_another'] : 0;
$form['registration_form']['register_as_another']['#description'] = 'You are logged in. Leaving this box unchecked will use your contact information for this registration.';
}
else {
if (empty($form_state['main_registrant_already_registered'])) {
$form['registration_form']['register_as_another']['#description'] = '<a href="/user/login">Login</a> if you already have an account.';
}
else {
$form['registration_form']['register_as_another']['#description'] = 'You are already registered, you can only register for another.';
}
$form['registration_form']['register_as_another']['#default_value'] = 1;
$form['registration_form']['register_as_another']['#disabled'] = TRUE;
}
$form['registration_form']['contacts'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'civicrm-entity-price-set-field-registration-form-contacts',
),
),
);
//Fetch event profiles
$main_profiles = $add_profiles = array();
if (module_exists('civicrm_entity_profile')) {
$main_profiles = _civicrm_entity_profile_get_profiles('civicrm_event', $form_state['event']->id, 'CiviEvent');
if (!empty($form_state['event']->is_multiple_registrations)) {
$add_profiles = _civicrm_entity_profile_get_profiles('civicrm_event', $form_state['event']->id, 'CiviEvent_Additional');
}
}
foreach ($form_state['contacts'] as $count => $contact) {
if ($count) {
$form['registration_form']['contacts'][$count]['heading'] = array(
'#type' => 'markup',
'#markup' => '<h2>' . 'Participant ' . ($count + 1) . '</h2>',
'#weight' => -10,
);
}
if (!empty($form_state['price_set_data'][$count])) {
_civicrm_entity_price_set_field_setup_price_set_fapi($form, $form_state, $default_values, 'registration_form', $count);
}
// setup profiles
$form['registration_form']['contacts'][$count]['contact_info'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'civicrm-entity-price-set-field-participant-form',
),
),
'#weight' => -4,
);
if ($count == 0) {
$profile_list = $main_profiles;
}
else {
$profile_list = $add_profiles;
}
// need at least one contact profile, if not, don't display form (should also not be able to add additional participant if this is the case!)
$profile_list_has_contact_entity = 0;
if (count($profile_list)) {
foreach ($profile_list as $index => $profile_id) {
// first check for 'mixed' profiles, if mixed, then don't render
$profile_entity_type = _civicrm_entity_profile_determine_profile_entity($profile_id);
if (!$profile_entity_type) {
unset($profile_list[$index]);
}
elseif ($profile_entity_type == 'contact') {
$profile_list_has_contact_entity = 1;
}
}
}
$additional_participant_profiles_has_contact_entity = 0;
if (count($add_profiles)) {
foreach ($add_profiles as $index => $profile_id) {
$profile_entity_type = _civicrm_entity_profile_determine_profile_entity($profile_id);
if (!$profile_entity_type) {
unset($profile_list[$index]);
}
elseif ($profile_entity_type == 'contact') {
$additional_participant_profiles_has_contact_entity = 1;
}
}
}
// render profiles
if (count($profile_list)) {
if (!$profile_list_has_contact_entity) {
$form['message'] = array(
'#type' => 'markup',
'#message' => 'online_registration_no_profiles',
'#markup' => 'Event must be configured with at least one contact profile',
);
return;
}
foreach ($profile_list as $profile_id) {
$profile_title = _civicrm_entity_profile_get_profile_title($profile_id);
// setup profile container
$form['registration_form']['contacts'][$count]['contact_info']['profile-' . $profile_id] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'civicrm-entity-price-set-field-profile-fapi',
),
),
'#prefix' => '<div class="civicrm-entity-price-set-field-profile">',
'#suffix' => '</div>',
);
// Title for the form set
if (!empty($profile_title)) {
$form['registration_form']['contacts'][$count]['contact_info']['profile-' . $profile_id]['#prefix'] = '<div class="civicrm-entity-price-set-field-profile">' . '<h3>' . $profile_title . '</h3>';
}
// Save profile metadata for future use
$form_state['profiles']['profile-' . $profile_id] = _civicrm_entity_profile_get_profile_metadata($profile_id, 'event');
// Get profile FAPI
$profile_fapi = _civicrm_entity_profile_generate_profile_fapi($profile_id, 'event');
if (!empty($profile_fapi)) {
// add profile FAPI to main form
$form['registration_form']['contacts'][$count]['contact_info']['profile-' . $profile_id]['profile'] = $profile_fapi;
// Setup default values
foreach ($form['registration_form']['contacts'][$count]['contact_info']['profile-' . $profile_id]['profile'] as $name => $field_fapi) {
if (!empty($default_values['contacts'][$count]['contact_info']['profile-' . $profile_id]['profile'][$name])) {
$form['registration_form']['contacts'][$count]['contact_info']['profile-' . $profile_id]['profile'][$name]['#default_value'] = $default_values['contacts'][$count]['contact_info']['profile-' . $profile_id]['profile'][$name];
}
elseif (!empty($form_state['contacts'][$count]->{$name})) {
$form['registration_form']['contacts'][$count]['contact_info']['profile-' . $profile_id]['profile'][$name]['#default_value'] = $form_state['contacts'][$count]->{$name};
}
else {
$form['registration_form']['contacts'][$count]['contact_info']['profile-' . $profile_id]['profile'][$name]['#default_value'] = '';
}
}
}
}
}
else {
$form['message'] = array(
'#type' => 'markup',
'#message' => 'online_registration_no_profiles',
'#markup' => 'Event must be configured with at least one contact profile',
);
return;
}
if ($count) {
$form['registration_form']['contacts'][$count]['remove_participant'] = array(
'#contact_count' => $count,
'#type' => 'submit',
'#value' => t('Remove participant ' . ($count + 1)),
'#limit_validation_errors' => array(),
'#submit' => array(
'_civicrm_entity_price_set_field_event_registration_remove_participant_submit',
),
'#ajax' => array(
'wrapper' => 'civicrm-price-set-field-event-registration',
'callback' => 'civicrm_entity_price_set_field_event_registration_form_ajax_callback',
),
'#weight' => -3,
);
}
}
// if event is configured to allow multiple registrations then add an "Add Participant" button
// to ajax load another contact price set and information container to the form
if (!empty($form_state['event']->is_multiple_registrations) && !empty($additional_participant_profiles_has_contact_entity)) {
// if max_participants has been reached disable add participant button, will be queried total of participants for event + number of participants being registered already by form
$registered_count = _civicrm_entity_price_set_field_get_participant_count_for_event($event->id);
if (!isset($event->max_participants) || isset($event->max_participants) && $registered_count + count($form_state['contacts']) < $event->max_participants) {
$form['registration_form']['add_participant'] = array(
'#type' => 'submit',
'#value' => t('Add a participant'),
'#limit_validation_errors' => array(),
'#submit' => array(
'_civicrm_entity_price_set_field_event_registration_add_participant_submit',
),
'#ajax' => array(
'wrapper' => 'civicrm-price-set-field-event-registration',
'callback' => 'civicrm_entity_price_set_field_event_registration_form_ajax_callback',
),
);
}
}
// setup pay options
if (!empty($form_state['event']->is_monetary)) {
if (!empty($form_state['event']->is_pay_later)) {
$form['registration_form']['pay_later'] = array(
'#type' => 'checkbox',
'#title' => !empty($form_state['event']->pay_later_text) ? $form_state['event']->pay_later_text : 'Pay by check',
'#return_value' => 1,
);
}
if (!empty($default_values['pay_later'])) {
$form['registration_form']['pay_later']['#default_value'] = $default_values['pay_later'];
}
else {
$form['registration_form']['pay_later']['#default_value'] = 0;
}
// if cc is selected, show billing block
$form['registration_form']['registration_cc_block'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'civicrm-entity-price-set-field-cc-block',
),
),
);
$payment_processor_options = array();
if (!empty($form_state['event']->payment_processor)) {
$pp_default = '';
if (is_array($form_state['event']->payment_processor)) {
foreach ($form_state['event']->payment_processor as $pp_delta => $pp_id) {
$pp = entity_load_single('civicrm_payment_processor', $pp_id);
$payment_processor_options[$pp_id] = empty($pp->title) ? $pp->name : $pp->title;
if (!empty($pp->is_default)) {
$pp_default = $pp_id;
}
}
}
else {
$pp = entity_load_single('civicrm_payment_processor', $form_state['event']->payment_processor);
$payment_processor_options[$form_state['event']->payment_processor] = empty($pp->title) ? $pp->name : $pp->title;
$pp_default = $form_state['event']->payment_processor;
}
$form['registration_form']['registration_cc_block']['payment_processor_selection'] = array(
'#title' => t('Payment method'),
'#type' => 'radios',
'#options' => $payment_processor_options,
'#default_value' => $pp_default,
);
}
else {
$form['registration_form']['registration_cc_block']['#access'] = FALSE;
}
$form['registration_form']['registration_cc_block']['first_name_on_card'] = array(
'#type' => 'textfield',
'#title' => 'First Name',
'#description' => 'First name as it appears on card. Required.',
'#default_value' => '',
'#size' => 36,
'#maxlength' => 100,
'#prefix' => '<h3>Credit Card Information</h3><div class="name-and-number-section">',
);
$form['registration_form']['registration_cc_block']['last_name_on_card'] = array(
'#type' => 'textfield',
'#title' => 'Last Name',
'#description' => 'Last name as it appears on card. Required.',
'#default_value' => '',
'#size' => 36,
'#maxlength' => 100,
);
$form['registration_form']['registration_cc_block']['cc_number'] = array(
'#type' => 'textfield',
'#title' => 'Credit Card Number',
'#description' => 'Enter numbers only, no dashes or spaces. Required.',
'#default_value' => '',
'#size' => 24,
'#maxlength' => 24,
'#suffix' => '</div>',
);
$form['registration_form']['registration_cc_block']['cc_exp'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'civicrm-entity-price-set-field-cc-exp-block',
),
),
'#prefix' => '<div class="expiration-and-cvv-section">',
);
$form['registration_form']['registration_cc_block']['cc_exp']['month'] = array(
'#prefix' => '<div class="form-item"><label>Credit Card Expiration Date</label></div>',
'#type' => 'select',
'#title' => 'Month',
'#default_value' => format_date(time(), 'custom', 'n'),
'#options' => array(
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
12 => 12,
),
);
$form['registration_form']['registration_cc_block']['cc_exp']['year'] = array(
'#type' => 'select',
'#title' => 'Year',
'#default_value' => format_date(time(), 'custom', 'Y'),
'#options' => array_combine(range(date('Y'), date('Y') + 15), range(date('Y'), date('Y') + 15)),
);
$form['registration_form']['registration_cc_block']['cvv'] = array(
'#type' => 'textfield',
'#title' => 'CVV',
'#default_value' => '',
'#size' => 4,
'#maxlength' => 4,
'#description' => '3-4 digit code from back of card. Required.',
'#suffix' => '</div>',
);
// add some javascript to hide/reveal cc block depending on pay later click
// add some css too
$form['#attached']['css'][] = drupal_get_path('module', 'civicrm_entity_price_set_field') . '/css/billing_block.css';
$form['#attached']['js'][] = drupal_get_path('module', 'civicrm_entity_price_set_field') . '/js/billing_block.js';
// jquery validation of billing block?
}
}
/**
* Submit handler for event registration form 'Register' button
*
* @param $form
* @param $form_state
*/
function civicrm_entity_price_set_field_display_form_event_submit($form, &$form_state) {
switch ($form_state['step']) {
case 1:
// Registration form submit
$form_state['storage']['registration_form'] = $form_state['values']['registration_form'];
$form_state['storage']['registration_form']['transaction'] = _civicrm_entity_price_set_field_calculate_total($form_state['price_set_data'], 'civicrm_event', $form_state['event'], $form_state['storage']['registration_form']);
$form_state['step']++;
break;
case 2:
// confirmation page submit
$event = $form_state['event'];
$success = TRUE;
// Dedupe the participants, and make sure nobody has already registered, if so kick it back to the register form, messaging
foreach ($form_state['contacts'] as $count => $contact) {
if (empty($contact->id)) {
// the de-dupe api way
$params = array(
'sequential' => 1,
'check_permission' => FALSE,
);
$params['match']['contact_type'] = 'Individual';
if (!empty($form_state['event']->dedupe_rule_group_id)) {
$params['dedupe_rule_id'] = $form_state['event']->dedupe_rule_group_id;
}
// build up match param array with values for each contact profile field
$first_pid = 0;
foreach ($form_state['storage']['registration_form']['contacts'][$count]['contact_info'] as $profile_id => $profile) {
$pids = explode('-', $profile_id);
$pid = $pids[1];
$profile_entity_type = _civicrm_entity_profile_determine_profile_entity($pid);
if ($profile_entity_type == 'contact') {
if (empty($first_pid)) {
$first_pid = $pid;
$first_profile = $profile;
}
// should we gather up all the contact profile fields and add those to the 'match' param array for the dedupe, instead of just the first?
foreach ($profile['profile'] as $name => $value) {
$params['match'][$name] = $value;
}
}
}
$dedupe_result = civicrm_api3('Contact', 'duplicatecheck', $params);
if (!empty($dedupe_result['id'])) {
// should we check here if the contact is already registered, and if so throw back a message?
$contact_registrations_for_event = _civicrm_entity_price_set_field_get_participant_count_for_event($event->id, $dedupe_result['id']);
if (empty($event->allow_same_participant_emails) && $contact_registrations_for_event) {
drupal_set_message('Participant ' . ($count + 1) . ' has already registered for this event.');
$form_state['step'] = 1;
$form_state['rebuild'] = TRUE;
return;
}
$form_state['contacts'][$count] = entity_load_single('civicrm_contact', $dedupe_result['id']);
}
// submit main registrant contact profile here, if there isn't a contact_id yet (its new)
// we need the contact_id to run the transaction and create a contribution
// if not, $success = false, and it displays an error and goes back to the registration form
if ($count == 0) {
if (empty($form_state['contacts'][$count]->id)) {
$submitted_result = 0;
if (!empty($first_pid) && !empty($first_profile)) {
$submitted_result = _civicrm_entity_profile_process_profile_submitted_data($first_pid, $first_profile['profile']);
}
if (!empty($submitted_result)) {
$form_state['contacts'][0] = $submitted_result;
$form_state['first_profile_submitted'] = 1;
}
else {
$success = FALSE;
}
}
}
}
}
if (!empty($form_state['storage']['registration_form']['transaction']['total']) && is_numeric($form_state['storage']['registration_form']['transaction']['total']) && $form_state['storage']['registration_form']['transaction']['total'] > 0) {
if (empty($form_state['storage']['registration_form']['pay_later'])) {
// if we have a main registrant contact id we continue to process the transaction
if ($success) {
$transact_result = _civicrm_entity_price_set_field_run_cc_transaction($form_state['display_settings'], $form_state['price_set_data'], 'civicrm_event', $event, $form_state['contacts'], $form_state['storage']['registration_form']);
if ($transact_result !== FALSE && !empty($transact_result['contribution']) && is_object($transact_result['contribution'])) {
$form_state['contribution'] = $transact_result['contribution'];
}
else {
$success = FALSE;
}
}
}
else {
// if is pay later, make a contribution with status Pending
if ($success) {
$contribution_params = array(
'is_new' => TRUE,
'financial_type_id' => $form_state['event']->financial_type_id,
'total_amount' => $form_state['storage']['registration_form']['transaction']['total'],
'contact_id' => $form_state['contacts'][0]->id,
'invoice_id' => md5(uniqid(rand(), TRUE)),
'source' => 'CiviCRM Entity Price Set Field -- Event Registration',
'is_pay_later' => 1,
'receive_date' => date('Y-m-d H:i:s'),
'contribution_status_id' => "Pending",
'skipLineItem' => 1,
);
$contribution = new CivicrmEntity($contribution_params, 'civicrm_contribution');
$contribution_wrapper = entity_metadata_wrapper('civicrm_contribution', $contribution);
$contribution_wrapper
->save();
$form_state['contribution'] = $contribution_wrapper
->value();
}
}
}
if (!empty($success)) {
_civicrm_entity_price_set_field_process_event_registration($form_state);
$form_state['step']++;
}
else {
drupal_set_message(t('Error processing registration. Contact Site Administrator.'));
$form_state['step']--;
}
break;
case 3:
$form_state['step'] = 1;
break;
}
$form_state['rebuild'] = TRUE;
}
/**
* Process event registration (after contacts deduped and reg status checked, successful cc transaction if paid event)
*
* @param $form_state
*/
function _civicrm_entity_price_set_field_process_event_registration(&$form_state) {
$form_state['participants'] = array();
if (empty($form_state['contribution'])) {
$form_state['contribution'] = NULL;
}
$line_items = array();
foreach ($form_state['contacts'] as $count => $contact) {
//_civicrm_entity_price_set_field_display_form_create_update_contact('other', $count, $form_state);
$submitted_count = 0;
foreach ($form_state['storage']['registration_form']['contacts'][$count]['contact_info'] as $profile_id => $profile_data) {
$pids = explode('-', $profile_id);
$pid = $pids[1];
$profile_entity_type = _civicrm_entity_profile_determine_profile_entity($pid);
if ($profile_entity_type != 'contact') {
continue;
}
if ($submitted_count == 0 && !empty($form_state['first_profile_submitted']) && $count == 0) {
continue;
}
// here we want to submit only the contact profiles first
if (!empty($contact->id)) {
$submit_result = _civicrm_entity_profile_process_profile_submitted_data($pid, $profile_data['profile'], 'contact', $contact->id);
}
else {
$submit_result = _civicrm_entity_profile_process_profile_submitted_data($pid, $profile_data['profile']);
}
if (!empty($submit_result)) {
$form_state['contacts'][$count] = $contact = $submit_result;
unset($submit_result);
}
$submitted_count += 1;
}
try {
// now create the participant record
$params = array(
'is_new' => TRUE,
'event_id' => $form_state['event']->id,
'contact_id' => $form_state['contacts'][$count]->id,
'source' => "CiviCRM Entity Price Set Field Event Registration Form",
'role_id' => !empty($form_state['event']->default_role_id) ? $form_state['event']->default_role_id : "Attendee",
'status_id' => "Registered",
'register_date' => date('Y-m-d H:i:s'),
'is_pay_later' => !empty($form_state['storage']['registration_form']['pay_later']) ? 1 : 0,
);
if (isset($form_state['storage']['registration_form']['transaction']['fee_amounts'][$count])) {
$params['fee_amount'] = $form_state['storage']['registration_form']['transaction']['fee_amounts'][$count];
}
if ($count) {
$params['registered_by_id'] = $form_state['participants'][0]->id;
}
if (!empty($form_state['storage']['registration_form']['pay_later'])) {
$params['status_id'] = "Pending from pay later";
}
$participant = new CivicrmEntity($params, 'civicrm_participant');
$participant_wrapper = entity_metadata_wrapper('civicrm_participant', $participant);
$participant_wrapper
->save();
$form_state['participants'][$count] = $participant_wrapper
->value();
// here run the participant profiles
foreach ($form_state['storage']['registration_form']['contacts'][$count]['contact_info'] as $profile_id => $profile_data) {
$pids = explode('-', $profile_id);
$pid = $pids[1];
$profile_entity_type = _civicrm_entity_profile_determine_profile_entity($pid);
if ($profile_entity_type != 'participant') {
continue;
}
$profile_data['profile']['participant_id'] = $form_state['participants'][$count]->id;
if (!empty($form_state['contacts'][$count]->id)) {
$submit_result = _civicrm_entity_profile_process_profile_submitted_data($pid, $profile_data['profile'], 'participant', $form_state['contacts'][$count]->id);
if (!empty($submit_result)) {
$form_state['participants'][$count] = $submit_result;
unset($submit_result);
}
}
}
// if there was a contribution make the LineItem and ParticipantPayment records
if (!empty($form_state['contribution'])) {
if ($count == 0) {
// create participant_payment entity
$participant_payment = new CivicrmEntity(array(
'contribution_id' => $form_state['contribution']->id,
'participant_id' => $form_state['participants'][$count]->id,
), 'civicrm_participant_payment');
$participant_payment_wrapper = entity_metadata_wrapper('civicrm_participant_payment', $participant_payment);
$participant_payment_wrapper
->save();
}
// create line items
foreach ($form_state['storage']['registration_form']['transaction']['line_items'][$count] as $pf_id => $price_field) {
foreach ($price_field as $pfv_id => $price_field_value) {
$line_item_params = array(
'entity_table' => 'civicrm_participant',
'entity_id' => $form_state['participants'][$count]->id,
'label' => $form_state['price_set_data'][$count]['price_fields'][$pf_id]['price_field_values'][$price_field_value['price_field_value_id']]->label,
'qty' => $price_field_value['qty'],
'contribution_id' => $form_state['contribution']->id,
'price_field_id' => $price_field_value['price_field_id'],
'price_field_value_id' => $price_field_value['price_field_value_id'],
'financial_type_id' => !empty($price_field_value['financial_type_id']) ? $price_field_value['financial_type_id'] : $form_state['event']->financial_type_id,
'line_total' => $price_field_value['line_total'],
'unit_price' => $price_field_value['unit_price'],
);
$line_item = new CivicrmEntity($line_item_params, 'civicrm_line_item');
$line_item_wrapper = entity_metadata_wrapper('civicrm_line_item', $line_item);
$line_item_wrapper
->save();
$line_items[] = $line_item_wrapper
->value();
}
}
}
} catch (Exception $e) {
drupal_set_message(check_plain('Error creating participant record or financial records for registration for contact: ' . $form_state['contacts'][$count]->first_name . ' ' . $form_state['contacts'][$count]->last_name . ' -- ' . $e
->getMessage()));
}
}
// trigger rule event with all the pertinent data here
if (module_exists('rules')) {
$event_variables = [
'event' => $form_state['event'],
'contacts' => $form_state['contacts'],
'participants' => $form_state['participants'],
];
rules_invoke_event_by_args('civicrm_entity_price_set_field_event_registration', $event_variables);
}
}
/**
* Validation Handler for the CiviCRM entity price set event registration form display
*
* @param $form
* @param $form_state
*/
function civicrm_entity_price_set_field_display_form_event_validate($form, $form_state) {
// cc card block validation
if ($form_state['step'] == 1 && !empty($form_state['event']->is_monetary) && empty($form_state['values']['registration_form']['pay_later'])) {
if (empty($form_state['values']['registration_form']['registration_cc_block']['first_name_on_card'])) {
form_set_error('registration_form][registration_cc_block][first_name_on_card', 'First name on card field required.');
}
if (empty($form_state['values']['registration_form']['registration_cc_block']['last_name_on_card'])) {
form_set_error('registration_form][registration_cc_block][last_name_on_card', 'Last name on card field required.');
}
if (empty($form_state['values']['registration_form']['registration_cc_block']['cc_number'])) {
form_set_error('registration_form][registration_cc_block][cc_number', 'Credit card number required.');
}
elseif (!is_numeric($form_state['values']['registration_form']['registration_cc_block']['cc_number'])) {
form_set_error('registration_form][registration_cc_block][cc_number', 'Credit card number must be numeric.');
}
if (empty($form_state['values']['registration_form']['registration_cc_block']['cvv'])) {
form_set_error('registration_form][registration_cc_block][cvv', 'CVV required.');
}
elseif (!is_numeric($form_state['values']['registration_form']['registration_cc_block']['cvv'])) {
form_set_error('registration_form][registration_cc_block][cvv', 'CVV must be numeric.');
}
if (empty($form_state['values']['registration_form']['registration_cc_block']['payment_processor_selection'])) {
form_set_error('registration_form][registration_cc_block][payment_processor_selection', 'Payment method selection is required.');
}
}
// price set field text widget validation
if ($form_state['step'] == 1) {
foreach ($form_state['price_set_data'] as $count => $ps_data) {
foreach ($form_state['price_set_data'][$count]['price_fields'] as $pf_id => $pf_data) {
if ($pf_data['pf_entity']->html_type == 'Text') {
foreach ($form_state['values']['registration_form']['contacts'] as $index => $submitted_values) {
if (!empty($submitted_values['price_set'][$pf_id]['price_field_values']) && !is_numeric($submitted_values['price_set'][$pf_id]['price_field_values'])) {
form_set_error("registration_form][contacts][{$index}][price_set][{$pf_id}][price_field_values", 'Must be numeric.');
}
}
}
}
}
}
}
/**
* Implements hook_form_FORMID_alter().
*
* Alter the civcrm-event edit/add form to add validation handler if a price set field is on the form
*
* @param $form
* @param $form_state
*/
function civicrm_entity_price_set_field_form_civicrm_event_form_alter(&$form, &$form_state) {
foreach ($form as $key => $element) {
if (strpos($key, 'field_') === 0) {
$field_info = field_info_field($key);
if ($field_info['type'] == 'civicrm_entity_price_set_field') {
$form['#validate'][] = 'civicrm_entity_price_set_field_event_form_additional_validation';
break;
}
}
}
}
/**
* Additional validation handler for event form when a price set field is on the form
*
* @param $form
* @param $form_state
*/
function civicrm_entity_price_set_field_event_form_additional_validation(&$form, &$form_state) {
if (!empty($form_state['values']['is_monetary'])) {
if (empty($form_state['values']['financial_type_id'])) {
form_set_error('financial_type_id', 'Financial Type is required when the event is a paid event.');
}
if (empty($form_state['values']['fee_label'])) {
form_set_error('fee_label', 'Fee Label is required when the event is a paid event.');
}
if (empty($form_state['values']['payment_processor'])) {
form_set_error('payment_processor', 'Payment Processor is required when the event is a paid event.');
}
}
}
/**
* Submit handler for event confirmation page back button
*
* @param $form
* @param $form_state
*/
function _civicrm_entity_price_set_field_event_confirmation_page_back_submit($form, &$form_state) {
$form_state['step']--;
$form_state['rebuild'] = TRUE;
}
/**
* Submit handler for the event registration add participant button
*
* @param $form
* @param $form_state
*/
function _civicrm_entity_price_set_field_event_registration_add_participant_submit($form, &$form_state) {
$contact = new CivicrmEntity(array(
'is_new' => TRUE,
), 'civicrm_contact');
$form_state['contacts'][count($form_state['contacts'])] = $contact;
$form_state['rebuild'] = TRUE;
}
/**
* Submit handler for the event registration remove participant button
*
* @param $form
* @param $form_state
*/
function _civicrm_entity_price_set_field_event_registration_remove_participant_submit($form, &$form_state) {
$count = $form_state['triggering_element']['#contact_count'];
unset($form_state['contacts'][$count]);
if (isset($form_state['storage']['registration_form']['contacts'][$count])) {
unset($form_state['storage']['registration_form']['contacts'][$count]);
}
$form_state['rebuild'] = TRUE;
}
/**
* Ajax callback for Event Registration form / pages
*
* @param $form
* @param $form_state
* @return mixed
*/
function civicrm_entity_price_set_field_event_registration_form_ajax_callback(&$form, &$form_state) {
$commands = array();
drupal_alter('form', $form, $form_state, $form['#form_id']);
drupal_alter('form_' . $form['#form_id'], $form, $form_state);
$commands[] = ajax_command_html('#civicrm-price-set-field-event-registration', render($form));
$commands[] = ajax_command_prepend('#civicrm-price-set-field-event-registration', '<div id="messages">' . theme('status_messages') . '</div>');
$commands[] = array(
'command' => 'afterPriceSetDisplayFormAjaxReplaceCallback',
);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
/**
* Ajax callback for Event registration form, Register as another user checkbox
*
* @param $form
* @param $form_state
* @return array
*/
function civicrm_entity_price_set_field_event_registration_form_register_as_another_ajax_callback(&$form, &$form_state) {
if (!empty($form_state['values']['registration_form']['register_as_another'])) {
if (count($form_state['input']['registration_form']['contacts'][0]['contact_info'])) {
foreach ($form_state['input']['registration_form']['contacts'][0]['contact_info'] as $profile => $fapi) {
if (count($form_state['input']['registration_form']['contacts'][0]['contact_info'][$profile]['profile'])) {
foreach ($form_state['input']['registration_form']['contacts'][0]['contact_info'][$profile]['profile'] as $name => $value) {
$form_state['input']['registration_form']['contacts'][0]['contact_info'][$profile]['profile'][$name] = '';
}
}
}
}
$form_state['contacts'][0] = new CivicrmEntity(array(
'is_new' => 1,
), 'civicrm_contact');
global $user;
if ($user->uid && empty($form_state['main_registrant_already_registered']) && empty($form_state['event']->allow_same_participant_emails)) {
$form_state['contacts'][0]->uid = $user->uid;
}
}
else {
global $user;
if ($user->uid && empty($default_values['register_as_another'])) {
$contact = civicrm_entity_user_contact_get($user, array(), '', '', '');
if ($contact) {
$form_state['contacts'][0] = $contact;
if (count($form_state['input']['registration_form']['contacts'][0]['contact_info'])) {
foreach ($form_state['input']['registration_form']['contacts'][0]['contact_info'] as $profile => $fapi) {
if (count($form_state['input']['registration_form']['contacts'][0]['contact_info'][$profile]['profile'])) {
foreach ($form_state['input']['registration_form']['contacts'][0]['contact_info'][$profile]['profile'] as $name => $value) {
$form_state['input']['registration_form']['contacts'][0]['contact_info'][$profile]['profile'][$name] = !empty($contact->{$name}) ? $contact->{$name} : '';
}
}
}
}
}
else {
$form_state['contacts'][0] = array(
new CivicrmEntity(array(
'is_new' => 1,
'uid' => $user->uid,
), 'civicrm_contact'),
);
}
}
else {
$form_state['contacts'][0] = new CivicrmEntity(array(
'is_new' => 1,
), 'civicrm_contact');
}
}
$form_state['rebuild'] = TRUE;
$commands = array();
$to_render = drupal_rebuild_form($form['#form_id'], $form_state, $form);
$commands[] = ajax_command_html('#civicrm-price-set-field-event-registration', render($to_render));
$commands[] = ajax_command_prepend('#civicrm-price-set-field-event-registration', '<div id="messages">' . theme('status_messages') . '</div>');
$commands[] = array(
'command' => 'afterPriceSetDisplayFormAjaxReplaceCallback',
);
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
/**
* Function to query number of participants for an event, with optional contact_id
*
* @param $event_id
* @param int $contact_id
* @return int
*/
function _civicrm_entity_price_set_field_get_participant_count_for_event($event_id, $contact_id = 0) {
if (!empty($event_id) && is_numeric($event_id)) {
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'civicrm_participant')
->propertyCondition('event_id', $event_id);
if (!empty($contact_id) && is_numeric($contact_id)) {
$query
->propertyCondition('contact_id', $contact_id);
}
$results = $query
->execute();
if (!empty($results['civicrm_participant'])) {
return count($results['civicrm_participant']);
}
}
return 0;
}
Functions
Name![]() |
Description |
---|---|
civicrm_entity_price_set_field_allow_registration | Utility function to find modules with custom event registration access callbacks |
civicrm_entity_price_set_field_display_form_event | Form callback for event registration form |
civicrm_entity_price_set_field_display_form_event_submit | Submit handler for event registration form 'Register' button |
civicrm_entity_price_set_field_display_form_event_validate | Validation Handler for the CiviCRM entity price set event registration form display |
civicrm_entity_price_set_field_event_form_additional_validation | Additional validation handler for event form when a price set field is on the form |
civicrm_entity_price_set_field_event_registration_form_ajax_callback | Ajax callback for Event Registration form / pages |
civicrm_entity_price_set_field_event_registration_form_register_as_another_ajax_callback | Ajax callback for Event registration form, Register as another user checkbox |
civicrm_entity_price_set_field_form_civicrm_event_form_alter | Implements hook_form_FORMID_alter(). |
civicrm_entity_price_set_field_get_registration_access_callbacks_info | CiviCRM Entity Price Set Field Get Registration Access Callback Info |
_civicrm_entity_price_set_field_event_confirmation_page_back_submit | Submit handler for event confirmation page back button |
_civicrm_entity_price_set_field_event_registration_add_participant_submit | Submit handler for the event registration add participant button |
_civicrm_entity_price_set_field_event_registration_remove_participant_submit | Submit handler for the event registration remove participant button |
_civicrm_entity_price_set_field_get_participant_count_for_event | Function to query number of participants for an event, with optional contact_id |
_civicrm_entity_price_set_field_process_event_registration | Process event registration (after contacts deduped and reg status checked, successful cc transaction if paid event) |
_civicrm_entity_price_set_field_setup_event_registration_form_fapi | Helper function to setup event registration form FAPI |