Merge pull request #18279 from eileenmcnaughton/ordertest
[civicrm-core.git] / Civi / Payment / System.php
1 <?php
2
3 namespace Civi\Payment;
4
5 /**
6 * Class System
7 * @package Civi\Payment
8 */
9 class System {
10
11 /**
12 * @var System
13 */
14 private static $singleton;
15
16 /**
17 * @var array
18 */
19 private $cache = [];
20
21 /**
22 * @return \Civi\Payment\System
23 */
24 public static function singleton() {
25 if (!self::$singleton) {
26 self::$singleton = new self();
27 }
28 return self::$singleton;
29 }
30
31 /**
32 * Starting from the processor as an array retrieve the processor as an object.
33 *
34 * If there is no valid configuration it will not be retrieved.
35 *
36 * @param array $processor
37 * @param bool $force
38 * Override the config check. This is required in uninstall as no valid instances exist
39 * but will deliberately not work with any valid processors.
40 *
41 * @return \CRM_Core_Payment|NULL
42 *
43 * @throws \CRM_Core_Exception
44 */
45 public function getByProcessor($processor, $force = FALSE) {
46 $id = $force ? 0 : $processor['id'];
47
48 if (!isset($this->cache[$id]) || $force) {
49 $ext = \CRM_Extension_System::singleton()->getMapper();
50 if ($ext->isExtensionKey($processor['class_name'])) {
51 $paymentClass = $ext->keyToClass($processor['class_name'], 'payment');
52 require_once $ext->classToPath($paymentClass);
53 }
54 else {
55 $paymentClass = 'CRM_Core_' . $processor['class_name'];
56 if (empty($processor['class_name'])) {
57 throw new \CRM_Core_Exception('no class provided');
58 }
59 }
60
61 $processorObject = NULL;
62 if (class_exists($paymentClass)) {
63 $processorObject = new $paymentClass(!empty($processor['is_test']) ? 'test' : 'live', $processor);
64 if ($force || !$processorObject->checkConfig()) {
65 $processorObject->setPaymentProcessor($processor);
66 }
67 }
68 $this->cache[$id] = $processorObject;
69 }
70
71 return $this->cache[$id];
72 }
73
74 /**
75 * Execute checkConfig() on the payment processor Object.
76 * This function creates a new instance of the processor object and returns the output of checkConfig
77 *
78 * @param array $processor
79 *
80 * @return string|NULL
81 *
82 * @throws \CRM_Core_Exception
83 */
84 public function checkProcessorConfig($processor) {
85 $ext = \CRM_Extension_System::singleton()->getMapper();
86 if ($ext->isExtensionKey($processor['class_name'])) {
87 $paymentClass = $ext->keyToClass($processor['class_name'], 'payment');
88 require_once $ext->classToPath($paymentClass);
89 }
90 else {
91 $paymentClass = 'CRM_Core_' . $processor['class_name'];
92 if (empty($paymentClass)) {
93 throw new \CRM_Core_Exception('no class provided');
94 }
95 require_once str_replace('_', DIRECTORY_SEPARATOR, $paymentClass) . '.php';
96 }
97
98 $processorObject = new $paymentClass(!empty($processor['is_test']) ? 'test' : 'live', $processor);
99 return $processorObject->checkConfig();
100 }
101
102 /**
103 * Get payment processor by it's ID.
104 *
105 * @param int $id
106 *
107 * @return \CRM_Core_Payment|NULL
108 *
109 * @throws \CiviCRM_API3_Exception
110 */
111 public function getById($id) {
112 if ($id == 0) {
113 return new \CRM_Core_Payment_Manual();
114 }
115 $processor = civicrm_api3('payment_processor', 'getsingle', ['id' => $id, 'is_test' => NULL]);
116 return self::getByProcessor($processor);
117 }
118
119 /**
120 * @param string $name
121 * @param bool $is_test
122 *
123 * @return \CRM_Core_Payment|NULL
124 * @throws \CiviCRM_API3_Exception
125 */
126 public function getByName($name, $is_test) {
127 $processor = civicrm_api3('payment_processor', 'getsingle', ['name' => $name, 'is_test' => $is_test]);
128 return self::getByProcessor($processor);
129 }
130
131 /**
132 * Flush processors from static cache.
133 *
134 * This is particularly used for tests.
135 */
136 public function flushProcessors() {
137 $this->cache = [];
138 if (isset(\Civi::$statics['CRM_Contribute_BAO_ContributionRecur'])) {
139 unset(\Civi::$statics['CRM_Contribute_BAO_ContributionRecur']);
140 }
141 \CRM_Core_PseudoConstant::flush('paymentProcessor');
142 civicrm_api3('PaymentProcessor', 'getfields', ['cache_clear' => 1]);
143 \CRM_Financial_BAO_PaymentProcessor::getAllPaymentProcessors('all', TRUE);
144 \CRM_Financial_BAO_PaymentProcessor::getAllPaymentProcessors('live', TRUE);
145 \CRM_Financial_BAO_PaymentProcessor::getAllPaymentProcessors('test', TRUE);
146 }
147
148 /**
149 * Sometimes we want to instantiate a processor object when no valid instance exists (eg. when uninstalling a
150 * processor).
151 *
152 * This function does not load instance specific details for the processor.
153 *
154 * @param string $className
155 *
156 * @return \Civi\Payment\CRM_Core_Payment|NULL
157 * @throws \CiviCRM_API3_Exception
158 */
159 public function getByClass($className) {
160 return $this->getByProcessor([
161 'class_name' => $className,
162 'id' => 0,
163 'is_test' => 0,
164 ],
165 TRUE);
166 }
167
168 }