Update Copywrite year to be 2019
[civicrm-core.git] / CRM / Admin / Form / PaymentProcessor.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
32 */
33
34/**
ce064e4f 35 * This class generates form components for Payment Processor.
6a488035
TO
36 */
37class CRM_Admin_Form_PaymentProcessor extends CRM_Admin_Form {
38 protected $_id = NULL;
39
40 protected $_testID = NULL;
41
42 protected $_fields = NULL;
43
8461467c
MW
44 protected $_paymentProcessorDAO;
45
46 /**
47 * @var int $_paymentProcessorType Payment processor Type ID
48 */
49 protected $_paymentProcessorType;
8ef12e64 50
1d2a585a 51 /**
b30c9316 52 * Get the name of the base entity being edited.
1d2a585a 53 *
54 * @return string
1d2a585a 55 */
56 public function getDefaultEntity() {
57 return 'PaymentProcessor';
58 }
59
00be9182 60 public function preProcess() {
6a488035
TO
61 parent::preProcess();
62
6a488035 63 if ($this->_id) {
8461467c
MW
64 $this->_paymentProcessorType = CRM_Utils_Request::retrieve('pp', 'String', $this, FALSE, NULL);
65 if (!$this->_paymentProcessorType) {
66 $this->_paymentProcessorType = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessor',
6a488035
TO
67 $this->_id,
68 'payment_processor_type_id'
69 );
70 }
8461467c 71 $this->set('pp', $this->_paymentProcessorType);
6a488035
TO
72 }
73 else {
8461467c 74 $this->_paymentProcessorType = CRM_Utils_Request::retrieve('pp', 'String', $this, TRUE, NULL);
6a488035
TO
75 }
76
8461467c 77 $this->assign('ppType', $this->_paymentProcessorType);
481a74f4 78 $ppTypeName = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessorType',
8461467c 79 $this->_paymentProcessorType,
6a488035
TO
80 'name'
81 );
481a74f4 82 $this->assign('ppTypeName', $ppTypeName);
6a488035 83
8461467c
MW
84 $this->_paymentProcessorDAO = new CRM_Financial_DAO_PaymentProcessorType();
85 $this->_paymentProcessorDAO->id = $this->_paymentProcessorType;
6a488035 86
8461467c 87 $this->_paymentProcessorDAO->find(TRUE);
6a488035
TO
88
89 if ($this->_id) {
90 $refreshURL = CRM_Utils_System::url('civicrm/admin/paymentProcessor',
91 "reset=1&action=update&id={$this->_id}",
92 FALSE, NULL, FALSE
93 );
94 }
95 else {
96 $refreshURL = CRM_Utils_System::url('civicrm/admin/paymentProcessor',
97 "reset=1&action=add",
98 FALSE, NULL, FALSE
99 );
100 }
101
102 //CRM-4129
103 $destination = CRM_Utils_Request::retrieve('civicrmDestination', 'String', $this);
104 if ($destination) {
105 $destination = urlencode($destination);
106 $refreshURL .= "&civicrmDestination=$destination";
107 }
108
3eecd5bc 109 $this->refreshURL = $refreshURL;
6a488035
TO
110 $this->assign('refreshURL', $refreshURL);
111
8461467c 112 $this->assign('is_recur', $this->_paymentProcessorDAO->is_recur);
6a488035
TO
113
114 $this->_fields = array(
115 array(
116 'name' => 'user_name',
8461467c 117 'label' => $this->_paymentProcessorDAO->user_name_label,
6a488035
TO
118 ),
119 array(
120 'name' => 'password',
8461467c 121 'label' => $this->_paymentProcessorDAO->password_label,
6a488035
TO
122 ),
123 array(
124 'name' => 'signature',
8461467c 125 'label' => $this->_paymentProcessorDAO->signature_label,
6a488035
TO
126 ),
127 array(
128 'name' => 'subject',
8461467c 129 'label' => $this->_paymentProcessorDAO->subject_label,
6a488035
TO
130 ),
131 array(
132 'name' => 'url_site',
133 'label' => ts('Site URL'),
134 'rule' => 'url',
135 'msg' => ts('Enter a valid URL'),
136 ),
137 );
138
8461467c 139 if ($this->_paymentProcessorDAO->is_recur) {
6a488035
TO
140 $this->_fields[] = array(
141 'name' => 'url_recur',
142 'label' => ts('Recurring Payments URL'),
143 'rule' => 'url',
144 'msg' => ts('Enter a valid URL'),
145 );
146 }
147
8461467c 148 if (!empty($this->_paymentProcessorDAO->url_button_default)) {
6a488035
TO
149 $this->_fields[] = array(
150 'name' => 'url_button',
151 'label' => ts('Button URL'),
152 'rule' => 'url',
153 'msg' => ts('Enter a valid URL'),
154 );
155 }
156
8461467c 157 if (!empty($this->_paymentProcessorDAO->url_api_default)) {
6a488035
TO
158 $this->_fields[] = array(
159 'name' => 'url_api',
160 'label' => ts('API URL'),
161 'rule' => 'url',
162 'msg' => ts('Enter a valid URL'),
163 );
164 }
165 }
166
167 /**
eceb18cc 168 * Build the form object.
6a488035 169 *
fd31fa4c 170 * @param bool $check
6a488035
TO
171 */
172 public function buildQuickForm($check = FALSE) {
173 parent::buildQuickForm();
174
175 if ($this->_action & CRM_Core_Action::DELETE) {
176 return;
177 }
178
179 $attributes = CRM_Core_DAO::getAttribute('CRM_Financial_DAO_PaymentProcessor');
180
181 $this->add('text', 'name', ts('Name'),
182 $attributes['name'], TRUE
183 );
184
353ffa53
TO
185 $this->addRule('name', ts('Name already exists in Database.'), 'objectExists', array(
186 'CRM_Financial_DAO_PaymentProcessor',
28a04ea9 187 $this->_id,
35b63106
DS
188 'name',
189 CRM_Core_Config::domainID(),
353ffa53 190 ));
6a488035
TO
191
192 $this->add('text', 'description', ts('Description'),
193 $attributes['description']
194 );
195
8461467c
MW
196 $this->add('select',
197 'payment_processor_type_id',
198 ts('Payment Processor Type'),
199 CRM_Financial_BAO_PaymentProcessor::buildOptions('payment_processor_type_id'),
200 TRUE,
8ef12e64 201 array('onchange' => "reload(true)")
6a488035
TO
202 );
203
204 // Financial Account of account type asset CRM-11515
f743a6eb 205 $accountType = CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name = 'Asset' ");
6a488035
TO
206 $financialAccount = CRM_Contribute_PseudoConstant::financialAccount(NULL, key($accountType));
207 if ($fcount = count($financialAccount)) {
208 $this->assign('financialAccount', $fcount);
209 }
8ef12e64 210 $this->add('select', 'financial_account_id', ts('Financial Account'),
6a488035 211 array('' => ts('- select -')) + $financialAccount,
02fc859b 212 TRUE
6a488035 213 );
b7e7f943 214 $this->addSelect('payment_instrument_id',
215 array(
216 'entity' => 'contribution',
217 'label' => ts('Payment Method'),
218 'placeholder' => NULL,
219 )
220 );
221
6a488035
TO
222 // is this processor active ?
223 $this->add('checkbox', 'is_active', ts('Is this Payment Processor active?'));
224 $this->add('checkbox', 'is_default', ts('Is this Payment Processor the default?'));
cb5962bd 225 $creditCardTypes = CRM_Contribute_PseudoConstant::creditCard();
660ef5f6 226 $this->addCheckBox('accept_credit_cards', ts('Accepted Credit Card Type(s)'),
cb5962bd 227 $creditCardTypes, NULL, NULL, NULL, NULL, '&nbsp;&nbsp;&nbsp;');
6a488035
TO
228 foreach ($this->_fields as $field) {
229 if (empty($field['label'])) {
230 continue;
231 }
232
1d2a585a 233 $this->addField($field['name'], array('label' => $field['label']));
234
235 $fieldSpec = civicrm_api3($this->getDefaultEntity(), 'getfield', array(
236 'name' => $field['name'],
237 'action' => 'create',
238 ));
239 $this->add($fieldSpec['values']['html']['type'], "test_{$field['name']}",
6a488035
TO
240 $field['label'], $attributes[$field['name']]
241 );
a7488080 242 if (!empty($field['rule'])) {
6a488035
TO
243 $this->addRule($field['name'], $field['msg'], $field['rule']);
244 $this->addRule("test_{$field['name']}", $field['msg'], $field['rule']);
245 }
246 }
247
248 $this->addFormRule(array('CRM_Admin_Form_PaymentProcessor', 'formRule'));
249 }
250
e0ef6999
EM
251 /**
252 * @param $fields
253 *
254 * @return array|bool
255 */
00be9182 256 public static function formRule($fields) {
6a488035
TO
257
258 // make sure that at least one of live or test is present
259 // and we have at least name and url_site
260 // would be good to make this processor specific
261 $errors = array();
262
263 if (!(self::checkSection($fields, $errors) ||
353ffa53
TO
264 self::checkSection($fields, $errors, 'test')
265 )
266 ) {
6a488035
TO
267 $errors['_qf_default'] = ts('You must have at least the test or live section filled');
268 }
269
270 if (!empty($errors)) {
271 return $errors;
272 }
273
274 return empty($errors) ? TRUE : $errors;
275 }
276
e0ef6999
EM
277 /**
278 * @param $fields
279 * @param $errors
280 * @param null $section
281 *
282 * @return bool
283 */
00be9182 284 public static function checkSection(&$fields, &$errors, $section = NULL) {
6a488035
TO
285 $names = array('user_name');
286
287 $present = FALSE;
288 $allPresent = TRUE;
289 foreach ($names as $name) {
290 if ($section) {
291 $name = "{$section}_$name";
292 }
293 if (!empty($fields[$name])) {
294 $present = TRUE;
295 }
296 else {
297 $allPresent = FALSE;
298 }
299 }
300
301 if ($present) {
302 if (!$allPresent) {
303 $errors['_qf_default'] = ts('You must have at least the user_name specified');
304 }
305 }
306 return $present;
307 }
308
e0ef6999
EM
309 /**
310 * @return array
311 */
00be9182 312 public function setDefaultValues() {
6a488035 313 $defaults = array();
6d5de837 314
6a488035
TO
315 if (!$this->_id) {
316 $defaults['is_active'] = $defaults['is_default'] = 1;
8461467c
MW
317 $defaults['url_site'] = $this->_paymentProcessorDAO->url_site_default;
318 $defaults['url_api'] = $this->_paymentProcessorDAO->url_api_default;
319 $defaults['url_recur'] = $this->_paymentProcessorDAO->url_recur_default;
320 $defaults['url_button'] = $this->_paymentProcessorDAO->url_button_default;
321 $defaults['test_url_site'] = $this->_paymentProcessorDAO->url_site_test_default;
322 $defaults['test_url_api'] = $this->_paymentProcessorDAO->url_api_test_default;
323 $defaults['test_url_recur'] = $this->_paymentProcessorDAO->url_recur_test_default;
324 $defaults['test_url_button'] = $this->_paymentProcessorDAO->url_button_test_default;
325 $defaults['payment_instrument_id'] = $this->_paymentProcessorDAO->payment_instrument_id;
6d5de837 326 // When user changes payment processor type, it is passed in via $this->_ppType so update defaults array.
8461467c
MW
327 if ($this->_paymentProcessorType) {
328 $defaults['payment_processor_type_id'] = $this->_paymentProcessorType;
6d5de837 329 }
8563c1ce 330 $defaults['financial_account_id'] = CRM_Financial_BAO_PaymentProcessor::getDefaultFinancialAccountID();
6a488035
TO
331 return $defaults;
332 }
333 $domainID = CRM_Core_Config::domainID();
334
481a74f4 335 $dao = new CRM_Financial_DAO_PaymentProcessor();
353ffa53 336 $dao->id = $this->_id;
6a488035
TO
337 $dao->domain_id = $domainID;
338 if (!$dao->find(TRUE)) {
339 return $defaults;
340 }
341
342 CRM_Core_DAO::storeValues($dao, $defaults);
8461467c
MW
343 // If payment processor ID does not exist, $paymentProcessorName will be FALSE
344 $paymentProcessorName = CRM_Core_PseudoConstant::getName('CRM_Financial_BAO_PaymentProcessor', 'payment_processor_type_id', $this->_paymentProcessorType);
345 if ($this->_paymentProcessorType && $paymentProcessorName) {
346 // When user changes payment processor type, it is passed in via $this->_ppType so update defaults array.
347 $defaults['payment_processor_type_id'] = $this->_paymentProcessorType;
6d5de837 348 }
8461467c
MW
349 else {
350 CRM_Core_Session::setStatus('Payment Processor Type (ID=' . $this->_paymentProcessorType . ') not found. Did you disable the payment processor extension?', 'Missing Payment Processor', 'alert');
351 }
352
c294dbbc 353 $cards = json_decode(CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessor',
cb5962bd
SL
354 $this->_id,
355 'accepted_credit_cards'
356 ), TRUE);
c294dbbc 357 $acceptedCards = array();
27b252af
SL
358 if (!empty($cards)) {
359 foreach ($cards as $card => $val) {
360 $acceptedCards[$card] = 1;
361 }
c294dbbc
SL
362 }
363 $defaults['accept_credit_cards'] = $acceptedCards;
cb5962bd 364 unset($defaults['accepted_credit_cards']);
6a488035
TO
365 // now get testID
366 $testDAO = new CRM_Financial_DAO_PaymentProcessor();
353ffa53
TO
367 $testDAO->name = $dao->name;
368 $testDAO->is_test = 1;
6a488035
TO
369 $testDAO->domain_id = $domainID;
370 if ($testDAO->find(TRUE)) {
371 $this->_testID = $testDAO->id;
372
373 foreach ($this->_fields as $field) {
374 $testName = "test_{$field['name']}";
375 $defaults[$testName] = $testDAO->{$field['name']};
376 }
377 }
74afdc40 378 $defaults['financial_account_id'] = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($dao->id, NULL, 'civicrm_payment_processor');
6a488035
TO
379
380 return $defaults;
381 }
382
383 /**
eceb18cc 384 * Process the form submission.
6a488035
TO
385 */
386 public function postProcess() {
6a488035
TO
387
388 if ($this->_action & CRM_Core_Action::DELETE) {
389 CRM_Financial_BAO_PaymentProcessor::del($this->_id);
390 CRM_Core_Session::setStatus("", ts('Payment Processor Deleted.'), "success");
28a04ea9 391 return NULL;
6a488035
TO
392 }
393
394 $values = $this->controller->exportValues($this->_name);
395 $domainID = CRM_Core_Config::domainID();
396
a7488080 397 if (!empty($values['is_default'])) {
6a488035 398 $query = "UPDATE civicrm_payment_processor SET is_default = 0 WHERE domain_id = $domainID";
33621c4f 399 CRM_Core_DAO::executeQuery($query);
6a488035
TO
400 }
401
8461467c
MW
402 if ($this->_paymentProcessorType !== $values['payment_processor_type_id']) {
403 // If we changed the payment processor type, need to update the object as well
404 $this->_paymentProcessorType = $values['payment_processor_type_id'];
405 $this->_paymentProcessorDAO = new CRM_Financial_DAO_PaymentProcessorType();
406 $this->_paymentProcessorDAO->id = $values['payment_processor_type_id'];
407 $this->_paymentProcessorDAO->find(TRUE);
408 }
6a488035
TO
409 $this->updatePaymentProcessor($values, $domainID, FALSE);
410 $this->updatePaymentProcessor($values, $domainID, TRUE);
3eecd5bc
MW
411
412 $processor = civicrm_api3('payment_processor', 'getsingle', array('name' => $values['name'], 'is_test' => 0));
413 $errors = Civi\Payment\System::singleton()->checkProcessorConfig($processor);
414 if ($errors) {
415 CRM_Core_Session::setStatus($errors, 'Payment processor configuration invalid', 'error');
416 Civi::log()->error('Payment processor configuration invalid: ' . $errors);
417 CRM_Core_Session::singleton()->pushUserContext($this->refreshURL);
418 }
419 else {
420 CRM_Core_Session::setStatus(ts('Payment processor %1 has been saved.', array(1 => "<em>{$values['name']}</em>")), ts('Saved'), 'success');
421 }
6a488035
TO
422 }
423
424 /**
eceb18cc 425 * Save a payment processor.
6a488035 426 *
ce064e4f 427 * @param array $values
100fef9d 428 * @param int $domainID
ce064e4f 429 * @param bool $test
6a488035 430 */
00be9182 431 public function updatePaymentProcessor(&$values, $domainID, $test) {
be725500 432 if ($test) {
421dade4 433 foreach (array('user_name', 'password', 'signature', 'url_site', 'url_recur', 'url_api', 'url_button', 'subject') as $field) {
be725500 434 $values[$field] = empty($values["test_{$field}"]) ? CRM_Utils_Array::value($field, $values) : $values["test_{$field}"];
435 }
436 }
c294dbbc
SL
437 if (!empty($values['accept_credit_cards'])) {
438 $creditCards = array();
439 $accptedCards = array_keys($values['accept_credit_cards']);
440 $creditCardTypes = CRM_Contribute_PseudoConstant::creditCard();
441 foreach ($creditCardTypes as $type => $val) {
442 if (in_array($type, $accptedCards)) {
443 $creditCards[$type] = $creditCardTypes[$type];
444 }
445 }
446 $creditCards = json_encode($creditCards);
447 }
448 else {
449 $creditCards = "NULL";
450 }
b7e7f943 451 $params = array_merge(array(
452 'id' => $test ? $this->_testID : $this->_id,
453 'domain_id' => $domainID,
454 'is_test' => $test,
455 'is_active' => 0,
456 'is_default' => 0,
8461467c
MW
457 'is_recur' => $this->_paymentProcessorDAO->is_recur,
458 'billing_mode' => $this->_paymentProcessorDAO->billing_mode,
459 'class_name' => $this->_paymentProcessorDAO->class_name,
460 'payment_type' => $this->_paymentProcessorDAO->payment_type,
461 'payment_instrument_id' => $this->_paymentProcessorDAO->payment_instrument_id,
21dfd5f5 462 'financial_account_id' => $values['financial_account_id'],
cb5962bd 463 'accepted_credit_cards' => $creditCards,
b7e7f943 464 ), $values);
465
466 civicrm_api3('PaymentProcessor', 'create', $params);
6a488035 467 }
96025800 468
6a488035 469}