Merge pull request #17614 from demeritcowboy/xmlproc-acttypes-more
[civicrm-core.git] / CRM / Extension / Manager / Payment.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 * This class stores logic for managing CiviCRM extensions.
14 *
15 * @package CRM
ca5cec67 16 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
17 */
18class CRM_Extension_Manager_Payment extends CRM_Extension_Manager_Base {
19
20 /**
d60f50a8 21 * @var CRM_Extension_Mapper
6a488035
TO
22 */
23 protected $mapper;
24
e0ef6999
EM
25 /**
26 * @param CRM_Extension_Mapper $mapper
27 */
6a488035
TO
28 public function __construct(CRM_Extension_Mapper $mapper) {
29 parent::__construct(TRUE);
30 $this->mapper = $mapper;
31 }
32
33 /**
e7c15cb6 34 * @inheritDoc
4faa436b
SB
35 *
36 * @param CRM_Extension_Info $info
df9f2d1a 37 * @throws CRM_Core_Exception
6a488035
TO
38 */
39 public function onPreInstall(CRM_Extension_Info $info) {
40 $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name');
41
42 if (array_key_exists($info->key, $paymentProcessorTypes)) {
df9f2d1a 43 throw new CRM_Core_Exception(ts('This payment processor type is already installed.'));
6a488035
TO
44 }
45
46 $ppByName = $this->_getAllPaymentProcessorTypes('name');
47 if (array_key_exists($info->name, $ppByName)) {
df9f2d1a 48 throw new CRM_Core_Exception(ts('This payment processor type already exists.'));
6a488035
TO
49 }
50
51 $dao = new CRM_Financial_DAO_PaymentProcessorType();
52
353ffa53
TO
53 $dao->is_active = 1;
54 $dao->class_name = trim($info->key);
55 $dao->title = trim($info->name) . ' (' . trim($info->key) . ')';
56 $dao->name = trim($info->name);
6a488035
TO
57 $dao->description = trim($info->description);
58
59 $dao->user_name_label = trim($info->typeInfo['userNameLabel']);
60 $dao->password_label = trim($info->typeInfo['passwordLabel']);
61 $dao->signature_label = trim($info->typeInfo['signatureLabel']);
62 $dao->subject_label = trim($info->typeInfo['subjectLabel']);
63 $dao->url_site_default = trim($info->typeInfo['urlSiteDefault']);
64 $dao->url_api_default = trim($info->typeInfo['urlApiDefault']);
65 $dao->url_recur_default = trim($info->typeInfo['urlRecurDefault']);
66 $dao->url_site_test_default = trim($info->typeInfo['urlSiteTestDefault']);
67 $dao->url_api_test_default = trim($info->typeInfo['urlApiTestDefault']);
68 $dao->url_recur_test_default = trim($info->typeInfo['urlRecurTestDefault']);
69 $dao->url_button_default = trim($info->typeInfo['urlButtonDefault']);
70 $dao->url_button_test_default = trim($info->typeInfo['urlButtonTestDefault']);
71
72 switch (trim($info->typeInfo['billingMode'])) {
73 case 'form':
74 $dao->billing_mode = CRM_Core_Payment::BILLING_MODE_FORM;
75 break;
76
77 case 'button':
78 $dao->billing_mode = CRM_Core_Payment::BILLING_MODE_BUTTON;
79 break;
80
81 case 'notify':
82 $dao->billing_mode = CRM_Core_Payment::BILLING_MODE_NOTIFY;
83 break;
84
85 default:
df9f2d1a 86 throw new CRM_Core_Exception(ts('Billing mode in info file has wrong value.'));
6a488035
TO
87 }
88
89 $dao->is_recur = trim($info->typeInfo['isRecur']);
90 $dao->payment_type = trim($info->typeInfo['paymentType']);
91
92 $dao->save();
93 }
94
95 /**
e7c15cb6 96 * @inheritDoc
4faa436b
SB
97 *
98 * @param CRM_Extension_Info $info
6a488035
TO
99 */
100 public function onPostInstall(CRM_Extension_Info $info) {
101 $this->_runPaymentHook($info, 'install');
102 }
103
104 /**
e7c15cb6 105 * @inheritDoc
4faa436b
SB
106 *
107 * @param CRM_Extension_Info $info
6a488035
TO
108 */
109 public function onPreUninstall(CRM_Extension_Info $info) {
110 $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name');
111 if (!array_key_exists($info->key, $paymentProcessorTypes)) {
ba968e38 112 throw new CRM_Core_Exception(ts('This payment processor type is not registered.'));
6a488035
TO
113 }
114
115 $dao = new CRM_Financial_DAO_PaymentProcessor();
116 $dao->payment_processor_type_id = $paymentProcessorTypes[$info->key];
117 $dao->find();
118 while ($dao->fetch()) {
119 throw new CRM_Extension_Exception_DependencyException('payment');
120 }
121
122 $this->_runPaymentHook($info, 'uninstall');
123 return CRM_Financial_BAO_PaymentProcessorType::del($paymentProcessorTypes[$info->key]);
124 }
125
126 /**
e7c15cb6 127 * @inheritDoc
4faa436b
SB
128 *
129 * @param CRM_Extension_Info $info
6a488035
TO
130 */
131 public function onPreDisable(CRM_Extension_Info $info) {
132 // HMM? // if ($this->type == 'payment' && $this->status != 'missing') {
133 $this->_runPaymentHook($info, 'disable');
134
135 $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name');
136 CRM_Financial_BAO_PaymentProcessorType::setIsActive($paymentProcessorTypes[$info->key], 0);
137 }
138
139 /**
e7c15cb6 140 * @inheritDoc
4faa436b
SB
141 *
142 * @param CRM_Extension_Info $info
6a488035
TO
143 */
144 public function onPreEnable(CRM_Extension_Info $info) {
145 $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name');
146 CRM_Financial_BAO_PaymentProcessorType::setIsActive($paymentProcessorTypes[$info->key], 1);
147 }
148
149 /**
e7c15cb6 150 * @inheritDoc
4faa436b
SB
151 *
152 * @param CRM_Extension_Info $info
6a488035
TO
153 */
154 public function onPostEnable(CRM_Extension_Info $info) {
155 // HMM? // if ($this->type == 'payment' && $this->status != 'missing') {
156 $this->_runPaymentHook($info, 'enable');
157 }
158
159 /**
f41911fd
TO
160 * @param string $attr
161 * The attribute used to key the array.
a6c01b45 162 * @return array
4faa436b 163 * ($attr => $id)
6a488035
TO
164 */
165 private function _getAllPaymentProcessorTypes($attr) {
be2fb01f 166 $ppt = [];
6a488035
TO
167 $dao = new CRM_Financial_DAO_PaymentProcessorType();
168 $dao->find();
169 while ($dao->fetch()) {
170 $ppt[$dao->$attr] = $dao->id;
171 }
172 return $ppt;
173 }
174
175 /**
fe482240 176 * Run hooks in the payment processor class.
6a488035
TO
177 * Load requested payment processor and call the method specified.
178 *
da6b46f4 179 * @param CRM_Extension_Info $info
f41911fd
TO
180 * @param string $method
181 * The method to call in the payment processor class.
6a488035
TO
182 */
183 private function _runPaymentHook(CRM_Extension_Info $info, $method) {
b44e3f84 184 // Not concerned about performance at this stage, as these are seldom performed tasks
6a488035
TO
185 // (payment processor enable/disable/install/uninstall). May wish to implement some
186 // kind of registry/caching system if more hooks are added.
187
188 try {
189 $paymentClass = $this->mapper->keyToClass($info->key, 'payment');
190 $file = $this->mapper->classToPath($paymentClass);
353ffa53 191 if (!file_exists($file)) {
be2fb01f 192 CRM_Core_Session::setStatus(ts('Failed to load file (%3) for payment processor (%1) while running "%2"', [
7b966967
SL
193 1 => $info->key,
194 2 => $method,
195 3 => $file,
196 ]), '', 'error');
6a488035 197 return;
0db6c3e1
TO
198 }
199 else {
6a488035
TO
200 require_once $file;
201 }
0db6c3e1
TO
202 }
203 catch (CRM_Extension_Exception $e) {
be2fb01f 204 CRM_Core_Session::setStatus(ts('Failed to determine file path for payment processor (%1) while running "%2"', [
7b966967
SL
205 1 => $info->key,
206 2 => $method,
207 ]), '', 'error');
6a488035
TO
208 return;
209 }
210
6b812400
EM
211 $processorDAO = CRM_Core_DAO::executeQuery(
212 " SELECT pp.id, ppt.class_name
6a488035
TO
213 FROM civicrm_extension ext
214 INNER JOIN civicrm_payment_processor_type ppt
215 ON ext.name = ppt.name
6b812400 216 LEFT JOIN civicrm_payment_processor pp
6a488035
TO
217 ON ppt.id = pp.payment_processor_type_id
218 WHERE ext.type = 'payment'
219 AND ext.full_name = %1
220 ",
be2fb01f
CW
221 [
222 1 => [$info->key, 'String'],
223 ]
6b812400
EM
224 );
225
226 while ($processorDAO->fetch()) {
227 $class_name = $processorDAO->class_name;
228 $processor_id = $processorDAO->id;
6a488035 229 }
6b812400
EM
230
231 if (empty($class_name)) {
ba968e38 232 throw new CRM_Core_Exception('Unable to find payment processor in ' . __CLASS__ . '::' . __METHOD__);
6a488035
TO
233 }
234
235 // In the case of uninstall, check for instances of PP first.
236 // Don't run hook if any are found.
6b812400 237 if ($method == 'uninstall' && $processor_id > 0) {
6a488035
TO
238 return;
239 }
240
241 switch ($method) {
242 case 'install':
243 case 'uninstall':
244 case 'enable':
245 case 'disable':
6b812400
EM
246 // Instantiate PP - the getClass function allows us to do this when no payment processor instances exist.
247 $processorInstance = Civi\Payment\System::singleton()->getByClass($class_name);
6a488035
TO
248
249 // Does PP implement this method, and can we call it?
be2fb01f 250 if (method_exists($processorInstance, $method) && is_callable([
7b966967
SL
251 $processorInstance,
252 $method,
253 ])) {
6a488035
TO
254 // If so, call it ...
255 $processorInstance->$method();
256 }
257 break;
258
259 default:
481a74f4 260 CRM_Core_Session::setStatus(ts("Unrecognized payment hook (%1) in %2::%3",
be2fb01f 261 [1 => $method, 2 => __CLASS__, 3 => __METHOD__]),
353ffa53 262 '', 'error');
6a488035
TO
263 }
264 }
96025800 265
6a488035 266}