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 / admin / helpers / src / notification / elements.php

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

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