Commit | Line | Data |
---|---|---|
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 | */ |
18 | class 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 | } |