Implement xKerman/restricted-unserialize package to guard against unsafe unserialize
[civicrm-core.git] / CRM / Contribute / Form / ContributionPage / Amount.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
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-2019
32 */
33
34 /**
35 * form to process actions on the group aspect of Custom Data
36 */
37 class CRM_Contribute_Form_ContributionPage_Amount extends CRM_Contribute_Form_ContributionPage {
38
39 /**
40 * Contribution amount block.
41 *
42 * @var array
43 */
44 protected $_amountBlock = [];
45
46 /**
47 * Constants for number of options for data types of multiple option.
48 */
49 const NUM_OPTION = 11;
50
51 /**
52 * Build the form object.
53 */
54 public function buildQuickForm() {
55
56 // do u want to allow a free form text field for amount
57 $this->addElement('checkbox', 'is_allow_other_amount', ts('Allow other amounts'), NULL, ['onclick' => "minMax(this);showHideAmountBlock( this, 'is_allow_other_amount' );"]);
58 $this->add('text', 'min_amount', ts('Minimum Amount'), ['size' => 8, 'maxlength' => 8]);
59 $this->addRule('min_amount', ts('Please enter a valid money value (e.g. %1).', [1 => CRM_Utils_Money::format('9.99', ' ')]), 'money');
60
61 $this->add('text', 'max_amount', ts('Maximum Amount'), ['size' => 8, 'maxlength' => 8]);
62 $this->addRule('max_amount', ts('Please enter a valid money value (e.g. %1).', [1 => CRM_Utils_Money::format('99.99', ' ')]), 'money');
63
64 //CRM-12055
65 $this->add('text', 'amount_label', ts('Contribution Amounts Label'));
66
67 $default = [$this->createElement('radio', NULL, NULL, NULL, 0)];
68 $this->add('hidden', "price_field_id", '', ['id' => "price_field_id"]);
69 $this->add('hidden', "price_field_other", '', ['id' => "price_field_option"]);
70 for ($i = 1; $i <= self::NUM_OPTION; $i++) {
71 // label
72 $this->add('text', "label[$i]", ts('Label'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'label'));
73
74 $this->add('hidden', "price_field_value[$i]", '', ['id' => "price_field_value[$i]"]);
75
76 // value
77 $this->add('text', "value[$i]", ts('Value'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'value'));
78 $this->addRule("value[$i]", ts('Please enter a valid money value (e.g. %1).', [1 => CRM_Utils_Money::format('99.99', ' ')]), 'money');
79
80 // default
81 $default[] = $this->createElement('radio', NULL, NULL, NULL, $i);
82 }
83
84 $this->addGroup($default, 'default');
85
86 $this->addElement('checkbox', 'amount_block_is_active', ts('Contribution Amounts section enabled'), NULL, ['onclick' => "showHideAmountBlock( this, 'amount_block_is_active' );"]);
87
88 $this->addElement('checkbox', 'is_monetary', ts('Execute real-time monetary transactions'));
89
90 $paymentProcessors = CRM_Financial_BAO_PaymentProcessor::getAllPaymentProcessors('live');
91 $recurringPaymentProcessor = $futurePaymentProcessor = $paymentProcessor = [];
92
93 if (!empty($paymentProcessors)) {
94 foreach ($paymentProcessors as $id => $processor) {
95 if ($id != 0) {
96 $paymentProcessor[$id] = $processor['name'];
97 }
98 if (!empty($processor['is_recur'])) {
99 $recurringPaymentProcessor[] = $id;
100 }
101 if (!empty($processor['object']) && $processor['object']->supports('FutureRecurStartDate')) {
102 $futurePaymentProcessor[] = $id;
103 }
104 }
105 }
106 if (count($recurringPaymentProcessor)) {
107 $this->assign('recurringPaymentProcessor', $recurringPaymentProcessor);
108 }
109 if (count($futurePaymentProcessor)) {
110 $this->assign('futurePaymentProcessor', $futurePaymentProcessor);
111 }
112 if (count($paymentProcessor)) {
113 $this->assign('paymentProcessor', $paymentProcessor);
114 }
115
116 $this->addCheckBox('payment_processor', ts('Payment Processor'),
117 array_flip($paymentProcessor),
118 NULL, NULL, NULL, NULL,
119 ['&nbsp;&nbsp;', '&nbsp;&nbsp;', '&nbsp;&nbsp;', '<br/>']
120 );
121
122 //check if selected payment processor supports recurring payment
123 if (!empty($recurringPaymentProcessor)) {
124 $this->addElement('checkbox', 'is_recur', ts('Recurring Contributions'), NULL,
125 ['onclick' => "showHideByValue('is_recur',true,'recurFields','table-row','radio',false);"]
126 );
127 $this->addCheckBox('recur_frequency_unit', ts('Supported recurring units'),
128 CRM_Core_OptionGroup::values('recur_frequency_units', FALSE, FALSE, TRUE),
129 NULL, NULL, NULL, NULL,
130 ['&nbsp;&nbsp;', '&nbsp;&nbsp;', '&nbsp;&nbsp;', '<br/>'], TRUE
131 );
132 $this->addElement('checkbox', 'is_recur_interval', ts('Support recurring intervals'));
133 $this->addElement('checkbox', 'is_recur_installments', ts('Offer installments'));
134 }
135
136 // add pay later options
137 $this->addElement('checkbox', 'is_pay_later', ts('Pay later option'), NULL);
138 $this->addElement('textarea', 'pay_later_text', ts('Pay later label'),
139 CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'pay_later_text'),
140 FALSE
141 );
142 $this->add('wysiwyg', 'pay_later_receipt', ts('Pay Later Instructions'), CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_ContributionPage', 'pay_later_receipt'));
143 $this->addElement('checkbox', 'is_billing_required', ts('Billing address required'));
144
145 //add partial payment options
146
147 // add price set fields
148 $price = CRM_Price_BAO_PriceSet::getAssoc(FALSE, 'CiviContribute');
149 if (CRM_Utils_System::isNull($price)) {
150 $this->assign('price', FALSE);
151 }
152 else {
153 $this->assign('price', TRUE);
154 }
155
156 $this->addField('price_set_id', [
157 'entity' => 'PriceSet',
158 'options' => $price,
159 'onchange' => "showHideAmountBlock( this.value, 'price_set_id' );",
160 ]);
161
162 //CiviPledge fields.
163 $config = CRM_Core_Config::singleton();
164 if (in_array('CiviPledge', $config->enableComponents)) {
165 $this->assign('civiPledge', TRUE);
166 $this->addElement('checkbox', 'is_pledge_active', ts('Pledges'),
167 NULL, ['onclick' => "showHideAmountBlock( this, 'is_pledge_active' ); return showHideByValue('is_pledge_active',true,'pledgeFields','table-row','radio',false);"]
168 );
169 $this->addCheckBox('pledge_frequency_unit', ts('Supported pledge frequencies'),
170 CRM_Core_OptionGroup::values('recur_frequency_units', FALSE, FALSE, TRUE),
171 NULL, NULL, NULL, NULL,
172 ['&nbsp;&nbsp;', '&nbsp;&nbsp;', '&nbsp;&nbsp;', '<br/>'], TRUE
173 );
174 $this->addElement('checkbox', 'is_pledge_interval', ts('Allow frequency intervals'));
175 $this->addElement('text', 'initial_reminder_day', ts('Send payment reminder'), ['size' => 3]);
176 $this->addElement('text', 'max_reminders', ts('Send up to'), ['size' => 3]);
177 $this->addElement('text', 'additional_reminder_day', ts('Send additional reminders'), ['size' => 3]);
178 if (!empty($futurePaymentProcessor)) {
179 // CRM-18854
180 $this->addElement('checkbox', 'adjust_recur_start_date', ts('Adjust Recurring Start Date'), NULL,
181 ['onclick' => "showHideByValue('adjust_recur_start_date',true,'recurDefaults','table-row','radio',false);"]
182 );
183 $this->add('datepicker', 'pledge_calendar_date', ts('Specific Calendar Date'), [], FALSE, ['time' => FALSE]);
184 $month = CRM_Utils_Date::getCalendarDayOfMonth();
185 $this->add('select', 'pledge_calendar_month', ts('Specific day of Month'), $month);
186 $pledgeDefaults = [
187 'contribution_date' => ts('Day of Contribution'),
188 'calendar_date' => ts('Specific Calendar Date'),
189 'calendar_month' => ts('Specific day of Month'),
190 ];
191 $this->addRadio('pledge_default_toggle', ts('Recurring Contribution Start Date Default'), $pledgeDefaults, ['allowClear' => FALSE], '<br/><br/>');
192 $this->addElement('checkbox', 'is_pledge_start_date_visible', ts('Show Recurring Donation Start Date?'), NULL);
193 $this->addElement('checkbox', 'is_pledge_start_date_editable', ts('Allow Edits to Recurring Donation Start date?'), NULL);
194 }
195 }
196
197 //add currency element.
198 $this->addCurrency('currency', ts('Currency'));
199
200 $this->addFormRule(['CRM_Contribute_Form_ContributionPage_Amount', 'formRule'], $this);
201
202 parent::buildQuickForm();
203 }
204
205 /**
206 * Set default values for the form. Note that in edit/view mode
207 * the default values are retrieved from the database
208 *
209 *
210 * @return array
211 */
212 public function setDefaultValues() {
213 $defaults = parent::setDefaultValues();
214
215 if (empty($defaults['pay_later_text'])) {
216 $defaults['pay_later_text'] = ts('I will send payment by check');
217 }
218
219 if (!empty($defaults['amount_block_is_active'])) {
220
221 if ($priceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $this->_id, NULL)) {
222 if ($isQuick = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config')) {
223 $this->assign('isQuick', $isQuick);
224 //$priceField = CRM_Core_DAO::getFieldValue( 'CRM_Price_DAO_PriceField', $priceSetId, 'id', 'price_set_id' );
225 $options = $pFIDs = [];
226 $priceFieldParams = ['price_set_id' => $priceSetId];
227 $priceFields = CRM_Core_DAO::commonRetrieveAll('CRM_Price_DAO_PriceField', 'price_set_id', $priceSetId, $pFIDs, $return = [
228 'html_type',
229 'name',
230 'is_active',
231 'label',
232 ]);
233 foreach ($priceFields as $priceField) {
234 if ($priceField['id'] && $priceField['html_type'] == 'Radio' && $priceField['name'] == 'contribution_amount') {
235 $defaults['price_field_id'] = $priceField['id'];
236 $priceFieldOptions = CRM_Price_BAO_PriceFieldValue::getValues($priceField['id'], $options, 'id', 1);
237 if (empty($priceFieldOptions)) {
238 continue;
239 }
240 $countRow = 0;
241 $defaults['amount_label'] = $priceField['label'];
242 foreach ($options as $optionId => $optionValue) {
243 $countRow++;
244 $defaults['value'][$countRow] = $optionValue['amount'];
245 $defaults['label'][$countRow] = CRM_Utils_Array::value('label', $optionValue);
246 $defaults['name'][$countRow] = CRM_Utils_Array::value('name', $optionValue);
247 $defaults['weight'][$countRow] = $optionValue['weight'];
248
249 $defaults["price_field_value"][$countRow] = $optionValue['id'];
250 if ($optionValue['is_default']) {
251 $defaults['default'] = $countRow;
252 }
253 }
254 }
255 elseif ($priceField['id'] && $priceField['html_type'] == 'Text' && $priceField['name'] = 'other_amount' && $priceField['is_active']) {
256 $defaults['price_field_other'] = $priceField['id'];
257 if (!isset($defaults['amount_label'])) {
258 $defaults['amount_label'] = $priceField['label'];
259 }
260 }
261 }
262 }
263 }
264
265 if (empty($defaults['amount_label'])) {
266 $defaults['amount_label'] = ts('Contribution Amount');
267 }
268
269 if (!empty($defaults['value']) && is_array($defaults['value'])) {
270
271 // CRM-4038: fix value display
272 foreach ($defaults['value'] as & $amount) {
273 $amount = trim(CRM_Utils_Money::format($amount, ' '));
274 }
275 }
276 }
277
278 // fix the display of the monetary value, CRM-4038
279 if (isset($defaults['min_amount'])) {
280 $defaults['min_amount'] = CRM_Utils_Money::format($defaults['min_amount'], NULL, '%a');
281 }
282 if (isset($defaults['max_amount'])) {
283 $defaults['max_amount'] = CRM_Utils_Money::format($defaults['max_amount'], NULL, '%a');
284 }
285
286 if (!empty($defaults['payment_processor'])) {
287 $defaults['payment_processor'] = array_fill_keys(explode(CRM_Core_DAO::VALUE_SEPARATOR,
288 $defaults['payment_processor']
289 ), '1');
290 }
291 return $defaults;
292 }
293
294 /**
295 * Global form rule.
296 *
297 * @param array $fields
298 * The input form values.
299 * @param array $files
300 * The uploaded files if any.
301 * @param $self
302 *
303 *
304 * @return bool|array
305 * true if no errors, else array of errors
306 */
307 public static function formRule($fields, $files, $self) {
308 $errors = [];
309 //as for separate membership payment we has to have
310 //contribution amount section enabled, hence to disable it need to
311 //check if separate membership payment enabled,
312 //if so disable first separate membership payment option
313 //then disable contribution amount section. CRM-3801,
314
315 $membershipBlock = new CRM_Member_DAO_MembershipBlock();
316 $membershipBlock->entity_table = 'civicrm_contribution_page';
317 $membershipBlock->entity_id = $self->_id;
318 $membershipBlock->is_active = 1;
319 $hasMembershipBlk = FALSE;
320 if ($membershipBlock->find(TRUE)) {
321 if (!empty($fields['amount_block_is_active']) &&
322 ($setID = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $self->_id, NULL, 1))
323 ) {
324 $extends = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $setID, 'extends');
325 if ($extends && $extends == CRM_Core_Component::getComponentID('CiviMember')) {
326 $errors['amount_block_is_active'] = ts('You cannot use a Membership Price Set when the Contribution Amounts section is enabled. Click the Memberships tab above, and select your Membership Price Set on that form. Membership Price Sets may include additional fields for non-membership options that require an additional fee (e.g. magazine subscription) or an additional voluntary contribution.');
327 return $errors;
328 }
329 }
330 $hasMembershipBlk = TRUE;
331 if ($membershipBlock->is_separate_payment && empty($fields['amount_block_is_active'])) {
332 $errors['amount_block_is_active'] = ts('To disable Contribution Amounts section you need to first disable Separate Membership Payment option from Membership Settings.');
333 }
334
335 //CRM-16165, Don't allow reccuring contribution if membership block contain any renewable membership option
336 $membershipTypes = CRM_Utils_String::unserialize($membershipBlock->membership_types);
337 if (!empty($fields['is_recur']) && !empty($membershipTypes)) {
338 if (!$membershipBlock->is_separate_payment) {
339 $errors['is_recur'] = ts('You need to enable Separate Membership Payment when online contribution page is configured for both Membership and Recurring Contribution.');
340 }
341 elseif (count(array_filter($membershipTypes)) != 0) {
342 $errors['is_recur'] = ts('You cannot enable both Recurring Contributions and Auto-renew memberships on the same online contribution page.');
343 }
344 }
345 }
346
347 // CRM-18854 Check if recurring start date is in the future.
348 if (!empty($fields['pledge_calendar_date'])) {
349 if (date('Ymd') > date('Ymd', strtotime($fields['pledge_calendar_date']))) {
350 $errors['pledge_calendar_date'] = ts('The recurring start date cannot be prior to the current date.');
351 }
352 }
353
354 //check for the amount label (mandatory)
355 if (!empty($fields['amount_block_is_active']) && empty($fields['price_set_id']) && empty($fields['amount_label'])) {
356 $errors['amount_label'] = ts('Please enter the contribution amount label.');
357 }
358 $minAmount = CRM_Utils_Array::value('min_amount', $fields);
359 $maxAmount = CRM_Utils_Array::value('max_amount', $fields);
360 if (!empty($minAmount) && !empty($maxAmount)) {
361 $minAmount = CRM_Utils_Rule::cleanMoney($minAmount);
362 $maxAmount = CRM_Utils_Rule::cleanMoney($maxAmount);
363 if ((float ) $minAmount > (float ) $maxAmount) {
364 $errors['min_amount'] = ts('Minimum Amount should be less than Maximum Amount');
365 }
366 }
367
368 if (isset($fields['is_pay_later'])) {
369 if (empty($fields['pay_later_text'])) {
370 $errors['pay_later_text'] = ts('Please enter the text for the \'pay later\' checkbox displayed on the contribution form.');
371 }
372 if (empty($fields['pay_later_receipt'])) {
373 $errors['pay_later_receipt'] = ts('Please enter the instructions to be sent to the contributor when they choose to \'pay later\'.');
374 }
375 }
376 else {
377 if ($fields['amount_block_is_active'] && empty($fields['payment_processor'])) {
378 $errors['payment_processor'] = ts('You have listed fixed contribution options or selected a price set, but no payment option has been selected. Please select at least one payment processor and/or enable the pay later option.');
379 }
380 }
381
382 // don't allow price set w/ membership signup, CRM-5095
383 if ($priceSetId = CRM_Utils_Array::value('price_set_id', $fields)) {
384 // don't allow price set w/ membership.
385 if ($hasMembershipBlk) {
386 $errors['price_set_id'] = ts('You cannot enable both a Contribution Price Set and Membership Signup on the same online contribution page.');
387 }
388 }
389 else {
390 if (isset($fields['is_recur'])) {
391 if (empty($fields['recur_frequency_unit'])) {
392 $errors['recur_frequency_unit'] = ts('At least one recurring frequency option needs to be checked.');
393 }
394 }
395
396 // validation for pledge fields.
397 if (!empty($fields['is_pledge_active'])) {
398 if (empty($fields['pledge_frequency_unit'])) {
399 $errors['pledge_frequency_unit'] = ts('At least one pledge frequency option needs to be checked.');
400 }
401 if (!empty($fields['is_recur'])) {
402 $errors['is_recur'] = ts('You cannot enable both Recurring Contributions AND Pledges on the same online contribution page.');
403 }
404 }
405
406 // If Contribution amount section is enabled, then
407 // Allow other amounts must be enabled OR the Fixed Contribution
408 // Contribution options must contain at least one set of values.
409 if (!empty($fields['amount_block_is_active'])) {
410 if (empty($fields['is_allow_other_amount']) &&
411 !$priceSetId
412 ) {
413 //get the values of amount block
414 $values = CRM_Utils_Array::value('value', $fields);
415 $isSetRow = FALSE;
416 for ($i = 1; $i < self::NUM_OPTION; $i++) {
417 if ((isset($values[$i]) && (strlen(trim($values[$i])) > 0))) {
418 $isSetRow = TRUE;
419 }
420 }
421 if (!$isSetRow) {
422 $errors['amount_block_is_active'] = ts('If you want to enable the \'Contribution Amounts section\', you need to either \'Allow Other Amounts\' and/or enter at least one row in the \'Fixed Contribution Amounts\' table.');
423 }
424 }
425 }
426 }
427
428 if (!empty($fields['payment_processor']) && $financialType = CRM_Contribute_BAO_Contribution::validateFinancialType($self->_defaultValues['financial_type_id'])) {
429 $errors['payment_processor'] = ts("Financial Account of account relationship of 'Expense Account is' is not configured for Financial Type : ") . $financialType;
430 }
431
432 return $errors;
433 }
434
435 /**
436 * Process the form.
437 */
438 public function postProcess() {
439 // get the submitted form values.
440 $params = $this->controller->exportValues($this->_name);
441
442 //update 'is_billing_required'
443 if (empty($params['is_pay_later'])) {
444 $params['is_billing_required'] = 0;
445 }
446
447 if (array_key_exists('payment_processor', $params)) {
448 if (array_key_exists(CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessor', 'AuthNet',
449 'id', 'payment_processor_type_id'
450 ),
451 CRM_Utils_Array::value('payment_processor', $params)
452 )) {
453 CRM_Core_Session::setStatus(ts(' Please note that the Authorize.net payment processor only allows recurring contributions and auto-renew memberships with payment intervals from 7-365 days or 1-12 months (i.e. not greater than 1 year).'), '', 'alert');
454 }
455 }
456
457 // check for price set.
458 $priceSetID = CRM_Utils_Array::value('price_set_id', $params);
459
460 // get required fields.
461 $fields = [
462 'id' => $this->_id,
463 'is_recur' => FALSE,
464 'min_amount' => "null",
465 'max_amount' => "null",
466 'is_monetary' => FALSE,
467 'is_pay_later' => FALSE,
468 'is_billing_required' => FALSE,
469 'is_recur_interval' => FALSE,
470 'is_recur_installments' => FALSE,
471 'recur_frequency_unit' => "null",
472 'default_amount_id' => "null",
473 'is_allow_other_amount' => FALSE,
474 'amount_block_is_active' => FALSE,
475 ];
476 $resetFields = [];
477 if ($priceSetID) {
478 $resetFields = ['min_amount', 'max_amount', 'is_allow_other_amount'];
479 }
480
481 if (empty($params['is_recur'])) {
482 $resetFields = array_merge($resetFields, ['is_recur_interval', 'recur_frequency_unit']);
483 }
484
485 foreach ($fields as $field => $defaultVal) {
486 $val = CRM_Utils_Array::value($field, $params, $defaultVal);
487 if (in_array($field, $resetFields)) {
488 $val = $defaultVal;
489 }
490
491 if (in_array($field, [
492 'min_amount',
493 'max_amount',
494 ])) {
495 $val = CRM_Utils_Rule::cleanMoney($val);
496 }
497
498 $params[$field] = $val;
499 }
500
501 if ($params['is_recur']) {
502 $params['recur_frequency_unit'] = implode(CRM_Core_DAO::VALUE_SEPARATOR,
503 array_keys($params['recur_frequency_unit'])
504 );
505 $params['is_recur_interval'] = CRM_Utils_Array::value('is_recur_interval', $params, FALSE);
506 $params['is_recur_installments'] = CRM_Utils_Array::value('is_recur_installments', $params, FALSE);
507 }
508
509 if (!empty($params['adjust_recur_start_date'])) {
510 $fieldValue = '';
511 $pledgeDateFields = [
512 'calendar_date' => 'pledge_calendar_date',
513 'calendar_month' => 'pledge_calendar_month',
514 ];
515 if ($params['pledge_default_toggle'] == 'contribution_date') {
516 $fieldValue = json_encode(['contribution_date' => date('Y-m-d')]);
517 }
518 else {
519 foreach ($pledgeDateFields as $key => $pledgeDateField) {
520 if (!empty($params[$pledgeDateField]) && $params['pledge_default_toggle'] == $key) {
521 $fieldValue = json_encode([$key => $params[$pledgeDateField]]);
522 break;
523 }
524 }
525 }
526 $params['pledge_start_date'] = $fieldValue;
527 }
528 else {
529 $params['pledge_start_date'] = '';
530 $params['adjust_recur_start_date'] = 0;
531 $params['is_pledge_start_date_visible'] = 0;
532 $params['is_pledge_start_date_editable'] = 0;
533 }
534 if (empty($params['is_pledge_start_date_visible'])) {
535 $params['is_pledge_start_date_visible'] = 0;
536 }
537 if (empty($params['is_pledge_start_date_editable'])) {
538 $params['is_pledge_start_date_editable'] = 0;
539 }
540
541 if (array_key_exists('payment_processor', $params) &&
542 !CRM_Utils_System::isNull($params['payment_processor'])
543 ) {
544 $params['payment_processor'] = implode(CRM_Core_DAO::VALUE_SEPARATOR, array_keys($params['payment_processor']));
545 }
546 else {
547 $params['payment_processor'] = 'null';
548 }
549
550 $contributionPage = CRM_Contribute_BAO_ContributionPage::create($params);
551 $contributionPageID = $contributionPage->id;
552
553 // prepare for data cleanup.
554 $deleteAmountBlk = $deletePledgeBlk = $deletePriceSet = FALSE;
555 if ($this->_priceSetID) {
556 $deletePriceSet = TRUE;
557 }
558 if ($this->_pledgeBlockID) {
559 $deletePledgeBlk = TRUE;
560 }
561 if (!empty($this->_amountBlock)) {
562 $deleteAmountBlk = TRUE;
563 }
564
565 if ($contributionPageID) {
566
567 if (!empty($params['amount_block_is_active'])) {
568 // handle price set.
569 if ($priceSetID) {
570 // add/update price set.
571 $deletePriceSet = FALSE;
572 if (!empty($params['price_field_id']) || !empty($params['price_field_other'])) {
573 $deleteAmountBlk = TRUE;
574 }
575
576 CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $contributionPageID, $priceSetID);
577 }
578 else {
579
580 $deletePriceSet = FALSE;
581 // process contribution amount block
582 $deleteAmountBlk = FALSE;
583
584 $labels = CRM_Utils_Array::value('label', $params);
585 $values = CRM_Utils_Array::value('value', $params);
586 $default = CRM_Utils_Array::value('default', $params);
587
588 $options = [];
589 for ($i = 1; $i < self::NUM_OPTION; $i++) {
590 if (isset($values[$i]) &&
591 (strlen(trim($values[$i])) > 0)
592 ) {
593 $values[$i] = $params['value'][$i] = CRM_Utils_Rule::cleanMoney(trim($values[$i]));
594 $options[] = [
595 'label' => trim($labels[$i]),
596 'value' => $values[$i],
597 'weight' => $i,
598 'is_active' => 1,
599 'is_default' => $default == $i,
600 ];
601 }
602 }
603 /* || !empty($params['price_field_value']) || CRM_Utils_Array::value( 'price_field_other', $params )*/
604 if (!empty($options) || !empty($params['is_allow_other_amount'])) {
605 $fieldParams['is_quick_config'] = 1;
606 $noContriAmount = NULL;
607 $usedPriceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $this->_id, 3);
608 if (!(!empty($params['price_field_id']) || !empty($params['price_field_other'])) && !$usedPriceSetId) {
609 $pageTitle = strtolower(CRM_Utils_String::munge($this->_values['title'], '_', 245));
610 $setParams['title'] = $this->_values['title'];
611 if (!CRM_Core_DAO::getFieldValue('CRM_Price_BAO_PriceSet', $pageTitle, 'id', 'name')) {
612 $setParams['name'] = $pageTitle;
613 }
614 elseif (!CRM_Core_DAO::getFieldValue('CRM_Price_BAO_PriceSet', $pageTitle . '_' . $this->_id, 'id', 'name')) {
615 $setParams['name'] = $pageTitle . '_' . $this->_id;
616 }
617 else {
618 $timeSec = explode(".", microtime(TRUE));
619 $setParams['name'] = $pageTitle . '_' . date('is', $timeSec[0]) . $timeSec[1];
620 }
621 $setParams['is_quick_config'] = 1;
622 $setParams['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $this->_values);
623 $setParams['extends'] = CRM_Core_Component::getComponentID('CiviContribute');
624 $priceSet = CRM_Price_BAO_PriceSet::create($setParams);
625 $priceSetId = $priceSet->id;
626 }
627 elseif ($usedPriceSetId && empty($params['price_field_id'])) {
628 $priceSetId = $usedPriceSetId;
629 }
630 else {
631 if ($priceFieldId = CRM_Utils_Array::value('price_field_id', $params)) {
632 foreach ($params['price_field_value'] as $arrayID => $fieldValueID) {
633 if (empty($params['label'][$arrayID]) && empty($params['value'][$arrayID]) && !empty($fieldValueID)) {
634 CRM_Price_BAO_PriceFieldValue::setIsActive($fieldValueID, '0');
635 unset($params['price_field_value'][$arrayID]);
636 }
637 }
638 if (implode('', $params['price_field_value'])) {
639 $fieldParams['id'] = CRM_Utils_Array::value('price_field_id', $params);
640 $fieldParams['option_id'] = $params['price_field_value'];
641 }
642 else {
643 $noContriAmount = 0;
644 CRM_Price_BAO_PriceField::setIsActive($priceFieldId, '0');
645 }
646 }
647 else {
648 $priceFieldId = CRM_Utils_Array::value('price_field_other', $params);
649 }
650 $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $priceFieldId, 'price_set_id');
651 }
652 CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $this->_id, $priceSetId);
653 if (!empty($options)) {
654 $editedFieldParams = [
655 'price_set_id' => $priceSetId,
656 'name' => 'contribution_amount',
657 ];
658 $editedResults = [];
659 $noContriAmount = 1;
660 CRM_Price_BAO_PriceField::retrieve($editedFieldParams, $editedResults);
661 if (empty($editedResults['id'])) {
662 $fieldParams['name'] = strtolower(CRM_Utils_String::munge("Contribution Amount", '_', 245));
663 }
664 else {
665 $fieldParams['id'] = CRM_Utils_Array::value('id', $editedResults);
666 }
667
668 $fieldParams['price_set_id'] = $priceSetId;
669 $fieldParams['is_active'] = 1;
670 $fieldParams['weight'] = 2;
671
672 if (!empty($params['is_allow_other_amount'])) {
673 $fieldParams['is_required'] = 0;
674 }
675 else {
676 $fieldParams['is_required'] = 1;
677 }
678 $fieldParams['label'] = $params['amount_label'];
679 $fieldParams['html_type'] = 'Radio';
680 $fieldParams['option_label'] = $params['label'];
681 $fieldParams['option_amount'] = $params['value'];
682 $fieldParams['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $this->_values);
683 foreach ($options as $value) {
684 $fieldParams['option_weight'][$value['weight']] = $value['weight'];
685 }
686 $fieldParams['default_option'] = $params['default'];
687 $priceField = CRM_Price_BAO_PriceField::create($fieldParams);
688 }
689 if (!empty($params['is_allow_other_amount']) && empty($params['price_field_other'])) {
690 $editedFieldParams = [
691 'price_set_id' => $priceSetId,
692 'name' => 'other_amount',
693 ];
694 $editedResults = [];
695
696 CRM_Price_BAO_PriceField::retrieve($editedFieldParams, $editedResults);
697
698 if (!$priceFieldID = CRM_Utils_Array::value('id', $editedResults)) {
699 $fieldParams = [
700 'name' => 'other_amount',
701 'label' => ts('Other Amount'),
702 'price_set_id' => $priceSetId,
703 'html_type' => 'Text',
704 'financial_type_id' => CRM_Utils_Array::value('financial_type_id', $this->_values),
705 'is_display_amounts' => 0,
706 'weight' => 3,
707 ];
708 $fieldParams['option_weight'][1] = 1;
709 $fieldParams['option_amount'][1] = 1;
710 if (!$noContriAmount) {
711 $fieldParams['is_required'] = 1;
712 $fieldParams['option_label'][1] = $fieldParams['label'] = $params['amount_label'];
713 }
714 else {
715 $fieldParams['is_required'] = 0;
716 $fieldParams['option_label'][1] = $fieldParams['label'] = ts('Other Amount');
717 }
718
719 $priceField = CRM_Price_BAO_PriceField::create($fieldParams);
720 }
721 else {
722 if (empty($editedResults['is_active'])) {
723 $fieldParams = $editedResults;
724 if (!$noContriAmount) {
725 $priceFieldValueID = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldID, 'id', 'price_field_id');
726 CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldValueID, 'label', $params['amount_label']);
727 $fieldParams = [
728 'is_required' => 1,
729 'label' => $params['amount_label'],
730 'id' => $priceFieldID,
731 ];
732 }
733 $fieldParams['is_active'] = 1;
734 $priceField = CRM_Price_BAO_PriceField::add($fieldParams);
735 }
736 }
737 }
738 elseif (empty($params['is_allow_other_amount']) && !empty($params['price_field_other'])) {
739 CRM_Price_BAO_PriceField::setIsActive($params['price_field_other'], '0');
740 }
741 elseif ($priceFieldID = CRM_Utils_Array::value('price_field_other', $params)) {
742 $priceFieldValueID = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldID, 'id', 'price_field_id');
743 if (!$noContriAmount) {
744 $fieldParams = [
745 'is_required' => 1,
746 'label' => $params['amount_label'],
747 'id' => $priceFieldID,
748 ];
749 CRM_Price_BAO_PriceField::add($fieldParams);
750 CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldValueID, 'label', $params['amount_label']);
751 }
752 else {
753 CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceField', $priceFieldID, 'is_required', 0);
754 CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceFieldValue', $priceFieldValueID, 'label', ts('Other Amount'));
755 }
756 }
757 }
758
759 if (!empty($params['is_pledge_active'])) {
760 $deletePledgeBlk = FALSE;
761 $pledgeBlockParams = [
762 'entity_id' => $contributionPageID,
763 'entity_table' => ts('civicrm_contribution_page'),
764 ];
765 if ($this->_pledgeBlockID) {
766 $pledgeBlockParams['id'] = $this->_pledgeBlockID;
767 }
768 $pledgeBlock = [
769 'pledge_frequency_unit',
770 'max_reminders',
771 'initial_reminder_day',
772 'additional_reminder_day',
773 'pledge_start_date',
774 'is_pledge_start_date_visible',
775 'is_pledge_start_date_editable',
776 ];
777 foreach ($pledgeBlock as $key) {
778 $pledgeBlockParams[$key] = CRM_Utils_Array::value($key, $params);
779 }
780 $pledgeBlockParams['is_pledge_interval'] = CRM_Utils_Array::value('is_pledge_interval',
781 $params, FALSE
782 );
783 $pledgeBlockParams['pledge_start_date'] = CRM_Utils_Array::value('pledge_start_date',
784 $params, FALSE
785 );
786 // create pledge block.
787 CRM_Pledge_BAO_PledgeBlock::create($pledgeBlockParams);
788 }
789 }
790 }
791 else {
792 if (!empty($params['price_field_id']) || !empty($params['price_field_other'])) {
793 $usedPriceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_contribution_page', $this->_id, 3);
794 if ($usedPriceSetId) {
795 if (!empty($params['price_field_id'])) {
796 CRM_Price_BAO_PriceField::setIsActive($params['price_field_id'], '0');
797 }
798 if (!empty($params['price_field_other'])) {
799 CRM_Price_BAO_PriceField::setIsActive($params['price_field_other'], '0');
800 }
801 }
802 else {
803 $deleteAmountBlk = TRUE;
804 $deletePriceSet = TRUE;
805 }
806 }
807 }
808
809 // delete pledge block.
810 if ($deletePledgeBlk) {
811 CRM_Pledge_BAO_PledgeBlock::deletePledgeBlock($this->_pledgeBlockID);
812 }
813
814 // delete previous price set.
815 if ($deletePriceSet) {
816 CRM_Price_BAO_PriceSet::removeFrom('civicrm_contribution_page', $contributionPageID);
817 }
818
819 if ($deleteAmountBlk) {
820 $priceField = !empty($params['price_field_id']) ? $params['price_field_id'] : CRM_Utils_Array::value('price_field_other', $params);
821 if ($priceField) {
822 $priceSetID = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $priceField, 'price_set_id');
823 CRM_Price_BAO_PriceSet::setIsQuickConfig($priceSetID, 0);
824 }
825 }
826 }
827 parent::endPostProcess();
828 }
829
830 /**
831 * Return a descriptive name for the page, used in wizard header
832 *
833 * @return string
834 */
835 public function getTitle() {
836 return ts('Amounts');
837 }
838
839 }