| @@ -94,14 +94,23 @@ | ||
| 94 | 94 | (new VBOChatSearch) |
| 95 | 95 | ->withContext($context) |
| 96 | 96 | ->message($threshold, '>') |
| 97 | 97 | ); |
| 98 | + | |
| 99 | + // maintain the user logged in | |
| 100 | + $chat->getUser()->keepAlive($context); | |
| 101 | + | |
| 102 | + // obtain the public context metadata | |
| 103 | + $metadata = $context->getMetadata($public = true); | |
| 98 | 104 | } catch (Exception $error) { |
| 99 | 105 | VBOHttpDocument::getInstance($app)->close($error->getCode() ?: 500, $error->getMessage()); |
| 100 | 106 | } |
| 101 | 107 | |
| 102 | 108 | // output the result content |
| 103 | - VBOHttpDocument::getInstance($app)->json($messages); | |
| 109 | + VBOHttpDocument::getInstance($app)->json([ | |
| 110 | + 'messages' => $messages, | |
| 111 | + 'metadata' => $metadata, | |
| 112 | + ]); | |
| 104 | 113 | } |
| 105 | 114 | |
| 106 | 115 | /** |
| 107 | 116 | * Task used to scan the pagination of a specified chat. |
| @@ -222,8 +231,10 @@ | ||
| 222 | 231 | VBOHttpDocument::getInstance($app)->close(403, JText::translate('JINVALID_TOKEN')); |
| 223 | 232 | } |
| 224 | 233 | |
| 225 | 234 | // fetch request data |
| 235 | + $contextId = $app->input->getUint('id_context', 0); | |
| 236 | + $context = $app->input->get('context', ''); | |
| 226 | 237 | $files = $app->input->files->get('attachments', [], 'raw'); |
| 227 | 238 | |
| 228 | 239 | if (isset($files['name'])) { |
| 229 | 240 | // we have a single associative array, we need to push it within a list, |
| @@ -236,9 +247,12 @@ | ||
| 236 | 247 | try { |
| 237 | 248 | /** @var VBOChatMediator */ |
| 238 | 249 | $chat = VBOFactory::getChatMediator(); |
| 239 | 250 | |
| 240 | - if (!$chat->getUser()->can('chat.attachment.add')) { | |
| 251 | + /** @var VBOChatContext */ | |
| 252 | + $context = $chat->createContext($context, $contextId); | |
| 253 | + | |
| 254 | + if (!$chat->getUser()->can('chat.attachment.add', $context)) { | |
| 241 | 255 | // not authorized |
| 242 | 256 | throw new RuntimeException(JText::translate('JERROR_ALERTNOAUTHOR'), 403); |
| 243 | 257 | } |
| 244 | 258 | |
| @@ -275,8 +289,10 @@ | ||
| 275 | 289 | VBOHttpDocument::getInstance($app)->close(403, JText::translate('JINVALID_TOKEN')); |
| 276 | 290 | } |
| 277 | 291 | |
| 278 | 292 | // fetch request data |
| 293 | + $contextId = $app->input->getUint('id_context', 0); | |
| 294 | + $context = $app->input->get('context', ''); | |
| 279 | 295 | $file = $app->input->get('attachment', [], 'array'); |
| 280 | 296 | |
| 281 | 297 | try { |
| 282 | 298 | /** @var VBOChatMediator */ |
| @@ -281,9 +297,12 @@ | ||
| 281 | 297 | try { |
| 282 | 298 | /** @var VBOChatMediator */ |
| 283 | 299 | $chat = VBOFactory::getChatMediator(); |
| 284 | 300 | |
| 285 | - if (!$chat->getUser()->can('chat.attachment.remove')) { | |
| 301 | + /** @var VBOChatContext */ | |
| 302 | + $context = $chat->createContext($context, $contextId); | |
| 303 | + | |
| 304 | + if (!$chat->getUser()->can('chat.attachment.remove', $context)) { | |
| 286 | 305 | // not authorized |
| 287 | 306 | throw new RuntimeException(JText::translate('JERROR_ALERTNOAUTHOR'), 403); |
| 288 | 307 | } |
| 289 | 308 | |
| @@ -338,6 +357,114 @@ | ||
| 338 | 357 | } |
| 339 | 358 | |
| 340 | 359 | // output the result content |
| 341 | 360 | VBOHttpDocument::getInstance($app)->json($messages); |
| 361 | + } | |
| 362 | + | |
| 363 | + /** | |
| 364 | + * Starts a new chat session as guest. | |
| 365 | + * In case the user already started a session from this browser, the existing | |
| 366 | + * session will be returned instead. | |
| 367 | + * | |
| 368 | + * @return void | |
| 369 | + * | |
| 370 | + * @since 1.8.8 | |
| 371 | + */ | |
| 372 | + public function start_session() | |
| 373 | + { | |
| 374 | + $app = JFactory::getApplication(); | |
| 375 | + | |
| 376 | + try { | |
| 377 | + if (!JSession::checkToken()) { | |
| 378 | + throw new Exception(JText::translate('JINVALID_TOKEN'), 403); | |
| 379 | + } | |
| 380 | + | |
| 381 | + $sessionModel = new VBOChatSessionModel; | |
| 382 | + | |
| 383 | + // get session from cookie | |
| 384 | + $session = $sessionModel->getFromCookie(); | |
| 385 | + | |
| 386 | + $sessionId = $session->id ?? null; | |
| 387 | + | |
| 388 | + // check whether a session was already started for this user | |
| 389 | + if (!$sessionId) | |
| 390 | + { | |
| 391 | + $data = []; | |
| 392 | + $data['name'] = $app->input->getString('name'); | |
| 393 | + $data['email'] = $app->input->getString('email'); | |
| 394 | + | |
| 395 | + // start a new session | |
| 396 | + $sessionId = $sessionModel->save($data); | |
| 397 | + } | |
| 398 | + | |
| 399 | + // validate session ID one more time | |
| 400 | + if (!$sessionId) { | |
| 401 | + throw new RuntimeException('Failed starting a new session', 400); | |
| 402 | + } | |
| 403 | + } catch (Exception $error) { | |
| 404 | + VBOHttpDocument::getInstance($app)->close($error->getCode() ?: 500, $error->getMessage()); | |
| 405 | + } | |
| 406 | + | |
| 407 | + // send session ID to the caller | |
| 408 | + VBOHttpDocument::getInstance($app)->json(['id' => $sessionId]); | |
| 409 | + } | |
| 410 | + | |
| 411 | + /** | |
| 412 | + * Ends an existing session as guest. | |
| 413 | + * It is possible to immediately start a new session after closing the existing one. | |
| 414 | + * | |
| 415 | + * @return void | |
| 416 | + * | |
| 417 | + * @since 1.8.8 | |
| 418 | + */ | |
| 419 | + public function end_session() | |
| 420 | + { | |
| 421 | + $app = JFactory::getApplication(); | |
| 422 | + | |
| 423 | + try { | |
| 424 | + if (!JSession::checkToken()) { | |
| 425 | + throw new Exception(JText::translate('JINVALID_TOKEN'), 403); | |
| 426 | + } | |
| 427 | + | |
| 428 | + $sessionModel = new VBOChatSessionModel; | |
| 429 | + | |
| 430 | + // load existing session first | |
| 431 | + $session = $sessionModel->getFromCookie(); | |
| 432 | + | |
| 433 | + if (!$session) { | |
| 434 | + throw new Exception('Session not started yet.', 400); | |
| 435 | + } | |
| 436 | + | |
| 437 | + if ($session->metadata['banned'] ?? false) { | |
| 438 | + throw new Exception('You cannot close and start a new session because you have been banned.', 403); | |
| 439 | + } | |
| 440 | + | |
| 441 | + /** @var VBOChatMediator */ | |
| 442 | + $chat = VBOFactory::getChatMediator(); | |
| 443 | + | |
| 444 | + // make sure the user is allowed to end the session | |
| 445 | + if (!$chat->getUser()->can('chat.session.end', new VBOChatContextSession($session->id))) { | |
| 446 | + // not authorized | |
| 447 | + throw new RuntimeException(JText::translate('JERROR_ALERTNOAUTHOR'), 403); | |
| 448 | + } | |
| 449 | + | |
| 450 | + // close session | |
| 451 | + $sessionModel->endSession(); | |
| 452 | + | |
| 453 | + $sessionId = 0; | |
| 454 | + | |
| 455 | + // check if we should restart a new one | |
| 456 | + if ($app->input->getBool('restart')) { | |
| 457 | + // start a new session | |
| 458 | + $sessionId = $sessionModel->save([ | |
| 459 | + 'name' => $session->name, | |
| 460 | + 'email' => $session->email, | |
| 461 | + ]); | |
| 462 | + } | |
| 463 | + } catch (Exception $error) { | |
| 464 | + VBOHttpDocument::getInstance($app)->close($error->getCode() ?: 500, $error->getMessage()); | |
| 465 | + } | |
| 466 | + | |
| 467 | + // send session ID to the caller | |
| 468 | + VBOHttpDocument::getInstance($app)->json(['id' => $sessionId]); | |
| 342 | 469 | } |
| 343 | 470 | } |