| @@ -17,13 +17,11 @@ | ||
| 17 | 17 | use FluentSupport\App\Services\ProfileInfoService; |
| 18 | 18 | use FluentSupport\App\Services\TicketHelper; |
| 19 | 19 | use FluentSupport\App\Services\TicketQueryService; |
| 20 | 20 | use FluentSupport\App\Modules\PermissionManager; |
| 21 | -use FluentSupport\App\Services\Tickets\AgentTicketAccess; | |
| 22 | 21 | use FluentSupport\App\Services\Tickets\ResponseService; |
| 23 | 22 | use FluentSupport\App\Models\AgentGroup; |
| 24 | 23 | use FluentSupport\App\Services\Tickets\TicketService; |
| 25 | -use FluentSupport\App\Services\Integrations\FluentBooking\FluentBookingService; | |
| 26 | 24 | |
| 27 | 25 | /** |
| 28 | 26 | * TicketController class for REST API related to ticket |
| 29 | 27 | * This class is responsible for getting / inserting/ modifying data for all request related to ticket |
| @@ -247,9 +245,9 @@ | ||
| 247 | 245 | $ticketWith = is_array($ticketWith) ? map_deep($ticketWith, 'sanitize_text_field') : null; |
| 248 | 246 | |
| 249 | 247 | if (!$ticketWith) { |
| 250 | 248 | $ticketWith = ['customer', 'agent', 'product', 'mailbox', 'tags', 'attachments' => function ($q) { |
| 251 | - $q->where('status', 'active'); | |
| 249 | + $q->whereIn('status', ['active', 'inline']); | |
| 252 | 250 | }]; |
| 253 | 251 | } |
| 254 | 252 | |
| 255 | 253 | //Get ticket by id |
| @@ -256,15 +254,9 @@ | ||
| 256 | 254 | $ticket = Ticket::with($ticketWith)->findOrFail($ticket_id); |
| 257 | 255 | |
| 258 | 256 | //Eager load responses with their nested relations to avoid N+1 queries |
| 259 | 257 | $ticket->load(['responses' => function ($q) { |
| 260 | - $q->with([ | |
| 261 | - 'person', | |
| 262 | - 'ccinfo', | |
| 263 | - 'attachments' => function ($q) { | |
| 264 | - $q->where('status', 'active'); | |
| 265 | - } | |
| 266 | - ]); | |
| 258 | + $q->with('person', 'attachments', 'ccinfo'); | |
| 267 | 259 | }]); |
| 268 | 260 | |
| 269 | 261 | //Check if ticket is in a restricted mailbox |
| 270 | 262 | $restrictedBusinessBoxes = PermissionManager::getRestrictedMailboxIds(); |
| @@ -315,40 +307,11 @@ | ||
| 315 | 307 | } |
| 316 | 308 | } |
| 317 | 309 | } |
| 318 | 310 | |
| 319 | - $contents = ['ticket' => $ticket->content]; | |
| 320 | - foreach ($ticket->responses as $response) { | |
| 321 | - $contents['response_' . $response->id] = $response->content; | |
| 322 | - } | |
| 323 | - | |
| 324 | - $contents = Helper::refreshSignedAttachmentUrlsInContents($contents, $ticket->id); | |
| 325 | - $ticket->content = $contents['ticket']; | |
| 326 | - | |
| 327 | 311 | //Format response content |
| 328 | 312 | foreach ($ticket->responses as $response) { |
| 329 | - $responseKey = 'response_' . $response->id; | |
| 330 | - if (isset($contents[$responseKey])) { | |
| 331 | - $response->content = $contents[$responseKey]; | |
| 332 | - } | |
| 333 | - | |
| 334 | - $responseContent = apply_filters( | |
| 335 | - 'fluent_support/response_content_before_render', | |
| 336 | - $response->content, | |
| 337 | - $response, | |
| 338 | - $ticket | |
| 339 | - ); | |
| 340 | - | |
| 341 | - $responseContent = links_add_target(make_clickable(wpautop($responseContent, false))); | |
| 342 | - | |
| 343 | - | |
| 344 | - $response->content = apply_filters( | |
| 345 | - 'fluent_support/response_content_after_render', | |
| 346 | - $responseContent, | |
| 347 | - $response, | |
| 348 | - $ticket | |
| 349 | - ); | |
| 350 | - | |
| 313 | + $response->content = links_add_target(make_clickable(wpautop($response->content, false))); | |
| 351 | 314 | if (!empty($response->ccinfo)) { |
| 352 | 315 | $val = Helper::safeUnserialize($response->ccinfo->value); |
| 353 | 316 | if (isset($val['cc_email']) && !empty($val['cc_email'])) { |
| 354 | 317 | $response->cc_info = $val['cc_email']; |
| @@ -359,22 +322,10 @@ | ||
| 359 | 322 | $response->cc_info = ''; |
| 360 | 323 | } |
| 361 | 324 | } |
| 362 | 325 | |
| 363 | - $ticketContent = apply_filters( | |
| 364 | - 'fluent_support/ticket_content_before_render', | |
| 365 | - $ticket->content, | |
| 366 | - $ticket | |
| 367 | - ); | |
| 326 | + $ticket->content = links_add_target(make_clickable(wpautop($ticket->content, false))); | |
| 368 | 327 | |
| 369 | - $ticketContent = links_add_target(make_clickable(wpautop($ticketContent, false))); | |
| 370 | - | |
| 371 | - $ticket->content = apply_filters( | |
| 372 | - 'fluent_support/ticket_content_after_render', | |
| 373 | - $ticketContent, | |
| 374 | - $ticket | |
| 375 | - ); | |
| 376 | - | |
| 377 | 328 | //Get last activity by agent |
| 378 | 329 | $ticket->live_activity = TicketHelper::getActivity($ticket->id, $agent->id); |
| 379 | 330 | |
| 380 | 331 | //Get all carbon copy customer |
| @@ -422,87 +373,8 @@ | ||
| 422 | 373 | ]); |
| 423 | 374 | } |
| 424 | 375 | } |
| 425 | 376 | |
| 426 | - public function getMentionableAgents(Request $request, $ticket_id) | |
| 427 | - { | |
| 428 | - try { | |
| 429 | - $ticket = Ticket::findOrFail($ticket_id); | |
| 430 | - | |
| 431 | - if (in_array($ticket->mailbox_id, PermissionManager::getRestrictedMailboxIds())) { | |
| 432 | - throw new \Exception(esc_html__('Ticket cannot be fetched due to restricted mailbox', 'fluent-support')); | |
| 433 | - } | |
| 434 | - | |
| 435 | - $this->ensureCanAccessTicket($ticket); | |
| 436 | - | |
| 437 | - $search = trim($request->getSafe('search', 'sanitize_text_field', '')); | |
| 438 | - $limit = min(max(absint($request->getSafe('limit', 'intval', 20)), 1), 50); | |
| 439 | - | |
| 440 | - return [ | |
| 441 | - 'agents' => $this->getMentionableAgentList($ticket, $search, $limit) | |
| 442 | - ]; | |
| 443 | - } catch (\Exception $e) { | |
| 444 | - return $this->sendError([ | |
| 445 | - 'message' => Helper::getSafeErrorMessage($e) | |
| 446 | - ]); | |
| 447 | - } | |
| 448 | - } | |
| 449 | - | |
| 450 | - protected function getMentionableAgentList($ticket, $search, $limit) | |
| 451 | - { | |
| 452 | - $allAgents = Agent::select(['id', 'first_name', 'last_name', 'email', 'user_id']) | |
| 453 | - ->mentionBy($search) | |
| 454 | - ->orderBy('first_name') | |
| 455 | - ->orderBy('last_name') | |
| 456 | - ->get(); | |
| 457 | - | |
| 458 | - if ($allAgents->isEmpty()) { | |
| 459 | - return []; | |
| 460 | - } | |
| 461 | - | |
| 462 | - $restrictions = $this->getAgentRestrictionsMap($allAgents->pluck('id')->all()); | |
| 463 | - $ticketAccess = new AgentTicketAccess(); | |
| 464 | - $results = []; | |
| 465 | - | |
| 466 | - foreach ($allAgents as $agent) { | |
| 467 | - if (!$ticketAccess->canAccess($agent, $ticket, $restrictions[$agent->id] ?? [])) { | |
| 468 | - continue; | |
| 469 | - } | |
| 470 | - | |
| 471 | - $results[] = [ | |
| 472 | - 'id' => strval($agent->id), | |
| 473 | - 'first_name' => $agent->first_name, | |
| 474 | - 'last_name' => $agent->last_name, | |
| 475 | - 'email' => $agent->email, | |
| 476 | - ]; | |
| 477 | - | |
| 478 | - if (count($results) >= $limit) { | |
| 479 | - break; | |
| 480 | - } | |
| 481 | - } | |
| 482 | - | |
| 483 | - return $results; | |
| 484 | - } | |
| 485 | - | |
| 486 | - protected function getAgentRestrictionsMap(array $agentIds) | |
| 487 | - { | |
| 488 | - if (!$agentIds) { | |
| 489 | - return []; | |
| 490 | - } | |
| 491 | - | |
| 492 | - $metas = Meta::where('object_type', 'person_meta') | |
| 493 | - ->where('key', 'agent_restrictions') | |
| 494 | - ->whereIn('object_id', $agentIds) | |
| 495 | - ->get(); | |
| 496 | - | |
| 497 | - $restrictions = []; | |
| 498 | - foreach ($metas as $meta) { | |
| 499 | - $restrictions[$meta->object_id] = Helper::safeUnserialize($meta->value) ?: []; | |
| 500 | - } | |
| 501 | - | |
| 502 | - return $restrictions; | |
| 503 | - } | |
| 504 | - | |
| 505 | 377 | /** |
| 506 | 378 | * createResponse method will create response by agent for the ticket |
| 507 | 379 | * @param Request $request |
| 508 | 380 | * @param Ticket $ticket |
| @@ -536,14 +408,8 @@ | ||
| 536 | 408 | $this->ensureCanAccessTicket($ticket); |
| 537 | 409 | |
| 538 | 410 | $responseData = (new ResponseService())->createResponse($data, $agent, $ticket); |
| 539 | 411 | |
| 540 | - $responseData['response']->content = Helper::refreshSignedAttachmentUrls($responseData['response']->content, $ticket->id); | |
| 541 | - $responseData['response']->load([ | |
| 542 | - 'attachments' => function ($q) { | |
| 543 | - $q->where('status', 'active'); | |
| 544 | - } | |
| 545 | - ]); | |
| 546 | 412 | $responseData['response']->content = wp_specialchars_decode(wpautop($responseData['response']->content, false)); |
| 547 | 413 | |
| 548 | 414 | return [ |
| 549 | 415 | 'message' => __('Response has been added', 'fluent-support'), |
| @@ -557,115 +423,8 @@ | ||
| 557 | 423 | ]); |
| 558 | 424 | } |
| 559 | 425 | } |
| 560 | 426 | |
| 561 | - public function getFluentBookingEventTypes() | |
| 562 | - { | |
| 563 | - try { | |
| 564 | - // All FluentBooking endpoints require manage permission; view-only agents cannot call a meeting. | |
| 565 | - $this->ensureCanManageTickets(); | |
| 566 | - | |
| 567 | - $service = new FluentBookingService(); | |
| 568 | - $eventTypes = $service->getEventTypes(); | |
| 569 | - | |
| 570 | - return [ | |
| 571 | - 'status' => $service->getStatus($eventTypes), | |
| 572 | - 'event_types' => $eventTypes | |
| 573 | - ]; | |
| 574 | - } catch (\Exception $e) { | |
| 575 | - return $this->sendError([ | |
| 576 | - 'message' => Helper::getSafeErrorMessage($e) | |
| 577 | - ]); | |
| 578 | - } | |
| 579 | - } | |
| 580 | - | |
| 581 | - public function createFluentBookingLink(Request $request, $ticket_id) | |
| 582 | - { | |
| 583 | - try { | |
| 584 | - // All FluentBooking endpoints require manage permission; view-only agents cannot call a meeting. | |
| 585 | - $this->ensureCanManageTickets(); | |
| 586 | - | |
| 587 | - $ticket = Ticket::with('customer')->findOrFail($ticket_id); | |
| 588 | - | |
| 589 | - // Enforces per-ticket visibility (e.g. own-tickets-only agents cannot access unassigned tickets). | |
| 590 | - $this->ensureCanAccessTicket($ticket); | |
| 591 | - | |
| 592 | - $eventId = $request->getSafe('event_type_id', 'intval'); | |
| 593 | - | |
| 594 | - if (!$eventId) { | |
| 595 | - throw new \Exception(esc_html__('Please select a FluentBooking event type.', 'fluent-support')); | |
| 596 | - } | |
| 597 | - | |
| 598 | - return (new FluentBookingService())->createBookingLink( | |
| 599 | - $ticket, | |
| 600 | - $eventId, | |
| 601 | - $request->getSafe('message', 'wp_kses_post'), | |
| 602 | - $request->get('selected_slots', []), | |
| 603 | - $request->getSafe('timezone', 'sanitize_text_field', '') | |
| 604 | - ); | |
| 605 | - } catch (\Exception $e) { | |
| 606 | - return $this->sendError([ | |
| 607 | - 'message' => Helper::getSafeErrorMessage($e) | |
| 608 | - ]); | |
| 609 | - } | |
| 610 | - } | |
| 611 | - | |
| 612 | - public function getFluentBookingAvailability(Request $request, $ticket_id) | |
| 613 | - { | |
| 614 | - try { | |
| 615 | - // All FluentBooking endpoints require manage permission; view-only agents cannot call a meeting. | |
| 616 | - $this->ensureCanManageTickets(); | |
| 617 | - | |
| 618 | - $ticket = Ticket::with('customer')->findOrFail($ticket_id); | |
| 619 | - | |
| 620 | - // Enforces per-ticket visibility (e.g. own-tickets-only agents cannot access unassigned tickets). | |
| 621 | - $this->ensureCanAccessTicket($ticket); | |
| 622 | - | |
| 623 | - $eventId = $request->getSafe('event_type_id', 'intval'); | |
| 624 | - | |
| 625 | - if (!$eventId) { | |
| 626 | - throw new \Exception(esc_html__('Please select a FluentBooking event type.', 'fluent-support')); | |
| 627 | - } | |
| 628 | - | |
| 629 | - return [ | |
| 630 | - 'availability' => (new FluentBookingService())->getAvailabilitySlots( | |
| 631 | - $eventId, | |
| 632 | - $request->getSafe('range', 'sanitize_key', 'next_3_days'), | |
| 633 | - $request->getSafe('timezone', 'sanitize_text_field'), | |
| 634 | - $request->getSafe('duration', 'intval'), | |
| 635 | - $ticket, | |
| 636 | - $request->get('selected_dates', []), | |
| 637 | - $request->getSafe('calendar_month', 'sanitize_text_field', '') | |
| 638 | - ) | |
| 639 | - ]; | |
| 640 | - } catch (\Exception $e) { | |
| 641 | - return $this->sendError([ | |
| 642 | - 'message' => Helper::getSafeErrorMessage($e) | |
| 643 | - ]); | |
| 644 | - } | |
| 645 | - } | |
| 646 | - | |
| 647 | - public function getFluentBookingMeetings($ticket_id) | |
| 648 | - { | |
| 649 | - try { | |
| 650 | - // All FluentBooking endpoints require manage permission; view-only agents cannot call a meeting. | |
| 651 | - $this->ensureCanManageTickets(); | |
| 652 | - | |
| 653 | - $ticket = Ticket::with('customer')->findOrFail($ticket_id); | |
| 654 | - | |
| 655 | - // Enforces per-ticket visibility (e.g. own-tickets-only agents cannot access unassigned tickets). | |
| 656 | - $this->ensureCanAccessTicket($ticket); | |
| 657 | - | |
| 658 | - return [ | |
| 659 | - 'meetings' => (new FluentBookingService())->getTicketMeetings($ticket) | |
| 660 | - ]; | |
| 661 | - } catch (\Exception $e) { | |
| 662 | - return $this->sendError([ | |
| 663 | - 'message' => Helper::getSafeErrorMessage($e) | |
| 664 | - ]); | |
| 665 | - } | |
| 666 | - } | |
| 667 | - | |
| 668 | 427 | /** |
| 669 | 428 | * createDraft method will create draft by agent for the ticket |
| 670 | 429 | * @param Request $request |
| 671 | 430 | * @param Ticket $ticket |
| @@ -885,14 +644,13 @@ | ||
| 885 | 644 | if ($propName == 'product_id') { |
| 886 | 645 | $ticket->load('product'); |
| 887 | 646 | $updateData['product'] = $ticket->product; |
| 888 | 647 | } else if ($propName == 'agent_id') { |
| 889 | - $previousAgentId = (int) $prevValue; | |
| 890 | 648 | $ticket->load('agent'); |
| 891 | 649 | $updateData['agent'] = $ticket->agent; |
| 892 | 650 | $updateData['assigner'] = (new TicketService())->onAgentChange($ticket, $assigner); |
| 893 | 651 | if ($prevValue != $ticket->{$propName}) { |
| 894 | - do_action('fluent_support/agent_assigned_to_ticket', $ticket->agent, $ticket, $assigner, $previousAgentId); | |
| 652 | + do_action('fluent_support/agent_assigned_to_ticket', $ticket->agent, $ticket, $assigner); | |
| 895 | 653 | } |
| 896 | 654 | } |
| 897 | 655 | |
| 898 | 656 | $message = sprintf( |
| @@ -1032,9 +790,8 @@ | ||
| 1032 | 790 | $assignedCount = 0; |
| 1033 | 791 | $skippedCount = 0; |
| 1034 | 792 | |
| 1035 | 793 | $tickets->each(function ($ticket) use ($assignAgent, $agent, &$assignedCount, &$skippedCount) { |
| 1036 | - $previousAgentId = (int) $ticket->agent_id; | |
| 1037 | 794 | $restrictions = $assignAgent->getMeta('agent_restrictions', []); |
| 1038 | 795 | |
| 1039 | 796 | //Skip ticket if mailbox is restricted for the agent |
| 1040 | 797 | if (!empty($restrictions) && in_array($ticket->mailbox_id, $restrictions['restrictedBusinessBoxes'])) { |
| @@ -1045,9 +802,9 @@ | ||
| 1045 | 802 | $ticket->agent_id = $assignAgent->id; |
| 1046 | 803 | $ticket->save(); |
| 1047 | 804 | $assignedCount++; |
| 1048 | 805 | |
| 1049 | - do_action('fluent_support/agent_assigned_to_ticket', $assignAgent, $ticket, $agent, $previousAgentId); | |
| 806 | + do_action('fluent_support/agent_assigned_to_ticket', $assignAgent, $ticket, $agent); | |
| 1050 | 807 | }); |
| 1051 | 808 | |
| 1052 | 809 | $assignedMessage = sprintf( |
| 1053 | 810 | /* translators: %1$d is the number of tickets assigned, %2$s is the agent's name. */ |
| @@ -1084,9 +841,8 @@ | ||
| 1084 | 841 | $skippedCount = 0; |
| 1085 | 842 | $currentCounts = []; |
| 1086 | 843 | |
| 1087 | 844 | foreach ($tickets as $ticket) { |
| 1088 | - $previousAgentId = (int) $ticket->agent_id; | |
| 1089 | 845 | $selectedAgent = $group->getLeastLoadedAgent( |
| 1090 | 846 | $ticket->mailbox_id, $currentCounts |
| 1091 | 847 | ); |
| 1092 | 848 | |
| @@ -1100,9 +856,9 @@ | ||
| 1100 | 856 | $assignedCount++; |
| 1101 | 857 | $currentCounts[$selectedAgent->id]++; |
| 1102 | 858 | |
| 1103 | 859 | as_enqueue_async_action('fluent_support/async_agent_assigned_to_ticket', [ |
| 1104 | - $selectedAgent->id, $ticket->id, $agent->id, $previousAgentId | |
| 860 | + $selectedAgent->id, $ticket->id, $agent->id | |
| 1105 | 861 | ], 'fluent-support'); |
| 1106 | 862 | } |
| 1107 | 863 | |
| 1108 | 864 | return [ |
| @@ -1275,11 +1031,9 @@ | ||
| 1275 | 1031 | public function deleteResponse($ticket_id, $response_id) |
| 1276 | 1032 | { |
| 1277 | 1033 | try { |
| 1278 | 1034 | $ticket = Ticket::findOrFail($ticket_id); |
| 1279 | - $response = Conversation::where('id', $response_id) | |
| 1280 | - ->where('ticket_id', $ticket_id) | |
| 1281 | - ->firstOrFail(); | |
| 1035 | + $response = Conversation::findOrFail($response_id); | |
| 1282 | 1036 | $agent = Helper::getAgentByUserId(); |
| 1283 | 1037 | |
| 1284 | 1038 | if (!PermissionManager::currentUserCan('fst_delete_tickets') && $ticket->agent_id !== $agent->id) { |
| 1285 | 1039 | throw new \Exception( |
| @@ -1311,11 +1065,9 @@ | ||
| 1311 | 1065 | public function updateResponse(TicketResponseRequest $request, $ticket_id, $response_id) |
| 1312 | 1066 | { |
| 1313 | 1067 | try { |
| 1314 | 1068 | $ticket = Ticket::findOrFail($ticket_id); |
| 1315 | - $response = Conversation::where('id', $response_id) | |
| 1316 | - ->where('ticket_id', $ticket_id) | |
| 1317 | - ->firstOrFail(); | |
| 1069 | + $response = Conversation::findOrFail($response_id); | |
| 1318 | 1070 | $agent = Helper::getAgentByUserId(); |
| 1319 | 1071 | |
| 1320 | 1072 | if (!PermissionManager::currentUserCan('fst_manage_other_tickets') && $ticket->agent_id !== $agent->id) { |
| 1321 | 1073 | throw new \Exception( |
| @@ -1322,23 +1074,22 @@ | ||
| 1322 | 1074 | esc_html__('Sorry, you do not have permission to update this response.', 'fluent-support') |
| 1323 | 1075 | ); |
| 1324 | 1076 | } |
| 1325 | 1077 | |
| 1326 | - $content = wp_unslash(wp_kses_post($request->getSafe('content', 'wp_kses_post'))); | |
| 1327 | - $response->content = $content; | |
| 1078 | + $response->content = wp_unslash(wp_kses_post($request->getSafe('content', 'wp_kses_post'))); | |
| 1328 | 1079 | |
| 1329 | - if ($response->conversation_type == 'draft_response' && $response->person_id != $agent->id && PermissionManager::currentUserCan('fst_approve_draft_reply')) { | |
| 1330 | - $response = $this->approveDraftConversation($ticket, $response, $agent, $content); | |
| 1331 | - } else if ($response->conversation_type == 'draft_response' && $response->person_id != $agent->id) { | |
| 1080 | + //If updating a draft response by someone other than the author, check approval permission | |
| 1081 | + if ($response->conversation_type == 'draft_response' && $response->person_id != $agent->id) { | |
| 1332 | 1082 | if (!PermissionManager::currentUserCan('fst_approve_draft_reply')) { |
| 1333 | 1083 | throw new \Exception( |
| 1334 | 1084 | esc_html__('Sorry, You do not have permission to approve this draft response', 'fluent-support') |
| 1335 | 1085 | ); |
| 1336 | 1086 | } |
| 1337 | - } else { | |
| 1338 | - $response->save(); | |
| 1087 | + $response->conversation_type = 'response'; | |
| 1339 | 1088 | } |
| 1340 | 1089 | |
| 1090 | + $response->save(); | |
| 1091 | + | |
| 1341 | 1092 | return [ |
| 1342 | 1093 | 'message' => __('Selected response has been updated', 'fluent-support'), |
| 1343 | 1094 | 'response' => $response |
| 1344 | 1095 | ]; |
| @@ -1366,15 +1117,34 @@ | ||
| 1366 | 1117 | ->firstOrFail(); |
| 1367 | 1118 | |
| 1368 | 1119 | $person = Helper::getAgentByUserId(); |
| 1369 | 1120 | |
| 1370 | - $response = $this->approveDraftConversation( | |
| 1371 | - $ticket, | |
| 1372 | - $response, | |
| 1373 | - $person, | |
| 1374 | - wp_unslash(wp_kses_post($request->getSafe('content', 'wp_kses_post'))) | |
| 1375 | - ); | |
| 1121 | + $content = wp_unslash(wp_kses_post($request->getSafe('content', 'wp_kses_post'))); | |
| 1122 | + $resetWaitingSince = apply_filters('fluent_support/reset_waiting_since', true, $content); | |
| 1376 | 1123 | |
| 1124 | + $response->conversation_type = 'response'; | |
| 1125 | + $response->created_at = current_time('mysql'); | |
| 1126 | + $response->save(); | |
| 1127 | + | |
| 1128 | + if ($person->person_type == 'agent' && $ticket->status == 'new') { | |
| 1129 | + $ticket->status = 'active'; | |
| 1130 | + if ($ticket->created_at) { | |
| 1131 | + $ticket->first_response_time = strtotime(current_time('mysql')) - strtotime($ticket->created_at); | |
| 1132 | + } else { | |
| 1133 | + $ticket->first_response_time = 300; | |
| 1134 | + } | |
| 1135 | + } | |
| 1136 | + | |
| 1137 | + if ($resetWaitingSince) { | |
| 1138 | + $ticket->last_agent_response = current_time('mysql'); | |
| 1139 | + $ticket->waiting_since = current_time('mysql'); | |
| 1140 | + } | |
| 1141 | + | |
| 1142 | + $ticket->response_count += 1; | |
| 1143 | + $ticket->save(); | |
| 1144 | + | |
| 1145 | + do_action('fluent_support/response_added_by_' . $person->person_type, $response, $ticket, $person); | |
| 1146 | + | |
| 1377 | 1147 | return [ |
| 1378 | 1148 | 'message' => __('Draft response has been successfully approved.', 'fluent-support'), |
| 1379 | 1149 | 'response' => $response, |
| 1380 | 1150 | ]; |
| @@ -1384,39 +1154,8 @@ | ||
| 1384 | 1154 | ]); |
| 1385 | 1155 | } |
| 1386 | 1156 | } |
| 1387 | 1157 | |
| 1388 | - protected function approveDraftConversation($ticket, $response, $person, $content) | |
| 1389 | - { | |
| 1390 | - $resetWaitingSince = apply_filters('fluent_support/reset_waiting_since', true, $content); | |
| 1391 | - | |
| 1392 | - $response->content = $content; | |
| 1393 | - $response->conversation_type = 'response'; | |
| 1394 | - $response->created_at = current_time('mysql'); | |
| 1395 | - $response->save(); | |
| 1396 | - | |
| 1397 | - if ($person->person_type == 'agent' && $ticket->status == 'new') { | |
| 1398 | - $ticket->status = 'active'; | |
| 1399 | - if ($ticket->created_at) { | |
| 1400 | - $ticket->first_response_time = strtotime(current_time('mysql')) - strtotime($ticket->created_at); | |
| 1401 | - } else { | |
| 1402 | - $ticket->first_response_time = 300; | |
| 1403 | - } | |
| 1404 | - } | |
| 1405 | - | |
| 1406 | - if ($resetWaitingSince) { | |
| 1407 | - $ticket->last_agent_response = current_time('mysql'); | |
| 1408 | - $ticket->waiting_since = current_time('mysql'); | |
| 1409 | - } | |
| 1410 | - | |
| 1411 | - $ticket->response_count += 1; | |
| 1412 | - $ticket->save(); | |
| 1413 | - | |
| 1414 | - do_action('fluent_support/response_added_by_' . $person->person_type, $response, $ticket, $person); | |
| 1415 | - | |
| 1416 | - return $response; | |
| 1417 | - } | |
| 1418 | - | |
| 1419 | 1158 | /** |
| 1420 | 1159 | * getLiveActivity method will return the activity in a ticket by agents |
| 1421 | 1160 | * @param Request $request |
| 1422 | 1161 | * @param $ticket_id |
| @@ -1498,11 +1237,11 @@ | ||
| 1498 | 1237 | * This method will get ticket id and customer id as parameter, it will replace existing customer id with new |
| 1499 | 1238 | * @param Request $request |
| 1500 | 1239 | * @return array |
| 1501 | 1240 | */ |
| 1502 | - public function changeTicketCustomer(Request $request, $ticket_id) | |
| 1241 | + public function changeTicketCustomer(Request $request) | |
| 1503 | 1242 | { |
| 1504 | - $ticketId = (int) $ticket_id; | |
| 1243 | + $ticketId = $request->getSafe('ticket_id', 'intval'); | |
| 1505 | 1244 | $newCustomerId = $request->getSafe('customer', 'intval'); |
| 1506 | 1245 | |
| 1507 | 1246 | if (!$newCustomerId) { |
| 1508 | 1247 | return $this->sendError(__('Invalid customer selected.', 'fluent-support')); |
| @@ -1664,4 +1403,5 @@ | ||
| 1664 | 1403 | ]); |
| 1665 | 1404 | } |
| 1666 | 1405 | } |
| 1667 | 1406 | } |
| 1407 | + | |