Merge pull request #43 from pradpnayak/webtest
[civicrm-core.git] / CRM / Contribute / Form / Contribution / Main.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
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. |
13 | |
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. |
18 | |
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 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35
36/**
37 * This class generates form components for processing a ontribution
38 *
39 */
40class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_ContributionBase {
41
42 /**
43 *Define default MembershipType Id
44 *
45 */
46 public $_defaultMemTypeId;
47
48 public $_relatedOrganizationFound;
49
50 public $_onBehalfRequired = 0;
51 public $_onbehalf = 0;
52 public $_paymentProcessors;
53 protected $_defaults;
54
55 public $_membershipTypeValues;
56
57 public $_useForMember;
58
59 protected $_ppType;
60
61 /**
62 * Function to set variables up before form is built
63 *
64 * @return void
65 * @access public
66 */
67 public function preProcess() {
68 parent::preProcess();
69
70 $this->_ppType = CRM_Utils_Array::value('type', $_GET);
71 $this->assign('ppType', FALSE);
72 if ($this->_ppType) {
73 $this->assign('ppType', TRUE);
74 return CRM_Core_Payment_ProcessorForm::preProcess($this);
75 }
76
77 //get payPal express id and make it available to template
78 $paymentProcessors = $this->get('paymentProcessors');
79 if (!empty($paymentProcessors)) {
80 foreach ($paymentProcessors as $ppId => $values) {
81 $payPalExpressId = ($values['payment_processor_type'] == 'PayPal_Express') ? $values['id'] : 0;
82 $this->assign('payPalExpressId', $payPalExpressId);
83 if ($payPalExpressId) {
84 break;
85 }
86 }
87 }
88
89 // Make the contributionPageID avilable to the template
90 $this->assign('contributionPageID', $this->_id);
91 $this->assign('isShare', CRM_Utils_Array::value('is_share', $this->_values));
92 $this->assign('isConfirmEnabled', CRM_Utils_Array::value('is_confirm_enabled', $this->_values));
93
94 // make sure we have right permission to edit this user
95 $csContactID = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE, $this->_userID);
96 $reset = CRM_Utils_Request::retrieve('reset', 'Boolean', CRM_Core_DAO::$_nullObject);
97 $mainDisplay = CRM_Utils_Request::retrieve('_qf_Main_display', 'Boolean', CRM_Core_DAO::$_nullObject);
98
99 if ($csContactID != $this->_userID) {
100 if (CRM_Contact_BAO_Contact_Permission::validateChecksumContact($csContactID, $this)) {
101 $session = CRM_Core_Session::singleton();
102 $session->set('userID', $csContactID);
103 $this->_userID = $csContactID;
104 }
105 }
106
107 if ($reset) {
108 $this->assign('reset', $reset);
109 }
110
111 if ($mainDisplay) {
112 $this->assign('mainDisplay', $mainDisplay);
113 }
114
115 $this->_onbehalf = FALSE;
116 if (CRM_Utils_Array::value('is_for_organization', $this->_values)) {
117 $urlParams = "&id={$this->_id}&qfKey={$this->controller->_key}";
118 $this->assign('urlParams', $urlParams);
119 $this->_onbehalf = CRM_Utils_Array::value('onbehalf', $_GET);
120
121 CRM_Contribute_Form_Contribution_OnBehalfOf::preProcess($this);
122 if (CRM_Utils_Array::value('hidden_onbehalf_profile', $_POST) &&
123 (CRM_Utils_Array::value('is_for_organization', $_POST) ||
124 CRM_Utils_Array::value('is_for_organization', $this->_values) == 2
125 )
126 ) {
127 CRM_Contribute_Form_Contribution_OnBehalfOf::buildQuickForm($this);
128 }
129 }
130
131 if (CRM_Utils_Array::value('id', $this->_pcpInfo) &&
132 CRM_Utils_Array::value('intro_text', $this->_pcpInfo)
133 ) {
134 $this->assign('intro_text', $this->_pcpInfo['intro_text']);
135 }
136 elseif (CRM_Utils_Array::value('intro_text', $this->_values)) {
137 $this->assign('intro_text', $this->_values['intro_text']);
138 }
139
140 $qParams = "reset=1&amp;id={$this->_id}";
141 if ( $pcpId = CRM_Utils_Array::value( 'pcp_id', $this->_pcpInfo ) ) {
142 $qParams .= "&amp;pcpId={$pcpId}";
143 }
144 $this->assign( 'qParams' , $qParams );
145
146 if (CRM_Utils_Array::value('footer_text', $this->_values)) {
147 $this->assign('footer_text', $this->_values['footer_text']);
148 }
149
150 //CRM-5001
151 if (CRM_Utils_Array::value('is_for_organization', $this->_values)) {
152 $msg = ts('Mixed profile not allowed for on behalf of registration/sign up.');
153 if ($preID = CRM_Utils_Array::value('custom_pre_id', $this->_values)) {
154 $preProfile = CRM_Core_BAO_UFGroup::profileGroups($preID);
155 foreach (array(
156 'Individual', 'Organization', 'Household') as $contactType) {
157 if (in_array($contactType, $preProfile) &&
158 (in_array('Membership', $preProfile) ||
159 in_array('Contribution', $preProfile)
160 )
161 ) {
162 CRM_Core_Error::fatal($msg);
163 }
164 }
165 }
166
167 if ($postID = CRM_Utils_Array::value('custom_post_id', $this->_values)) {
168 $postProfile = CRM_Core_BAO_UFGroup::profileGroups($postID);
169 foreach (array(
170 'Individual', 'Organization', 'Household') as $contactType) {
171 if (in_array($contactType, $postProfile) &&
172 (in_array('Membership', $postProfile) ||
173 in_array('Contribution', $postProfile)
174 )
175 ) {
176 CRM_Core_Error::fatal($msg);
177 }
178 }
179 }
180 }
181
182 if (CRM_Utils_Array::value('hidden_processor', $_POST)) {
183 $this->set('type', CRM_Utils_Array::value('payment_processor', $_POST));
184 $this->set('mode', $this->_mode);
185 $this->set('paymentProcessor', $this->_paymentProcessor);
186
187 CRM_Core_Payment_ProcessorForm::preProcess($this);
188 CRM_Core_Payment_ProcessorForm::buildQuickForm($this);
189 }
190 }
191
192 function setDefaultValues() {
193 if ($this->_onbehalf) {
194 return;
195 }
196
197 // check if the user is registered and we have a contact ID
198 $contactID = $this->_userID;
199
200 if ($contactID) {
201 $fields = array();
202 $removeCustomFieldTypes = array('Contribution', 'Membership');
203 $contribFields = CRM_Contribute_BAO_Contribution::getContributionFields();
204
205 // remove component related fields
206 foreach ($this->_fields as $name => $dontCare) {
207 //don't set custom data Used for Contribution (CRM-1344)
208 if (substr($name, 0, 7) == 'custom_') {
209 $id = substr($name, 7);
210 if (!CRM_Core_BAO_CustomGroup::checkCustomField($id, $removeCustomFieldTypes)) {
211 continue;
212 }
213 // ignore component fields
214 }
215 elseif (array_key_exists($name, $contribFields) || (substr($name, 0, 11) == 'membership_') || (substr($name, 0, 13) == 'contribution_')) {
216 continue;
217 }
218 $fields[$name] = 1;
219 }
220
221 $names = array(
222 'first_name', 'middle_name', 'last_name', "street_address-{$this->_bltID}", "city-{$this->_bltID}",
223 "postal_code-{$this->_bltID}", "country_id-{$this->_bltID}", "state_province_id-{$this->_bltID}",
224 );
225 foreach ($names as $name) {
226 $fields[$name] = 1;
227 }
228 $fields["state_province-{$this->_bltID}"] = 1;
229 $fields["country-{$this->_bltID}"] = 1;
230 $fields["email-{$this->_bltID}"] = 1;
231 $fields['email-Primary'] = 1;
232
233 CRM_Core_BAO_UFGroup::setProfileDefaults($contactID, $fields, $this->_defaults);
234
235 // use primary email address if billing email address is empty
236 if (empty($this->_defaults["email-{$this->_bltID}"]) &&
237 !empty($this->_defaults['email-Primary'])
238 ) {
239 $this->_defaults["email-{$this->_bltID}"] = $this->_defaults['email-Primary'];
240 }
241
242 foreach ($names as $name) {
243 if (!empty($this->_defaults[$name])) {
244 $this->_defaults['billing_' . $name] = $this->_defaults[$name];
245 }
246 }
247 }
248
249 //set custom field defaults set by admin if value is not set
250 if (!empty($this->_fields)) {
251 //load default campaign from page.
252 if (array_key_exists('contribution_campaign_id', $this->_fields)) {
253 $this->_defaults['contribution_campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values);
254 }
255
256 //set custom field defaults
257 foreach ($this->_fields as $name => $field) {
258 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($name)) {
259 if (!isset($this->_defaults[$name])) {
260 CRM_Core_BAO_CustomField::setProfileDefaults($customFieldID, $name, $this->_defaults,
261 NULL, CRM_Profile_Form::MODE_REGISTER
262 );
263 }
264 }
265 }
266 }
267
268 //set default membership for membershipship block
269 if ($this->_membershipBlock) {
270 $this->_defaults['selectMembership'] = $defaultMemType = $this->_defaultMemTypeId ? $this->_defaultMemTypeId : CRM_Utils_Array::value('membership_type_default', $this->_membershipBlock);
271 }
272
273 // // hack to simplify credit card entry for testing
274 // $this->_defaults['credit_card_type'] = 'Visa';
275 // $this->_defaults['amount'] = 168;
276 // $this->_defaults['credit_card_number'] = '4111111111111111';
277 // $this->_defaults['cvv2'] = '000';
278 // $this->_defaults['credit_card_exp_date'] = array('Y' => '2014', 'M' => '05');
279
280 // // hack to simplify direct debit entry for testing
281 // $this->_defaults['account_holder'] = 'Max Müller';
282 // $this->_defaults['bank_account_number'] = '12345678';
283 // $this->_defaults['bank_identification_number'] = '12030000';
284 // $this->_defaults['bank_name'] = 'Bankname';
285
286 //build set default for pledge overdue payment.
287 if (CRM_Utils_Array::value('pledge_id', $this->_values)) {
288 //get all payment statuses.
289 $statuses = array();
290 $returnProperties = array('status_id');
291 CRM_Core_DAO::commonRetrieveAll('CRM_Pledge_DAO_PledgePayment', 'pledge_id', $this->_values['pledge_id'],
292 $statuses, $returnProperties
293 );
294
295 $paymentStatusTypes = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
296 $duePayment = FALSE;
297 foreach ($statuses as $payId => $value) {
298 if ($paymentStatusTypes[$value['status_id']] == 'Overdue') {
299 $this->_defaults['pledge_amount'][$payId] = 1;
300 }
301 elseif (!$duePayment && $paymentStatusTypes[$value['status_id']] == 'Pending') {
302 $this->_defaults['pledge_amount'][$payId] = 1;
303 $duePayment = TRUE;
304 }
305 }
306 }
307 elseif (CRM_Utils_Array::value('pledge_block_id', $this->_values)) {
308 //set default to one time contribution.
309 $this->_defaults['is_pledge'] = 0;
310 }
311
312 // to process Custom data that are appended to URL
313 $getDefaults = CRM_Core_BAO_CustomGroup::extractGetParams($this, "'Contact', 'Individual', 'Contribution'");
314 if (!empty($getDefaults)) {
315 $this->_defaults = array_merge($this->_defaults, $getDefaults);
316 }
317
318 $config = CRM_Core_Config::singleton();
319 // set default country from config if no country set
320 if (!CRM_Utils_Array::value("billing_country_id-{$this->_bltID}", $this->_defaults)) {
321 $this->_defaults["billing_country_id-{$this->_bltID}"] = $config->defaultContactCountry;
322 }
323
324 // set default state/province from config if no state/province set
325 if (!CRM_Utils_Array::value("billing_state_province_id-{$this->_bltID}", $this->_defaults)) {
326 $this->_defaults["billing_state_province_id-{$this->_bltID}"] = $config->defaultContactStateProvince;
327 }
328
329 // now fix all state country selectors
330 CRM_Core_BAO_Address::fixAllStateSelects($this, $this->_defaults);
331
332 if ($this->_priceSetId) {
333 if ($this->_useForMember && !empty($this->_currentMemberships)) {
334 $selectedCurrentMemTypes = array();
335 foreach ($this->_priceSet['fields'] as $key => $val) {
336 foreach ($val['options'] as $keys => $values) {
337 $opMemTypeId = CRM_Utils_Array::value('membership_type_id', $values);
338 if ($opMemTypeId &&
339 in_array($opMemTypeId, $this->_currentMemberships) &&
340 !in_array($opMemTypeId, $selectedCurrentMemTypes)
341 ) {
342 if ($val['html_type'] == 'CheckBox') {
343 $this->_defaults["price_{$key}"][$keys] = 1;
344 }
345 else {
346 $this->_defaults["price_{$key}"] = $keys;
347 }
348 $selectedCurrentMemTypes[] = $values['membership_type_id'];
349 }
350 elseif (CRM_Utils_Array::value('is_default', $values) &&
351 !$opMemTypeId &&
352 (!isset($this->_defaults["price_{$key}"]) ||
353 ($val['html_type'] == 'CheckBox' && !isset($this->_defaults["price_{$key}"][$keys]))
354 )
355 ) {
356 if ($val['html_type'] == 'CheckBox') {
357 $this->_defaults["price_{$key}"][$keys] = 1;
358 }
359 else {
360 $this->_defaults["price_{$key}"] = $keys;
361 }
362 }
363 }
364 }
365 }
366 else {
367 CRM_Price_BAO_Set::setDefaultPriceSet($this, $this->_defaults);
368 }
369 }
370
371 if (!empty($this->_paymentProcessors)) {
372 foreach ($this->_paymentProcessors as $pid => $value) {
373 if (CRM_Utils_Array::value('is_default', $value)) {
374 $this->_defaults['payment_processor'] = $pid;
375 }
376 }
377 }
378
379 return $this->_defaults;
380 }
381
382 /**
383 * Function to build the form
384 *
385 * @return None
386 * @access public
387 */
388 public function buildQuickForm() {
389 if ($this->_ppType) {
390 return CRM_Core_Payment_ProcessorForm::buildQuickForm($this);
391 }
392
393 $config = CRM_Core_Config::singleton();
394 if (CRM_Utils_Array::value('is_for_organization', $this->_values) == 2) {
395 $this->assign('onBehalfRequired', TRUE);
396 $this->_onBehalfRequired = 1;
397 }
398 if ($this->_onbehalf) {
399 $this->assign('onbehalf', TRUE);
400 return CRM_Contribute_Form_Contribution_OnBehalfOf::buildQuickForm($this);
401 }
402
403 $this->applyFilter('__ALL__', 'trim');
404 $this->add('text', "email-{$this->_bltID}",
405 ts('Email Address'),
406 array('size' => 30, 'maxlength' => 60, 'class' => 'email'),
407 TRUE
408 );
409 $this->addRule("email-{$this->_bltID}", ts('Email is not valid.'), 'email');
410 $this->_paymentProcessors = $this->get('paymentProcessors');
411 $pps = array();
412 if (!empty($this->_paymentProcessors)) {
413 $pps = $this->_paymentProcessors;
414 foreach ($pps as $key => & $name) {
415 $pps[$key] = $name['name'];
416 }
417 }
418 if (CRM_Utils_Array::value('is_pay_later', $this->_values)) {
419 $pps[0] = $this->_values['pay_later_text'];
420 }
421
422 if (count($pps) > 1) {
423 $this->addRadio('payment_processor', ts('Payment Method'), $pps,
424 NULL, "&nbsp;", TRUE
425 );
426 }
427 elseif (!empty($pps)) {
428 $key = array_keys($pps);
429 $key = array_pop($key);
430 $this->addElement('hidden', 'payment_processor', $key);
431 if ($key === 0) {
432 $this->assign('is_pay_later', $this->_values['is_pay_later']);
433 $this->assign('pay_later_text', $this->_values['pay_later_text']);
434 }
435 }
436 //build pledge block.
437 $this->_useForMember = 0;
438 //don't build membership block when pledge_id is passed
439 if (!CRM_Utils_Array::value('pledge_id', $this->_values)) {
440 $this->_separateMembershipPayment = FALSE;
441 if (in_array('CiviMember', $config->enableComponents)) {
442 $isTest = 0;
443 if ($this->_action & CRM_Core_Action::PREVIEW) {
444 $isTest = 1;
445 }
446
447 if ($this->_priceSetId &&
448 (CRM_Core_Component::getComponentID('CiviMember') == CRM_Utils_Array::value('extends', $this->_priceSet))
449 ) {
450 $this->_useForMember = 1;
451 $this->set('useForMember', $this->_useForMember);
452 }
453
454 $this->_separateMembershipPayment = CRM_Member_BAO_Membership::buildMembershipBlock($this,
455 $this->_id,
456 TRUE, NULL, FALSE,
457 $isTest, $this->_membershipContactID
458 );
459 }
460 $this->set('separateMembershipPayment', $this->_separateMembershipPayment);
461 }
462 $this->assign('useForMember', $this->_useForMember);
463 // If we configured price set for contribution page
464 // we are not allow membership signup as well as any
465 // other contribution amount field, CRM-5095
466 if (isset($this->_priceSetId) && $this->_priceSetId) {
467 $this->add('hidden', 'priceSetId', $this->_priceSetId);
468 // build price set form.
469 $this->set('priceSetId', $this->_priceSetId);
470 CRM_Price_BAO_Set::buildPriceSet($this);
471 if ($this->_values['is_monetary'] &&
472 $this->_values['is_recur'] && !CRM_Utils_Array::value('pledge_id', $this->_values)
473 ) {
474 self::buildRecur($this);
475 }
476 }
477 elseif (CRM_Utils_Array::value('amount_block_is_active', $this->_values)
478 && !CRM_Utils_Array::value('pledge_id', $this->_values)
479 ) {
480 $this->buildAmount($this->_separateMembershipPayment);
481 }
482
483 if ($this->_priceSetId) {
484 $is_quick_config = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_Set', $this->_priceSetId, 'is_quick_config');
485 if ($is_quick_config) {
486 $this->_useForMember = 0;
487 $this->set('useForMember', $this->_useForMember);
488 }
489 }
490
491 if ($this->_values['is_for_organization']) {
492 $this->buildOnBehalfOrganization();
493 }
494
495 //we allow premium for pledge during pledge creation only.
496 if (!CRM_Utils_Array::value('pledge_id', $this->_values)) {
497 CRM_Contribute_BAO_Premium::buildPremiumBlock($this, $this->_id, TRUE);
498 }
499
500 if ($this->_values['honor_block_is_active']) {
501 $this->buildHonorBlock();
502 }
503
504
505 //don't build pledge block when mid is passed
506 if (!$this->_mid) {
507 $config = CRM_Core_Config::singleton();
508 if (in_array('CiviPledge', $config->enableComponents)
509 && CRM_Utils_Array::value('pledge_block_id', $this->_values)
510 ) {
511 CRM_Pledge_BAO_PledgeBlock::buildPledgeBlock($this);
512 }
513 }
514
515 $this->buildCustom($this->_values['custom_pre_id'], 'customPre');
516 $this->buildCustom($this->_values['custom_post_id'], 'customPost');
517
518 if ( !empty( $this->_fields ) ) {
519 $profileAddressFields = array();
520 foreach( $this->_fields as $key => $value ) {
521 CRM_Core_BAO_UFField::assignAddressField($key, $profileAddressFields);
522 }
523 $this->set('profileAddressFields', $profileAddressFields);
524 }
525
526 //to create an cms user
527 if (!$this->_userID) {
528 $createCMSUser = FALSE;
529
530 if ($this->_values['custom_pre_id']) {
531 $profileID = $this->_values['custom_pre_id'];
532 $createCMSUser = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'is_cms_user');
533 }
534
535 if (!$createCMSUser &&
536 $this->_values['custom_post_id']
537 ) {
538 if (!is_array($this->_values['custom_post_id'])) {
539 $profileIDs = array($this->_values['custom_post_id']);
540 }
541 else {
542 $profileIDs = $this->_values['custom_post_id'];
543 }
544 foreach ($profileIDs as $pid) {
545 if (CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $pid, 'is_cms_user')) {
546 $profileID = $pid;
547 $createCMSUser = TRUE;
548 break;
549 }
550 }
551 }
552
553 if ($createCMSUser) {
554 CRM_Core_BAO_CMSUser::buildForm($this, $profileID, TRUE);
555 }
556 }
557 if ($this->_pcpId) {
558 if ($pcpSupporter = CRM_PCP_BAO_PCP::displayName($this->_pcpId)) {
559 $this->assign('pcpSupporterText', ts('This contribution is being made thanks to effort of <strong>%1</strong>, who supports our campaign. You can support it as well - once you complete the donation, you will be able to create your own Personal Campaign Page!', array(1 => $pcpSupporter)));
560 }
561 $this->assign('pcp', TRUE);
562 $this->add('checkbox', 'pcp_display_in_roll', ts('Show my contribution in the public honor roll'), NULL, NULL,
563 array('onclick' => "showHideByValue('pcp_display_in_roll','','nameID|nickID|personalNoteID','block','radio',false); pcpAnonymous( );")
564 );
565 $extraOption = array('onclick' => "return pcpAnonymous( );");
566 $elements = array();
567 $elements[] = &$this->createElement('radio', NULL, '', ts('Include my name and message'), 0, $extraOption);
568 $elements[] = &$this->createElement('radio', NULL, '', ts('List my contribution anonymously'), 1, $extraOption);
569 $this->addGroup($elements, 'pcp_is_anonymous', NULL, '&nbsp;&nbsp;&nbsp;');
94fe3c35 570 $this->_defaults['pcp_is_anonymous'] = 0;
6a488035
TO
571
572 $this->add('text', 'pcp_roll_nickname', ts('Name'), array('maxlength' => 30));
573 $this->add('textarea', 'pcp_personal_note', ts('Personal Note'), array('style' => 'height: 3em; width: 40em;'));
574 }
575
576 //we have to load confirm contribution button in template
577 //when multiple payment processor as the user
578 //can toggle with payment processor selection
579 $billingModePaymentProcessors = 0;
580 if ( !empty( $this->_paymentProcessors ) ) {
581 foreach ($this->_paymentProcessors as $key => $values) {
582 if ($values['billing_mode'] == CRM_Core_Payment::BILLING_MODE_BUTTON) {
583 $billingModePaymentProcessors++;
584 }
585 }
586 }
587
588 if ($billingModePaymentProcessors && count($this->_paymentProcessors) == $billingModePaymentProcessors) {
589 $allAreBillingModeProcessors = TRUE;
590 } else {
591 $allAreBillingModeProcessors = FALSE;
592 }
593
594 if (!($allAreBillingModeProcessors && !$this->_values['is_pay_later'])) {
595 $this->addButtons(array(
596 array(
597 'type' => 'upload',
598 'name' => ts('Contribute'),
599 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
600 'isDefault' => TRUE,
601 ),
602 )
603 );
604 }
605
606 $this->addFormRule(array('CRM_Contribute_Form_Contribution_Main', 'formRule'), $this);
607
608 }
609
610 /**
611 * build the radio/text form elements for the amount field
612 *
613 * @return void
614 * @access private
615 */
616 function buildAmount($separateMembershipPayment = FALSE) {
617 $elements = array();
618 if (!empty($this->_values['amount'])) {
619 // first build the radio boxes
620 CRM_Utils_Hook::buildAmount('contribution', $this, $this->_values['amount']);
621
622 foreach ($this->_values['amount'] as $amount) {
623 $elements[] = &$this->createElement('radio', NULL, '',
624 CRM_Utils_Money::format($amount['value']) . ' ' . $amount['label'],
625 $amount['amount_id'],
626 array('onclick' => 'clearAmountOther();')
627 );
628 }
629 }
630
631 if ($separateMembershipPayment) {
632 $elements[''] = $this->createElement('radio', NULL, NULL, ts('No thank you'), 'no_thanks', array('onclick' => 'clearAmountOther();'));
633 $this->assign('is_separate_payment', TRUE);
634 }
635
636 if (isset($this->_values['default_amount_id'])) {
637 $this->_defaults['amount'] = $this->_values['default_amount_id'];
638 }
639 $title = ts('Contribution Amount');
640 if ($this->_values['is_allow_other_amount']) {
641 if (!empty($this->_values['amount'])) {
642 $elements[] = &$this->createElement('radio', NULL, '',
643 ts('Other Amount'), 'amount_other_radio'
644 );
645
646 $this->addGroup($elements, 'amount', $title, '<br />');
647
648 if (!$separateMembershipPayment) {
649 $this->addRule('amount', ts('%1 is a required field.', array(1 => ts('Amount'))), 'required');
650 }
651 $this->add('text', 'amount_other', ts('Other Amount'), array('size' => 10, 'maxlength' => 10, 'onfocus' => 'useAmountOther();'));
652 }
653 else {
654 if ($separateMembershipPayment) {
655 $title = ts('Additional Contribution');
656 }
657 $this->add('text', 'amount_other', $title, array('size' => 10, 'maxlength' => 10, 'onfocus' => 'useAmountOther();'));
658 if (!$separateMembershipPayment) {
659 $this->addRule('amount_other', ts('%1 is a required field.', array(1 => $title)), 'required');
660 }
661 }
662
663 $this->assign('is_allow_other_amount', TRUE);
664
665 $this->addRule('amount_other', ts('Please enter a valid amount (numbers and decimal point only).'), 'money');
666 }
667 else {
668 if (!empty($this->_values['amount'])) {
669 if ($separateMembershipPayment) {
670 $title = ts('Additional Contribution');
671 }
672 $this->addGroup($elements, 'amount', $title, '<br />');
673
674 if (!$separateMembershipPayment) {
675 $this->addRule('amount', ts('%1 is a required field.', array(1 => ts('Amount'))), 'required');
676 }
677 }
678 $this->assign('is_allow_other_amount', FALSE);
679 }
680 }
681
682 /**
683 * Function to add the honor block
684 *
685 * @return None
686 * @access public
687 */
688 function buildHonorBlock() {
689 $this->assign('honor_block_is_active', TRUE);
690 $this->set('honor_block_is_active', TRUE);
691
692 $this->assign('honor_block_title', CRM_Utils_Array::value('honor_block_title', $this->_values));
693 $this->assign('honor_block_text', CRM_Utils_Array::value('honor_block_text', $this->_values));
694
695 $attributes = CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Contact');
696 $extraOption = array('onclick' => "enableHonorType();");
697 // radio button for Honor Type
698 $honorOptions = array();
699 $honor = CRM_Core_PseudoConstant::honor();
700 foreach ($honor as $key => $var) {
701 $honorTypes[$key] = $this->createElement('radio', NULL, NULL, $var, $key, $extraOption);
702 }
703 $this->addGroup($honorTypes, 'honor_type_id', NULL);
704
705 // prefix
706 $this->addElement('select', 'honor_prefix_id', ts('Prefix'), array('' => ts('- prefix -')) + CRM_Core_PseudoConstant::individualPrefix());
707 // first_name
708 $this->addElement('text', 'honor_first_name', ts('First Name'), $attributes['first_name']);
709
710 //last_name
711 $this->addElement('text', 'honor_last_name', ts('Last Name'), $attributes['last_name']);
712
713 //email
714 $this->addElement('text', 'honor_email', ts('Email Address'), array('class' => 'email'));
715 $this->addRule('honor_email', ts('Honoree Email is not valid.'), 'email');
716 }
717
718 /**
719 * build elements to enable pay on behalf of an organization.
720 *
721 * @access public
722 */
723 function buildOnBehalfOrganization() {
724 if ($this->_membershipContactID) {
725 $entityBlock = array('contact_id' => $this->_membershipContactID);
726 CRM_Core_BAO_Location::getValues($entityBlock, $this->_defaults);
727 }
728
729 if ($this->_values['is_for_organization'] != 2) {
730 $this->addElement('checkbox', 'is_for_organization',
731 $this->_values['for_organization'],
732 NULL, array('onclick' => "showOnBehalf( );")
733 );
734 }
735 else {
736 $this->assign('onBehalfRequired', TRUE);
737 $this->_onBehalfRequired = 1;
738 }
739
740 $this->assign('is_for_organization', TRUE);
741 $this->assign('urlPath', 'civicrm/contribute/transact');
742 }
743
744 /**
745 * build elements to collect information for recurring contributions
746 *
747 * @access public
748 */
749 function buildRecur($form) {
750 $attributes = CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionRecur');
751 $className = get_class($form);
752
753 $this->assign('is_recur_interval', CRM_Utils_Array::value('is_recur_interval', $this->_values));
754 $this->assign('is_recur_installments', CRM_Utils_Array::value('is_recur_installments', $this->_values));
755
756 $form->add('checkbox', 'is_recur', ts('I want to contribute this amount'), NULL);
757
758 if (CRM_Utils_Array::value('is_recur_interval', $form->_values) || $className == 'CRM_Contribute_Form_Contribution') {
759 $form->add('text', 'frequency_interval', ts('Every'), $attributes['frequency_interval']);
760 $form->addRule('frequency_interval', ts('Frequency must be a whole number (EXAMPLE: Every 3 months).'), 'integer');
761 }
762 else {
763 // make sure frequency_interval is submitted as 1 if given no choice to user.
764 $form->add('hidden', 'frequency_interval', 1);
765 }
766
767 $frUnits = CRM_Utils_Array::value('recur_frequency_unit', $form->_values);
768 if (empty($frUnits) &&
769 $className == 'CRM_Contribute_Form_Contribution'
770 ) {
771 $frUnits = implode(CRM_Core_DAO::VALUE_SEPARATOR,
772 CRM_Core_OptionGroup::values('recur_frequency_units')
773 );
774 }
775
776 $unitVals = explode(CRM_Core_DAO::VALUE_SEPARATOR, $frUnits);
777
778 // CRM 10860, display text instead of a dropdown if there's only 1 frequency unit
779 if(sizeof($unitVals) == 1) {
780 $this->assign('one_frequency_unit', true);
781 $unit = $unitVals[0];
782 $form->add('hidden', 'frequency_unit', $unit);
783 if (CRM_Utils_Array::value('is_recur_interval', $form->_values) || $className == 'CRM_Contribute_Form_Contribution') {
784 $unit .= "(s)";
785 }
786 $this->assign('frequency_unit', $unit);
787 } else {
788 $this->assign('one_frequency_unit', false);
789 $units = array();
790 $frequencyUnits = CRM_Core_OptionGroup::values('recur_frequency_units');
791 foreach ($unitVals as $key => $val) {
792 if (array_key_exists($val, $frequencyUnits)) {
793 $units[$val] = $frequencyUnits[$val];
794 if (CRM_Utils_Array::value('is_recur_interval', $form->_values) || $className == 'CRM_Contribute_Form_Contribution') {
795 $units[$val] = "{$frequencyUnits[$val]}(s)";
796 }
797 }
798 }
799 $frequencyUnit = &$form->add('select', 'frequency_unit', NULL, $units);
800 }
801
802
803 // FIXME: Ideally we should freeze select box if there is only
804 // one option but looks there is some problem /w QF freeze.
805 //if ( count( $units ) == 1 ) {
806 //$frequencyUnit->freeze( );
807 //}
808
809 $form->add('text', 'installments', ts('installments'),
810 $attributes['installments']
811 );
812 $form->addRule('installments', ts('Number of installments must be a whole number.'), 'integer');
813 }
814
815 /**
816 * global form rule
817 *
818 * @param array $fields the input form values
819 * @param array $files the uploaded files if any
820 * @param array $options additional user data
821 *
822 * @return true if no errors, else array of errors
823 * @access public
824 * @static
825 */
826 static function formRule($fields, $files, $self) {
827 $errors = array();
828 $amount = self::computeAmount($fields, $self);
829
830 if ((CRM_Utils_Array::value('selectMembership', $fields) &&
831 $fields['selectMembership'] != 'no_thanks'
832 ) ||
833 (CRM_Utils_Array::value('priceSetId', $fields) &&
834 $self->_useForMember
835 )
836 ) {
837 $lifeMember = CRM_Member_BAO_Membership::getAllContactMembership($self->_userID, FALSE, TRUE);
838
839 $membershipOrgDetails = CRM_Member_BAO_MembershipType::getMembershipTypeOrganization();
840
841 $unallowedOrgs = array();
842 foreach (array_keys($lifeMember) as $memTypeId) {
843 $unallowedOrgs[] = $membershipOrgDetails[$memTypeId];
844 }
845 }
846
847 //check for atleast one pricefields should be selected
848 if (CRM_Utils_Array::value('priceSetId', $fields)) {
849 $priceField = new CRM_Price_DAO_Field();
850 $priceField->price_set_id = $fields['priceSetId'];
851 $priceField->orderBy('weight');
852 $priceField->find();
853
854 $check = array();
855 $membershipIsActive = TRUE;
856 $previousId = $otherAmount = FALSE;
857 while ($priceField->fetch()) {
858
859 if ($self->_quickConfig && ($priceField->name == 'contribution_amount' || $priceField->name == 'membership_amount')) {
860 $previousId = $priceField->id;
861 if ($priceField->name == 'membership_amount' && !$priceField->is_active ) {
862 $membershipIsActive = FALSE;
863 }
864 }
865 if ($priceField->name == 'other_amount') {
866 if ($self->_quickConfig && !CRM_Utils_Array::value("price_{$priceField->id}", $fields) &&
867 array_key_exists("price_{$previousId}", $fields) && isset($fields["price_{$previousId}"]) && $self->_values['fee'][$previousId]['name'] == 'contribution_amount' && empty($fields["price_{$previousId}"])) {
868 $otherAmount = $priceField->id;
869 }
870 elseif (!empty($fields["price_{$priceField->id}"])) {
871 $otherAmountVal = $fields["price_{$priceField->id}"];
872 $min = CRM_Utils_Array::value('min_amount', $self->_values);
873 $max = CRM_Utils_Array::value('max_amount', $self->_values);
874 if ($min && $otherAmountVal < $min) {
875 $errors["price_{$priceField->id}"] = ts('Contribution amount must be at least %1',
876 array(1 => $min)
877 );
878 }
879 if ($max && $otherAmountVal > $max) {
880 $errors["price_{$priceField->id}"] = ts('Contribution amount cannot be more than %1.',
881 array(1 => $max)
882 );
883 }
884 }
885 }
886 if (!empty($fields["price_{$priceField->id}"]) || ($previousId == $priceField->id && isset($fields["price_{$previousId}"])
887 && empty($fields["price_{$previousId}"]))) {
888 $check[] = $priceField->id;
889 }
890 }
891
892 if (empty($check)) {
893 if ($self->_useForMember == 1 && $membershipIsActive) {
894 $errors['_qf_default'] = ts('Select at least one option from Membership Type(s).');
895 }
896 else {
897 $errors['_qf_default'] = ts('Select at least one option from Contribution(s).');
898 }
899 }
900 if($otherAmount && !empty($check)) {
901 $errors["price_{$otherAmount}"] = ts('Amount is required field.');
902 }
903
904 if ($self->_useForMember == 1 && !empty($check) && $membershipIsActive) {
905 $priceFieldIDS = array();
906 $priceFieldMemTypes = array();
907
908 foreach ($self->_priceSet['fields'] as $priceId => $value) {
909 if (!empty($fields['price_' . $priceId]) || ($self->_quickConfig && $value['name'] == 'membership_amount' && !CRM_Utils_Array::value('is_required', $self->_membershipBlock))) {
910 if (CRM_Utils_Array::value('price_' . $priceId, $fields) && is_array($fields['price_' . $priceId])) {
911 foreach ($fields['price_' . $priceId] as $priceFldVal => $isSet) {
912 if ($isSet) {
913 $priceFieldIDS[] = $priceFldVal;
914 }
915 }
916 }
917 elseif (!$value['is_enter_qty'] && CRM_Utils_Array::value('price_' . $priceId, $fields)) {
918 // The check for {!$value['is_enter_qty']} is done since, quantity fields allow entering
919 // quantity. And the quantity can't be conisdered as civicrm_price_field_value.id, CRM-9577
920 $priceFieldIDS[] = $fields['price_' . $priceId];
921 }
922
923 if (CRM_Utils_Array::value('options', $value)) {
924 foreach ($value['options'] as $val) {
925 if (CRM_Utils_Array::value('membership_type_id', $val)) {
926 $priceFieldMemTypes[] = $val['membership_type_id'];
927 }
928 }
929 }
930 }
931 }
932
933 if (!empty($lifeMember)) {
934 foreach ($priceFieldIDS as $priceFieldId) {
935 if (($id = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_FieldValue', $priceFieldId, 'membership_type_id')) &&
936 in_array($membershipOrgDetails[$id], $unallowedOrgs)
937 ) {
938 $errors['_qf_default'] = ts('You already have a lifetime membership and cannot select a membership with a shorter term.');
939 break;
940 }
941 }
942 }
943
944 if (!empty($priceFieldIDS)) {
945 $ids = implode(',', $priceFieldIDS);
946
947 $priceFieldIDS['id'] = $fields['priceSetId'];
948 $self->set('memberPriceFieldIDS', $priceFieldIDS);
949 $count = CRM_Price_BAO_Set::getMembershipCount($ids);
950 foreach ($count as $id => $occurance) {
951 if ($occurance > 1) {
952 $errors['_qf_default'] = ts('You have selected multiple memberships for the same organization or entity. Please review your selections and choose only one membership per entity. Contact the site administrator if you need assistance.');
953 }
954 }
955 }
956
957 if (empty($priceFieldMemTypes)) {
958 $errors['_qf_default'] = ts('Please select at least one membership option.');
959 }
960 }
961
962 $fieldId = $memPresent = $membershipLabel = $fieldOption = $proceFieldAmount = NULL;
963 if ($self->_separateMembershipPayment == 0 && $self->_quickConfig) {
964 foreach ($self->_priceSet['fields'] as $fieldKey => $fieldVal) {
965 if ($fieldVal['name'] == 'membership_amount') {
966 $fieldId = $fieldVal['id'];
967 $fieldOption = $fields['price_' . $fieldId];
968 $memPresent = TRUE;
969 }
970 else {
971 if (CRM_Utils_Array::value('price_' . $fieldKey, $fields) && $memPresent && ($fieldVal['name'] == 'other_amount' || $fieldVal['name'] == 'contribution_amount')) {
972 $fieldId = $fieldVal['id'];
973 if ($fieldVal['name'] == 'other_amount') {
974 $proceFieldAmount = $self->_submitValues['price_' . $fieldId];
975 }
976 else $proceFieldAmount = $fieldVal['options'][$self->_submitValues['price_' . $fieldId]]['amount'];
977 unset($fields['price_' . $fieldId]);
978 break;
979 }
980 }
981 }
982 }
983
984 CRM_Price_BAO_Set::processAmount($self->_values['fee'],
985 $fields, $lineItem
986 );
987 if ($proceFieldAmount) {
988 if ($proceFieldAmount < $lineItem[$fieldOption]['line_total']) {
989 $errors["price_$fieldId"] = ts('The Membership you have selected requires a minimum contribution of %1',
990 array(1 => CRM_Utils_Money::format($lineItem[$fieldOption]['line_total']))
991 );
992 }
993 $fields['amount'] = $proceFieldAmount;
994 }
995 if ($fields['amount'] < 0) {
996 $errors['_qf_default'] = ts('Contribution can not be less than zero. Please select the options accordingly');
997 }
998 $amount = $fields['amount'];
999 }
1000
1001 if (isset($fields['selectProduct']) &&
1002 $fields['selectProduct'] != 'no_thanks' &&
1003 $self->_values['amount_block_is_active']
1004 ) {
1005 $productDAO = new CRM_Contribute_DAO_Product();
1006 $productDAO->id = $fields['selectProduct'];
1007 $productDAO->find(TRUE);
1008 $min_amount = $productDAO->min_contribution;
1009
1010 if ($amount < $min_amount) {
1011 $errors['selectProduct'] = ts('The premium you have selected requires a minimum contribution of %1', array(1 => CRM_Utils_Money::format($min_amount)));
1012 CRM_Core_Session::setStatus($errors['selectProduct']);
1013 }
1014 }
1015
1016 if ($self->_values['honor_block_is_active'] && CRM_Utils_Array::value('honor_type_id', $fields)) {
1017 // make sure there is a first name and last name if email is not there
1018 if (!CRM_Utils_Array::value('honor_email', $fields)) {
1019 if (!CRM_Utils_Array::value('honor_first_name', $fields) ||
1020 !CRM_Utils_Array::value('honor_last_name', $fields)
1021 ) {
1022 $errors['honor_last_name'] = ts('In Honor Of - First Name and Last Name, OR an Email Address is required.');
1023 }
1024 }
1025 }
1026
1027 if ( CRM_Utils_Array::value( 'is_recur', $fields ) ) {
1028 if ($fields['frequency_interval'] <= 0) {
1029 $errors['frequency_interval'] = ts('Please enter a number for how often you want to make this recurring contribution (EXAMPLE: Every 3 months).');
1030 }
1031 if ($fields['frequency_unit'] == '0') {
1032 $errors['frequency_unit'] = ts('Please select a period (e.g. months, years ...) for how often you want to make this recurring contribution (EXAMPLE: Every 3 MONTHS).');
1033 }
1034 }
1035
1036 if (CRM_Utils_Array::value('is_recur', $fields) &&
1037 CRM_Utils_Array::value('payment_processor', $fields) == 0) {
1038 $errors['_qf_default'] = ts('You cannot set up a recurring contribution if you are not paying online by credit card.');
1039 }
1040
1041 if (CRM_Utils_Array::value('is_for_organization', $fields) &&
1042 !property_exists($self, 'organizationName')
1043 ) {
1044
1045 if (!CRM_Utils_Array::value('organization_name', $fields['onbehalf'])) {
1046 if (CRM_Utils_Array::value('org_option', $fields) && !$fields['onbehalfof_id']) {
1047 $errors['organization_id'] = ts('Please select an organization or enter a new one.');
1048 }
1049 elseif (!CRM_Utils_Array::value('org_option', $fields)) {
1050 $errors['onbehalf']['organization_name'] = ts('Please enter the organization name.');
1051 }
1052 }
1053
1054 foreach ($fields['onbehalf'] as $key => $value) {
1055 if (strstr($key, 'email')) {
1056 $emailLocType = explode('-', $key);
1057 }
1058 }
1059 if (!CRM_Utils_Array::value("email-{$emailLocType[1]}", $fields['onbehalf'])) {
1060 $errors['onbehalf']["email-{$emailLocType[1]}"] = ts('Organization email is required.');
1061 }
1062 }
1063
1064 // validate PCP fields - if not anonymous, we need a nick name value
1065 if ($self->_pcpId && CRM_Utils_Array::value('pcp_display_in_roll', $fields) &&
1066 (CRM_Utils_Array::value('pcp_is_anonymous', $fields) == 0) &&
1067 CRM_Utils_Array::value('pcp_roll_nickname', $fields) == ''
1068 ) {
1069 $errors['pcp_roll_nickname'] = ts('Please enter a name to include in the Honor Roll, or select \'contribute anonymously\'.');
1070 }
1071
1072 // return if this is express mode
1073 $config = CRM_Core_Config::singleton();
1074 if ($self->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON) {
1075 if (CRM_Utils_Array::value($self->_expressButtonName . '_x', $fields) ||
1076 CRM_Utils_Array::value($self->_expressButtonName . '_y', $fields) ||
1077 CRM_Utils_Array::value($self->_expressButtonName, $fields)
1078 ) {
1079 return $errors;
1080 }
1081 }
1082
1083 //validate the pledge fields.
1084 if (CRM_Utils_Array::value('pledge_block_id', $self->_values)) {
1085 //validation for pledge payment.
1086 if (CRM_Utils_Array::value('pledge_id', $self->_values)) {
1087 if (empty($fields['pledge_amount'])) {
1088 $errors['pledge_amount'] = ts('At least one payment option needs to be checked.');
1089 }
1090 }
1091 elseif (CRM_Utils_Array::value('is_pledge', $fields)) {
1092 if (CRM_Utils_Rule::positiveInteger(CRM_Utils_Array::value('pledge_installments', $fields)) == FALSE) {
1093 $errors['pledge_installments'] = ts('Please enter a valid pledge installment.');
1094 }
1095 else {
1096 if (CRM_Utils_Array::value('pledge_installments', $fields) == NULL) {
1097 $errors['pledge_installments'] = ts('Pledge Installments is required field.');
1098 }
1099 elseif (CRM_Utils_array::value('pledge_installments', $fields) == 1) {
1100 $errors['pledge_installments'] = ts('Pledges consist of multiple scheduled payments. Select one-time contribution if you want to make your gift in a single payment.');
1101 }
1102 elseif (CRM_Utils_array::value('pledge_installments', $fields) == 0) {
1103 $errors['pledge_installments'] = ts('Pledge Installments field must be > 1.');
1104 }
1105 }
1106
1107 //validation for Pledge Frequency Interval.
1108 if (CRM_Utils_Rule::positiveInteger(CRM_Utils_Array::value('pledge_frequency_interval', $fields)) == FALSE) {
1109 $errors['pledge_frequency_interval'] = ts('Please enter a valid Pledge Frequency Interval.');
1110 }
1111 else {
1112 if (CRM_Utils_Array::value('pledge_frequency_interval', $fields) == NULL) {
1113 $errors['pledge_frequency_interval'] = ts('Pledge Frequency Interval. is required field.');
1114 }
1115 elseif (CRM_Utils_array::value('pledge_frequency_interval', $fields) == 0) {
1116 $errors['pledge_frequency_interval'] = ts('Pledge frequency interval field must be > 0');
1117 }
1118 }
1119 }
1120 }
1121
1122 // also return if paylater mode
1123 if (CRM_Utils_Array::value('payment_processor', $fields) == 0) {
1124 return empty($errors) ? TRUE : $errors;
1125 }
1126
1127 // if the user has chosen a free membership or the amount is less than zero
1128 // i.e. we skip calling the payment processor and hence dont need credit card
1129 // info
1130 if ((float ) $amount <= 0.0) {
1131 return $errors;
1132 }
1133
1134 if(isset($self->_paymentFields)) {
1135 foreach ($self->_paymentFields as $name => $fld) {
1136 if ($fld['is_required'] &&
1137 CRM_Utils_System::isNull(CRM_Utils_Array::value($name, $fields))
1138 ) {
1139 $errors[$name] = ts('%1 is a required field.', array(1 => $fld['title']));
1140 }
1141 }
1142 }
1143
1144 // make sure that credit card number and cvv are valid
1145 if (CRM_Utils_Array::value('credit_card_type', $fields)) {
1146 if (CRM_Utils_Array::value('credit_card_number', $fields) &&
1147 !CRM_Utils_Rule::creditCardNumber($fields['credit_card_number'], $fields['credit_card_type'])
1148 ) {
1149 $errors['credit_card_number'] = ts('Please enter a valid Credit Card Number');
1150 }
1151
1152 if (CRM_Utils_Array::value('cvv2', $fields) &&
1153 !CRM_Utils_Rule::cvv($fields['cvv2'], $fields['credit_card_type'])
1154 ) {
1155 $errors['cvv2'] = ts('Please enter a valid Credit Card Verification Number');
1156 }
1157 }
1158 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
1159 if ($greetingType = CRM_Utils_Array::value($greeting, $fields)) {
1160 $customizedValue = CRM_Core_OptionGroup::getValue($greeting, 'Customized', 'name');
1161 if ($customizedValue == $greetingType && empty($fielse[$greeting . '_custom'])) {
1162 $errors[$greeting . '_custom'] = ts('Custom %1 is a required field if %1 is of type Customized.',
1163 array(1 => ucwords(str_replace('_', " ", $greeting)))
1164 );
1165 }
1166 }
1167 }
1168
1169 return empty($errors) ? TRUE : $errors;
1170 }
1171
1172 public function computeAmount(&$params, &$form) {
1173 $amount = NULL;
1174
1175 // first clean up the other amount field if present
1176 if (isset($params['amount_other'])) {
1177 $params['amount_other'] = CRM_Utils_Rule::cleanMoney($params['amount_other']);
1178 }
1179
1180 if (CRM_Utils_Array::value('amount', $params) == 'amount_other_radio' ||
1181 CRM_Utils_Array::value('amount_other', $params)
1182 ) {
1183 $amount = $params['amount_other'];
1184 }
1185 elseif (!empty($params['pledge_amount'])) {
1186 $amount = 0;
1187 foreach ($params['pledge_amount'] as $paymentId => $dontCare) {
1188 $amount += CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_PledgePayment', $paymentId, 'scheduled_amount');
1189 }
1190 }
1191 else {
1192 if (CRM_Utils_Array::value('amount', $form->_values)) {
1193 $amountID = CRM_Utils_Array::value('amount', $params);
1194
1195 if ($amountID) {
1196 $params['amount_level'] = CRM_Utils_Array::value('label', $form->_values[$amountID]);
1197 $amount = CRM_Utils_Array::value('value', $form->_values[$amountID]);
1198 }
1199 }
1200 }
1201 return $amount;
1202 }
1203
1204 /**
1205 * Function to process the form
1206 *
1207 * @access public
1208 *
1209 * @return None
1210 */
1211 public function postProcess() {
1212 $config = CRM_Core_Config::singleton();
1213
1214 // we first reset the confirm page so it accepts new values
1215 $this->controller->resetPage('Confirm');
1216
1217 // get the submitted form values.
1218 $params = $this->controller->exportValues($this->_name);
1219 if (CRM_Utils_Array::value('priceSetId', $params)) {
1220 $is_quick_config = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_Set', $this->_priceSetId, 'is_quick_config');
1221 $formValue = array();
1222 if ($is_quick_config) {
1223 $priceField = new CRM_Price_DAO_Field();
1224 $priceField->price_set_id = $params['priceSetId'];
1225 $priceField->orderBy('weight');
1226 $priceField->find();
1227
1228 $check = array();
1229 $otherAmount = FALSE;
1230 while ($priceField->fetch()) {
1231 CRM_Price_BAO_FieldValue::getValues($priceField->id, $values);
1232 if ($priceField->name == 'membership_amount') {
1233 if ($priceFiledID = CRM_Utils_Array::value("price_{$priceField->id}", $params)) {
1234 $this->_params['selectMembership'] = $params['selectMembership'] = CRM_Utils_Array::value('membership_type_id', $values[$priceFiledID]);
1235 $this->set('selectMembership',CRM_Utils_Array::value('selectMembership', $params));
1236 if (CRM_Utils_Array::value('is_separate_payment', $this->_membershipBlock) == 0) {
1237 $this->_values['amount'] = CRM_Utils_Array::value('amount', $values[$priceFiledID]);
1238 }
1239 }
1240 }
1241 if ($priceField->name == 'contribution_amount') {
1242 $priceFiledID = CRM_Utils_Array::value("price_{$priceField->id}", $params);
1243 if ($priceFiledID > 0 && !empty($priceFiledID)) {
1244 $params['amount'] = $priceFiledID;
1245 $this->_values['amount'] = CRM_Utils_Array::value('amount', $values[$priceFiledID]);
1246 $this->_values[$priceFiledID]['value'] = CRM_Utils_Array::value('amount', $values[$priceFiledID]);
1247 $this->_values[$priceFiledID]['label'] = CRM_Utils_Array::value('label', $values[$priceFiledID]);
1248 $this->_values[$priceFiledID]['amount_id'] = CRM_Utils_Array::value('id', $values[$priceFiledID]);
1249 $this->_values[$priceFiledID]['weight'] = CRM_Utils_Array::value('weight', $values[$priceFiledID]);
1250 }
1251 }
1252 if ($priceField->name == 'other_amount' && $priceFiledID = CRM_Utils_Array::value("price_{$priceField->id}", $params)) {
1253 $params['amount_other'] = $priceFiledID;
1254 }
1255 }
1256 }
1257 }
1258
1259 if (($this->_values['is_pay_later'] &&
1260 empty($this->_paymentProcessor) &&
1261 !array_key_exists('hidden_processor', $params)) ||
1262 CRM_Utils_Array::value('payment_processor', $params) == 0) {
1263 $params['is_pay_later'] = 1;
1264 }
1265 else {
1266 $params['is_pay_later'] = 0;
1267 }
1268
1269 $this->set('is_pay_later', $params['is_pay_later']);
1270 // assign pay later stuff
1271 $this->_params['is_pay_later'] = CRM_Utils_Array::value('is_pay_later', $params, FALSE);
1272 $this->assign('is_pay_later', $params['is_pay_later']);
1273 if ($params['is_pay_later']) {
1274 $this->assign('pay_later_text', $this->_values['pay_later_text']);
1275 $this->assign('pay_later_receipt', $this->_values['pay_later_receipt']);
1276 }
1277
1278 //carry campaign from profile.
1279 if (array_key_exists('contribution_campaign_id', $params)) {
1280 $params['campaign_id'] = $params['contribution_campaign_id'];
1281 }
1282
1283 if (CRM_Utils_Array::value('onbehalfof_id', $params)) {
1284 $params['organization_id'] = $params['onbehalfof_id'];
1285 }
1286
1287 $params['currencyID'] = $config->defaultCurrency;
1288 $params['amount'] = self::computeAmount($params, $this);
1289 $params['separate_amount'] = $params['amount'];
1290 $memFee = NULL;
1291 if (CRM_Utils_Array::value('selectMembership', $params)) {
1292 if (!empty($this->_membershipTypeValues)) {
1293 $membershipTypeValues = $this->_membershipTypeValues[$params['selectMembership']];
1294 }
1295 else {
1296 $membershipTypeValues = CRM_Member_BAO_Membership::buildMembershipTypeValues($this,
1297 $params['selectMembership']
1298 );
1299 }
1300 $memFee = $membershipTypeValues['minimum_fee'];
1301 if (!$params['amount'] && !$this->_separateMembershipPayment) {
1302 $params['amount'] = $memFee ? $memFee : 0;
1303 }
1304 }
1305
1306 //If the membership & contribution is used in contribution page & not seperate payment
1307 $fieldId = $memPresent = $membershipLabel = $fieldOption = $proceFieldAmount = $is_quick_config = NULL;
1308 if ($this->_separateMembershipPayment == 0) {
1309 $is_quick_config = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_Set', $this->_priceSetId, 'is_quick_config');
1310 if ($is_quick_config) {
1311 foreach ($this->_priceSet['fields'] as $fieldKey => $fieldVal) {
1312 if ($fieldVal['name'] == 'membership_amount') {
1313 $fieldId = $fieldVal['id'];
1314 $fieldOption = $params['price_' . $fieldId];
1315 $memPresent = TRUE;
1316 }
1317 else {
1318 if (CRM_Utils_Array::value('price_' . $fieldKey, $params) && $memPresent && ($fieldVal['name'] == 'other_amount' || $fieldVal['name'] == 'contribution_amount')) {
1319 $fieldId = $fieldVal['id'];
1320 if ($fieldVal['name'] == 'other_amount') {
1321 $proceFieldAmount = $this->_submitValues['price_' . $fieldId];
1322 }
1323 else $proceFieldAmount = $fieldVal['options'][$this->_submitValues['price_' . $fieldId]]['amount'];
1324 unset($params['price_' . $fieldId]);
1325 break;
1326 }
1327 }
1328 }
1329 }
1330 }
1331
1332 if (!isset($params['amount_other'])) {
1333 $this->set('amount_level', CRM_Utils_Array::value('amount_level', $params));
1334 }
1335
1336 if ($priceSetId = CRM_Utils_Array::value('priceSetId', $params)) {
1337 $lineItem = array();
1338 $is_quick_config = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_Set', $priceSetId, 'is_quick_config' );
1339 if ( $is_quick_config ) {
1340 foreach ( $this->_values['fee'] as $key => & $val ) {
1341 if ( $val['name'] == 'other_amount' && $val['html_type'] == 'Text' && array_key_exists( 'price_'.$key, $params ) && $params['price_'.$key] != 0 ) {
1342 foreach ( $val['options'] as $optionKey => & $options ) {
1343 $options['amount'] = CRM_Utils_Array::value( 'price_'.$key, $params );
1344 break;
1345 }
1346 $params['price_'.$key] = 1;
1347 break;
1348 }
1349 }
1350 }
1351
1352 $component = '';
1353 if ($this->_membershipBlock) {
1354 $component = 'membership';
1355 }
1356 CRM_Price_BAO_Set::processAmount($this->_values['fee'], $params, $lineItem[$priceSetId], $component);
1357
1358 if ($proceFieldAmount) {
1359 $lineItem[$params['priceSetId']][$fieldOption]['line_total'] = $proceFieldAmount;
1360 $lineItem[$params['priceSetId']][$fieldOption]['unit_price'] = $proceFieldAmount;
1361 if (!$this->_membershipBlock['is_separate_payment']) {
1362 $params['amount'] = $proceFieldAmount; //require when separate membership not used
1363 }
1364 }
1365 $this->set('lineItem', $lineItem);
1366 }
1367
1368 if ($this->_membershipBlock['is_separate_payment'] && CRM_Utils_Array::value('separate_amount', $params)) {
1369 $this->set('amount', $params['separate_amount']);
1370 } else {
1371 $this->set('amount', $params['amount']);
1372 }
1373
1374 // generate and set an invoiceID for this transaction
1375 $invoiceID = md5(uniqid(rand(), TRUE));
1376 $this->set('invoiceID', $invoiceID);
1377
1378 // required only if is_monetary and valid postive amount
1379 if ($this->_values['is_monetary'] &&
1380 is_array($this->_paymentProcessor) &&
1381 ((float ) $params['amount'] > 0.0 || $memFee > 0.0)
1382 ) {
1383
1384 // default mode is direct
1385 $this->set('contributeMode', 'direct');
1386
1387 if ($this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_BUTTON) {
1388 //get the button name
1389 $buttonName = $this->controller->getButtonName();
1390 if (in_array($buttonName,
1391 array($this->_expressButtonName, $this->_expressButtonName . '_x', $this->_expressButtonName . '_y')
1392 ) &&
1393 !CRM_Utils_Array::value('is_pay_later', $params)
1394 ) {
1395 $this->set('contributeMode', 'express');
1396
1397 $donateURL = CRM_Utils_System::url('civicrm/contribute', '_qf_Contribute_display=1');
1398 $params['cancelURL'] = CRM_Utils_System::url('civicrm/contribute/transact', "_qf_Main_display=1&qfKey={$params['qfKey']}", TRUE, NULL, FALSE);
1399 $params['returnURL'] = CRM_Utils_System::url('civicrm/contribute/transact', "_qf_Confirm_display=1&rfp=1&qfKey={$params['qfKey']}", TRUE, NULL, FALSE);
1400 $params['invoiceID'] = $invoiceID;
1401
1402 //default action is Sale
1403 $params['payment_action'] = 'Sale';
1404
1405 $payment = CRM_Core_Payment::singleton($this->_mode, $this->_paymentProcessor, $this);
1406 $token = $payment->setExpressCheckout($params);
1407 if (is_a($token, 'CRM_Core_Error')) {
1408 CRM_Core_Error::displaySessionError($token);
1409 CRM_Utils_System::redirect($params['cancelURL']);
1410 }
1411
1412 $this->set('token', $token);
1413
1414 $paymentURL = $this->_paymentProcessor['url_site'] . "/cgi-bin/webscr?cmd=_express-checkout&token=$token";
1415 CRM_Utils_System::redirect($paymentURL);
1416 }
1417 }
1418 elseif ($this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_NOTIFY) {
1419 $this->set('contributeMode', 'notify');
1420 }
1421 }
1422
1423 // should we skip the confirm page?
1424 if (!CRM_Utils_Array::value('is_confirm_enabled', $this->_values)) {
94fe3c35
DL
1425 // call the post process hook for the main page before we switch to confirm
1426 $this->postProcessHook();
1427
6a488035
TO
1428 // build the confirm page
1429 $confirmForm = &$this->controller->_pages['Confirm'];
1430 $confirmForm->preProcess();
1431 $confirmForm->buildQuickForm();
1432
1433 // the confirmation page is valid
1434 $data = &$this->controller->container();
1435 $data['valid']['Confirm'] = 1;
1436
1437 // confirm the contribution
94fe3c35
DL
1438 // mainProcess calls the hook also
1439 $confirmForm->mainProcess();
6a488035
TO
1440 $qfKey = $this->controller->_key;
1441
1442 // redirect to thank you page
1443 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contribute/transact', "_qf_ThankYou_display=1&qfKey=$qfKey", TRUE, NULL, FALSE));
1444 }
1445 }
1446}
1447