PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.7.2
VikBooking Hotel Booking Engine & PMS v1.7.2
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / libraries / adapter / sms / driver.php

driver.php in VikBooking Hotel Booking Engine & PMS 1.7.2, at libraries/adapter/sms/driver.php

528 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikWP - Libraries
4 * @subpackage adapter.sms
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2023 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 JLoader::import('adapter.sms.status');
15
16 /**
17 * This class describes the events that an abstract sms driver should handle.
18 *
19 * @since 10.1.30
20 */
21 abstract class JSmsDriver
22 {
23 /**
24 * The name of the plugin that has requested the sms.
25 *
26 * @var string
27 */
28 protected $caller;
29
30 /**
31 * The driver identifier.
32 *
33 * @var string
34 */
35 protected $driver;
36
37 /**
38 * The order details.
39 *
40 * @var JObject
41 */
42 protected $order;
43
44 /**
45 * The driver configuration parameters.
46 *
47 * @var JObject
48 */
49 protected $params;
50
51 /**
52 * Class constructor.
53 *
54 * @param string $caller The name of the plugin that requested the sms.
55 * @param mixed $order The order details to start the transaction.
56 * @param mixed $params The configuration of the driver.
57 */
58 public function __construct($caller, $order, $params = array())
59 {
60 if (is_string($params))
61 {
62 $params = (array) json_decode($params);
63 }
64
65 $this->caller = $caller;
66 $this->order = new JObject($order);
67 $this->params = new JObject($params);
68 }
69
70 /**
71 * Returns the name of the plugin that dispatched the sms.
72 *
73 * @return string
74 */
75 public function getCaller()
76 {
77 return $this->caller;
78 }
79
80 /**
81 * Checks if the given caller matches the current one.
82 *
83 * @param string $caller The caller to check.
84 *
85 * @return boolean True if the callers are equal, otherwise false.
86 *
87 * @uses getCaller()
88 */
89 public function isCaller($caller)
90 {
91 return !strcasecmp($this->getCaller(), $caller);
92 }
93
94 /**
95 * Returns the name of the driver.
96 *
97 * @return string
98 */
99 public function getDriver()
100 {
101 if (!$this->driver)
102 {
103 $class = get_class($this);
104
105 // extract driver name from classname
106 $this->driver = preg_replace_callback("/{$this->caller}Sms(.*?)/i", function($match)
107 {
108 return $match[1];
109 }, $class);
110
111 $this->driver = strtolower($this->driver);
112 }
113
114 return $this->driver;
115 }
116
117 /**
118 * Checks if the given driver matches the current one.
119 *
120 * @param string $driver The driver to check.
121 *
122 * @return boolean True if the drivers are equal, otherwise false.
123 *
124 * @uses getDriver()
125 */
126 public function isDriver($driver)
127 {
128 return !strcasecmp($this->getDriver(), $driver);
129 }
130
131 /**
132 * Returns the order detail related to the specified key.
133 *
134 * @param string $key The registry key.
135 * @param mixed $def The default value if the key is not set.
136 *
137 * @return mixed The registry value, or the default one.
138 */
139 public function get($key, $def = null)
140 {
141 return $this->order->get($key, $def);
142 }
143
144 /**
145 * Updates the specified key into the order details object.
146 *
147 * @param string $key The registry key.
148 * @param mixed $val The value to update.
149 *
150 * @param mixed The old value.
151 */
152 public function set($key, $val)
153 {
154 return $this->order->set($key, $val);
155 }
156
157 /**
158 * Returns an associative array containing the order details.
159 *
160 * @return array
161 */
162 public function getOrder()
163 {
164 return $this->order->getProperties();
165 }
166
167 /**
168 * Returns the configuration parameter related to the specified key.
169 *
170 * @param string $key The registry key.
171 * @param mixed $def The default value if the key is not set.
172 *
173 * @return mixed The registry value, or the default one.
174 */
175 public function getParam($key, $def = null)
176 {
177 return $this->params->get($key, $def);
178 }
179
180 /**
181 * Updates the specified key into the configuration object.
182 *
183 * @param string $key The registry key.
184 * @param mixed $val The value to update.
185 *
186 * @param mixed The old value.
187 */
188 public function setParam($key, $val)
189 {
190 return $this->params->set($key, $val);
191 }
192
193 /**
194 * Returns an associative array containing the driver parameters.
195 *
196 * @return array
197 */
198 public function getParams()
199 {
200 return $this->params->getProperties();
201 }
202
203 /**
204 * Returns an associative array containing the form
205 * fields used to construct the configuration of the driver.
206 *
207 * This method triggers two ACTIONS to manipulate the
208 * configuration array before it is returned:
209 * - sms_driver_before_admin_params
210 * - sms_driver_after_admin_params
211 *
212 * @return array The sms driver configuration.
213 *
214 * @uses buildAdminParameters()
215 */
216 public function getAdminParameters()
217 {
218 /**
219 * Plugins can manipulate the properties of this object.
220 * Fires before the configuration array is generated.
221 *
222 * @param self A reference to this object.
223 *
224 * @since 10.1.30
225 */
226 do_action('sms_driver_before_admin_params_' . $this->caller, array(&$this));
227
228 // children drivers will create the configuration form (as array)
229 $config = $this->buildAdminParameters();
230
231 /**
232 * Plugins can manipulate the configuration form of the driver.
233 * Fires after generating the config form.
234 *
235 * @param self A reference to this object.
236 * @param array A reference to the configuration array.
237 *
238 * @since 10.1.30
239 */
240 do_action_ref_array('sms_driver_after_admin_params_' . $this->caller, array(&$this, &$config));
241
242 return $config;
243 }
244
245 /**
246 * Abstract method used to build the associative array
247 * to allow the plugins to construct a configuration form.
248 *
249 * In case the driver needs an API Key, the array should
250 * be built as follows:
251 *
252 * {"apikey": {"type": "text", "label": "API Key"}}
253 *
254 * @return array The associative array.
255 */
256 protected function buildAdminParameters()
257 {
258 // return an empty array because a sms driver
259 // may not need a configuration
260 return array();
261 }
262
263 /**
264 * Dispatches the SMS to the specified phone number.
265 *
266 * This method triggers the ACTIONS below:
267 * - sms_driver_before_send
268 * - sms_driver_after_send
269 *
270 * @param string $phone The sms receiver.
271 * @param string $text The message to send.
272 *
273 * @return mixed An object describing the status of the sms.
274 *
275 * @uses dispatch()
276 */
277 public function sendMessage($phone, $text)
278 {
279 /**
280 * Plugins can manipulate the properties of this object.
281 * Fires before sending the SMS.
282 *
283 * @param self A reference to this object.
284 * @param string The sms receiver.
285 * @param string The message to send.
286 *
287 * @since 10.1.30
288 */
289 do_action('sms_driver_before_send_' . $this->caller, array(&$this, &$phone, &$text));
290
291 $status = new JSmsStatus();
292
293 // sanitize phone number
294 $phone = $this->sanitizePhone($phone);
295
296 // children drivers will dispatch the message
297 $this->dispatch($phone, $text, $status);
298
299 // inject receiver and SMS within the status object
300 $status->setData('phone', $phone);
301 $status->setData('sms', $text);
302
303 $response = null;
304
305 /**
306 * Plugins can manipulate the response object to return.
307 * By filling the &$response variable, this method will return
308 * it instead of the default &$status one.
309 * Fires after dispatching the sms.
310 *
311 * @param self A reference to this object.
312 * @param JSmsStatus A reference to the status object.
313 * @param mixed A reference to the final response (null by default).
314 *
315 * @since 10.1.30
316 */
317 do_action_ref_array('sms_driver_after_send_' . $this->caller, array(&$this, &$status, &$response));
318
319 if (is_null($response))
320 {
321 // no hook fired, the response will be equals to the status object
322 $response = $status;
323 }
324
325 return $response;
326 }
327
328 /**
329 * Abstract method used to dispatch a SMS to the specified phone.
330 *
331 * @param string $phone The sms receiver.
332 * @param string $text The message to send.
333 * @param JSmsStatus &$status The status of the notification.
334 *
335 * @return void
336 */
337 abstract protected function dispatch($phone, $text, JSmsStatus &$status);
338
339 /**
340 * Checks whether the current driver is able to estimate the credit.
341 *
342 * @return boolean
343 */
344 public function canEstimate()
345 {
346 // inherit in chidlren classes
347 return false;
348 }
349
350 /**
351 * Tries to recover the remaining balance.
352 *
353 * This method triggers the ACTIONS below:
354 * - sms_driver_before_estimate
355 * - sms_driver_after_estimate
356 *
357 * @param string $phone An optional receiver.
358 * @param string $text An optional message.
359 *
360 * @return mixed The remaining balance on success, false otherwise.
361 *
362 * @uses estimate()
363 */
364 public function getCredit($phone = null, $text = null)
365 {
366 /**
367 * Plugins can manipulate the properties of this object.
368 * Fires before estimating the remaining credit.
369 *
370 * @param self A reference to this object.
371 * @param string The sms receiver.
372 * @param string The message to send.
373 *
374 * @since 10.1.30
375 */
376 do_action('sms_driver_before_estimate_' . $this->caller, array(&$this, &$phone, &$text));
377
378 // sanitize phone number
379 $phone = $this->sanitizePhone($phone);
380
381 try
382 {
383 // children drivers will estimate the credit
384 $credit = $this->estimateCredit($phone, $text);
385 }
386 catch (Exception $e)
387 {
388 $credit = false;
389 }
390
391 /**
392 * Plugins can manipulate the resulting credit.
393 * Fires after estimating the user credit.
394 *
395 * @param self A reference to this object.
396 * @param mixed A reference to the user credit (null by default).
397 *
398 * @since 10.1.30
399 */
400 do_action_ref_array('sms_driver_after_estimate_' . $this->caller, array(&$this, &$credit));
401
402 return $credit;
403 }
404
405 /**
406 * Tries to estimate the remaining user credit.
407 *
408 * @param string $phone An optional receiver.
409 * @param string $text An optional message.
410 *
411 * @return mixed The remaining balance on success, false otherwise.
412 *
413 * @throws Exception
414 */
415 protected function estimateCredit($phone, $text)
416 {
417 // inherit in children classes to estimate credit
418 throw new Exception('Not implemented', 501);
419 }
420
421 /**
422 * Validates the response.
423 * Implement for platform BC.
424 *
425 * @param mixed $response
426 *
427 * @return boolean
428 */
429 public function validateResponse($response)
430 {
431 // reset log
432 $this->log = '';
433
434 if (!$response instanceof JSmsStatus)
435 {
436 // invalid argument
437 return false;
438 }
439
440 // register log
441 $this->log = $response->log;
442
443 // check sms status
444 return $response->isVerified();
445 }
446
447 /**
448 * Returns the latest logs.
449 *
450 * @return string
451 */
452 public function getLog()
453 {
454 return isset($this->log) ? $this->log : '';
455 }
456
457 /**
458 * Helper method used to sanitize phone numbers.
459 *
460 * @param string $phone The phone number to sanitize.
461 *
462 * @return string The cleansed number.
463 */
464 public function sanitizePhone($phone)
465 {
466 // trim unexpected characters
467 $phone = preg_replace("/[^0-9+]/", '', $phone);
468
469 // replace 00 dial code with +
470 if (substr($phone, 0, 2) == '00')
471 {
472 $phone = '+' . substr($phone, 2);
473 }
474
475 return $phone;
476 }
477
478 /**
479 * Adds the dial code to the phone number.
480 *
481 * @param string $prefix The dial code to prepend.
482 * @param string $phone The phone number.
483 *
484 * @return string The resulting phone number.
485 */
486 public function addDialCode($prefix, $phone)
487 {
488 // check if the phone number already owns a dial code
489 if ($prefix && !preg_match("/^\+/", $phone))
490 {
491 // sanitize dial code
492 $prefix = $this->sanitizePhone($prefix);
493
494 // normalize dial code
495 $prefix = '+' . ltrim($prefix, '+');
496
497 // prepend dial code
498 $phone = $prefix . $phone;
499 }
500
501 return $phone;
502 }
503
504 /**
505 * Check if the specified message contains UTF-8 characters.
506 *
507 * @param string $message The string to check.
508 *
509 * @return boolean True if unicode, otherwise false.
510 */
511 public function isUnicode($message)
512 {
513 if (function_exists('iconv'))
514 {
515 $latin = @iconv('UTF-8', 'ISO-8859-1', $message);
516
517 if (strcmp($latin, $message))
518 {
519 $arr = unpack('H*hex', @iconv('UTF-8', 'UCS-2BE', $message));
520 //return strtoupper($arr['hex']);
521 return true;
522 }
523 }
524
525 return false;
526 }
527 }
528