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'];
244 if (isset($v['billing_' . $name]) &&
247 $v[$name] = $v['billing_' . $name];
251 if (!empty($v['first_name']) && !empty($v['last_name'])) {
252 $append = $v['first_name'] . ' ' . $v['last_name'];
255 //use an email if we have one
256 foreach ($v as $v_key => $v_val) {
257 if (substr($v_key, 0, 6) == 'email-') {
258 $append = $v[$v_key];
263 $this->_amount
[$k]['amount'] = $v['amount'];
264 if (!empty($v['discountAmount'])) {
265 $this->_amount
[$k]['amount'] -= $v['discountAmount'];
268 $this->_amount
[$k]['label'] = preg_replace('/\ 1/', '', $v['amount_level']) . ' - ' . $append;
269 $this->_part
[$k]['info'] = CRM_Utils_Array
::value('first_name', $v) . ' ' . CRM_Utils_Array
::value('last_name', $v);
270 if (empty($v['first_name'])) {
271 $this->_part
[$k]['info'] = $append;
273 $this->_totalAmount
= $this->_totalAmount +
$this->_amount
[$k]['amount'];
274 if (!empty($v['is_primary'])) {
275 $this->set('primaryParticipantAmount', $this->_amount
[$k]['amount']);
280 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
, 'contribution_invoice_settings');
281 $taxTerm = CRM_Utils_Array
::value('tax_term', $invoiceSettings);
282 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
284 $this->assign('totalTaxAmount', $taxAmount);
285 $this->assign('taxTerm', $taxTerm);
287 $this->assign('part', $this->_part
);
288 $this->set('part', $this->_part
);
289 $this->assign('amounts', $this->_amount
);
290 $this->assign('totalAmount', $this->_totalAmount
);
291 $this->set('totalAmount', $this->_totalAmount
);
294 if ($this->_priceSetId
&& !CRM_Core_DAO
::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId
, 'is_quick_config')) {
295 $lineItemForTemplate = array();
296 $getTaxDetails = FALSE;
297 foreach ($this->_lineItem
as $key => $value) {
298 if (!empty($value)) {
299 $lineItemForTemplate[$key] = $value;
302 foreach ($value as $v) {
303 if (isset($v['tax_rate'])) {
304 $getTaxDetails = TRUE;
309 if (!empty($lineItemForTemplate)) {
310 $this->assign('lineItem', $lineItemForTemplate);
312 $this->assign('getTaxDetails', $getTaxDetails);
315 //display additional participants profile.
316 self
::assignProfiles($this);
318 //consider total amount.
319 $this->assign('isAmountzero', ($this->_totalAmount
<= 0) ?
TRUE : FALSE);
321 if ($this->_paymentProcessor
['payment_processor_type'] == 'Google_Checkout' && empty($this->_params
[0]['is_pay_later']) && !($this->_params
[0]['amount'] == 0) &&
322 !$this->_allowWaitlist
&& !$this->_requireApproval
324 $this->_checkoutButtonName
= $this->getButtonName('next', 'checkout');
326 $this->_checkoutButtonName
,
327 $this->_paymentProcessor
['url_button'],
328 array('class' => 'crm-form-submit')
331 $this->addButtons(array(
334 'name' => ts('Go Back'),
340 $contribButton = ts('Continue');
341 $this->addButtons(array(
344 'name' => ts('Go Back'),
348 'name' => $contribButton,
350 'js' => array('onclick' => "return submitOnce(this,'" . $this->_name
. "','" . ts('Processing') . "');"),
358 if (!empty($this->_fields
)) {
359 foreach ($this->_fields
as $name => $dontCare) {
363 $fields["billing_state_province-{$this->_bltID}"] = $fields["billing_country-{$this->_bltID}"] = $fields["email-{$this->_bltID}"] = 1;
364 foreach ($fields as $name => $dontCare) {
365 if (isset($this->_params
[0][$name])) {
366 $defaults[$name] = $this->_params
[0][$name];
367 if (substr($name, 0, 7) == 'custom_') {
368 $timeField = "{$name}_time";
369 if (isset($this->_params
[0][$timeField])) {
370 $defaults[$timeField] = $this->_params
[0][$timeField];
372 if (isset($this->_params
[0]["{$name}_id"])) {
373 $defaults["{$name}_id"] = $this->_params
[0]["{$name}_id"];
376 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)
377 && !empty($this->_params
[0][$name . '_custom'])
379 $defaults[$name . '_custom'] = $this->_params
[0][$name . '_custom'];
384 $this->setDefaults($defaults);
387 //lets give meaningful status message, CRM-4320.
388 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
389 $this->assign('isRequireApproval', $this->_requireApproval
);
391 // Assign Participant Count to Lineitem Table
392 $this->assign('pricesetFieldsCount', CRM_Price_BAO_PriceSet
::getPricesetCount($this->_priceSetId
));
393 $this->addFormRule(array('CRM_Event_Form_Registration_Confirm', 'formRule'), $this);
403 public static function formRule($fields, $files, $self) {
405 $eventFull = CRM_Event_BAO_Participant
::eventFull($self->_eventId
, FALSE, CRM_Utils_Array
::value('has_waitlist', $self->_values
['event']));
406 if ($eventFull && empty($self->_allowConfirmation
)) {
407 if (empty($self->_allowWaitlist
)) {
408 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "reset=1&id={$self->_eventId}", FALSE, NULL, FALSE, TRUE));
411 $self->_feeBlock
= $self->_values
['fee'];
412 CRM_Event_Form_Registration_Register
::formatFieldsForOptionFull($self);
414 if (!empty($self->_priceSetId
)) {
415 $priceSetErrors = self
::validatePriceSet($self, $self->_params
);
416 //get price set fields errors in.
417 $errors = array_merge($errors, CRM_Utils_Array
::value(0, $priceSetErrors, array()));
420 if (!empty($errors)) {
421 $soldOutOptions = implode("<br/>", $priceSetErrors['soldOutOptions']);
422 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');
423 CRM_Core_Session
::setStatus(ts("{$soldOutOptions}"), ts('Sold out:'), 'error');
424 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "_qf_Register_display=true&qfKey=" . $fields['qfKey']));
426 return empty($errors) ?
TRUE : $errors;
430 * Process the form submission.
435 public function postProcess() {
436 $now = date('YmdHis');
438 $this->_params
= $this->get('params');
439 if (!empty($this->_params
[0]['contact_id'])) {
440 // unclear when this would be set & whether it could be checked in getContactID.
441 // perhaps it relates to when cid is in the url
442 //@todo someone who knows add comments on the various contactIDs in this form
443 $contactID = $this->_params
[0]['contact_id'];
446 $contactID = $this->getContactID();
449 // if a discount has been applied, lets now deduct it from the amount
450 // and fix the fee level
451 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
452 foreach ($this->_params
as $k => $v) {
453 if (CRM_Utils_Array
::value('amount', $this->_params
[$k]) > 0 && !empty($this->_params
[$k]['discountAmount'])) {
454 $this->_params
[$k]['amount'] -= $this->_params
[$k]['discountAmount'];
455 $this->_params
[$k]['amount_level'] .= CRM_Utils_Array
::value('discountMessage', $this->_params
[$k]);
458 $this->set('params', $this->_params
);
461 // CRM-4320, lets build array of cancelled additional participant ids
462 // those are drop or skip by primary at the time of confirmation.
463 // get all in and then unset those we want to process.
464 $cancelledIds = $this->_additionalParticipantIds
;
466 $params = $this->_params
;
467 if ($this->_values
['event']['is_monetary']) {
468 $this->set('finalAmount', $this->_amount
);
470 $participantCount = array();
472 //unset the skip participant from params.
473 //build the $participantCount array.
474 //maintain record for all participants.
475 foreach ($params as $participantNum => $record) {
476 if ($record == 'skip') {
477 unset($params[$participantNum]);
478 $participantCount[$participantNum] = 'skip';
480 elseif ($participantNum) {
481 $participantCount[$participantNum] = 'participant';
484 //lets get additional participant id to cancel.
485 if ($this->_allowConfirmation
&& is_array($cancelledIds)) {
486 $additonalId = CRM_Utils_Array
::value('participant_id', $record);
487 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
488 unset($cancelledIds[$key]);
493 $payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
494 $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.');
496 $this->participantIDS
= array();
498 foreach ($params as $key => $value) {
499 CRM_Event_Form_Registration_Confirm
::fixLocationFields($value, $fields, $this);
500 //unset the billing parameters if it is pay later mode
501 //to avoid creation of billing location
502 if ($this->_allowWaitlist
503 ||
$this->_requireApproval
504 ||
(!empty($value['is_pay_later']) && !$this->_isBillingAddressRequiredForPayLater
)
505 ||
empty($value['is_primary'])
507 $billingFields = array(
508 "email-{$this->_bltID}",
509 'billing_first_name',
510 'billing_middle_name',
512 "billing_street_address-{$this->_bltID}",
513 "billing_city-{$this->_bltID}",
514 "billing_state_province-{$this->_bltID}",
515 "billing_state_province_id-{$this->_bltID}",
516 "billing_postal_code-{$this->_bltID}",
517 "billing_country-{$this->_bltID}",
518 "billing_country_id-{$this->_bltID}",
519 "address_name-{$this->_bltID}",
521 foreach ($billingFields as $field) {
522 unset($value[$field]);
524 if (!empty($value['is_pay_later'])) {
525 $this->_values
['params']['is_pay_later'] = TRUE;
529 //Unset ContactID for additional participants and set RegisterBy Id.
530 if (empty($value['is_primary'])) {
531 $contactID = CRM_Utils_Array
::value('contact_id', $value);
532 $registerByID = $this->get('registerByID');
534 $value['registered_by_id'] = $registerByID;
538 $value['amount'] = $this->_totalAmount
;
541 $contactID = CRM_Event_Form_Registration_Confirm
::updateContactFields($contactID, $value, $fields, $this);
543 // lets store the contactID in the session
544 // we dont store in userID in case the user is doing multiple
546 // for things like tell a friend
547 if (!$this->getContactID() && !empty($value['is_primary'])) {
548 $session = CRM_Core_Session
::singleton();
549 $session->set('transaction.userID', $contactID);
552 $value['description'] = ts('Online Event Registration') . ': ' . $this->_values
['event']['title'];
553 $value['accountingCode'] = CRM_Utils_Array
::value('accountingCode',
554 $this->_values
['event']
557 // required only if paid event
558 if ($this->_values
['event']['is_monetary']) {
559 if (is_array($this->_paymentProcessor
)) {
560 $payment = CRM_Core_Payment
::singleton($this->_mode
, $this->_paymentProcessor
, $this);
565 if ($this->_allowWaitlist ||
$this->_requireApproval
) {
566 //get the participant statuses.
567 $waitingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Waiting'");
568 if ($this->_allowWaitlist
) {
569 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
572 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
575 //there might be case user seleted pay later and
576 //now becomes part of run time waiting list.
577 $value['is_pay_later'] = FALSE;
579 elseif (!empty($value['is_pay_later']) ||
580 $value['amount'] == 0 ||
581 $this->_contributeMode
== 'checkout' ||
582 $this->_contributeMode
== 'notify'
584 if ($value['amount'] != 0) {
586 //get the participant statuses.
587 $pendingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Pending'");
588 $status = !empty($value['is_pay_later']) ?
'Pending from pay later' : 'Pending from incomplete transaction';
589 $value['participant_status_id'] = $value['participant_status'] = array_search($status, $pendingStatuses);
592 elseif ($this->_contributeMode
== 'express' && !empty($value['is_primary'])) {
593 if (is_object($payment)) {
594 $result = $payment->doExpressCheckout($value);
597 CRM_Core_Error
::fatal($paymentObjError);
600 elseif (!empty($value['is_primary'])) {
601 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $value, $value, TRUE);
602 // payment email param can be empty for _bltID mapping
603 // thus provide mapping for it with a different email value
604 if (empty($value['email'])) {
605 $value['email'] = CRM_Utils_Array
::valueByRegexKey('/^email-/', $value);
608 if (is_object($payment)) {
609 $result = $payment->doDirectPayment($value);
612 CRM_Core_Error
::fatal($paymentObjError);
616 if (is_a($result, 'CRM_Core_Error')) {
617 CRM_Core_Error
::displaySessionError($result);
618 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "id={$this->_eventId}"));
622 $value = array_merge($value, $result);
625 $value['receive_date'] = $now;
626 if ($this->_allowConfirmation
) {
627 $value['participant_register_date'] = $this->_values
['participant']['register_date'];
630 $createContrib = ($value['amount'] != 0) ?
TRUE : FALSE;
631 // force to create zero amount contribution, CRM-5095
632 if (!$createContrib && ($value['amount'] == 0)
633 && $this->_priceSetId
&& $this->_lineItem
635 $createContrib = TRUE;
638 if ($createContrib && !empty($value['is_primary']) &&
639 !$this->_allowWaitlist
&& !$this->_requireApproval
641 // if paid event add a contribution record
642 //if primary participant contributing additional amount
643 //append (multiple participants) to its fee level. CRM-4196.
644 $isAdditionalAmount = FALSE;
645 if (count($params) > 1) {
646 $isAdditionalAmount = TRUE;
649 //passing contribution id is already registered.
650 $contribution = self
::processContribution($this, $value, $result, $contactID, $pending, $isAdditionalAmount);
651 $value['contributionID'] = $contribution->id
;
652 $value['contributionTypeID'] = $contribution->financial_type_id
;
653 $value['receive_date'] = $contribution->receive_date
;
654 $value['trxn_id'] = $contribution->trxn_id
;
655 $value['contributionID'] = $contribution->id
;
656 $value['contributionTypeID'] = $contribution->financial_type_id
;
658 $value['contactID'] = $contactID;
659 $value['eventID'] = $this->_eventId
;
660 $value['item_name'] = $value['description'];
663 if (!empty($value['contributionID'])) {
664 $this->_values
['contributionId'] = $value['contributionID'];
668 if (!empty($value['is_primary'])) {
669 $primaryCurrencyID = CRM_Utils_Array
::value('currencyID', $value);
671 if (empty($value['currencyID'])) {
672 $value['currencyID'] = $primaryCurrencyID;
675 // CRM-11182 - Confirmation page might not be monetary
676 if ($this->_values
['event']['is_monetary']) {
677 if (!$pending && !empty($value['is_primary']) &&
678 !$this->_allowWaitlist
&& !$this->_requireApproval
680 // transactionID & receive date required while building email template
681 $this->assign('trxn_id', $value['trxn_id']);
682 $this->assign('receive_date', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
683 $this->set('receiveDate', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
684 $this->set('trxnId', CRM_Utils_Array
::value('trxn_id', $value));
688 $value['fee_amount'] = CRM_Utils_Array
::value('amount', $value);
689 $this->set('value', $value);
691 // handle register date CRM-4320
692 if ($this->_allowConfirmation
) {
693 $registerDate = CRM_Utils_Array
::value('participant_register_date', $params);
695 elseif (!empty($params['participant_register_date']) &&
696 is_array($params['participant_register_date']) &&
697 !empty($params['participant_register_date'])
699 $registerDate = CRM_Utils_Date
::format($params['participant_register_date']);
702 $registerDate = date('YmdHis');
704 $this->assign('register_date', $registerDate);
706 $this->confirmPostProcess($contactID, $contribution, $payment);
709 //handle if no additional participant.
710 if (!$registerByID) {
711 $registerByID = $this->get('registerByID');
714 $this->set('participantIDs', $this->_participantIDS
);
716 // create line items, CRM-5313
717 if ($this->_priceSetId
&&
718 !empty($this->_lineItem
)
720 // take all processed participant ids.
721 $allParticipantIds = $this->_participantIDS
;
723 // when participant re-walk wizard.
724 if ($this->_allowConfirmation
&&
725 !empty($this->_additionalParticipantIds
)
727 $allParticipantIds = array_merge(array($registerByID), $this->_additionalParticipantIds
);
730 $entityTable = 'civicrm_participant';
731 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
, 'contribution_invoice_settings');
732 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
734 $dataArray = array();
735 foreach ($this->_lineItem
as $key => $value) {
736 if (($value != 'skip') &&
737 ($entityId = CRM_Utils_Array
::value($key, $allParticipantIds))
740 // do cleanup line items if participant re-walking wizard.
741 if ($this->_allowConfirmation
) {
742 CRM_Price_BAO_LineItem
::deleteLineItems($entityId, $entityTable);
744 $lineItem[$this->_priceSetId
] = $value;
745 CRM_Price_BAO_LineItem
::processPriceSet($entityId, $lineItem, $contribution, $entityTable);
748 foreach ($value as $line) {
749 if (isset($line['tax_amount']) && isset($line['tax_rate'])) {
750 $totalTaxAmount = $line['tax_amount'] +
$totalTaxAmount;
751 if (isset($dataArray[$line['tax_rate']])) {
752 $dataArray[$line['tax_rate']] = $dataArray[$line['tax_rate']] + CRM_Utils_Array
::value('tax_amount', $line);
755 $dataArray[$line['tax_rate']] = CRM_Utils_Array
::value('tax_amount', $line);
762 $this->assign('dataArray', $dataArray);
763 $this->assign('totalTaxAmount', $totalTaxAmount);
767 //update status and send mail to cancelled additonal participants, CRM-4320
768 if ($this->_allowConfirmation
&& is_array($cancelledIds) && !empty($cancelledIds)) {
769 $cancelledId = array_search('Cancelled',
770 CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'")
772 CRM_Event_BAO_Participant
::transitionParticipants($cancelledIds, $cancelledId);
776 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
780 // for Transfer checkout.
781 if (($this->_contributeMode
== 'checkout' ||
782 $this->_contributeMode
== 'notify'
783 ) && empty($params[0]['is_pay_later']) &&
784 !$this->_allowWaitlist
&& !$this->_requireApproval
&&
785 $this->_totalAmount
> 0
788 $primaryParticipant = $this->get('primaryParticipant');
790 if (empty($primaryParticipant['participantID'])) {
791 $primaryParticipant['participantID'] = $registerByID;
794 //build an array of custom profile and assigning it to template
795 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, $this->_values
, NULL, $isTest);
796 if (count($customProfile)) {
797 $this->assign('customProfile', $customProfile);
798 $this->set('customProfile', $customProfile);
801 // do a transfer only if a monetary payment greater than 0
802 if ($this->_values
['event']['is_monetary'] && $primaryParticipant) {
803 if ($payment && is_object($payment)) {
804 //CRM 14512 provide line items of all participants to payment gateway
805 $primaryContactId = $this->get('primaryContactId');
807 //build an array of cId/pId of participants
808 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, NULL, $primaryContactId, $isTest, TRUE);
810 //need to copy, since we are unsetting on the way.
811 $copyParticipantCountLines = $participantCount;
813 //lets carry all participant params w/ values.
814 foreach ($additionalIDs as $participantID => $contactId) {
815 $participantNum = NULL;
816 $participantNum = $participantID;
817 if ($participantID == $registerByID) {
818 $participantNum = 0; // is primary particpant
821 if ($participantNum = array_search('participant', $copyParticipantCountLines)) {
822 //if no participant found break.
823 if ($participantNum === NULL) {
826 //unset current particpant so we don't check them again
827 unset($copyParticipantCountLines[$participantNum]);
830 // get values of line items
831 if ($this->_amount
) {
833 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
834 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
835 $params[$participantNum]['amounts'] = $amount;
838 if (!empty($this->_lineItem
)) {
839 $lineItems = $this->_lineItem
;
841 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
842 $lineItem[] = $lineItemValue;
844 $params[$participantNum]['lineItem'] = $lineItem;
847 //only add additional particpants and not the primary particpant as we already have that
848 //added to $primaryParticipant so that this change doesn't break or require changes to
849 //existing gateway implementations
850 $primaryParticipant['participants_info'][$participantID] = $params[$participantNum];
853 //get event custom field information
854 $groupTree = CRM_Core_BAO_CustomGroup
::getTree('Event', $this, $this->_eventId
, 0, $this->_values
['event']['event_type_id']);
855 $primaryParticipant['eventCustomFields'] = $groupTree;
857 // call postprocess hook before leaving
858 $this->postProcessHook();
859 // this does not return
860 $payment->doTransferCheckout($primaryParticipant, 'event');
863 CRM_Core_Error
::fatal($paymentObjError);
868 //otherwise send mail Confirmation/Receipt
869 $primaryContactId = $this->get('primaryContactId');
871 //build an array of cId/pId of participants
872 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID,
873 NULL, $primaryContactId, $isTest,
876 //lets send mails to all with meaningful text, CRM-4320.
877 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
878 $this->assign('isRequireApproval', $this->_requireApproval
);
880 //need to copy, since we are unsetting on the way.
881 $copyParticipantCount = $participantCount;
883 //lets carry all paticipant params w/ values.
884 foreach ($additionalIDs as $participantID => $contactId) {
885 $participantNum = NULL;
886 if ($participantID == $registerByID) {
890 if ($participantNum = array_search('participant', $copyParticipantCount)) {
891 unset($copyParticipantCount[$participantNum]);
894 if ($participantNum === NULL) {
898 //carry the participant submitted values.
899 $this->_values
['params'][$participantID] = $params[$participantNum];
902 foreach ($additionalIDs as $participantID => $contactId) {
904 if ($participantID == $registerByID) {
905 //set as Primary Participant
906 $this->assign('isPrimary', 1);
907 //build an array of custom profile and assigning it to template.
908 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($participantID, $this->_values
, NULL, $isTest);
910 if (count($customProfile)) {
911 $this->assign('customProfile', $customProfile);
912 $this->set('customProfile', $customProfile);
914 $this->_values
['params']['additionalParticipant'] = FALSE;
917 //take the Additional participant number.
918 if ($participantNum = array_search('participant', $participantCount)) {
919 unset($participantCount[$participantNum]);
921 $this->assign('isPrimary', 0);
922 $this->assign('customProfile', NULL);
923 //Additional Participant should get only it's payment information
924 if (!empty($this->_amount
)) {
926 $params = $this->get('params');
927 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
928 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
929 $this->assign('amounts', $amount);
931 if ($this->_lineItem
) {
932 $lineItems = $this->_lineItem
;
934 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
935 $lineItem[] = $lineItemValue;
937 $this->assign('lineItem', $lineItem);
939 $this->_values
['params']['additionalParticipant'] = TRUE;
940 $this->assign('isAdditionalParticipant', $this->_values
['params']['additionalParticipant']);
943 //pass these variables since these are run time calculated.
944 $this->_values
['params']['isOnWaitlist'] = $this->_allowWaitlist
;
945 $this->_values
['params']['isRequireApproval'] = $this->_requireApproval
;
947 //send mail to primary as well as additional participants.
948 $this->assign('contactID', $contactId);
949 $this->assign('participantID', $participantID);
950 CRM_Event_BAO_Event
::sendMail($contactId, $this->_values
, $participantID, $isTest);
956 * Process the contribution.
958 * @param CRM_Core_Form $form
959 * @param array $params
961 * @param int $contactID
962 * @param bool $pending
963 * @param bool $isAdditionalAmount
967 public static function processContribution(
968 &$form, $params, $result, $contactID,
969 $pending = FALSE, $isAdditionalAmount = FALSE
971 $transaction = new CRM_Core_Transaction();
973 $now = date('YmdHis');
976 if (!empty($form->_values
['event']['is_email_confirm'])) {
980 if ($isAdditionalAmount) {
981 $params['amount_level'] = $params['amount_level'] . ts(' (multiple participants)') . CRM_Core_DAO
::VALUE_SEPARATOR
;
984 $contribParams = array(
985 'contact_id' => $contactID,
986 'financial_type_id' => !empty($form->_values
['event']['financial_type_id']) ?
$form->_values
['event']['financial_type_id'] : $params['financial_type_id'],
987 'receive_date' => $now,
988 'total_amount' => $params['amount'],
989 'tax_amount' => $params['tax_amount'],
990 'amount_level' => $params['amount_level'],
991 'invoice_id' => $params['invoiceID'],
992 'currency' => $params['currencyID'],
993 'source' => !empty($params['participant_source']) ?
$params['participant_source'] : $params['description'],
994 'is_pay_later' => CRM_Utils_Array
::value('is_pay_later', $params, 0),
995 'campaign_id' => CRM_Utils_Array
::value('campaign_id', $params),
998 if (empty($params['is_pay_later'])) {
999 $contribParams['payment_instrument_id'] = 1;
1002 if (!$pending && $result) {
1003 $contribParams +
= array(
1004 'fee_amount' => CRM_Utils_Array
::value('fee_amount', $result),
1005 'net_amount' => CRM_Utils_Array
::value('net_amount', $result, $params['amount']),
1006 'trxn_id' => $result['trxn_id'],
1007 'receipt_date' => $receiptDate,
1011 $allStatuses = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
1012 $contribParams['contribution_status_id'] = array_search('Completed', $allStatuses);
1014 $contribParams['contribution_status_id'] = array_search('Pending', $allStatuses);
1017 $contribParams['is_test'] = 0;
1018 if ($form->_action
& CRM_Core_Action
::PREVIEW || CRM_Utils_Array
::value('mode', $params) == 'test') {
1019 $contribParams['is_test'] = 1;
1023 if (!empty($contribParams['invoice_id'])) {
1024 $contribID = CRM_Core_DAO
::getFieldValue('CRM_Contribute_DAO_Contribution',
1025 $contribParams['invoice_id'],
1033 $ids['contribution'] = $contribID;
1034 $contribParams['id'] = $contribID;
1037 //create an contribution address
1038 if ($form->_contributeMode
!= 'notify' && empty($params['is_pay_later'])) {
1039 $contribParams['address_id'] = CRM_Contribute_BAO_Contribution
::createAddress($params, $form->_bltID
);
1042 // Prepare soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin.
1043 if (!empty($params['pcp_made_through_id']) ||
!empty($params['soft_credit_to'])) {
1045 // if its due to pcp
1046 if (!empty($params['pcp_made_through_id'])) {
1047 $contribSoftContactId = CRM_Core_DAO
::getFieldValue('CRM_PCP_DAO_PCP',
1048 $params['pcp_made_through_id'],
1053 $contribSoftContactId = CRM_Utils_Array
::value('soft_credit_to', $params);
1056 // Pass these details onto with the contribution to make them
1057 // available at hook_post_process, CRM-8908
1058 $contribParams['soft_credit_to'] = $params['soft_credit_to'] = $contribSoftContactId;
1060 $contribParams['payment_processor'] = CRM_Utils_Array
::value('payment_processor', $params);
1061 $contribParams['skipLineItem'] = 1;
1062 // create contribution record
1063 $contribution = CRM_Contribute_BAO_Contribution
::add($contribParams, $ids);
1065 CRM_Event_BAO_Participant
::createDiscountTrxn($form->_eventId
, $contribParams, CRM_Utils_Array
::value('amount_priceset_level_radio', $params, NULL));
1067 // process soft credit / pcp pages
1068 CRM_Contribute_Form_Contribution_Confirm
::processPcpSoft($params, $contribution);
1070 $transaction->commit();
1072 return $contribution;
1076 * Fix the Location Fields.
1078 * @param array $params
1080 * @param CRM_Core_Form $form
1084 public static function fixLocationFields(&$params, &$fields, &$form) {
1085 if (!empty($form->_fields
)) {
1086 foreach ($form->_fields
as $name => $dontCare) {
1091 if (is_array($fields)) {
1092 if (!array_key_exists('first_name', $fields)) {
1093 $nameFields = array('first_name', 'middle_name', 'last_name');
1094 foreach ($nameFields as $name) {
1096 if (array_key_exists("billing_$name", $params)) {
1097 $params[$name] = $params["billing_{$name}"];
1098 $params['preserveDBName'] = TRUE;
1104 // also add location name to the array
1105 if ($form->_values
['event']['is_monetary']) {
1106 $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);
1107 $fields["address_name-{$form->_bltID}"] = 1;
1109 $fields["email-{$form->_bltID}"] = 1;
1110 $fields['email-Primary'] = 1;
1112 //if its pay later or additional participant set email address as primary.
1113 if ((!empty($params['is_pay_later']) ||
empty($params['is_primary']) ||
1114 !$form->_values
['event']['is_monetary'] ||
1115 $form->_allowWaitlist ||
1116 $form->_requireApproval
1117 ) && !empty($params["email-{$form->_bltID}"])
1119 $params['email-Primary'] = $params["email-{$form->_bltID}"];
1124 * Update contact fields.
1126 * @param int $contactID
1127 * @param array $params
1129 * @param CRM_Core_Form $form
1133 public static function updateContactFields($contactID, $params, $fields, &$form) {
1134 //add the contact to group, if add to group is selected for a
1135 //particular uf group
1137 // get the add to groups
1138 $addToGroups = array();
1140 if (!empty($form->_fields
)) {
1141 foreach ($form->_fields
as $key => $value) {
1142 if (!empty($value['add_to_group_id'])) {
1143 $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
1148 // check for profile double opt-in and get groups to be subscribed
1149 $subscribeGroupIds = CRM_Core_BAO_UFGroup
::getDoubleOptInGroupIds($params, $contactID);
1151 foreach ($addToGroups as $k) {
1152 if (array_key_exists($k, $subscribeGroupIds)) {
1153 unset($addToGroups[$k]);
1157 // since we are directly adding contact to group lets unset it from mailing
1158 if (!empty($addToGroups)) {
1159 foreach ($addToGroups as $groupId) {
1160 if (isset($subscribeGroupIds[$groupId])) {
1161 unset($subscribeGroupIds[$groupId]);
1166 $ctype = CRM_Core_DAO
::getFieldValue(
1167 'CRM_Contact_DAO_Contact',
1172 if (array_key_exists('contact_id', $params) && empty($params['contact_id'])) {
1173 // we unset this here because the downstream function ignores the contactID we give it
1174 // if it is set & it is difficult to understand the implications of 'fixing' this downstream
1175 // but if we are passing a contact id into this function it's reasonable to assume we don't
1177 unset($params['contact_id']);
1180 $contactID = CRM_Contact_BAO_Contact
::createProfileContact(
1192 foreach (CRM_Contact_BAO_Contact
::$_greetingTypes as $greeting) {
1193 if (!isset($params[$greeting . '_id'])) {
1194 $params[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils
::defaultGreeting('Individual', $greeting);
1198 $contactID = CRM_Contact_BAO_Contact
::createProfileContact($params,
1206 $form->set('contactID', $contactID);
1209 //get email primary first if exist
1210 $subscribtionEmail = array('email' => CRM_Utils_Array
::value('email-Primary', $params));
1211 if (!$subscribtionEmail['email']) {
1212 $subscribtionEmail['email'] = CRM_Utils_Array
::value("email-{$form->_bltID}", $params);
1214 // subscribing contact to groups
1215 if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
1216 CRM_Mailing_Event_BAO_Subscribe
::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
1225 public static function assignProfiles(&$form) {
1226 $participantParams = $form->_params
;
1227 $formattedValues = $profileFields = array();
1229 foreach ($participantParams as $participantNum => $participantValue) {
1230 if ($participantNum) {
1231 $prefix1 = 'additional';
1232 $prefix2 = 'additional_';
1238 if ($participantValue != 'skip') {
1239 //get the customPre profile info
1240 if (!empty($form->_values
[$prefix2 . 'custom_pre_id'])) {
1241 $values = $groupName = array();
1242 CRM_Event_BAO_Event
::displayProfile($participantValue,
1243 $form->_values
[$prefix2 . 'custom_pre_id'],
1249 if (count($values)) {
1250 $formattedValues[$count][$prefix1 . 'CustomPre'] = $values;
1252 $formattedValues[$count][$prefix1 . 'CustomPreGroupTitle'] = CRM_Utils_Array
::value('groupTitle', $groupName);
1254 //get the customPost profile info
1255 if (!empty($form->_values
[$prefix2 . 'custom_post_id'])) {
1256 $values = $groupName = array();
1257 foreach ($form->_values
[$prefix2 . 'custom_post_id'] as $gids) {
1259 CRM_Event_BAO_Event
::displayProfile($participantValue,
1265 $values[$gids] = $val;
1266 $groupName[$gids] = $group;
1269 if (count($values)) {
1270 $formattedValues[$count][$prefix1 . 'CustomPost'] = $values;
1273 if (isset($formattedValues[$count][$prefix1 . 'CustomPre'])) {
1274 $formattedValues[$count][$prefix1 . 'CustomPost'] = array_diff_assoc($formattedValues[$count][$prefix1 . 'CustomPost'],
1275 $formattedValues[$count][$prefix1 . 'CustomPre']
1279 $formattedValues[$count][$prefix1 . 'CustomPostGroupTitle'] = $groupName;
1283 $form->_fields
= $profileFields;
1285 if (!empty($formattedValues)) {
1286 $form->assign('primaryParticipantProfile', $formattedValues[1]);
1287 $form->set('primaryParticipantProfile', $formattedValues[1]);
1289 unset($formattedValues[1]);
1290 $form->assign('addParticipantProfile', $formattedValues);
1291 $form->set('addParticipantProfile', $formattedValues);