Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
39de6fd5 | 4 | | CiviCRM version 4.6 | |
6a488035 | 5 | +--------------------------------------------------------------------+ |
e7112fa7 | 6 | | Copyright CiviCRM LLC (c) 2004-2015 | |
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 | * This class stores logic for managing CiviCRM extensions. | |
30 | * | |
31 | * @package CRM | |
e7112fa7 | 32 | * @copyright CiviCRM LLC (c) 2004-2015 |
6a488035 TO |
33 | * $Id$ |
34 | * | |
35 | */ | |
36 | class CRM_Extension_Manager_Payment extends CRM_Extension_Manager_Base { | |
37 | ||
38 | /** | |
d60f50a8 | 39 | * @var CRM_Extension_Mapper |
6a488035 TO |
40 | */ |
41 | protected $mapper; | |
42 | ||
e0ef6999 EM |
43 | /** |
44 | * @param CRM_Extension_Mapper $mapper | |
45 | */ | |
6a488035 TO |
46 | public function __construct(CRM_Extension_Mapper $mapper) { |
47 | parent::__construct(TRUE); | |
48 | $this->mapper = $mapper; | |
49 | } | |
50 | ||
51 | /** | |
e7c15cb6 | 52 | * @inheritDoc |
6a488035 TO |
53 | */ |
54 | public function onPreInstall(CRM_Extension_Info $info) { | |
55 | $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name'); | |
56 | ||
57 | if (array_key_exists($info->key, $paymentProcessorTypes)) { | |
58 | CRM_Core_Error::fatal('This payment processor type is already installed.'); | |
59 | } | |
60 | ||
61 | $ppByName = $this->_getAllPaymentProcessorTypes('name'); | |
62 | if (array_key_exists($info->name, $ppByName)) { | |
63 | CRM_Core_Error::fatal('This payment processor type already exists.'); | |
64 | } | |
65 | ||
66 | $dao = new CRM_Financial_DAO_PaymentProcessorType(); | |
67 | ||
353ffa53 TO |
68 | $dao->is_active = 1; |
69 | $dao->class_name = trim($info->key); | |
70 | $dao->title = trim($info->name) . ' (' . trim($info->key) . ')'; | |
71 | $dao->name = trim($info->name); | |
6a488035 TO |
72 | $dao->description = trim($info->description); |
73 | ||
74 | $dao->user_name_label = trim($info->typeInfo['userNameLabel']); | |
75 | $dao->password_label = trim($info->typeInfo['passwordLabel']); | |
76 | $dao->signature_label = trim($info->typeInfo['signatureLabel']); | |
77 | $dao->subject_label = trim($info->typeInfo['subjectLabel']); | |
78 | $dao->url_site_default = trim($info->typeInfo['urlSiteDefault']); | |
79 | $dao->url_api_default = trim($info->typeInfo['urlApiDefault']); | |
80 | $dao->url_recur_default = trim($info->typeInfo['urlRecurDefault']); | |
81 | $dao->url_site_test_default = trim($info->typeInfo['urlSiteTestDefault']); | |
82 | $dao->url_api_test_default = trim($info->typeInfo['urlApiTestDefault']); | |
83 | $dao->url_recur_test_default = trim($info->typeInfo['urlRecurTestDefault']); | |
84 | $dao->url_button_default = trim($info->typeInfo['urlButtonDefault']); | |
85 | $dao->url_button_test_default = trim($info->typeInfo['urlButtonTestDefault']); | |
86 | ||
87 | switch (trim($info->typeInfo['billingMode'])) { | |
88 | case 'form': | |
89 | $dao->billing_mode = CRM_Core_Payment::BILLING_MODE_FORM; | |
90 | break; | |
91 | ||
92 | case 'button': | |
93 | $dao->billing_mode = CRM_Core_Payment::BILLING_MODE_BUTTON; | |
94 | break; | |
95 | ||
96 | case 'notify': | |
97 | $dao->billing_mode = CRM_Core_Payment::BILLING_MODE_NOTIFY; | |
98 | break; | |
99 | ||
100 | default: | |
101 | CRM_Core_Error::fatal('Billing mode in info file has wrong value.'); | |
102 | } | |
103 | ||
104 | $dao->is_recur = trim($info->typeInfo['isRecur']); | |
105 | $dao->payment_type = trim($info->typeInfo['paymentType']); | |
106 | ||
107 | $dao->save(); | |
108 | } | |
109 | ||
110 | /** | |
e7c15cb6 | 111 | * @inheritDoc |
6a488035 TO |
112 | */ |
113 | public function onPostInstall(CRM_Extension_Info $info) { | |
114 | $this->_runPaymentHook($info, 'install'); | |
115 | } | |
116 | ||
117 | /** | |
e7c15cb6 | 118 | * @inheritDoc |
6a488035 TO |
119 | */ |
120 | public function onPreUninstall(CRM_Extension_Info $info) { | |
121 | $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name'); | |
122 | if (!array_key_exists($info->key, $paymentProcessorTypes)) { | |
123 | CRM_Core_Error::fatal('This payment processor type is not registered.'); | |
124 | } | |
125 | ||
126 | $dao = new CRM_Financial_DAO_PaymentProcessor(); | |
127 | $dao->payment_processor_type_id = $paymentProcessorTypes[$info->key]; | |
128 | $dao->find(); | |
129 | while ($dao->fetch()) { | |
130 | throw new CRM_Extension_Exception_DependencyException('payment'); | |
131 | } | |
132 | ||
133 | $this->_runPaymentHook($info, 'uninstall'); | |
134 | return CRM_Financial_BAO_PaymentProcessorType::del($paymentProcessorTypes[$info->key]); | |
135 | } | |
136 | ||
137 | /** | |
e7c15cb6 | 138 | * @inheritDoc |
6a488035 TO |
139 | */ |
140 | public function onPreDisable(CRM_Extension_Info $info) { | |
141 | // HMM? // if ($this->type == 'payment' && $this->status != 'missing') { | |
142 | $this->_runPaymentHook($info, 'disable'); | |
143 | ||
144 | $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name'); | |
145 | CRM_Financial_BAO_PaymentProcessorType::setIsActive($paymentProcessorTypes[$info->key], 0); | |
146 | } | |
147 | ||
148 | /** | |
e7c15cb6 | 149 | * @inheritDoc |
6a488035 TO |
150 | */ |
151 | public function onPreEnable(CRM_Extension_Info $info) { | |
152 | $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name'); | |
153 | CRM_Financial_BAO_PaymentProcessorType::setIsActive($paymentProcessorTypes[$info->key], 1); | |
154 | } | |
155 | ||
156 | /** | |
e7c15cb6 | 157 | * @inheritDoc |
6a488035 TO |
158 | */ |
159 | public function onPostEnable(CRM_Extension_Info $info) { | |
160 | // HMM? // if ($this->type == 'payment' && $this->status != 'missing') { | |
161 | $this->_runPaymentHook($info, 'enable'); | |
162 | } | |
163 | ||
164 | /** | |
f41911fd TO |
165 | * @param string $attr |
166 | * The attribute used to key the array. | |
a6c01b45 CW |
167 | * @return array |
168 | * ($$attr => $id) | |
6a488035 TO |
169 | */ |
170 | private function _getAllPaymentProcessorTypes($attr) { | |
171 | $ppt = array(); | |
172 | $dao = new CRM_Financial_DAO_PaymentProcessorType(); | |
173 | $dao->find(); | |
174 | while ($dao->fetch()) { | |
175 | $ppt[$dao->$attr] = $dao->id; | |
176 | } | |
177 | return $ppt; | |
178 | } | |
179 | ||
180 | /** | |
fe482240 | 181 | * Run hooks in the payment processor class. |
6a488035 TO |
182 | * Load requested payment processor and call the method specified. |
183 | * | |
da6b46f4 | 184 | * @param CRM_Extension_Info $info |
f41911fd TO |
185 | * @param string $method |
186 | * The method to call in the payment processor class. | |
6a488035 TO |
187 | */ |
188 | private function _runPaymentHook(CRM_Extension_Info $info, $method) { | |
b44e3f84 | 189 | // Not concerned about performance at this stage, as these are seldom performed tasks |
6a488035 TO |
190 | // (payment processor enable/disable/install/uninstall). May wish to implement some |
191 | // kind of registry/caching system if more hooks are added. | |
192 | ||
193 | try { | |
194 | $paymentClass = $this->mapper->keyToClass($info->key, 'payment'); | |
195 | $file = $this->mapper->classToPath($paymentClass); | |
353ffa53 TO |
196 | if (!file_exists($file)) { |
197 | CRM_Core_Session::setStatus(ts('Failed to load file (%3) for payment processor (%1) while running "%2"', array( | |
198 | 1 => $info->key, | |
199 | 2 => $method, | |
317fceb4 | 200 | 3 => $file, |
353ffa53 | 201 | )), '', 'error'); |
6a488035 | 202 | return; |
0db6c3e1 TO |
203 | } |
204 | else { | |
6a488035 TO |
205 | require_once $file; |
206 | } | |
0db6c3e1 TO |
207 | } |
208 | catch (CRM_Extension_Exception $e) { | |
353ffa53 TO |
209 | CRM_Core_Session::setStatus(ts('Failed to determine file path for payment processor (%1) while running "%2"', array( |
210 | 1 => $info->key, | |
317fceb4 | 211 | 2 => $method, |
353ffa53 | 212 | )), '', 'error'); |
6a488035 TO |
213 | return; |
214 | } | |
215 | ||
216 | // See if we have any instances of this PP defined .. | |
217 | if ($processor_id = CRM_Core_DAO::singleValueQuery(" | |
218 | SELECT pp.id | |
219 | FROM civicrm_extension ext | |
220 | INNER JOIN civicrm_payment_processor_type ppt | |
221 | ON ext.name = ppt.name | |
222 | INNER JOIN civicrm_payment_processor pp | |
223 | ON ppt.id = pp.payment_processor_type_id | |
224 | WHERE ext.type = 'payment' | |
225 | AND ext.full_name = %1 | |
226 | ", | |
353ffa53 TO |
227 | array( |
228 | 1 => array($info->key, 'String'), | |
229 | ) | |
230 | ) | |
231 | ) { | |
6a488035 TO |
232 | // If so, load params in the usual way .. |
233 | $paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($processor_id, NULL); | |
234 | } | |
235 | else { | |
236 | // Otherwise, do the best we can to construct some .. | |
237 | $dao = CRM_Core_DAO::executeQuery(" | |
238 | SELECT ppt.* | |
239 | FROM civicrm_extension ext | |
240 | INNER JOIN civicrm_payment_processor_type ppt | |
241 | ON ppt.name = ext.name | |
242 | WHERE ext.name = %1 | |
243 | AND ext.type = 'payment' | |
244 | ", | |
245 | array( | |
246 | 1 => array($info->name, 'String'), | |
247 | ) | |
248 | ); | |
69e56359 TO |
249 | if ($dao->fetch()) { |
250 | $paymentProcessor = array( | |
251 | 'id' => -1, | |
252 | 'name' => $dao->title, | |
253 | 'payment_processor_type_id' => $dao->id, | |
254 | 'user_name' => 'nothing', | |
255 | 'password' => 'nothing', | |
256 | 'signature' => '', | |
257 | 'url_site' => $dao->url_site_default, | |
258 | 'url_api' => $dao->url_api_default, | |
259 | 'url_recur' => $dao->url_recur_default, | |
260 | 'url_button' => $dao->url_button_default, | |
261 | 'subject' => '', | |
262 | 'class_name' => $dao->class_name, | |
263 | 'is_recur' => $dao->is_recur, | |
264 | 'billing_mode' => $dao->billing_mode, | |
265 | 'payment_type' => $dao->payment_type, | |
b3a4b879 TO |
266 | ); |
267 | } | |
4f99ca55 TO |
268 | else { |
269 | CRM_Core_Error::fatal("Unable to find payment processor in " . __CLASS__ . '::' . __METHOD__); | |
b3a4b879 | 270 | } |
6a488035 TO |
271 | } |
272 | ||
273 | // In the case of uninstall, check for instances of PP first. | |
274 | // Don't run hook if any are found. | |
275 | if ($method == 'uninstall' && $paymentProcessor['id'] > 0) { | |
276 | return; | |
277 | } | |
278 | ||
279 | switch ($method) { | |
280 | case 'install': | |
281 | case 'uninstall': | |
282 | case 'enable': | |
283 | case 'disable': | |
284 | ||
285 | // Instantiate PP | |
0e6e8724 | 286 | $processorInstance = $paymentClass::singleton(NULL, $paymentProcessor); |
6a488035 TO |
287 | |
288 | // Does PP implement this method, and can we call it? | |
289 | if (method_exists($processorInstance, $method) && is_callable(array( | |
353ffa53 | 290 | $processorInstance, |
317fceb4 | 291 | $method, |
353ffa53 TO |
292 | )) |
293 | ) { | |
6a488035 TO |
294 | // If so, call it ... |
295 | $processorInstance->$method(); | |
296 | } | |
297 | break; | |
298 | ||
299 | default: | |
481a74f4 | 300 | CRM_Core_Session::setStatus(ts("Unrecognized payment hook (%1) in %2::%3", |
353ffa53 TO |
301 | array(1 => $method, 2 => __CLASS__, 3 => __METHOD__)), |
302 | '', 'error'); | |
6a488035 TO |
303 | } |
304 | } | |
96025800 | 305 | |
6a488035 | 306 | } |