3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 |
9 +--------------------------------------------------------------------+
13 * This class stores logic for managing CiviCRM extensions.
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
18 class CRM_Extension_Manager_Payment
extends CRM_Extension_Manager_Base
{
21 * @var CRM_Extension_Mapper
26 * @param CRM_Extension_Mapper $mapper
28 public function __construct(CRM_Extension_Mapper
$mapper) {
29 parent
::__construct(TRUE);
30 $this->mapper
= $mapper;
36 * @param CRM_Extension_Info $info
38 public function onPreInstall(CRM_Extension_Info
$info) {
39 $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name');
41 if (array_key_exists($info->key
, $paymentProcessorTypes)) {
42 CRM_Core_Error
::fatal(ts('This payment processor type is already installed.'));
45 $ppByName = $this->_getAllPaymentProcessorTypes('name');
46 if (array_key_exists($info->name
, $ppByName)) {
47 CRM_Core_Error
::fatal(ts('This payment processor type already exists.'));
50 $dao = new CRM_Financial_DAO_PaymentProcessorType();
53 $dao->class_name
= trim($info->key
);
54 $dao->title
= trim($info->name
) . ' (' . trim($info->key
) . ')';
55 $dao->name
= trim($info->name
);
56 $dao->description
= trim($info->description
);
58 $dao->user_name_label
= trim($info->typeInfo
['userNameLabel']);
59 $dao->password_label
= trim($info->typeInfo
['passwordLabel']);
60 $dao->signature_label
= trim($info->typeInfo
['signatureLabel']);
61 $dao->subject_label
= trim($info->typeInfo
['subjectLabel']);
62 $dao->url_site_default
= trim($info->typeInfo
['urlSiteDefault']);
63 $dao->url_api_default
= trim($info->typeInfo
['urlApiDefault']);
64 $dao->url_recur_default
= trim($info->typeInfo
['urlRecurDefault']);
65 $dao->url_site_test_default
= trim($info->typeInfo
['urlSiteTestDefault']);
66 $dao->url_api_test_default
= trim($info->typeInfo
['urlApiTestDefault']);
67 $dao->url_recur_test_default
= trim($info->typeInfo
['urlRecurTestDefault']);
68 $dao->url_button_default
= trim($info->typeInfo
['urlButtonDefault']);
69 $dao->url_button_test_default
= trim($info->typeInfo
['urlButtonTestDefault']);
71 switch (trim($info->typeInfo
['billingMode'])) {
73 $dao->billing_mode
= CRM_Core_Payment
::BILLING_MODE_FORM
;
77 $dao->billing_mode
= CRM_Core_Payment
::BILLING_MODE_BUTTON
;
81 $dao->billing_mode
= CRM_Core_Payment
::BILLING_MODE_NOTIFY
;
85 CRM_Core_Error
::fatal(ts('Billing mode in info file has wrong value.'));
88 $dao->is_recur
= trim($info->typeInfo
['isRecur']);
89 $dao->payment_type
= trim($info->typeInfo
['paymentType']);
97 * @param CRM_Extension_Info $info
99 public function onPostInstall(CRM_Extension_Info
$info) {
100 $this->_runPaymentHook($info, 'install');
106 * @param CRM_Extension_Info $info
108 public function onPreUninstall(CRM_Extension_Info
$info) {
109 $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name');
110 if (!array_key_exists($info->key
, $paymentProcessorTypes)) {
111 CRM_Core_Error
::fatal(ts('This payment processor type is not registered.'));
114 $dao = new CRM_Financial_DAO_PaymentProcessor();
115 $dao->payment_processor_type_id
= $paymentProcessorTypes[$info->key
];
117 while ($dao->fetch()) {
118 throw new CRM_Extension_Exception_DependencyException('payment');
121 $this->_runPaymentHook($info, 'uninstall');
122 return CRM_Financial_BAO_PaymentProcessorType
::del($paymentProcessorTypes[$info->key
]);
128 * @param CRM_Extension_Info $info
130 public function onPreDisable(CRM_Extension_Info
$info) {
131 // HMM? // if ($this->type == 'payment' && $this->status != 'missing') {
132 $this->_runPaymentHook($info, 'disable');
134 $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name');
135 CRM_Financial_BAO_PaymentProcessorType
::setIsActive($paymentProcessorTypes[$info->key
], 0);
141 * @param CRM_Extension_Info $info
143 public function onPreEnable(CRM_Extension_Info
$info) {
144 $paymentProcessorTypes = $this->_getAllPaymentProcessorTypes('class_name');
145 CRM_Financial_BAO_PaymentProcessorType
::setIsActive($paymentProcessorTypes[$info->key
], 1);
151 * @param CRM_Extension_Info $info
153 public function onPostEnable(CRM_Extension_Info
$info) {
154 // HMM? // if ($this->type == 'payment' && $this->status != 'missing') {
155 $this->_runPaymentHook($info, 'enable');
159 * @param string $attr
160 * The attribute used to key the array.
164 private function _getAllPaymentProcessorTypes($attr) {
166 $dao = new CRM_Financial_DAO_PaymentProcessorType();
168 while ($dao->fetch()) {
169 $ppt[$dao->$attr] = $dao->id
;
175 * Run hooks in the payment processor class.
176 * Load requested payment processor and call the method specified.
178 * @param CRM_Extension_Info $info
179 * @param string $method
180 * The method to call in the payment processor class.
182 private function _runPaymentHook(CRM_Extension_Info
$info, $method) {
183 // Not concerned about performance at this stage, as these are seldom performed tasks
184 // (payment processor enable/disable/install/uninstall). May wish to implement some
185 // kind of registry/caching system if more hooks are added.
188 $paymentClass = $this->mapper
->keyToClass($info->key
, 'payment');
189 $file = $this->mapper
->classToPath($paymentClass);
190 if (!file_exists($file)) {
191 CRM_Core_Session
::setStatus(ts('Failed to load file (%3) for payment processor (%1) while running "%2"', [
202 catch (CRM_Extension_Exception
$e) {
203 CRM_Core_Session
::setStatus(ts('Failed to determine file path for payment processor (%1) while running "%2"', [
210 $processorDAO = CRM_Core_DAO
::executeQuery(
211 " SELECT pp.id, ppt.class_name
212 FROM civicrm_extension ext
213 INNER JOIN civicrm_payment_processor_type ppt
214 ON ext.name = ppt.name
215 LEFT JOIN civicrm_payment_processor pp
216 ON ppt.id = pp.payment_processor_type_id
217 WHERE ext.type = 'payment'
218 AND ext.full_name = %1
221 1 => [$info->key
, 'String'],
225 while ($processorDAO->fetch()) {
226 $class_name = $processorDAO->class_name
;
227 $processor_id = $processorDAO->id
;
230 if (empty($class_name)) {
231 CRM_Core_Error
::fatal("Unable to find payment processor in " . __CLASS__
. '::' . __METHOD__
);
234 // In the case of uninstall, check for instances of PP first.
235 // Don't run hook if any are found.
236 if ($method == 'uninstall' && $processor_id > 0) {
245 // Instantiate PP - the getClass function allows us to do this when no payment processor instances exist.
246 $processorInstance = Civi\Payment\System
::singleton()->getByClass($class_name);
248 // Does PP implement this method, and can we call it?
249 if (method_exists($processorInstance, $method) && is_callable([
253 // If so, call it ...
254 $processorInstance->$method();
259 CRM_Core_Session
::setStatus(ts("Unrecognized payment hook (%1) in %2::%3",
260 [1 => $method, 2 => __CLASS__
, 3 => __METHOD__
]),