PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
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 1.7.3 All 36 releases
vikbooking / admin / helpers / src / chat / context / session.php

session.php in VikBooking Hotel Booking Engine & PMS trunk, at admin/helpers/src/chat/context/session.php

350 lines 11.0 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 E4J s.r.l.
6 * @copyright Copyright (C) 2026 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 * Session chat context class.
16 *
17 * @since 1.8.8
18 */
19 class VBOChatContextSession extends VBOChatContextaware
20 {
21 /** @var object */
22 private $session;
23
24 /**
25 * @inheritDoc
26 */
27 final public function getAlias()
28 {
29 return 'session';
30 }
31
32 /**
33 * @inheritDoc
34 */
35 public function getRecipients()
36 {
37 $recipients = [];
38
39 // adds support to administrator (create a placeholder to simulate a false login)
40 $recipients[] = new VBOChatUserAdmin((object) [
41 'id' => 0,
42 'guest' => false,
43 'name' => '',
44 ]);
45
46 if ($session = $this->getSession()) {
47 // adds support to guest user
48 $recipients[] = new VBOChatUserGuest($session);
49
50 // create AI user for auto-replies (inject session token as thread ID)
51 $aiUser = new VBOChatUserAi($session->token);
52
53 // make sure the AI is allowed to participate to a conversation
54 if ($aiUser->can('chat.join', $this)) {
55 // adds support to AI user
56 $recipients[] = $aiUser;
57 }
58 }
59
60 return $recipients;
61 }
62
63 /**
64 * @inheritDoc
65 */
66 public function getSubject()
67 {
68 $session = $this->getSession();
69
70 if (!$session) {
71 return sprintf('<em>Session #%d (deleted)</em>', $this->getID());
72 }
73
74 // fetch session (user) name
75 $sessionName = $session->name;
76
77 if (!empty($session->phone)) {
78 // the user wrote via WhatsApp, append icon after name
79 $sessionName .= '&nbsp;<i class="' . VikBookingIcons::i('whatsapp', '', 'fab') . '" style="color: #090;font-size: larger;"></i>';
80 }
81
82 // fetch metadata to elaborate an appropriate topic
83 $metadata = $this->getMetadata();
84
85 // check if we have an interest on a specific query
86 if (!empty($metadata['query'])) {
87 $checkin = JFactory::getDate($metadata['query']['checkin'] ?? 'now');
88 $checkout = JFactory::getDate($metadata['query']['checkout'] ?? 'now');
89
90 // build the best dates format depending on checkin-checkout
91 if ($checkin->format('Y') != $checkout->format('Y')) {
92 $dates = $checkin->format('j M Y') . ' - ' . $checkout->format('j M Y');
93 } else if ($checkin->format('m') != $checkout->format('m')) {
94 $dates = $checkin->format('j M') . ' - ' . $checkout->format('j M') . ' ' . $checkin->format('Y');
95 } else {
96 $dates = $checkin->format('j') . '-' . $checkout->format('j') . ' ' . $checkin->format('M Y');
97 }
98
99 return $sessionName . ' • ' . $dates;
100 }
101
102 // use default inquiry
103 return JText::sprintf('VBO_CHAT_SESSION_SUMMARY', $sessionName);
104 }
105
106 /**
107 * @inheritDoc
108 */
109 public function getURL()
110 {
111 $url = 'index.php?option=com_vikbooking&view=chat';
112
113 if ($session = $this->getSession()) {
114 // inject session token
115 $url .= '&token=' . $this->session->token;
116 }
117
118 return VBOFactory::getPlatform()->getUri()->route($url);
119 }
120
121 /**
122 * @inheritDoc
123 */
124 public function getMetadata(bool $public = false)
125 {
126 $metadata = [
127 'use_ai' => true,
128 'banned' => false,
129 ];
130
131 if ($session = $this->getSession()) {
132 // replace default values with session metadata
133 $metadata = array_merge($metadata, $session->metadata);
134
135 // normalize values
136 $metadata['use_ai'] = (bool) $metadata['use_ai'];
137 $metadata['banned'] = (bool) $metadata['banned'];
138 }
139
140 return $metadata;
141 }
142
143 /**
144 * @inheritDoc
145 */
146 public function setMetadata(string $key, $value)
147 {
148 try {
149 // insert/update metadata
150 (new VBOChatSessionModel)->setMetadata($this->getID(), $key, $value);
151 } catch (Exception $error) {
152 // unable to save the metadata
153 }
154 }
155
156 /**
157 * @inheritDoc
158 */
159 public function useAssets(VBOChatUser $user)
160 {
161 $options = [
162 'version' => VIKBOOKING_SOFTWARE_VERSION,
163 ];
164
165 $document = JFactory::getDocument();
166
167 if (JFactory::getApplication()->isClient('site')) {
168 $document->addScript(VIKBOOKING_ADMIN_ASSETS_URI . 'vbocore.js', $options);
169 $document->addScript(VIKBOOKING_ADMIN_ASSETS_URI . 'toast.js', $options);
170 $document->addStylesheet(VIKBOOKING_ADMIN_ASSETS_URI . 'toast.css', $options);
171
172 $document->addScriptDeclaration(
173 <<<JS
174 (function($) {
175 'use strict';
176
177 $(function() {
178 VBOToast.create(VBOToast.POSITION_TOP_RIGHT);
179 });
180 })(jQuery);
181 JS
182 );
183 }
184
185 if ($user->getID() == -1) {
186 JText::script('VBO_WANT_PROCEED');
187 JText::script('VBO_CHAT_AI_THINKING');
188
189 // load scripts for guest
190 $document->addScript(VBO_SITE_URI . 'resources/chat/session/guest.js', $options);
191 $document->addStylesheet(VBO_SITE_URI . 'resources/chat/session/guest.css', $options);
192 } else if ($user->getID() == 0) {
193 JText::script('VBO_CHAT_BAN_SESSION');
194 JText::script('VBO_CHAT_UNBAN_SESSION');
195 JText::script('VBO_CHAT_STOP_AI_SESSION');
196 JText::script('VBO_CHAT_RESUME_AI_SESSION');
197 JText::script('VBO_CHAT_QUERY_SUMMARY_TITLE');
198 JText::script('VBO_CHAT_QUERY_SUMMARY_PREF_ROOMS');
199 JText::script('VBO_CHAT_SUMMARIZE_TITLE');
200 JText::script('VBO_CONDTEXT_RULE_STAYDATES');
201 JText::script('VBO_NOTIFS_GROUP_GUESTS');
202 JText::script('VBOSEASONCALNUMNIGHT');
203 JText::script('VBOSEASONCALNUMNIGHTS');
204 JText::script('VBMAILROOMNUM');
205 JText::script('VBO_N_ADULTS');
206 JText::script('VBO_N_ADULTS_1');
207 JText::script('VBO_N_CHILDREN');
208 JText::script('VBO_N_CHILDREN_1');
209 JText::script('VBO_PET');
210 JText::script('VBO_PETS');
211 JText::script('VBO_MESSAGE_TEMPLATE');
212 JText::script('JGLOBAL_SELECT_AN_OPTION');
213
214 // load scripts for admin
215 $document->addScript(VBO_SITE_URI . 'resources/chat/session/admin.js', $options);
216 $document->addStylesheet(VBO_SITE_URI . 'resources/chat/session/admin.css', $options);
217 }
218 }
219
220 /**
221 * @inheritDoc
222 */
223 public function getActions(VBOChatUser $user)
224 {
225 $actions = [];
226
227 $session = $this->getSession();
228
229 if ($user->getID() == -1) {
230 // add button to start a new session
231 $actions[] = [
232 'namespace' => 'session.restart',
233 'text' => JText::translate('VBO_CHAT_RESTART_SESSION'),
234 'icon' => VikBookingIcons::i('broom'),
235 ];
236
237 // add button to share the conversation
238 $actions[] = [
239 'namespace' => 'session.share',
240 'text' => JText::translate('VBO_CHAT_SHARE_SESSION'),
241 'icon' => VikBookingIcons::i('link'),
242 'url' => $this->getURL(),
243 'separator' => true,
244 ];
245 } if ($user->getID() == 0) {
246 // add button to ban/unban the session
247 $actions[] = [
248 'namespace' => 'session.ban',
249 'separator' => true,
250 ];
251
252 if (VBOChatUserAi::isSupported()) {
253 // add button to stop/resume AI auto-replies
254 $actions[] = [
255 'namespace' => 'session.ai.autoreply',
256 ];
257
258 // add button to summarize the conversation
259 $actions[] = [
260 'namespace' => 'session.ai.summarize',
261 'text' => JText::translate('VBO_CHAT_SUMMARIZE'),
262 'icon' => VikBookingIcons::i('clipboard-list'),
263 'supported' => method_exists('VCMAiModelService', 'summarizeThread'),
264 'separator' => true,
265 ];
266 }
267
268 // add button to create a quotation
269 $actions[] = [
270 'namespace' => 'session.query.quote',
271 'text' => JText::translate('VBO_CREATE_QUOTE'),
272 'icon' => VikBookingIcons::i('file-invoice-dollar'),
273 'url' => VBOFactory::getPlatform()->getUri()->admin('index.php?option=com_vikbooking&view=managequote&session_id=' . ($session->id ?? null), false),
274 ];
275
276 // add button to overview the search query
277 $actions[] = [
278 'namespace' => 'session.query.see',
279 'text' => JText::translate('VBO_CHAT_SESSION_QUERY_SEE'),
280 'icon' => VikBookingIcons::i('eye'),
281 'separator' => true,
282 ];
283
284 // session started via phone, add button to send a template
285 if (!empty($session->phone)) {
286 // get session metadata
287 $metadata = $this->getMetadata();
288
289 // load configured messaging templates
290 $templates = VCMMessagingAccountsModel::getInstance()->getConfigurationsData(
291 new VCMMessagingTemplateDecoratorChat($session),
292 [
293 'filter_items' => [
294 'account_id' => $metadata['waba_id'] ?? null,
295 'phone_id' => $metadata['phone_id'] ?? null,
296 ],
297 ]
298 );
299
300 $actions[] = [
301 'namespace' => 'session.messaging.sendtmpl',
302 'text' => JText::translate('VBO_CHAT_SESSION_SEND_TMPL'),
303 'icon' => VikBookingIcons::i('comment-alt'),
304 'templates' => $templates,
305 ];
306 }
307 }
308
309 return $actions;
310 }
311
312 /**
313 * @inheritDoc
314 */
315 public function can(string $scope, VBOChatUser $user)
316 {
317 if ($user->getID() != -1) {
318 return true;
319 }
320
321 // obtain token from cookie
322 $token = (new VBOChatSessionModel)->getCookieToken();
323
324 if (!$token) {
325 return false;
326 }
327
328 // fetch details of the current session
329 $session = $this->getSession();
330
331 // validate cookie token against session token
332 return !strcmp($session->token ?? '', $token);
333 }
334
335 /**
336 * Returns the details of this session context.
337 *
338 * @return object|null
339 */
340 protected function getSession()
341 {
342 if ($this->session === null) {
343 // fetch session details
344 $this->session = (new VBOChatSessionModel)->getItem($this->getID()) ?: false;
345 }
346
347 return $this->session;
348 }
349 }
350