3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
32 * @copyright CiviCRM LLC (c) 2004-2014
38 * This class generates form components for processing Event
41 class CRM_Event_Form_Registration_Confirm
extends CRM_Event_Form_Registration
{
44 * The values for the contribution db object
58 * Set variables up before form is built
62 public function preProcess() {
65 // lineItem isn't set until Register postProcess
66 $this->_lineItem
= $this->get('lineItem');
68 $this->_params
= $this->get('params');
69 $this->_params
[0]['tax_amount'] = $this->get('tax_amount');
71 $this->_params
[0]['is_pay_later'] = $this->get('is_pay_later');
72 $this->assign('is_pay_later', $this->_params
[0]['is_pay_later']);
73 if ($this->_params
[0]['is_pay_later']) {
74 $this->assign('pay_later_receipt', $this->_values
['event']['pay_later_receipt']);
77 CRM_Utils_Hook
::eventDiscount($this, $this->_params
);
79 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
80 $this->set('hookDiscount', $this->_params
[0]['discount']);
81 $this->assign('hookDiscount', $this->_params
[0]['discount']);
84 if ($this->_contributeMode
== 'express') {
86 // rfp == redirect from paypal
87 $rfp = CRM_Utils_Request
::retrieve('rfp', 'Boolean',
88 CRM_Core_DAO
::$_nullObject, FALSE, NULL, 'GET'
91 //we lost rfp in case of additional participant. So set it explicitly.
92 if ($rfp || CRM_Utils_Array
::value('additional_participants', $this->_params
[0], FALSE)) {
93 $payment = CRM_Core_Payment
::singleton($this->_mode
, $this->_paymentProcessor
, $this);
94 $paymentObjError = ts('The system did not record payment details for this payment and so could not process the transaction. Please report this error to the site administrator.');
95 if (is_object($payment)) {
96 $expressParams = $payment->getExpressCheckoutDetails($this->get('token'));
99 CRM_Core_Error
::fatal($paymentObjError);
102 $params['payer'] = CRM_Utils_Array
::value('payer', $expressParams);
103 $params['payer_id'] = $expressParams['payer_id'];
104 $params['payer_status'] = $expressParams['payer_status'];
106 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $expressParams, $params, FALSE);
108 // fix state and country id if present
109 if (isset($params["billing_state_province_id-{$this->_bltID}"])) {
110 $params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($params["billing_state_province_id-{$this->_bltID}"]);
112 if (isset($params['billing_country_id'])) {
113 $params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant
::countryIsoCode($params["billing_country_id-{$this->_bltID}"]);
116 // set a few other parameters for PayPal
117 $params['token'] = $this->get('token');
118 $params['amount'] = $this->_params
[0]['amount'];
119 if (!empty($this->_params
[0]['discount'])) {
120 $params['discount'] = $this->_params
[0]['discount'];
121 $params['discountAmount'] = $this->_params
[0]['discountAmount'];
122 $params['discountMessage'] = $this->_params
[0]['discountMessage'];
124 if (!empty($this->_params
[0]['amount_priceset_level_radio'])) {
125 $params['amount_priceset_level_radio'] = $this->_params
[0]['amount_priceset_level_radio'];
127 $params['amount_level'] = $this->_params
[0]['amount_level'];
128 $params['currencyID'] = $this->_params
[0]['currencyID'];
129 $params['payment_action'] = 'Sale';
131 // also merge all the other values from the profile fields
132 $values = $this->controller
->exportValues('Register');
135 "street_address-{$this->_bltID}",
136 "city-{$this->_bltID}",
137 "state_province_id-{$this->_bltID}",
138 "postal_code-{$this->_bltID}",
139 "country_id-{$this->_bltID}",
142 foreach ($values as $name => $value) {
144 if (!in_array($name, $skipFields)) {
145 $params[$name] = $value;
148 $this->set('getExpressCheckoutDetails', $params);
151 $params = $this->get('getExpressCheckoutDetails');
153 $this->_params
[0] = $params;
154 $this->_params
[0]['is_primary'] = 1;
157 //process only primary participant params.
158 $registerParams = $this->_params
[0];
159 if (isset($registerParams["billing_state_province_id-{$this->_bltID}"])
160 && $registerParams["billing_state_province_id-{$this->_bltID}"]
162 $registerParams["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($registerParams["billing_state_province_id-{$this->_bltID}"]);
165 if (isset($registerParams["billing_country_id-{$this->_bltID}"]) && $registerParams["billing_country_id-{$this->_bltID}"]) {
166 $registerParams["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant
::countryIsoCode($registerParams["billing_country_id-{$this->_bltID}"]);
168 if (isset($registerParams['credit_card_exp_date'])) {
169 $registerParams['year'] = CRM_Core_Payment_Form
::getCreditCardExpirationYear($registerParams);
170 $registerParams['month'] = CRM_Core_Payment_Form
::getCreditCardExpirationMonth($registerParams);
172 if ($this->_values
['event']['is_monetary']) {
173 $registerParams['ip_address'] = CRM_Utils_System
::ipAddress();
174 $registerParams['currencyID'] = $this->_params
[0]['currencyID'];
175 $registerParams['payment_action'] = 'Sale';
177 //assign back primary participant params.
178 $this->_params
[0] = $registerParams;
181 if ($this->_values
['event']['is_monetary']) {
182 $this->_params
[0]['invoiceID'] = $this->get('invoiceID');
184 $this->assign('defaultRole', FALSE);
185 if (CRM_Utils_Array
::value('defaultRole', $this->_params
[0]) == 1) {
186 $this->assign('defaultRole', TRUE);
189 if (empty($this->_params
[0]['participant_role_id']) &&
190 $this->_values
['event']['default_role_id']
192 $this->_params
[0]['participant_role_id'] = $this->_values
['event']['default_role_id'];
195 if (isset($this->_values
['event']['confirm_title'])) {
196 CRM_Utils_System
::setTitle($this->_values
['event']['confirm_title']);
200 $params = CRM_Contribute_Form_Contribution_Confirm
::processPcp($this, $this->_params
[0]);
201 $this->_params
[0] = $params;
204 $this->set('params', $this->_params
);
208 * Overwrite action, since we are only showing elements in frozen mode
209 * no help display needed
213 public function getAction() {
214 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
215 return CRM_Core_Action
::VIEW | CRM_Core_Action
::PREVIEW
;
218 return CRM_Core_Action
::VIEW
;
223 * Build the form object
227 public function buildQuickForm() {
228 $this->assignToTemplate();
230 if ($this->_values
['event']['is_monetary'] &&
231 ($this->_params
[0]['amount'] ||
$this->_params
[0]['amount'] == 0)
233 $this->_amount
= array();
236 foreach ($this->_params
as $k => $v) {
237 //display tax amount on confirmation page
238 $taxAmount +
= $v['tax_amount'];
241 'first_name', 'last_name') as $name) {
242 if (isset($v['billing_' . $name]) &&
245 $v[$name] = $v['billing_' . $name];
249 if (!empty($v['first_name']) && !empty($v['last_name'])) {
250 $append = $v['first_name'] . ' ' . $v['last_name'];
253 //use an email if we have one
254 foreach ($v as $v_key => $v_val) {
255 if (substr($v_key, 0, 6) == 'email-') {
256 $append = $v[$v_key];
261 $this->_amount
[$k]['amount'] = $v['amount'];
262 if (!empty($v['discountAmount'])) {
263 $this->_amount
[$k]['amount'] -= $v['discountAmount'];
266 $this->_amount
[$k]['label'] = preg_replace('/\ 1/', '', $v['amount_level']) . ' - ' . $append;
267 $this->_part
[$k]['info'] = CRM_Utils_Array
::value('first_name', $v) . ' ' . CRM_Utils_Array
::value('last_name', $v);
268 if (empty($v['first_name'])) {
269 $this->_part
[$k]['info'] = $append;
271 $this->_totalAmount
= $this->_totalAmount +
$this->_amount
[$k]['amount'];
272 if (!empty($v['is_primary'])) {
273 $this->set('primaryParticipantAmount', $this->_amount
[$k]['amount']);
278 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
, 'contribution_invoice_settings');
279 $taxTerm = CRM_Utils_Array
::value('tax_term', $invoiceSettings);
280 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
282 $this->assign('totalTaxAmount', $taxAmount);
283 $this->assign('taxTerm', $taxTerm);
285 $this->assign('part', $this->_part
);
286 $this->set('part', $this->_part
);
287 $this->assign('amounts', $this->_amount
);
288 $this->assign('totalAmount', $this->_totalAmount
);
289 $this->set('totalAmount', $this->_totalAmount
);
292 if ($this->_priceSetId
&& !CRM_Core_DAO
::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId
, 'is_quick_config')) {
293 $lineItemForTemplate = array();
294 $getTaxDetails = FALSE;
295 foreach ($this->_lineItem
as $key => $value) {
296 if (!empty($value)) {
297 $lineItemForTemplate[$key] = $value;
300 foreach ($value as $v) {
301 if (isset($v['tax_rate'])) {
302 $getTaxDetails = TRUE;
307 if (!empty($lineItemForTemplate)) {
308 $this->assign('lineItem', $lineItemForTemplate);
310 $this->assign('getTaxDetails', $getTaxDetails);
313 //display additional participants profile.
314 self
::assignProfiles($this);
316 //consider total amount.
317 $this->assign('isAmountzero', ($this->_totalAmount
<= 0) ?
TRUE : FALSE);
319 if ($this->_paymentProcessor
['payment_processor_type'] == 'Google_Checkout' && empty($this->_params
[0]['is_pay_later']) && !($this->_params
[0]['amount'] == 0) &&
320 !$this->_allowWaitlist
&& !$this->_requireApproval
322 $this->_checkoutButtonName
= $this->getButtonName('next', 'checkout');
324 $this->_checkoutButtonName
,
325 $this->_paymentProcessor
['url_button'],
326 array('class' => 'crm-form-submit')
329 $this->addButtons(array(
332 'name' => ts('<< Go Back'),
338 $contribButton = ts('Continue >>');
339 $this->addButtons(array(
342 'name' => ts('<< Go Back'),
346 'name' => $contribButton,
348 'js' => array('onclick' => "return submitOnce(this,'" . $this->_name
. "','" . ts('Processing') . "');"),
356 if (!empty($this->_fields
)) {
357 foreach ($this->_fields
as $name => $dontCare) {
361 $fields["billing_state_province-{$this->_bltID}"] = $fields["billing_country-{$this->_bltID}"] = $fields["email-{$this->_bltID}"] = 1;
362 foreach ($fields as $name => $dontCare) {
363 if (isset($this->_params
[0][$name])) {
364 $defaults[$name] = $this->_params
[0][$name];
365 if (substr($name, 0, 7) == 'custom_') {
366 $timeField = "{$name}_time";
367 if (isset($this->_params
[0][$timeField])) {
368 $defaults[$timeField] = $this->_params
[0][$timeField];
370 if (isset($this->_params
[0]["{$name}_id"])) {
371 $defaults["{$name}_id"] = $this->_params
[0]["{$name}_id"];
374 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)
375 && !empty($this->_params
[0][$name . '_custom'])
377 $defaults[$name . '_custom'] = $this->_params
[0][$name . '_custom'];
382 $this->setDefaults($defaults);
385 //lets give meaningful status message, CRM-4320.
386 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
387 $this->assign('isRequireApproval', $this->_requireApproval
);
389 // Assign Participant Count to Lineitem Table
390 $this->assign('pricesetFieldsCount', CRM_Price_BAO_PriceSet
::getPricesetCount($this->_priceSetId
));
391 $this->addFormRule(array('CRM_Event_Form_Registration_Confirm', 'formRule'), $this);
394 public static function formRule($fields, $files, $self) {
396 $eventFull = CRM_Event_BAO_Participant
::eventFull($self->_eventId
, FALSE, CRM_Utils_Array
::value('has_waitlist', $self->_values
['event']));
397 if ($eventFull && empty($self->_allowConfirmation
)) {
398 if (empty($self->_allowWaitlist
)) {
399 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "reset=1&id={$self->_eventId}", FALSE, NULL, FALSE, TRUE));
402 $self->_feeBlock
= $self->_values
['fee'];
403 CRM_Event_Form_Registration_Register
::formatFieldsForOptionFull($self);
405 if (!empty($self->_priceSetId
)) {
406 $priceSetErrors = self
::validatePriceSet($self, $self->_params
);
407 //get price set fields errors in.
408 $errors = array_merge($errors, CRM_Utils_Array
::value(0, $priceSetErrors, array()));
411 if (!empty($errors)) {
412 $soldOutOptions = implode("<br>", $priceSetErrors['soldOutOptions']);
413 CRM_Core_Session
::setStatus(ts('You have been returned to the start of the registration process and any sold out events have been removed from your selections. You will not be able to continue until you review your booking and select different events if you wish. The following events were sold out:'), ts('Unfortunately some of your options have now sold out for one or more participants.'), 'error');
414 CRM_Core_Session
::setStatus(ts("{$soldOutOptions}"), ts('Sold out:'), 'error');
415 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "_qf_Register_display=true&qfKey=" . $fields['qfKey']));
417 return empty($errors) ?
TRUE : $errors;
420 * Process the form submission
425 public function postProcess() {
426 $now = date('YmdHis');
428 $this->_params
= $this->get('params');
429 if (!empty($this->_params
[0]['contact_id'])) {
430 // unclear when this would be set & whether it could be checked in getContactID.
431 // perhaps it relates to when cid is in the url
432 //@todo someone who knows add comments on the various contactIDs in this form
433 $contactID = $this->_params
[0]['contact_id'];
436 $contactID = $this->getContactID();
439 // if a discount has been applied, lets now deduct it from the amount
440 // and fix the fee level
441 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
442 foreach ($this->_params
as $k => $v) {
443 if (CRM_Utils_Array
::value('amount', $this->_params
[$k]) > 0 && !empty($this->_params
[$k]['discountAmount'])) {
444 $this->_params
[$k]['amount'] -= $this->_params
[$k]['discountAmount'];
445 $this->_params
[$k]['amount_level'] .= CRM_Utils_Array
::value('discountMessage', $this->_params
[$k]);
448 $this->set('params', $this->_params
);
451 // CRM-4320, lets build array of cancelled additional participant ids
452 // those are drop or skip by primary at the time of confirmation.
453 // get all in and then unset those we want to process.
454 $cancelledIds = $this->_additionalParticipantIds
;
456 $params = $this->_params
;
457 if ($this->_values
['event']['is_monetary']) {
458 $this->set('finalAmount', $this->_amount
);
460 $participantCount = array();
462 //unset the skip participant from params.
463 //build the $participantCount array.
464 //maintain record for all participants.
465 foreach ($params as $participantNum => $record) {
466 if ($record == 'skip') {
467 unset($params[$participantNum]);
468 $participantCount[$participantNum] = 'skip';
470 elseif ($participantNum) {
471 $participantCount[$participantNum] = 'participant';
474 //lets get additional participant id to cancel.
475 if ($this->_allowConfirmation
&& is_array($cancelledIds)) {
476 $additonalId = CRM_Utils_Array
::value('participant_id', $record);
477 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
478 unset($cancelledIds[$key]);
483 $payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
484 $paymentObjError = ts('The system did not record payment details for this payment and so could not process the transaction. Please report this error to the site administrator.');
486 $this->participantIDS
= array();
488 foreach ($params as $key => $value) {
489 CRM_Event_Form_Registration_Confirm
::fixLocationFields($value, $fields, $this);
490 //unset the billing parameters if it is pay later mode
491 //to avoid creation of billing location
492 if ($this->_allowWaitlist
493 ||
$this->_requireApproval
494 ||
(!empty($value['is_pay_later']) && !$this->_isBillingAddressRequiredForPayLater
)
495 ||
empty($value['is_primary'])
497 $billingFields = array(
498 "email-{$this->_bltID}",
499 'billing_first_name',
500 'billing_middle_name',
502 "billing_street_address-{$this->_bltID}",
503 "billing_city-{$this->_bltID}",
504 "billing_state_province-{$this->_bltID}",
505 "billing_state_province_id-{$this->_bltID}",
506 "billing_postal_code-{$this->_bltID}",
507 "billing_country-{$this->_bltID}",
508 "billing_country_id-{$this->_bltID}",
509 "address_name-{$this->_bltID}",
511 foreach ($billingFields as $field) {
512 unset($value[$field]);
514 if (!empty($value['is_pay_later'])) {
515 $this->_values
['params']['is_pay_later'] = TRUE;
519 //Unset ContactID for additional participants and set RegisterBy Id.
520 if (empty($value['is_primary'])) {
521 $contactID = CRM_Utils_Array
::value('contact_id', $value);
522 $registerByID = $this->get('registerByID');
524 $value['registered_by_id'] = $registerByID;
528 $value['amount'] = $this->_totalAmount
;
531 $contactID = CRM_Event_Form_Registration_Confirm
::updateContactFields($contactID, $value, $fields, $this);
533 // lets store the contactID in the session
534 // we dont store in userID in case the user is doing multiple
536 // for things like tell a friend
537 if (!$this->getContactID() && !empty($value['is_primary'])) {
538 $session = CRM_Core_Session
::singleton();
539 $session->set('transaction.userID', $contactID);
542 $value['description'] = ts('Online Event Registration') . ': ' . $this->_values
['event']['title'];
543 $value['accountingCode'] = CRM_Utils_Array
::value('accountingCode',
544 $this->_values
['event']
547 // required only if paid event
548 if ($this->_values
['event']['is_monetary']) {
549 if (is_array($this->_paymentProcessor
)) {
550 $payment = CRM_Core_Payment
::singleton($this->_mode
, $this->_paymentProcessor
, $this);
555 if ($this->_allowWaitlist ||
$this->_requireApproval
) {
556 //get the participant statuses.
557 $waitingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Waiting'");
558 if ($this->_allowWaitlist
) {
559 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
562 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
565 //there might be case user seleted pay later and
566 //now becomes part of run time waiting list.
567 $value['is_pay_later'] = FALSE;
569 elseif (!empty($value['is_pay_later']) ||
570 $value['amount'] == 0 ||
571 $this->_contributeMode
== 'checkout' ||
572 $this->_contributeMode
== 'notify'
574 if ($value['amount'] != 0) {
576 //get the participant statuses.
577 $pendingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Pending'");
578 $status = !empty($value['is_pay_later']) ?
'Pending from pay later' : 'Pending from incomplete transaction';
579 $value['participant_status_id'] = $value['participant_status'] = array_search($status, $pendingStatuses);
582 elseif ($this->_contributeMode
== 'express' && !empty($value['is_primary'])) {
583 if (is_object($payment)) {
584 $result = $payment->doExpressCheckout($value);
587 CRM_Core_Error
::fatal($paymentObjError);
590 elseif (!empty($value['is_primary'])) {
591 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $value, $value, TRUE);
592 // payment email param can be empty for _bltID mapping
593 // thus provide mapping for it with a different email value
594 if (empty($value['email'])) {
595 $value['email'] = CRM_Utils_Array
::valueByRegexKey('/^email-/', $value);
598 if (is_object($payment)) {
599 $result = $payment->doDirectPayment($value);
602 CRM_Core_Error
::fatal($paymentObjError);
606 if (is_a($result, 'CRM_Core_Error')) {
607 CRM_Core_Error
::displaySessionError($result);
608 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "id={$this->_eventId}"));
612 $value = array_merge($value, $result);
615 $value['receive_date'] = $now;
616 if ($this->_allowConfirmation
) {
617 $value['participant_register_date'] = $this->_values
['participant']['register_date'];
620 $createContrib = ($value['amount'] != 0) ?
TRUE : FALSE;
621 // force to create zero amount contribution, CRM-5095
622 if (!$createContrib && ($value['amount'] == 0)
623 && $this->_priceSetId
&& $this->_lineItem
625 $createContrib = TRUE;
628 if ($createContrib && !empty($value['is_primary']) &&
629 !$this->_allowWaitlist
&& !$this->_requireApproval
631 // if paid event add a contribution record
632 //if primary participant contributing additional amount
633 //append (multiple participants) to its fee level. CRM-4196.
634 $isAdditionalAmount = FALSE;
635 if (count($params) > 1) {
636 $isAdditionalAmount = TRUE;
639 //passing contribution id is already registered.
641 self
::processContribution($this, $value, $result, $contactID, $pending, $isAdditionalAmount);
642 $value['contributionID'] = $contribution->id
;
643 $value['contributionTypeID'] = $contribution->financial_type_id
;
644 $value['receive_date'] = $contribution->receive_date
;
645 $value['trxn_id'] = $contribution->trxn_id
;
646 $value['contributionID'] = $contribution->id
;
647 $value['contributionTypeID'] = $contribution->financial_type_id
;
649 $value['contactID'] = $contactID;
650 $value['eventID'] = $this->_eventId
;
651 $value['item_name'] = $value['description'];
654 if (!empty($value['contributionID'])) {
655 $this->_values
['contributionId'] = $value['contributionID'];
659 if (!empty($value['is_primary'])) {
660 $primaryCurrencyID = CRM_Utils_Array
::value('currencyID', $value);
662 if (empty($value['currencyID'])) {
663 $value['currencyID'] = $primaryCurrencyID;
666 // CRM-11182 - Confirmation page might not be monetary
667 if ($this->_values
['event']['is_monetary']) {
668 if (!$pending && !empty($value['is_primary']) &&
669 !$this->_allowWaitlist
&& !$this->_requireApproval
671 // transactionID & receive date required while building email template
672 $this->assign('trxn_id', $value['trxn_id']);
673 $this->assign('receive_date', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
674 $this->set('receiveDate', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
675 $this->set('trxnId', CRM_Utils_Array
::value('trxn_id', $value));
679 $value['fee_amount'] = CRM_Utils_Array
::value('amount', $value);
680 $this->set('value', $value);
682 // handle register date CRM-4320
683 if ($this->_allowConfirmation
) {
684 $registerDate = CRM_Utils_Array
::value('participant_register_date', $params);
686 elseif (!empty($params['participant_register_date']) &&
687 is_array($params['participant_register_date']) &&
688 !empty($params['participant_register_date'])
690 $registerDate = CRM_Utils_Date
::format($params['participant_register_date']);
693 $registerDate = date('YmdHis');
695 $this->assign('register_date', $registerDate);
697 $this->confirmPostProcess($contactID, $contribution, $payment);
700 //handle if no additional participant.
701 if (!$registerByID) {
702 $registerByID = $this->get('registerByID');
705 $this->set('participantIDs', $this->_participantIDS
);
707 // create line items, CRM-5313
708 if ($this->_priceSetId
&&
709 !empty($this->_lineItem
)
711 // take all processed participant ids.
712 $allParticipantIds = $this->_participantIDS
;
714 // when participant re-walk wizard.
715 if ($this->_allowConfirmation
&&
716 !empty($this->_additionalParticipantIds
)
718 $allParticipantIds = array_merge(array($registerByID), $this->_additionalParticipantIds
);
721 $entityTable = 'civicrm_participant';
722 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
, 'contribution_invoice_settings');
723 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
725 $dataArray = array();
726 foreach ($this->_lineItem
as $key => $value) {
727 if (($value != 'skip') &&
728 ($entityId = CRM_Utils_Array
::value($key, $allParticipantIds))
731 // do cleanup line items if participant re-walking wizard.
732 if ($this->_allowConfirmation
) {
733 CRM_Price_BAO_LineItem
::deleteLineItems($entityId, $entityTable);
735 $lineItem[$this->_priceSetId
] = $value;
736 CRM_Price_BAO_LineItem
::processPriceSet($entityId, $lineItem, $contribution, $entityTable);
739 foreach ($value as $line) {
740 if (isset($line['tax_amount']) && isset($line['tax_rate'])) {
741 $totalTaxAmount = $line['tax_amount'] +
$totalTaxAmount;
742 if (isset($dataArray[$line['tax_rate']])) {
743 $dataArray[$line['tax_rate']] = $dataArray[$line['tax_rate']] + CRM_Utils_Array
::value('tax_amount', $line);
746 $dataArray[$line['tax_rate']] = CRM_Utils_Array
::value('tax_amount', $line);
753 $this->assign('dataArray', $dataArray);
754 $this->assign('totalTaxAmount', $totalTaxAmount);
758 //update status and send mail to cancelled additonal participants, CRM-4320
759 if ($this->_allowConfirmation
&& is_array($cancelledIds) && !empty($cancelledIds)) {
760 $cancelledId = array_search('Cancelled',
761 CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'")
763 CRM_Event_BAO_Participant
::transitionParticipants($cancelledIds, $cancelledId);
767 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
771 // for Transfer checkout.
772 if (($this->_contributeMode
== 'checkout' ||
773 $this->_contributeMode
== 'notify'
774 ) && empty($params[0]['is_pay_later']) &&
775 !$this->_allowWaitlist
&& !$this->_requireApproval
&&
776 $this->_totalAmount
> 0
779 $primaryParticipant = $this->get('primaryParticipant');
781 if (empty($primaryParticipant['participantID'])) {
782 $primaryParticipant['participantID'] = $registerByID;
785 //build an array of custom profile and assigning it to template
786 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, $this->_values
, NULL, $isTest);
787 if (count($customProfile)) {
788 $this->assign('customProfile', $customProfile);
789 $this->set('customProfile', $customProfile);
792 // do a transfer only if a monetary payment greater than 0
793 if ($this->_values
['event']['is_monetary'] && $primaryParticipant) {
794 if ($payment && is_object($payment)) {
795 //CRM 14512 provide line items of all participants to payment gateway
796 $primaryContactId = $this->get('primaryContactId');
798 //build an array of cId/pId of participants
799 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, NULL, $primaryContactId, $isTest, TRUE);
801 //need to copy, since we are unsetting on the way.
802 $copyParticipantCountLines = $participantCount;
804 //lets carry all participant params w/ values.
805 foreach ($additionalIDs as $participantID => $contactId) {
806 $participantNum = NULL;
807 $participantNum = $participantID;
808 if ($participantID == $registerByID) {
809 $participantNum = 0; // is primary particpant
812 if ($participantNum = array_search('participant', $copyParticipantCountLines)) {
813 //if no participant found break.
814 if ($participantNum === NULL) {
817 //unset current particpant so we don't check them again
818 unset($copyParticipantCountLines[$participantNum]);
821 // get values of line items
822 if ($this->_amount
) {
824 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
825 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
826 $params[$participantNum]['amounts'] = $amount;
829 if (!empty($this->_lineItem
)) {
830 $lineItems = $this->_lineItem
;
832 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
833 $lineItem[] = $lineItemValue;
835 $params[$participantNum]['lineItem'] = $lineItem;
838 //only add additional particpants and not the primary particpant as we already have that
839 //added to $primaryParticipant so that this change doesn't break or require changes to
840 //existing gateway implementations
841 $primaryParticipant['participants_info'][$participantID] = $params[$participantNum];
844 //get event custom field information
845 $groupTree = CRM_Core_BAO_CustomGroup
::getTree('Event', $this, $this->_eventId
, 0, $this->_values
['event']['event_type_id']);
846 $primaryParticipant['eventCustomFields'] = $groupTree;
848 // call postprocess hook before leaving
849 $this->postProcessHook();
850 // this does not return
851 $payment->doTransferCheckout($primaryParticipant, 'event');
854 CRM_Core_Error
::fatal($paymentObjError);
859 //otherwise send mail Confirmation/Receipt
860 $primaryContactId = $this->get('primaryContactId');
862 //build an array of cId/pId of participants
863 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID,
864 NULL, $primaryContactId, $isTest,
867 //lets send mails to all with meaningful text, CRM-4320.
868 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
869 $this->assign('isRequireApproval', $this->_requireApproval
);
871 //need to copy, since we are unsetting on the way.
872 $copyParticipantCount = $participantCount;
874 //lets carry all paticipant params w/ values.
875 foreach ($additionalIDs as $participantID => $contactId) {
876 $participantNum = NULL;
877 if ($participantID == $registerByID) {
881 if ($participantNum = array_search('participant', $copyParticipantCount)) {
882 unset($copyParticipantCount[$participantNum]);
885 if ($participantNum === NULL) {
889 //carry the participant submitted values.
890 $this->_values
['params'][$participantID] = $params[$participantNum];
893 foreach ($additionalIDs as $participantID => $contactId) {
895 if ($participantID == $registerByID) {
896 //set as Primary Participant
897 $this->assign('isPrimary', 1);
898 //build an array of custom profile and assigning it to template.
899 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($participantID, $this->_values
, NULL, $isTest);
901 if (count($customProfile)) {
902 $this->assign('customProfile', $customProfile);
903 $this->set('customProfile', $customProfile);
905 $this->_values
['params']['additionalParticipant'] = FALSE;
908 //take the Additional participant number.
909 if ($participantNum = array_search('participant', $participantCount)) {
910 unset($participantCount[$participantNum]);
912 $this->assign('isPrimary', 0);
913 $this->assign('customProfile', NULL);
914 //Additional Participant should get only it's payment information
915 if (!empty($this->_amount
)) {
917 $params = $this->get('params');
918 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
919 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
920 $this->assign('amounts', $amount);
922 if ($this->_lineItem
) {
923 $lineItems = $this->_lineItem
;
925 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
926 $lineItem[] = $lineItemValue;
928 $this->assign('lineItem', $lineItem);
930 $this->_values
['params']['additionalParticipant'] = TRUE;
931 $this->assign('isAdditionalParticipant', $this->_values
['params']['additionalParticipant']);
934 //pass these variables since these are run time calculated.
935 $this->_values
['params']['isOnWaitlist'] = $this->_allowWaitlist
;
936 $this->_values
['params']['isRequireApproval'] = $this->_requireApproval
;
938 //send mail to primary as well as additional participants.
939 $this->assign('contactID', $contactId);
940 $this->assign('participantID', $participantID);
941 CRM_Event_BAO_Event
::sendMail($contactId, $this->_values
, $participantID, $isTest);
947 * Process the contribution
949 * @param CRM_Core_Form $form
950 * @param array $params
952 * @param int $contactID
953 * @param bool $pending
954 * @param bool $isAdditionalAmount
958 static function processContribution(
959 &$form, $params, $result, $contactID,
960 $pending = FALSE, $isAdditionalAmount = FALSE
962 $transaction = new CRM_Core_Transaction();
964 $now = date('YmdHis');
967 if (!empty($form->_values
['event']['is_email_confirm'])) {
971 if ($isAdditionalAmount) {
972 $params['amount_level'] = $params['amount_level'] . ts(' (multiple participants)') . CRM_Core_DAO
::VALUE_SEPARATOR
;
975 $contribParams = array(
976 'contact_id' => $contactID,
977 'financial_type_id' => !empty($form->_values
['event']['financial_type_id']) ?
$form->_values
['event']['financial_type_id'] : $params['financial_type_id'],
978 'receive_date' => $now,
979 'total_amount' => $params['amount'],
980 'tax_amount' => $params['tax_amount'],
981 'amount_level' => $params['amount_level'],
982 'invoice_id' => $params['invoiceID'],
983 'currency' => $params['currencyID'],
984 'source' => !empty($params['participant_source']) ?
$params['participant_source'] : $params['description'],
985 'is_pay_later' => CRM_Utils_Array
::value('is_pay_later', $params, 0),
986 'campaign_id' => CRM_Utils_Array
::value('campaign_id', $params),
989 if (empty($params['is_pay_later'])) {
990 $contribParams['payment_instrument_id'] = 1;
993 if (!$pending && $result) {
994 $contribParams +
= array(
995 'fee_amount' => CRM_Utils_Array
::value('fee_amount', $result),
996 'net_amount' => CRM_Utils_Array
::value('net_amount', $result, $params['amount']),
997 'trxn_id' => $result['trxn_id'],
998 'receipt_date' => $receiptDate,
1002 $allStatuses = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
1003 $contribParams['contribution_status_id'] = array_search('Completed', $allStatuses);
1005 $contribParams['contribution_status_id'] = array_search('Pending', $allStatuses);
1008 $contribParams['is_test'] = 0;
1009 if ($form->_action
& CRM_Core_Action
::PREVIEW || CRM_Utils_Array
::value('mode', $params) == 'test') {
1010 $contribParams['is_test'] = 1;
1014 if (!empty($contribParams['invoice_id'])) {
1015 $contribID = CRM_Core_DAO
::getFieldValue('CRM_Contribute_DAO_Contribution',
1016 $contribParams['invoice_id'],
1024 $ids['contribution'] = $contribID;
1025 $contribParams['id'] = $contribID;
1028 //create an contribution address
1029 if ($form->_contributeMode
!= 'notify' && empty($params['is_pay_later'])) {
1030 $contribParams['address_id'] = CRM_Contribute_BAO_Contribution
::createAddress($params, $form->_bltID
);
1033 // Prepare soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin.
1034 if (!empty($params['pcp_made_through_id']) ||
!empty($params['soft_credit_to'])) {
1036 // if its due to pcp
1037 if (!empty($params['pcp_made_through_id'])) {
1038 $contribSoftContactId = CRM_Core_DAO
::getFieldValue('CRM_PCP_DAO_PCP',
1039 $params['pcp_made_through_id'],
1044 $contribSoftContactId = CRM_Utils_Array
::value('soft_credit_to', $params);
1047 // Pass these details onto with the contribution to make them
1048 // available at hook_post_process, CRM-8908
1049 $contribParams['soft_credit_to'] = $params['soft_credit_to'] = $contribSoftContactId;
1051 $contribParams['payment_processor'] = CRM_Utils_Array
::value('payment_processor', $params);
1052 $contribParams['skipLineItem'] = 1;
1053 // create contribution record
1054 $contribution = CRM_Contribute_BAO_Contribution
::add($contribParams, $ids);
1056 CRM_Event_BAO_Participant
::createDiscountTrxn($form->_eventId
, $contribParams, CRM_Utils_Array
::value('amount_priceset_level_radio', $params, NULL));
1058 // process soft credit / pcp pages
1059 CRM_Contribute_Form_Contribution_Confirm
::processPcpSoft($params, $contribution);
1061 $transaction->commit();
1063 return $contribution;
1067 * Fix the Location Fields
1069 * @param array $params
1071 * @param CRM_Core_Form $form
1075 public static function fixLocationFields(&$params, &$fields, &$form) {
1076 if (!empty($form->_fields
)) {
1077 foreach ($form->_fields
as $name => $dontCare) {
1082 if (is_array($fields)) {
1083 if (!array_key_exists('first_name', $fields)) {
1084 $nameFields = array('first_name', 'middle_name', 'last_name');
1085 foreach ($nameFields as $name) {
1087 if (array_key_exists("billing_$name", $params)) {
1088 $params[$name] = $params["billing_{$name}"];
1089 $params['preserveDBName'] = TRUE;
1095 // also add location name to the array
1096 if ($form->_values
['event']['is_monetary']) {
1097 $params["address_name-{$form->_bltID}"] = CRM_Utils_Array
::value('billing_first_name', $params) . ' ' . CRM_Utils_Array
::value('billing_middle_name', $params) . ' ' . CRM_Utils_Array
::value('billing_last_name', $params);
1098 $fields["address_name-{$form->_bltID}"] = 1;
1100 $fields["email-{$form->_bltID}"] = 1;
1101 $fields['email-Primary'] = 1;
1103 //if its pay later or additional participant set email address as primary.
1104 if ((!empty($params['is_pay_later']) ||
empty($params['is_primary']) ||
1105 !$form->_values
['event']['is_monetary'] ||
1106 $form->_allowWaitlist ||
1107 $form->_requireApproval
1108 ) && !empty($params["email-{$form->_bltID}"])) {
1109 $params['email-Primary'] = $params["email-{$form->_bltID}"];
1114 * Update contact fields
1116 * @param int $contactID
1117 * @param array $params
1119 * @param CRM_Core_Form $form
1123 public static function updateContactFields($contactID, $params, $fields, &$form) {
1124 //add the contact to group, if add to group is selected for a
1125 //particular uf group
1127 // get the add to groups
1128 $addToGroups = array();
1130 if (!empty($form->_fields
)) {
1131 foreach ($form->_fields
as $key => $value) {
1132 if (!empty($value['add_to_group_id'])) {
1133 $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
1138 // check for profile double opt-in and get groups to be subscribed
1139 $subscribeGroupIds = CRM_Core_BAO_UFGroup
::getDoubleOptInGroupIds($params, $contactID);
1141 foreach ($addToGroups as $k) {
1142 if (array_key_exists($k, $subscribeGroupIds)) {
1143 unset($addToGroups[$k]);
1147 // since we are directly adding contact to group lets unset it from mailing
1148 if (!empty($addToGroups)) {
1149 foreach ($addToGroups as $groupId) {
1150 if (isset($subscribeGroupIds[$groupId])) {
1151 unset($subscribeGroupIds[$groupId]);
1156 $ctype = CRM_Core_DAO
::getFieldValue(
1157 'CRM_Contact_DAO_Contact',
1162 if (array_key_exists('contact_id', $params) && empty($params['contact_id'])) {
1163 // we unset this here because the downstream function ignores the contactID we give it
1164 // if it is set & it is difficult to understand the implications of 'fixing' this downstream
1165 // but if we are passing a contact id into this function it's reasonable to assume we don't
1167 unset($params['contact_id']);
1170 $contactID = CRM_Contact_BAO_Contact
::createProfileContact(
1182 foreach (CRM_Contact_BAO_Contact
::$_greetingTypes as $greeting) {
1183 if (!isset($params[$greeting . '_id'])) {
1184 $params[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils
::defaultGreeting('Individual', $greeting);
1188 $contactID = CRM_Contact_BAO_Contact
::createProfileContact($params,
1196 $form->set('contactID', $contactID);
1199 //get email primary first if exist
1200 $subscribtionEmail = array('email' => CRM_Utils_Array
::value('email-Primary', $params));
1201 if (!$subscribtionEmail['email']) {
1202 $subscribtionEmail['email'] = CRM_Utils_Array
::value("email-{$form->_bltID}", $params);
1204 // subscribing contact to groups
1205 if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
1206 CRM_Mailing_Event_BAO_Subscribe
::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
1215 public static function assignProfiles(&$form) {
1216 $participantParams = $form->_params
;
1217 $formattedValues = $profileFields = array();
1219 foreach ($participantParams as $participantNum => $participantValue) {
1220 if ($participantNum) {
1221 $prefix1 = 'additional';
1222 $prefix2 = 'additional_';
1228 if ($participantValue != 'skip') {
1229 //get the customPre profile info
1230 if (!empty($form->_values
[$prefix2 . 'custom_pre_id'])) {
1231 $values = $groupName = array();
1232 CRM_Event_BAO_Event
::displayProfile($participantValue,
1233 $form->_values
[$prefix2 . 'custom_pre_id'],
1239 if (count($values)) {
1240 $formattedValues[$count][$prefix1 . 'CustomPre'] = $values;
1242 $formattedValues[$count][$prefix1 . 'CustomPreGroupTitle'] = CRM_Utils_Array
::value('groupTitle', $groupName);
1244 //get the customPost profile info
1245 if (!empty($form->_values
[$prefix2 . 'custom_post_id'])) {
1246 $values = $groupName = array();
1247 foreach ($form->_values
[$prefix2 . 'custom_post_id'] as $gids) {
1249 CRM_Event_BAO_Event
::displayProfile($participantValue,
1255 $values[$gids] = $val;
1256 $groupName[$gids] = $group;
1259 if (count($values)) {
1260 $formattedValues[$count][$prefix1 . 'CustomPost'] = $values;
1263 if (isset($formattedValues[$count][$prefix1 . 'CustomPre'])) {
1264 $formattedValues[$count][$prefix1 . 'CustomPost'] = array_diff_assoc($formattedValues[$count][$prefix1 . 'CustomPost'],
1265 $formattedValues[$count][$prefix1 . 'CustomPre']
1269 $formattedValues[$count][$prefix1 . 'CustomPostGroupTitle'] = $groupName;
1273 $form->_fields
= $profileFields;
1275 if (!empty($formattedValues)) {
1276 $form->assign('primaryParticipantProfile', $formattedValues[1]);
1277 $form->set('primaryParticipantProfile', $formattedValues[1]);
1279 unset($formattedValues[1]);
1280 $form->assign('addParticipantProfile', $formattedValues);
1281 $form->set('addParticipantProfile', $formattedValues);