PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.9
VikBooking Hotel Booking Engine & PMS v1.6.9
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 / admin / helpers / src / notification / elements.php

elements.php in VikBooking Hotel Booking Engine & PMS 1.6.9, at admin/helpers/src/notification/elements.php

383 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage core
5 * @author Alessio Gaggii - E4J s.r.l.
6 * @copyright Copyright (C) 2024 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 * Notification elements registry to store a record for the Notification Center.
16 *
17 * @since 1.16.8 (J) - 1.6.8 (WP)
18 */
19 final class VBONotificationElements extends JObject
20 {
21 /**
22 * Valid notification group enumerations.
23 *
24 * @var array
25 */
26 private $groupEnums = [
27 // notifications from Website
28 'website',
29 // notifications from OTAs
30 'otas',
31 // notifications from Channel Manager
32 'cm',
33 // notifications from Guests
34 'guests',
35 // notifications from Operators
36 'operators',
37 ];
38
39 /**
40 * Default notification type.
41 *
42 * @var string
43 */
44 private $defaultType = 'info';
45
46 /**
47 * Determines and returns the group to which the notification belongs.
48 *
49 * @return string
50 */
51 public function getGroup()
52 {
53 // check if the group was already determined
54 $group = (string) $this->get('_group', '');
55
56 if (!$group) {
57 // access the notification sender property
58 $group = strtolower((string) $this->get('sender', $this->groupEnums[0]));
59
60 // validate the group property
61 $group = in_array($group, $this->groupEnums) ? $group : $this->groupEnums[0];
62
63 // cache determined group
64 $this->set('_group', $group);
65 }
66
67 return $group;
68 }
69
70 /**
71 * Returns the notification type.
72 *
73 * @return string
74 */
75 public function getType()
76 {
77 // access the notification type
78 $type = strtolower((string) $this->get('type', $this->defaultType));
79
80 // ensure the maximum length of 32 chars is respected
81 return $this->shortenString($type, 32, $this->defaultType);
82 }
83
84 /**
85 * Returns the notification title.
86 *
87 * @return string
88 */
89 public function getTitle()
90 {
91 // access the notification title
92 $title = (string) $this->get('title', '');
93
94 // try to guess the title
95 if (!$title) {
96 // check for virtual credit card balance
97 if (strpos($this->getType(), 'vcc_balance') === 0) {
98 $title = JText::translate('VBO_VCC_BALANCE');
99 if ($title == 'VBO_VCC_BALANCE') {
100 $title = ucwords(str_replace('_', ' ', $this->getType()));
101 }
102 }
103 }
104
105 // ensure the maximum length of 64 chars is respected
106 return $this->shortenString($title, 64);
107 }
108
109 /**
110 * Returns the notification summary.
111 *
112 * @return string
113 */
114 public function getSummary()
115 {
116 // access the notification summary
117 $summary = (string) $this->get('summary', '');
118
119 // normalize the summary, if needed
120 if ($summary && $this->getChannel() && !strcasecmp($this->getType(), 'lvf')) {
121 // listing verification framework (LVF)
122 $summary = JText::sprintf('VBO_VERIFY_LISTING_INFO', $summary);
123 }
124
125 // ensure the maximum length of 256 chars is respected
126 return $this->shortenString($summary, 256);
127 }
128
129 /**
130 * Builds and returns the notification call-to-action data.
131 *
132 * @return null|string
133 */
134 public function getCallToActionData()
135 {
136 $cta_data = [];
137
138 // check if a widget identifier was provided
139 $widget = (string) $this->get('widget', '');
140 if ($widget) {
141 $cta_data['widget'] = $widget;
142 }
143
144 // check if some widget options were provided
145 $widget_options = (array) $this->get('widget_options', []);
146 if ($widget_options) {
147 $cta_data['widget_options'] = $widget_options;
148 }
149
150 // check if a notification URL was provided
151 $cta_url = (string) $this->get('cta_url', $this->get('url'));
152 if ($cta_url) {
153 $cta_data['url'] = $cta_url;
154 }
155
156 // check if a custom label was provided
157 if ($cta_data && is_string($this->get('label'))) {
158 $cta_data['label'] = $this->get('label');
159 }
160
161 if (!$cta_data) {
162 // attempt to determine the CTA payload to set
163 if (strpos($this->getType(), 'vcc_balance') === 0 && ($this->getReservationID() || $this->getOTAReservationID())) {
164 // set call-to-action for Virtual Terminal admin-widget for VCC balance
165 $cta_data = [
166 'label' => JText::translate('VBO_CC_DOCHARGE'),
167 'widget' => 'virtual_terminal',
168 'widget_options' => [
169 'bid' => $this->getReservationID() ?: $this->getOTAReservationID(),
170 ],
171 ];
172 } elseif (!strcasecmp($this->getType(), 'guest_message') && ($this->getReservationID() || $this->getOTAReservationID())) {
173 // set call-to-action for Guest Messages admin-widget to reply to the guest message
174 $cta_data = [
175 'label' => JText::translate('VBO_REPLY'),
176 'widget' => 'guest_messages',
177 'widget_options' => [
178 'bid' => $this->getReservationID() ?: $this->getOTAReservationID(),
179 ],
180 ];
181 } elseif (!strcasecmp($this->getType(), 'ob') && $this->getReservationID()) {
182 // set call-to-action for Bookings Calendar admin-widget in case of overbooking
183 $cta_data = [
184 'widget' => 'bookings_calendar',
185 'widget_options' => [
186 'bid' => $this->getReservationID(),
187 'overbooking' => 1,
188 ],
189 ];
190 }
191 }
192
193 return $cta_data ? json_encode($cta_data) : null;
194 }
195
196 /**
197 * Returns the VikBooking reservation ID.
198 *
199 * @return null|int
200 */
201 public function getReservationID()
202 {
203 $res_id = $this->get('idorder', null);
204
205 return $res_id ? (int) $res_id : null;
206 }
207
208 /**
209 * Returns the OTA reservation ID.
210 *
211 * @return null|string
212 */
213 public function getOTAReservationID()
214 {
215 $ota_res_id = $this->get('idorderota', null);
216
217 return $ota_res_id ? (string) $ota_res_id : null;
218 }
219
220 /**
221 * Returns the channel name.
222 *
223 * @return null|string
224 */
225 public function getChannel()
226 {
227 $channel = $this->get('channel', null);
228
229 return $channel ? (string) $channel : null;
230 }
231
232 /**
233 * Returns the notification date and time.
234 *
235 * @return string
236 */
237 public function getDate()
238 {
239 try {
240 $date = JFactory::getDate($this->get('date') ?: 'now');
241 } catch(Exception $e) {
242 $date = JFactory::getDate();
243 }
244
245 return $date->toSql();
246 }
247
248 /**
249 * Returns the notification signature.
250 *
251 * @return string
252 */
253 public function getSignature()
254 {
255 $signature = (string) $this->get('_signature', '');
256
257 if (!$signature) {
258 $signature = $this->buildSignature();
259 }
260
261 return $signature;
262 }
263
264 /**
265 * Sets the notification signature.
266 *
267 * @return self
268 */
269 public function setSignature(string $signature = '')
270 {
271 $this->set('_signature', $signature);
272
273 return $this;
274 }
275
276 /**
277 * Builds, sets and returns the notification signature.
278 *
279 * @return string
280 */
281 public function buildSignature()
282 {
283 // build notification signature elements
284 $elements = [
285 'id' => $this->get('id', $this->get('notification_id', 0)),
286 'idorder' => $this->get('idorder', 0),
287 'sender' => $this->get('sender', ''),
288 'type' => $this->get('type', ''),
289 'title' => $this->get('title', ''),
290 'summary' => $this->get('summary', ''),
291 ];
292
293 // build notification signature string
294 $signature = md5(serialize($elements));
295
296 // set signature string
297 $this->setSignature($signature);
298
299 return $signature;
300 }
301
302 /**
303 * Returns the notification error code.
304 *
305 * @return int
306 */
307 public function getErrorCode()
308 {
309 return (int) $this->get('_errorCode', 500);
310 }
311
312 /**
313 * Sets the notification error code.
314 *
315 * @return self
316 */
317 public function setErrorCode($code = 500)
318 {
319 $this->set('_errorCode', $code);
320
321 return $this;
322 }
323
324 /**
325 * Ensures a string reflects the given length, or it will be eventually shortened or replaced.
326 *
327 * @param string $value the string to check.
328 * @param int $length the length to reflect.
329 * @param string $fallback optional string to replace as fallback.
330 *
331 * @return string
332 */
333 private function shortenString(string $value, int $length, string $fallback = null)
334 {
335 if (strlen($value) <= $length || $length <= 0) {
336 // length is safe
337 return $value;
338 }
339
340 if ($fallback) {
341 // replace string with provided fallback
342 return $fallback;
343 }
344
345 // shorten the string to the desired length
346 if (!function_exists('mb_strlen')) {
347 // use a regular sub-string without multi-byte support
348 return substr($value, 0, $length);
349 }
350
351 // calculate string length
352 $size = strlen($value);
353 $mb_size = mb_strlen($value);
354 $ch_diff = $size - $mb_size;
355
356 if ($ch_diff <= 0) {
357 // no multi-byte chars found
358 return substr($value, 0, $length);
359 }
360
361 // safely construct the string with one multibyte char per time
362 $mb_value = '';
363 $mb_char_start = 0;
364 while (strlen($mb_value) < $length) {
365 // get a one-char multi-byte portion
366 $mb_portion = mb_substr($value, $mb_char_start, 1, 'UTF-8');
367
368 if (strlen($mb_value . $mb_portion) > $length) {
369 // abort to not exceed the length
370 return $mb_value;
371 }
372
373 // add portion to string value
374 $mb_value .= $mb_portion;
375
376 // increase chart start counter
377 $mb_char_start++;
378 }
379
380 return $mb_value;
381 }
382 }
383