Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
7e9e8871 | 4 | | CiviCRM version 4.7 | |
6a488035 | 5 | +--------------------------------------------------------------------+ |
0f03f337 | 6 | | Copyright CiviCRM LLC (c) 2004-2017 | |
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 | |
0f03f337 | 32 | * @copyright CiviCRM LLC (c) 2004-2017 |
6a488035 TO |
33 | */ |
34 | class CRM_Extension_Manager_Payment extends CRM_Extension_Manager_Base { | |
35 | ||
36 | /** | |
d60f50a8 | 37 | * @var CRM_Extension_Mapper |
6a488035 TO |
38 | */ |
39 | protected $mapper; | |
40 | ||
e0ef6999 EM |
41 | /** |
42 | * @param CRM_Extension_Mapper $mapper | |
43 | */ | |
6a488035 TO |
44 | public function __construct(CRM_Extension_Mapper $mapper) { |
45 | parent::__construct(TRUE); | |
46 | $this->mapper = $mapper; | |
47 | } | |
48 | ||
49 | /** | |
e7c15cb6 | 50 | * @inheritDoc |
4faa436b SB |
51 | * |
52 | * @param CRM_Extension_Info $info | |
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 |
4faa436b SB |
112 | * |
113 | * @param CRM_Extension_Info $info | |
6a488035 TO |
114 | */ |
115 | public function onPostInstall(CRM_Extension_Info $info) { | |
116 | $this->_runPaymentHook($info, 'install'); | |
117 | } | |
118 | ||
119 | /** | |
e7c15cb6 | 120 | * @inheritDoc |
4faa436b SB |
121 | * |
122 | * @param CRM_Extension_Info $info | |
6a488035 TO |
123 | */ |
124 | public function onPreUninstall(CRM_Extension_Info $info) { | |
125 | $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name'); | |
126 | if (!array_key_exists($info->key, $paymentProcessorTypes)) { | |
127 | CRM_Core_Error::fatal('This payment processor type is not registered.'); | |
128 | } | |
129 | ||
130 | $dao = new CRM_Financial_DAO_PaymentProcessor(); | |
131 | $dao->payment_processor_type_id = $paymentProcessorTypes[$info->key]; | |
132 | $dao->find(); | |
133 | while ($dao->fetch()) { | |
134 | throw new CRM_Extension_Exception_DependencyException('payment'); | |
135 | } | |
136 | ||
137 | $this->_runPaymentHook($info, 'uninstall'); | |
138 | return CRM_Financial_BAO_PaymentProcessorType::del($paymentProcessorTypes[$info->key]); | |
139 | } | |
140 | ||
141 | /** | |
e7c15cb6 | 142 | * @inheritDoc |
4faa436b SB |
143 | * |
144 | * @param CRM_Extension_Info $info | |
6a488035 TO |
145 | */ |
146 | public function onPreDisable(CRM_Extension_Info $info) { | |
147 | // HMM? // if ($this->type == 'payment' && $this->status != 'missing') { | |
148 | $this->_runPaymentHook($info, 'disable'); | |
149 | ||
150 | $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name'); | |
151 | CRM_Financial_BAO_PaymentProcessorType::setIsActive($paymentProcessorTypes[$info->key], 0); | |
152 | } | |
153 | ||
154 | /** | |
e7c15cb6 | 155 | * @inheritDoc |
4faa436b SB |
156 | * |
157 | * @param CRM_Extension_Info $info | |
6a488035 TO |
158 | */ |
159 | public function onPreEnable(CRM_Extension_Info $info) { | |
160 | $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name'); | |
161 | CRM_Financial_BAO_PaymentProcessorType::setIsActive($paymentProcessorTypes[$info->key], 1); | |
162 | } | |
163 | ||
164 | /** | |
e7c15cb6 | 165 | * @inheritDoc |
4faa436b SB |
166 | * |
167 | * @param CRM_Extension_Info $info | |
6a488035 TO |
168 | */ |
169 | public function onPostEnable(CRM_Extension_Info $info) { | |
170 | // HMM? // if ($this->type == 'payment' && $this->status != 'missing') { | |
171 | $this->_runPaymentHook($info, 'enable'); | |
172 | } | |
173 | ||
174 | /** | |
f41911fd TO |
175 | * @param string $attr |
176 | * The attribute used to key the array. | |
a6c01b45 | 177 | * @return array |
4faa436b | 178 | * ($attr => $id) |
6a488035 TO |
179 | */ |
180 | private function _getAllPaymentProcessorTypes($attr) { | |
181 | $ppt = array(); | |
182 | $dao = new CRM_Financial_DAO_PaymentProcessorType(); | |
183 | $dao->find(); | |
184 | while ($dao->fetch()) { | |
185 | $ppt[$dao->$attr] = $dao->id; | |
186 | } | |
187 | return $ppt; | |
188 | } | |
189 | ||
190 | /** | |
fe482240 | 191 | * Run hooks in the payment processor class. |
6a488035 TO |
192 | * Load requested payment processor and call the method specified. |
193 | * | |
da6b46f4 | 194 | * @param CRM_Extension_Info $info |
f41911fd TO |
195 | * @param string $method |
196 | * The method to call in the payment processor class. | |
6a488035 TO |
197 | */ |
198 | private function _runPaymentHook(CRM_Extension_Info $info, $method) { | |
b44e3f84 | 199 | // Not concerned about performance at this stage, as these are seldom performed tasks |
6a488035 TO |
200 | // (payment processor enable/disable/install/uninstall). May wish to implement some |
201 | // kind of registry/caching system if more hooks are added. | |
202 | ||
203 | try { | |
204 | $paymentClass = $this->mapper->keyToClass($info->key, 'payment'); | |
205 | $file = $this->mapper->classToPath($paymentClass); | |
353ffa53 TO |
206 | if (!file_exists($file)) { |
207 | CRM_Core_Session::setStatus(ts('Failed to load file (%3) for payment processor (%1) while running "%2"', array( | |
208 | 1 => $info->key, | |
209 | 2 => $method, | |
317fceb4 | 210 | 3 => $file, |
353ffa53 | 211 | )), '', 'error'); |
6a488035 | 212 | return; |
0db6c3e1 TO |
213 | } |
214 | else { | |
6a488035 TO |
215 | require_once $file; |
216 | } | |
0db6c3e1 TO |
217 | } |
218 | catch (CRM_Extension_Exception $e) { | |
353ffa53 TO |
219 | CRM_Core_Session::setStatus(ts('Failed to determine file path for payment processor (%1) while running "%2"', array( |
220 | 1 => $info->key, | |
317fceb4 | 221 | 2 => $method, |
353ffa53 | 222 | )), '', 'error'); |
6a488035 TO |
223 | return; |
224 | } | |
225 | ||
6b812400 EM |
226 | $processorDAO = CRM_Core_DAO::executeQuery( |
227 | " SELECT pp.id, ppt.class_name | |
6a488035 TO |
228 | FROM civicrm_extension ext |
229 | INNER JOIN civicrm_payment_processor_type ppt | |
230 | ON ext.name = ppt.name | |
6b812400 | 231 | LEFT JOIN civicrm_payment_processor pp |
6a488035 TO |
232 | ON ppt.id = pp.payment_processor_type_id |
233 | WHERE ext.type = 'payment' | |
234 | AND ext.full_name = %1 | |
235 | ", | |
353ffa53 TO |
236 | array( |
237 | 1 => array($info->key, 'String'), | |
238 | ) | |
6b812400 EM |
239 | ); |
240 | ||
241 | while ($processorDAO->fetch()) { | |
242 | $class_name = $processorDAO->class_name; | |
243 | $processor_id = $processorDAO->id; | |
6a488035 | 244 | } |
6b812400 EM |
245 | |
246 | if (empty($class_name)) { | |
247 | CRM_Core_Error::fatal("Unable to find payment processor in " . __CLASS__ . '::' . __METHOD__); | |
6a488035 TO |
248 | } |
249 | ||
250 | // In the case of uninstall, check for instances of PP first. | |
251 | // Don't run hook if any are found. | |
6b812400 | 252 | if ($method == 'uninstall' && $processor_id > 0) { |
6a488035 TO |
253 | return; |
254 | } | |
255 | ||
256 | switch ($method) { | |
257 | case 'install': | |
258 | case 'uninstall': | |
259 | case 'enable': | |
260 | case 'disable': | |
6b812400 EM |
261 | // Instantiate PP - the getClass function allows us to do this when no payment processor instances exist. |
262 | $processorInstance = Civi\Payment\System::singleton()->getByClass($class_name); | |
6a488035 TO |
263 | |
264 | // Does PP implement this method, and can we call it? | |
265 | if (method_exists($processorInstance, $method) && is_callable(array( | |
353ffa53 | 266 | $processorInstance, |
317fceb4 | 267 | $method, |
353ffa53 TO |
268 | )) |
269 | ) { | |
6a488035 TO |
270 | // If so, call it ... |
271 | $processorInstance->$method(); | |
272 | } | |
273 | break; | |
274 | ||
275 | default: | |
481a74f4 | 276 | CRM_Core_Session::setStatus(ts("Unrecognized payment hook (%1) in %2::%3", |
353ffa53 TO |
277 | array(1 => $method, 2 => __CLASS__, 3 => __METHOD__)), |
278 | '', 'error'); | |
6a488035 TO |
279 | } |
280 | } | |
96025800 | 281 | |
6a488035 | 282 | } |