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 / session / model.php

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

226 lines 6.1 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 * Chat session model.
16 *
17 * @since 1.8.8
18 */
19 class VBOChatSessionModel extends VBOMvcModel
20 {
21 /**
22 * Used to cache the current session based on cookie token.
23 *
24 * @var object|null
25 */
26 protected static $currentSession = null;
27
28 /**
29 * The database table name.
30 *
31 * @var string
32 */
33 protected $tableName = '#__vikbooking_chat_sessions';
34
35 /**
36 * The cookie name of the token.
37 *
38 * @var string
39 */
40 protected $cookieTokenName = 'vbo_chat_session';
41
42 /**
43 * Returns the cookie token currently set for this user.
44 *
45 * @return string|null
46 */
47 public function getCookieToken()
48 {
49 // fetch session secret ID from cookie
50 $token = JFactory::getApplication()->input->cookie->getString($this->cookieTokenName);
51
52 // fetch token from PHP session as well
53 $sessionToken = JFactory::getSession()->get($this->cookieTokenName);
54
55 // in case we have a token within the PHP session and the cookie token does not match,
56 // prefer the one saved in the session
57 if ($sessionToken && strcmp($token, $sessionToken)) {
58 $token = $sessionToken;
59
60 $this->setCookieToken($token);
61 }
62
63 return $token;
64 }
65
66 /**
67 * Updates the cookie token for this user.
68 *
69 * @param string $token The session token.
70 *
71 * @return void
72 */
73 public function setCookieToken(string $token)
74 {
75 // in case of provided token, preserve cookie for 60 days, otherwise immediately expire it
76 $exp = $token ? 86400 * 60 : -3600;
77
78 // save the session token within the cookie
79 JFactory::getApplication()->input->cookie->set($this->cookieTokenName, $token, [
80 'expires' => time() + $exp,
81 'path' => '/',
82 'httponly' => true,
83 ]);
84
85 // save the token within the PHP session as well
86 JFactory::getSession()->set($this->cookieTokenName, $token);
87 }
88
89 /**
90 * Returns the session record according to the cookie token currently set, if any.
91 *
92 * @return object|null
93 */
94 public function getFromCookie()
95 {
96 if (static::$currentSession === null) {
97 // fetch session secret ID from cookie
98 $sessionSecretId = $this->getCookieToken();
99
100 if (!$sessionSecretId) {
101 return null;
102 }
103
104 // load session cookie (cache for later use)
105 static::$currentSession = $this->getItem(['token' => $sessionSecretId]);
106 }
107
108 return static::$currentSession;
109 }
110
111 /**
112 * Starts a new session by removing the current cookie token.
113 *
114 * @return void
115 */
116 public function endSession()
117 {
118 // clear the configured token
119 $this->setCookieToken('');
120
121 // reset the token from the PHP session as well
122 JFactory::getSession()->set($this->cookieTokenName, '');
123 }
124
125 /**
126 * Updates a metadata for the specified session.
127 *
128 * @param int|object $session Either a session ID or the session object.
129 * @param string $key The metadata name.
130 * @param mixed $value The metadata value.
131 *
132 * @return void
133 */
134 public function setMetadata($session, string $key, $value)
135 {
136 if (is_numeric($session)) {
137 $session = $this->getItem((int) $session);
138 }
139
140 if (!$session) {
141 throw new InvalidArgumentException('Invalid session.', 400);
142 }
143
144 if (!$key) {
145 throw new InvalidArgumentException('Invalid metadata name.', 400);
146 }
147
148 // update metadata
149 $session->metadata[$key] = $value;
150
151 // update session
152 $this->save([
153 'id' => $session->id,
154 'metadata' => $session->metadata,
155 ]);
156 }
157
158 /**
159 * @inheritDoc
160 */
161 public function getItem($pk)
162 {
163 $item = parent::getItem($pk);
164
165 if ($item) {
166 // decode metadata from JSON
167 $item->metadata = (array) ($item->metadata ? json_decode($item->metadata, true) : []);
168 }
169
170 return $item;
171 }
172
173 /**
174 * @inheritDoc
175 */
176 protected function preflight(array &$data)
177 {
178 if (empty($data['id'])) {
179 do {
180 // always generate a unique secret token for new sessions
181 $data['token'] = VikBooking::getCPinInstance()->generateSerialCode(32);
182 // repeat in case a session with the generated token already exists
183 } while ($this->getItem(['token' => $data['token']]));
184
185 $user = JFactory::getUser();
186
187 if (empty($data['name'])) {
188 // always use force a name
189 $data['name'] = $user->name ?: 'Guest';
190 }
191
192 if (!isset($data['id_user'])) {
193 $data['id_user'] = $user->id;
194 }
195
196 $data['created'] = JFactory::getDate('now')->toSql();
197 }
198
199 if (!empty($data['phone'])) {
200 // normalize phone number (accept letters and dots to support WhatsApp BSUID as well)
201 $data['phone'] = preg_replace("/[^0-9A-Z.]+/", '', $data['phone']);
202 }
203
204 if (isset($data['metadata']) && is_string($data['metadata'])) {
205 $data['metadata'] = json_encode($data['metadata']);
206 }
207
208 // always postpone the logout by one minute every time we save the record
209 $data['logout'] = JFactory::getDate('+1 minute')->toSql();
210
211 return parent::preflight($data);
212 }
213
214 /**
215 * @inheritDoc
216 */
217 protected function postflight(array $data, $isNew)
218 {
219 // do not save session token in case we are starting a WhatsApp session
220 if ($isNew && empty($data['phone'])) {
221 // save the session token within the cookie
222 $this->setCookieToken($data['token']);
223 }
224 }
225 }
226