PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / payment / factory.php
vikappointments / site / helpers / libraries / payment Last commit date
factory.php 2 days ago index.html 2 days ago plugin.php 2 days ago status.php 2 days ago
factory.php
265 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * Payments abstract factory.
16 *
17 * The I/O of this class MUST be the same for all the E4J programs that support
18 * extendable payment methods.
19 *
20 * @note The class prefix is equals to the 3-letter name of the program,
21 * "VAP" in this case.
22 *
23 * @since 1.7.1
24 */
25 final class VAPPaymentFactory
26 {
27 /**
28 * Returns a list of supported payment gateways.
29 *
30 * @return array A list of paths.
31 */
32 public static function getSupportedDrivers()
33 {
34 /**
35 * Add support for the existing payment gateways.
36 *
37 * @note Use the correct payments path of the current program.
38 */
39 $files = glob(VAPADMIN . DIRECTORY_SEPARATOR . 'payments' . DIRECTORY_SEPARATOR . '*.php');
40
41 // get rid of the file path and file extension
42 $drivers = array_map(function($driver)
43 {
44 return preg_replace("/\.php$/i", '', basename($driver));
45 }, $files);
46
47 /**
48 * Access the event dispatcher instance.
49 *
50 * @note Handle the dispatcher according to the platform version.
51 */
52 $dispatcher = VAPFactory::getEventDispatcher();
53
54 /**
55 * Trigger hook to extend the available payment methods.
56 *
57 * @note The caller (1st argument) must be equals to the program in use.
58 *
59 * @param string $element The component that triggered this event.
60 *
61 * @return string|array Either a string or an array of payment drivers.
62 *
63 * @since 1.7.1
64 */
65 $results = $dispatcher->trigger('onLoadSupportedPaymentMethods', array('vikappointments'));
66
67 // join returned payment drivers with the existing ones
68 foreach ($results as $result)
69 {
70 $drivers = array_merge($drivers, (array) $result);
71 }
72
73 // get rid of duplicates and empty elements
74 $drivers = array_values(array_unique(array_filter($drivers)));
75
76 // sort drivers in ascending order
77 sort($drivers);
78
79 return $drivers;
80 }
81
82 /**
83 * Returns the configuration form of a payment.
84 *
85 * @param string $payment The name of the payment.
86 *
87 * @return array The configuration array.
88 *
89 * @throws RuntimeException
90 */
91 public static function getPaymentConfig($payment)
92 {
93 // strip file extension, if specified
94 $payment = preg_replace("/\.php$/i", '', $payment);
95
96 /**
97 * Build internal payments path.
98 *
99 * @note Use the correct payments path of the current program.
100 */
101 $path = VAPADMIN . DIRECTORY_SEPARATOR . 'payments' . DIRECTORY_SEPARATOR . $payment . '.php';
102
103 if (is_file($path))
104 {
105 // load internal payment driver
106 require_once $path;
107
108 // build camel case notation
109 $paymentCamelCase = preg_replace("/[^a-z0-9]+/", ' ', $payment);
110 $paymentCamelCase = preg_replace("/\s+/", '', ucwords($paymentCamelCase));
111
112 // use specific class name
113 $classname = self::PAYMENT_METHOD_CLASS_PREFIX . $paymentCamelCase;
114
115 if (!class_exists($classname))
116 {
117 // class not found, fallback to the old notation
118 $classname = self::PAYMENT_METHOD_CLASS_PREFIX_DEPRECATED;
119
120 if (!class_exists($classname))
121 {
122 // the loaded file doesn't contain a valid payment processor
123 throw new RuntimeException(sprintf("Payment [%s] not found", $payment), 404);
124 }
125 }
126
127 // make sure we have a valid instance
128 if (method_exists($classname, 'getAdminParameters'))
129 {
130 // return configuration array
131 return $classname::getAdminParameters();
132 }
133 }
134 else
135 {
136 /**
137 * Attempt to load the configuration from an external payment driver.
138 *
139 * @note Handle the dispatcher according to the platform version.
140 */
141 $dispatcher = VAPFactory::getEventDispatcher();
142
143 /**
144 * Trigger hook to allow third-party plugins to build a configuration array.
145 *
146 * @note The caller (1st argument) must be equals to the program in use.
147 * Also make sure that the dispatcher supports triggerOnce method.
148 *
149 * @param string $element The component that triggered this event.
150 * @param string $payment The ID of the payment driver.
151 *
152 * @return array The configuration array.
153 *
154 * @since 1.7.1
155 */
156 $config = $dispatcher->triggerOnce('onLoadPaymentMethodConfigurationForm', array('vikappointments', $payment));
157
158 if ($config)
159 {
160 return (array) $config;
161 }
162 }
163
164 // fallback to an empty array
165 return array();
166 }
167
168 /**
169 * Provides a new payment instance for the specified arguments.
170 *
171 * @param string $payment The name of the payment that should be instantiated.
172 * @param mixed $order The details of the order that has to be paid.
173 * @param mixed $config The payment configuration array or a JSON string.
174 *
175 * @return mixed The payment instance.
176 *
177 * @throws RuntimeException
178 */
179 public static function getPaymentInstance($payment, $order = array(), $config = array())
180 {
181 if (is_string($config))
182 {
183 // decode config from JSON
184 $config = (array) json_decode($config, true);
185 }
186 else
187 {
188 // always cast to array
189 $config = (array) $config;
190 }
191
192 // strip file extension, if specified
193 $payment = preg_replace("/\.php$/i", '', $payment);
194
195 /**
196 * Build internal payments path.
197 *
198 * @note Use the correct payments path of the current program.
199 */
200 $path = VAPADMIN . DIRECTORY_SEPARATOR . 'payments' . DIRECTORY_SEPARATOR . $payment . '.php';
201
202 if (is_file($path))
203 {
204 // load internal payment driver
205 require_once $path;
206
207 // build camel case notation
208 $paymentCamelCase = preg_replace("/[^a-z0-9]+/", ' ', $payment);
209 $paymentCamelCase = preg_replace("/\s+/", '', ucwords($paymentCamelCase));
210
211 // use specific class name
212 $classname = self::PAYMENT_METHOD_CLASS_PREFIX . $paymentCamelCase;
213
214 if (!class_exists($classname))
215 {
216 // class not found, fallback to the old notation
217 $classname = self::PAYMENT_METHOD_CLASS_PREFIX_DEPRECATED;
218
219 if (!class_exists($classname))
220 {
221 // the loaded file doesn't contain a valid payment processor
222 throw new RuntimeException(sprintf("Payment [%s] not found", $payment), 404);
223 }
224 }
225
226 // create default payment processor
227 $processor = new $classname($order, $config);
228 }
229 else
230 {
231 /**
232 * Load payment plugin adapter class and instantiate the it
233 * to process the payment transaction through a plugin.
234 *
235 * @note The adapter class must be loaded and renamed
236 * according to the program requirements.
237 */
238 VAPLoader::import('libraries.payment.plugin');
239 // the payment process will be handled by a third-party plugin
240 $processor = new VAPPaymentPlugin($payment, $order, $config);
241 }
242
243 return $processor;
244 }
245
246 /**
247 * The class prefix of the instance that should be loaded.
248 *
249 * @note The class should start with the 3-letter name of the program.
250 *
251 * @var string
252 */
253 const PAYMENT_METHOD_CLASS_PREFIX = 'VAPPaymentMethod';
254
255 /**
256 * The deprecated class notation used before the implementation
257 * of this new framework.
258 *
259 * @note The class should start with the name of the program.
260 *
261 * @var string
262 */
263 const PAYMENT_METHOD_CLASS_PREFIX_DEPRECATED = 'VikAppointmentsPayment';
264 }
265