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);
396 public static function formRule($fields, $files, $self) {
398 $eventFull = CRM_Event_BAO_Participant
::eventFull($self->_eventId
, FALSE, CRM_Utils_Array
::value('has_waitlist', $self->_values
['event']));
399 if ($eventFull && empty($self->_allowConfirmation
)) {
400 if (empty($self->_allowWaitlist
)) {
401 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "reset=1&id={$self->_eventId}", FALSE, NULL, FALSE, TRUE));
404 $self->_feeBlock
= $self->_values
['fee'];
405 CRM_Event_Form_Registration_Register
::formatFieldsForOptionFull($self);
407 if (!empty($self->_priceSetId
)) {
408 $priceSetErrors = self
::validatePriceSet($self, $self->_params
);
409 //get price set fields errors in.
410 $errors = array_merge($errors, CRM_Utils_Array
::value(0, $priceSetErrors, array()));
413 if (!empty($errors)) {
414 $soldOutOptions = implode("<br/>", $priceSetErrors['soldOutOptions']);
415 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');
416 CRM_Core_Session
::setStatus(ts("{$soldOutOptions}"), ts('Sold out:'), 'error');
417 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "_qf_Register_display=true&qfKey=" . $fields['qfKey']));
419 return empty($errors) ?
TRUE : $errors;
423 * Process the form submission
428 public function postProcess() {
429 $now = date('YmdHis');
431 $this->_params
= $this->get('params');
432 if (!empty($this->_params
[0]['contact_id'])) {
433 // unclear when this would be set & whether it could be checked in getContactID.
434 // perhaps it relates to when cid is in the url
435 //@todo someone who knows add comments on the various contactIDs in this form
436 $contactID = $this->_params
[0]['contact_id'];
439 $contactID = $this->getContactID();
442 // if a discount has been applied, lets now deduct it from the amount
443 // and fix the fee level
444 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
445 foreach ($this->_params
as $k => $v) {
446 if (CRM_Utils_Array
::value('amount', $this->_params
[$k]) > 0 && !empty($this->_params
[$k]['discountAmount'])) {
447 $this->_params
[$k]['amount'] -= $this->_params
[$k]['discountAmount'];
448 $this->_params
[$k]['amount_level'] .= CRM_Utils_Array
::value('discountMessage', $this->_params
[$k]);
451 $this->set('params', $this->_params
);
454 // CRM-4320, lets build array of cancelled additional participant ids
455 // those are drop or skip by primary at the time of confirmation.
456 // get all in and then unset those we want to process.
457 $cancelledIds = $this->_additionalParticipantIds
;
459 $params = $this->_params
;
460 if ($this->_values
['event']['is_monetary']) {
461 $this->set('finalAmount', $this->_amount
);
463 $participantCount = array();
465 //unset the skip participant from params.
466 //build the $participantCount array.
467 //maintain record for all participants.
468 foreach ($params as $participantNum => $record) {
469 if ($record == 'skip') {
470 unset($params[$participantNum]);
471 $participantCount[$participantNum] = 'skip';
473 elseif ($participantNum) {
474 $participantCount[$participantNum] = 'participant';
477 //lets get additional participant id to cancel.
478 if ($this->_allowConfirmation
&& is_array($cancelledIds)) {
479 $additonalId = CRM_Utils_Array
::value('participant_id', $record);
480 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
481 unset($cancelledIds[$key]);
486 $payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
487 $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.');
489 $this->participantIDS
= array();
491 foreach ($params as $key => $value) {
492 CRM_Event_Form_Registration_Confirm
::fixLocationFields($value, $fields, $this);
493 //unset the billing parameters if it is pay later mode
494 //to avoid creation of billing location
495 if ($this->_allowWaitlist
496 ||
$this->_requireApproval
497 ||
(!empty($value['is_pay_later']) && !$this->_isBillingAddressRequiredForPayLater
)
498 ||
empty($value['is_primary'])
500 $billingFields = array(
501 "email-{$this->_bltID}",
502 'billing_first_name',
503 'billing_middle_name',
505 "billing_street_address-{$this->_bltID}",
506 "billing_city-{$this->_bltID}",
507 "billing_state_province-{$this->_bltID}",
508 "billing_state_province_id-{$this->_bltID}",
509 "billing_postal_code-{$this->_bltID}",
510 "billing_country-{$this->_bltID}",
511 "billing_country_id-{$this->_bltID}",
512 "address_name-{$this->_bltID}",
514 foreach ($billingFields as $field) {
515 unset($value[$field]);
517 if (!empty($value['is_pay_later'])) {
518 $this->_values
['params']['is_pay_later'] = TRUE;
522 //Unset ContactID for additional participants and set RegisterBy Id.
523 if (empty($value['is_primary'])) {
524 $contactID = CRM_Utils_Array
::value('contact_id', $value);
525 $registerByID = $this->get('registerByID');
527 $value['registered_by_id'] = $registerByID;
531 $value['amount'] = $this->_totalAmount
;
534 $contactID = CRM_Event_Form_Registration_Confirm
::updateContactFields($contactID, $value, $fields, $this);
536 // lets store the contactID in the session
537 // we dont store in userID in case the user is doing multiple
539 // for things like tell a friend
540 if (!$this->getContactID() && !empty($value['is_primary'])) {
541 $session = CRM_Core_Session
::singleton();
542 $session->set('transaction.userID', $contactID);
545 $value['description'] = ts('Online Event Registration') . ': ' . $this->_values
['event']['title'];
546 $value['accountingCode'] = CRM_Utils_Array
::value('accountingCode',
547 $this->_values
['event']
550 // required only if paid event
551 if ($this->_values
['event']['is_monetary']) {
552 if (is_array($this->_paymentProcessor
)) {
553 $payment = CRM_Core_Payment
::singleton($this->_mode
, $this->_paymentProcessor
, $this);
558 if ($this->_allowWaitlist ||
$this->_requireApproval
) {
559 //get the participant statuses.
560 $waitingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Waiting'");
561 if ($this->_allowWaitlist
) {
562 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
565 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
568 //there might be case user seleted pay later and
569 //now becomes part of run time waiting list.
570 $value['is_pay_later'] = FALSE;
572 elseif (!empty($value['is_pay_later']) ||
573 $value['amount'] == 0 ||
574 $this->_contributeMode
== 'checkout' ||
575 $this->_contributeMode
== 'notify'
577 if ($value['amount'] != 0) {
579 //get the participant statuses.
580 $pendingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Pending'");
581 $status = !empty($value['is_pay_later']) ?
'Pending from pay later' : 'Pending from incomplete transaction';
582 $value['participant_status_id'] = $value['participant_status'] = array_search($status, $pendingStatuses);
585 elseif ($this->_contributeMode
== 'express' && !empty($value['is_primary'])) {
586 if (is_object($payment)) {
587 $result = $payment->doExpressCheckout($value);
590 CRM_Core_Error
::fatal($paymentObjError);
593 elseif (!empty($value['is_primary'])) {
594 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $value, $value, TRUE);
595 // payment email param can be empty for _bltID mapping
596 // thus provide mapping for it with a different email value
597 if (empty($value['email'])) {
598 $value['email'] = CRM_Utils_Array
::valueByRegexKey('/^email-/', $value);
601 if (is_object($payment)) {
602 $result = $payment->doDirectPayment($value);
605 CRM_Core_Error
::fatal($paymentObjError);
609 if (is_a($result, 'CRM_Core_Error')) {
610 CRM_Core_Error
::displaySessionError($result);
611 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "id={$this->_eventId}"));
615 $value = array_merge($value, $result);
618 $value['receive_date'] = $now;
619 if ($this->_allowConfirmation
) {
620 $value['participant_register_date'] = $this->_values
['participant']['register_date'];
623 $createContrib = ($value['amount'] != 0) ?
TRUE : FALSE;
624 // force to create zero amount contribution, CRM-5095
625 if (!$createContrib && ($value['amount'] == 0)
626 && $this->_priceSetId
&& $this->_lineItem
628 $createContrib = TRUE;
631 if ($createContrib && !empty($value['is_primary']) &&
632 !$this->_allowWaitlist
&& !$this->_requireApproval
634 // if paid event add a contribution record
635 //if primary participant contributing additional amount
636 //append (multiple participants) to its fee level. CRM-4196.
637 $isAdditionalAmount = FALSE;
638 if (count($params) > 1) {
639 $isAdditionalAmount = TRUE;
642 //passing contribution id is already registered.
643 $contribution = self
::processContribution($this, $value, $result, $contactID, $pending, $isAdditionalAmount);
644 $value['contributionID'] = $contribution->id
;
645 $value['contributionTypeID'] = $contribution->financial_type_id
;
646 $value['receive_date'] = $contribution->receive_date
;
647 $value['trxn_id'] = $contribution->trxn_id
;
648 $value['contributionID'] = $contribution->id
;
649 $value['contributionTypeID'] = $contribution->financial_type_id
;
651 $value['contactID'] = $contactID;
652 $value['eventID'] = $this->_eventId
;
653 $value['item_name'] = $value['description'];
656 if (!empty($value['contributionID'])) {
657 $this->_values
['contributionId'] = $value['contributionID'];
661 if (!empty($value['is_primary'])) {
662 $primaryCurrencyID = CRM_Utils_Array
::value('currencyID', $value);
664 if (empty($value['currencyID'])) {
665 $value['currencyID'] = $primaryCurrencyID;
668 // CRM-11182 - Confirmation page might not be monetary
669 if ($this->_values
['event']['is_monetary']) {
670 if (!$pending && !empty($value['is_primary']) &&
671 !$this->_allowWaitlist
&& !$this->_requireApproval
673 // transactionID & receive date required while building email template
674 $this->assign('trxn_id', $value['trxn_id']);
675 $this->assign('receive_date', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
676 $this->set('receiveDate', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
677 $this->set('trxnId', CRM_Utils_Array
::value('trxn_id', $value));
681 $value['fee_amount'] = CRM_Utils_Array
::value('amount', $value);
682 $this->set('value', $value);
684 // handle register date CRM-4320
685 if ($this->_allowConfirmation
) {
686 $registerDate = CRM_Utils_Array
::value('participant_register_date', $params);
688 elseif (!empty($params['participant_register_date']) &&
689 is_array($params['participant_register_date']) &&
690 !empty($params['participant_register_date'])
692 $registerDate = CRM_Utils_Date
::format($params['participant_register_date']);
695 $registerDate = date('YmdHis');
697 $this->assign('register_date', $registerDate);
699 $this->confirmPostProcess($contactID, $contribution, $payment);
702 //handle if no additional participant.
703 if (!$registerByID) {
704 $registerByID = $this->get('registerByID');
707 $this->set('participantIDs', $this->_participantIDS
);
709 // create line items, CRM-5313
710 if ($this->_priceSetId
&&
711 !empty($this->_lineItem
)
713 // take all processed participant ids.
714 $allParticipantIds = $this->_participantIDS
;
716 // when participant re-walk wizard.
717 if ($this->_allowConfirmation
&&
718 !empty($this->_additionalParticipantIds
)
720 $allParticipantIds = array_merge(array($registerByID), $this->_additionalParticipantIds
);
723 $entityTable = 'civicrm_participant';
724 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
, 'contribution_invoice_settings');
725 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
727 $dataArray = array();
728 foreach ($this->_lineItem
as $key => $value) {
729 if (($value != 'skip') &&
730 ($entityId = CRM_Utils_Array
::value($key, $allParticipantIds))
733 // do cleanup line items if participant re-walking wizard.
734 if ($this->_allowConfirmation
) {
735 CRM_Price_BAO_LineItem
::deleteLineItems($entityId, $entityTable);
737 $lineItem[$this->_priceSetId
] = $value;
738 CRM_Price_BAO_LineItem
::processPriceSet($entityId, $lineItem, $contribution, $entityTable);
741 foreach ($value as $line) {
742 if (isset($line['tax_amount']) && isset($line['tax_rate'])) {
743 $totalTaxAmount = $line['tax_amount'] +
$totalTaxAmount;
744 if (isset($dataArray[$line['tax_rate']])) {
745 $dataArray[$line['tax_rate']] = $dataArray[$line['tax_rate']] + CRM_Utils_Array
::value('tax_amount', $line);
748 $dataArray[$line['tax_rate']] = CRM_Utils_Array
::value('tax_amount', $line);
755 $this->assign('dataArray', $dataArray);
756 $this->assign('totalTaxAmount', $totalTaxAmount);
760 //update status and send mail to cancelled additonal participants, CRM-4320
761 if ($this->_allowConfirmation
&& is_array($cancelledIds) && !empty($cancelledIds)) {
762 $cancelledId = array_search('Cancelled',
763 CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'")
765 CRM_Event_BAO_Participant
::transitionParticipants($cancelledIds, $cancelledId);
769 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
773 // for Transfer checkout.
774 if (($this->_contributeMode
== 'checkout' ||
775 $this->_contributeMode
== 'notify'
776 ) && empty($params[0]['is_pay_later']) &&
777 !$this->_allowWaitlist
&& !$this->_requireApproval
&&
778 $this->_totalAmount
> 0
781 $primaryParticipant = $this->get('primaryParticipant');
783 if (empty($primaryParticipant['participantID'])) {
784 $primaryParticipant['participantID'] = $registerByID;
787 //build an array of custom profile and assigning it to template
788 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, $this->_values
, NULL, $isTest);
789 if (count($customProfile)) {
790 $this->assign('customProfile', $customProfile);
791 $this->set('customProfile', $customProfile);
794 // do a transfer only if a monetary payment greater than 0
795 if ($this->_values
['event']['is_monetary'] && $primaryParticipant) {
796 if ($payment && is_object($payment)) {
797 //CRM 14512 provide line items of all participants to payment gateway
798 $primaryContactId = $this->get('primaryContactId');
800 //build an array of cId/pId of participants
801 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, NULL, $primaryContactId, $isTest, TRUE);
803 //need to copy, since we are unsetting on the way.
804 $copyParticipantCountLines = $participantCount;
806 //lets carry all participant params w/ values.
807 foreach ($additionalIDs as $participantID => $contactId) {
808 $participantNum = NULL;
809 $participantNum = $participantID;
810 if ($participantID == $registerByID) {
811 $participantNum = 0; // is primary particpant
814 if ($participantNum = array_search('participant', $copyParticipantCountLines)) {
815 //if no participant found break.
816 if ($participantNum === NULL) {
819 //unset current particpant so we don't check them again
820 unset($copyParticipantCountLines[$participantNum]);
823 // get values of line items
824 if ($this->_amount
) {
826 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
827 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
828 $params[$participantNum]['amounts'] = $amount;
831 if (!empty($this->_lineItem
)) {
832 $lineItems = $this->_lineItem
;
834 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
835 $lineItem[] = $lineItemValue;
837 $params[$participantNum]['lineItem'] = $lineItem;
840 //only add additional particpants and not the primary particpant as we already have that
841 //added to $primaryParticipant so that this change doesn't break or require changes to
842 //existing gateway implementations
843 $primaryParticipant['participants_info'][$participantID] = $params[$participantNum];
846 //get event custom field information
847 $groupTree = CRM_Core_BAO_CustomGroup
::getTree('Event', $this, $this->_eventId
, 0, $this->_values
['event']['event_type_id']);
848 $primaryParticipant['eventCustomFields'] = $groupTree;
850 // call postprocess hook before leaving
851 $this->postProcessHook();
852 // this does not return
853 $payment->doTransferCheckout($primaryParticipant, 'event');
856 CRM_Core_Error
::fatal($paymentObjError);
861 //otherwise send mail Confirmation/Receipt
862 $primaryContactId = $this->get('primaryContactId');
864 //build an array of cId/pId of participants
865 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID,
866 NULL, $primaryContactId, $isTest,
869 //lets send mails to all with meaningful text, CRM-4320.
870 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
871 $this->assign('isRequireApproval', $this->_requireApproval
);
873 //need to copy, since we are unsetting on the way.
874 $copyParticipantCount = $participantCount;
876 //lets carry all paticipant params w/ values.
877 foreach ($additionalIDs as $participantID => $contactId) {
878 $participantNum = NULL;
879 if ($participantID == $registerByID) {
883 if ($participantNum = array_search('participant', $copyParticipantCount)) {
884 unset($copyParticipantCount[$participantNum]);
887 if ($participantNum === NULL) {
891 //carry the participant submitted values.
892 $this->_values
['params'][$participantID] = $params[$participantNum];
895 foreach ($additionalIDs as $participantID => $contactId) {
897 if ($participantID == $registerByID) {
898 //set as Primary Participant
899 $this->assign('isPrimary', 1);
900 //build an array of custom profile and assigning it to template.
901 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($participantID, $this->_values
, NULL, $isTest);
903 if (count($customProfile)) {
904 $this->assign('customProfile', $customProfile);
905 $this->set('customProfile', $customProfile);
907 $this->_values
['params']['additionalParticipant'] = FALSE;
910 //take the Additional participant number.
911 if ($participantNum = array_search('participant', $participantCount)) {
912 unset($participantCount[$participantNum]);
914 $this->assign('isPrimary', 0);
915 $this->assign('customProfile', NULL);
916 //Additional Participant should get only it's payment information
917 if (!empty($this->_amount
)) {
919 $params = $this->get('params');
920 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
921 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
922 $this->assign('amounts', $amount);
924 if ($this->_lineItem
) {
925 $lineItems = $this->_lineItem
;
927 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
928 $lineItem[] = $lineItemValue;
930 $this->assign('lineItem', $lineItem);
932 $this->_values
['params']['additionalParticipant'] = TRUE;
933 $this->assign('isAdditionalParticipant', $this->_values
['params']['additionalParticipant']);
936 //pass these variables since these are run time calculated.
937 $this->_values
['params']['isOnWaitlist'] = $this->_allowWaitlist
;
938 $this->_values
['params']['isRequireApproval'] = $this->_requireApproval
;
940 //send mail to primary as well as additional participants.
941 $this->assign('contactID', $contactId);
942 $this->assign('participantID', $participantID);
943 CRM_Event_BAO_Event
::sendMail($contactId, $this->_values
, $participantID, $isTest);
949 * Process the contribution
951 * @param CRM_Core_Form $form
952 * @param array $params
954 * @param int $contactID
955 * @param bool $pending
956 * @param bool $isAdditionalAmount
960 public static function processContribution(
961 &$form, $params, $result, $contactID,
962 $pending = FALSE, $isAdditionalAmount = FALSE
964 $transaction = new CRM_Core_Transaction();
966 $now = date('YmdHis');
969 if (!empty($form->_values
['event']['is_email_confirm'])) {
973 if ($isAdditionalAmount) {
974 $params['amount_level'] = $params['amount_level'] . ts(' (multiple participants)') . CRM_Core_DAO
::VALUE_SEPARATOR
;
977 $contribParams = array(
978 'contact_id' => $contactID,
979 'financial_type_id' => !empty($form->_values
['event']['financial_type_id']) ?
$form->_values
['event']['financial_type_id'] : $params['financial_type_id'],
980 'receive_date' => $now,
981 'total_amount' => $params['amount'],
982 'tax_amount' => $params['tax_amount'],
983 'amount_level' => $params['amount_level'],
984 'invoice_id' => $params['invoiceID'],
985 'currency' => $params['currencyID'],
986 'source' => !empty($params['participant_source']) ?
$params['participant_source'] : $params['description'],
987 'is_pay_later' => CRM_Utils_Array
::value('is_pay_later', $params, 0),
988 'campaign_id' => CRM_Utils_Array
::value('campaign_id', $params),
991 if (empty($params['is_pay_later'])) {
992 $contribParams['payment_instrument_id'] = 1;
995 if (!$pending && $result) {
996 $contribParams +
= array(
997 'fee_amount' => CRM_Utils_Array
::value('fee_amount', $result),
998 'net_amount' => CRM_Utils_Array
::value('net_amount', $result, $params['amount']),
999 'trxn_id' => $result['trxn_id'],
1000 'receipt_date' => $receiptDate,
1004 $allStatuses = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
1005 $contribParams['contribution_status_id'] = array_search('Completed', $allStatuses);
1007 $contribParams['contribution_status_id'] = array_search('Pending', $allStatuses);
1010 $contribParams['is_test'] = 0;
1011 if ($form->_action
& CRM_Core_Action
::PREVIEW || CRM_Utils_Array
::value('mode', $params) == 'test') {
1012 $contribParams['is_test'] = 1;
1016 if (!empty($contribParams['invoice_id'])) {
1017 $contribID = CRM_Core_DAO
::getFieldValue('CRM_Contribute_DAO_Contribution',
1018 $contribParams['invoice_id'],
1026 $ids['contribution'] = $contribID;
1027 $contribParams['id'] = $contribID;
1030 //create an contribution address
1031 if ($form->_contributeMode
!= 'notify' && empty($params['is_pay_later'])) {
1032 $contribParams['address_id'] = CRM_Contribute_BAO_Contribution
::createAddress($params, $form->_bltID
);
1035 // Prepare soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin.
1036 if (!empty($params['pcp_made_through_id']) ||
!empty($params['soft_credit_to'])) {
1038 // if its due to pcp
1039 if (!empty($params['pcp_made_through_id'])) {
1040 $contribSoftContactId = CRM_Core_DAO
::getFieldValue('CRM_PCP_DAO_PCP',
1041 $params['pcp_made_through_id'],
1046 $contribSoftContactId = CRM_Utils_Array
::value('soft_credit_to', $params);
1049 // Pass these details onto with the contribution to make them
1050 // available at hook_post_process, CRM-8908
1051 $contribParams['soft_credit_to'] = $params['soft_credit_to'] = $contribSoftContactId;
1053 $contribParams['payment_processor'] = CRM_Utils_Array
::value('payment_processor', $params);
1054 $contribParams['skipLineItem'] = 1;
1055 // create contribution record
1056 $contribution = CRM_Contribute_BAO_Contribution
::add($contribParams, $ids);
1058 CRM_Event_BAO_Participant
::createDiscountTrxn($form->_eventId
, $contribParams, CRM_Utils_Array
::value('amount_priceset_level_radio', $params, NULL));
1060 // process soft credit / pcp pages
1061 CRM_Contribute_Form_Contribution_Confirm
::processPcpSoft($params, $contribution);
1063 $transaction->commit();
1065 return $contribution;
1069 * Fix the Location Fields
1071 * @param array $params
1073 * @param CRM_Core_Form $form
1077 public static function fixLocationFields(&$params, &$fields, &$form) {
1078 if (!empty($form->_fields
)) {
1079 foreach ($form->_fields
as $name => $dontCare) {
1084 if (is_array($fields)) {
1085 if (!array_key_exists('first_name', $fields)) {
1086 $nameFields = array('first_name', 'middle_name', 'last_name');
1087 foreach ($nameFields as $name) {
1089 if (array_key_exists("billing_$name", $params)) {
1090 $params[$name] = $params["billing_{$name}"];
1091 $params['preserveDBName'] = TRUE;
1097 // also add location name to the array
1098 if ($form->_values
['event']['is_monetary']) {
1099 $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);
1100 $fields["address_name-{$form->_bltID}"] = 1;
1102 $fields["email-{$form->_bltID}"] = 1;
1103 $fields['email-Primary'] = 1;
1105 //if its pay later or additional participant set email address as primary.
1106 if ((!empty($params['is_pay_later']) ||
empty($params['is_primary']) ||
1107 !$form->_values
['event']['is_monetary'] ||
1108 $form->_allowWaitlist ||
1109 $form->_requireApproval
1110 ) && !empty($params["email-{$form->_bltID}"])
1112 $params['email-Primary'] = $params["email-{$form->_bltID}"];
1117 * Update contact fields
1119 * @param int $contactID
1120 * @param array $params
1122 * @param CRM_Core_Form $form
1126 public static function updateContactFields($contactID, $params, $fields, &$form) {
1127 //add the contact to group, if add to group is selected for a
1128 //particular uf group
1130 // get the add to groups
1131 $addToGroups = array();
1133 if (!empty($form->_fields
)) {
1134 foreach ($form->_fields
as $key => $value) {
1135 if (!empty($value['add_to_group_id'])) {
1136 $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
1141 // check for profile double opt-in and get groups to be subscribed
1142 $subscribeGroupIds = CRM_Core_BAO_UFGroup
::getDoubleOptInGroupIds($params, $contactID);
1144 foreach ($addToGroups as $k) {
1145 if (array_key_exists($k, $subscribeGroupIds)) {
1146 unset($addToGroups[$k]);
1150 // since we are directly adding contact to group lets unset it from mailing
1151 if (!empty($addToGroups)) {
1152 foreach ($addToGroups as $groupId) {
1153 if (isset($subscribeGroupIds[$groupId])) {
1154 unset($subscribeGroupIds[$groupId]);
1159 $ctype = CRM_Core_DAO
::getFieldValue(
1160 'CRM_Contact_DAO_Contact',
1165 if (array_key_exists('contact_id', $params) && empty($params['contact_id'])) {
1166 // we unset this here because the downstream function ignores the contactID we give it
1167 // if it is set & it is difficult to understand the implications of 'fixing' this downstream
1168 // but if we are passing a contact id into this function it's reasonable to assume we don't
1170 unset($params['contact_id']);
1173 $contactID = CRM_Contact_BAO_Contact
::createProfileContact(
1185 foreach (CRM_Contact_BAO_Contact
::$_greetingTypes as $greeting) {
1186 if (!isset($params[$greeting . '_id'])) {
1187 $params[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils
::defaultGreeting('Individual', $greeting);
1191 $contactID = CRM_Contact_BAO_Contact
::createProfileContact($params,
1199 $form->set('contactID', $contactID);
1202 //get email primary first if exist
1203 $subscribtionEmail = array('email' => CRM_Utils_Array
::value('email-Primary', $params));
1204 if (!$subscribtionEmail['email']) {
1205 $subscribtionEmail['email'] = CRM_Utils_Array
::value("email-{$form->_bltID}", $params);
1207 // subscribing contact to groups
1208 if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
1209 CRM_Mailing_Event_BAO_Subscribe
::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
1218 public static function assignProfiles(&$form) {
1219 $participantParams = $form->_params
;
1220 $formattedValues = $profileFields = array();
1222 foreach ($participantParams as $participantNum => $participantValue) {
1223 if ($participantNum) {
1224 $prefix1 = 'additional';
1225 $prefix2 = 'additional_';
1231 if ($participantValue != 'skip') {
1232 //get the customPre profile info
1233 if (!empty($form->_values
[$prefix2 . 'custom_pre_id'])) {
1234 $values = $groupName = array();
1235 CRM_Event_BAO_Event
::displayProfile($participantValue,
1236 $form->_values
[$prefix2 . 'custom_pre_id'],
1242 if (count($values)) {
1243 $formattedValues[$count][$prefix1 . 'CustomPre'] = $values;
1245 $formattedValues[$count][$prefix1 . 'CustomPreGroupTitle'] = CRM_Utils_Array
::value('groupTitle', $groupName);
1247 //get the customPost profile info
1248 if (!empty($form->_values
[$prefix2 . 'custom_post_id'])) {
1249 $values = $groupName = array();
1250 foreach ($form->_values
[$prefix2 . 'custom_post_id'] as $gids) {
1252 CRM_Event_BAO_Event
::displayProfile($participantValue,
1258 $values[$gids] = $val;
1259 $groupName[$gids] = $group;
1262 if (count($values)) {
1263 $formattedValues[$count][$prefix1 . 'CustomPost'] = $values;
1266 if (isset($formattedValues[$count][$prefix1 . 'CustomPre'])) {
1267 $formattedValues[$count][$prefix1 . 'CustomPost'] = array_diff_assoc($formattedValues[$count][$prefix1 . 'CustomPost'],
1268 $formattedValues[$count][$prefix1 . 'CustomPre']
1272 $formattedValues[$count][$prefix1 . 'CustomPostGroupTitle'] = $groupName;
1276 $form->_fields
= $profileFields;
1278 if (!empty($formattedValues)) {
1279 $form->assign('primaryParticipantProfile', $formattedValues[1]);
1280 $form->set('primaryParticipantProfile', $formattedValues[1]);
1282 unset($formattedValues[1]);
1283 $form->assign('addParticipantProfile', $formattedValues);
1284 $form->set('addParticipantProfile', $formattedValues);