PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 1.5.5
Fluent Support – Helpdesk & Customer Support Ticket System v1.5.5
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
fluent-support / app / Http / Controllers / TicketController.php

TicketController.php in Fluent Support – Helpdesk & Customer Support Ticket System 1.5.5, at app/Http/Controllers/TicketController.php

916 lines 30.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Http\Controllers;
4
5 use FluentSupport\App\Models\Agent;
6 use FluentSupport\App\Models\Attachment;
7 use FluentSupport\App\Models\Customer;
8 use FluentSupport\App\Models\MailBox;
9 use FluentSupport\App\Models\Conversation;
10 use FluentSupport\App\Models\Product;
11 use FluentSupport\App\Models\Ticket;
12 use FluentSupport\App\Modules\PermissionManager;
13 use FluentSupport\App\Services\EmailNotification\Settings;
14 use FluentSupport\App\Services\Helper;
15 use FluentSupport\App\Services\ProfileInfoService;
16 use FluentSupport\App\Services\TicketHelper;
17 use FluentSupport\App\Services\TicketQueryService;
18 use FluentSupport\App\Services\Tickets\ResponseService;
19 use FluentSupport\App\Services\Tickets\TicketService;
20 use FluentSupport\Framework\Request\Request;
21
22 /**
23 * TicketController class for REST API related to ticket
24 * This class is responsible for getting / inserting/ modifying data for all request related to ticket
25 * @package FluentSupport\App\Http\Controllers
26 *
27 * @version 1.0.0
28 */
29
30 class TicketController extends Controller
31 {
32 public function me(Request $request)
33 {
34 $user = wp_get_current_user();
35
36 $settings = [
37 'user_id' => $user->ID,
38 'email' => $user->user_email,
39 'person' => Helper::getAgentByUserId($user->ID),
40 'permissions' => PermissionManager::currentUserPermissions(),
41 'request' => $request->all()
42 ];
43
44 if ($request->get('with_portal_settings')) {
45
46 $mimeHeadings = Helper::getAcceptedMimeHeadings();
47 $businessSettings = (new Settings())->globalBusinessSettings();
48 $maxFileSize = absint($businessSettings['max_file_size']);
49
50 $portalSettings = [
51 'support_products' => Product::select(['id', 'title'])->get(),
52 'customer_ticket_priorities' => Helper::customerTicketPriorities(),
53 'has_file_upload' => !!Helper::ticketAcceptedFileMiles(),
54 'has_rich_text_editor' => true,
55 'max_file_size' => $maxFileSize,
56 'mime_headings' => $mimeHeadings
57 ];
58 /**
59 * Filter customer portal settings
60 *
61 * @since v1.0.0
62 * @param array $portalSettings
63 */
64 $portalSettings = apply_filters('fluent_support/customer_portal_vars', $portalSettings);
65
66 $settings['portal_settings'] = $portalSettings;
67 }
68
69
70 return $settings;
71 }
72
73 /**
74 * index method will return the list of ticket based on the selected filter
75 * @param Request $request
76 * @return array
77 */
78 public function index(Request $request)
79 {
80 //Selected filter type, either simple or Advanced
81 $filterType = $request->get('filter_type', 'simple');
82
83 /*Prepare Query Arguments*/
84 $queryArgs = [
85 'with' => [],
86 'filter_type' => $filterType,
87 'sort_by' => $request->get('order_by', 'id'),
88 'sort_type' => $request->get('order_type', 'DESC'),
89 ];
90
91
92 //If the selected filter type is advanced
93 if($request->get('filter_type')=='advanced'){
94 //Get the selected query params for advanced filter
95 $queryArgs['filters_groups_raw'] = json_decode($this->request->get('advanced_filters'), true);
96 } else {
97 //Selected filter type is simple
98 $queryArgs['simple_filters'] = $request->get('filters', []);
99 $queryArgs['search'] = trim(sanitize_text_field($request->get('search', '')));
100 if ($customerId = $request->get('customer_id')) {
101 $queryArgs['customer_id'] = intval($customerId);
102 }
103 }
104
105 /*End Prepare Query Arguments*/
106
107 $ticketsModel = (new TicketQueryService($queryArgs))->getModel();
108
109 $ticketsModel = $ticketsModel->with([
110 'customer' => function ($query) {
111 $query->select(['first_name', 'last_name', 'email', 'id', 'avatar']);
112 }, 'agent' => function ($query) {
113 $query->select(['first_name', 'last_name', 'id']);
114 },
115 'product',
116 'tags',
117 'preview_response' => function ($query) {
118 $query->orderBy('id', 'desc');
119 }
120 ]);
121
122
123 // apply filters by access level
124 do_action_ref_array('fluent_support/tickets_query_by_permission_ref', [&$ticketsModel, false]);
125
126
127 $tickets = $ticketsModel->paginate();
128
129 $perPage = $request->get('per_page');
130
131 foreach ($tickets as $ticket) {
132 if ($perPage < 15) {
133 if ($ticket->status != 'closed') {
134 $ticket->live_activity = TicketHelper::getActivity($ticket->id);
135 } else {
136 $ticket->live_activity = [];
137 }
138 }
139 }
140
141 return [
142 'tickets' => $tickets
143 ];
144 }
145
146 /**
147 * createTicket method will create new ticket as well as customer or WP user
148 * @param Request $request
149 * @return array
150 * @throws \FluentSupport\Framework\Validator\ValidationException
151 */
152 public function createTicket(Request $request)
153 {
154 $ticketData = $request->get('ticket', []);
155 $maybeNewCustomer = $request->get('newCustomer');
156
157 //If user select create WP user during ticket creation
158 if ($ticketData['create_wp_user'] == 'yes'){
159 //Check if username already in use, if not create new user
160 if(!username_exists($maybeNewCustomer['username'])){
161 $authController = new AuthController();
162 $createdUser = $authController->createUser($maybeNewCustomer);
163 $authController->maybeUpdateUser($createdUser, $maybeNewCustomer);
164 }else{
165 return $this->sendError(__('This username is already exist in WordPress', 'fluent-support'));
166 }
167 }
168 //If user select create customer during ticket creation
169 if($ticketData['create_customer'] == 'yes'){
170 //Check user already exist as customer, if not create new
171 if (!empty($maybeNewCustomer) && is_null(Customer::where('email', $maybeNewCustomer['email'])->first())){
172 $createCustomer = Customer::create($maybeNewCustomer);
173 if ($createCustomer){
174 $ticketData['customer_id'] = $createCustomer->id;
175 }
176 }
177 else{
178 return $this->sendError(__('Customer with this email already exist', 'fluent-support'));
179 }
180 }
181
182 $this->validate($ticketData, [
183 'customer_id' => 'required',
184 'title' => 'required',
185 'content' => 'required'
186 ]);
187
188 //Get customer information from db
189 $customer = Customer::findOrFail($ticketData['customer_id']);
190
191 if (empty($ticketData['mailbox_id'])) {
192 $mailbox = Helper::getDefaultMailBox();
193 $ticketData['mailbox_id'] = $mailbox->id;
194 } else {
195 $mailbox = MailBox::findOrFail($ticketData['mailbox_id']); // just for validation
196 }
197
198 if (!empty($ticketData['product_id'])) {
199 $data['product_source'] = 'local';
200 }
201
202 $ticketData['title'] = sanitize_text_field(wp_unslash($ticketData['title']));
203
204 $ticketData['content'] = wp_unslash(wp_kses_post($ticketData['content']));
205
206 if (!empty($ticketData['priority'])) {
207 $ticketData['priority'] = sanitize_text_field($ticketData['priority']);
208 }
209
210 $ticketData['client_priority'] = sanitize_text_field($ticketData['client_priority']);
211
212 /*
213 * Filter ticket data
214 *
215 * @since v1.0.0
216 * @param array $ticketData
217 * @param object $customer
218 */
219 $ticketData = apply_filters('fluent_support/create_ticket_data', $ticketData, $customer);
220
221 /*
222 * Action before ticket create
223 *
224 * @since v1.0.0
225 * @param array $ticketData
226 * @param object $customer
227 */
228 do_action('fluent_support/before_ticket_create', $ticketData, $customer);
229
230 $createdTicket = Ticket::create($ticketData);
231
232 if (defined('FLUENTSUPPORTPRO') && !empty($ticketData['custom_fields'])) {
233 $createdTicket->syncCustomFields($ticketData['custom_fields']);
234 }
235
236 /*
237 * Action on ticket create
238 *
239 * @since v1.0.0
240 * @param object $createdTicket
241 * @param object $customer
242 */
243 do_action('fluent_support/ticket_created', $createdTicket, $customer);
244
245 return [
246 'message' => __('Ticket has been created successfully', 'fluent-support'),
247 'ticket' => $createdTicket
248 ];
249
250 }
251
252 /**
253 * getTicket method will return ticket information by ticket id
254 * @param Request $request
255 * @param $ticketId
256 * @return array
257 */
258 public function getTicket(Request $request, $ticketId)
259 {
260 //Get logged in agent information
261 $agent = Helper::getAgentByUserId();
262
263 $ticketWith = $request->get('with', ['customer', 'agent', 'product', 'mailbox', 'tags', 'attachments' => function ($q) {
264 $q->whereIn('status', ['active', 'inline']);
265 }]);
266 $responseWith = $request->get('response_with', ['person', 'attachments']);
267
268 //Get ticket by id
269 $ticket = Ticket::with($ticketWith)
270 ->findOrFail($ticketId);
271
272 //If ticket has customer
273 if ($ticket->customer) {
274 //Get and set customer profile url
275 $ticket->customer->profile_edit_url = $ticket->customer->getUserProfileEditUrl();
276 }
277
278 //If user do not have permission in this ticket
279 if (!PermissionManager::hasTicketPermission($ticket)) {
280 return $this->sendError([
281 'message' => __('Sorry, You do not have permission to this ticket', 'fluent-support')
282 ]);
283 }
284
285
286 if ($ticket->status == 'closed') {
287 $ticket->load('closed_by_person');
288 }
289
290 //Get ticket responses
291 $responses = Conversation::where('ticket_id', $ticketId)
292 ->with($responseWith)
293 ->orderBy('id', 'DESC')
294 ->get();
295
296 foreach ($responses as $response) {
297 $response->content = make_clickable(wpautop($response->content, false));
298 }
299
300 $ticket->content = make_clickable(wpautop($ticket->content, false));
301
302 //Get last activity by agent
303 $ticket->live_activity = TicketHelper::getActivity($ticketId, $agent->id);
304
305 if (defined('FLUENTSUPPORTPRO')) {
306 $ticket->custom_fields = $ticket->customData('admin', true);
307 }
308
309 $data = [
310 'ticket' => $ticket,
311 'responses' => $responses,
312 'agent_id' => $agent->id
313 ];
314
315 //Is request come with fluentcrm_profile, get fluent crm contack information
316 if (in_array('fluentcrm_profile', $request->get('with_data', [])) && defined('FLUENTCRM')) {
317 $data['fluentcrm_profile'] = Helper::getFluentCrmContactData($ticket->customer);
318 }
319
320 return $data;
321
322 }
323
324 /**
325 * createResponse method will create response by agent for the ticket
326 * @param Request $request
327 * @param $ticketId
328 * @return array
329 * @throws \FluentSupport\Framework\Validator\ValidationException
330 */
331 public function createResponse(Request $request, $ticketId)
332 {
333 $data = $request->all();
334
335 $this->validate($data, [
336 'content' => 'required'
337 ]);
338
339 //Get logged-in agent information
340 $agent = Helper::getAgentByUserId(get_current_user_id());
341
342 if (!$agent) {
343 return $this->sendError([
344 'message' => __('Sorry, You do not have permission. Please add yourself as support agent first', 'fluent-support')
345 ]);
346 }
347
348 $ticket = Ticket::findOrFail($ticketId);
349
350 //If the agent has permission to view this ticket
351 if (!PermissionManager::hasTicketPermission($ticket)) {
352 return $this->sendError([
353 'message' => __('Sorry, You do not have permission to this ticket', 'fluent-support')
354 ]);
355 }
356 // Adding support for shortcode in agent response
357 $data = apply_filters('fluent_support/parse_smartcode_data', $data, [
358 'customer' => $ticket->customer,
359 'agent' => Helper::getAgentByUserId(get_current_user_id())
360 ]);
361 $responseData = (new ResponseService())->createResponse($data, $agent, $ticket);
362
363 $responseData['response']->content = make_clickable(wpautop($responseData['response']->content, false));
364
365 return [
366 'message' => __('Response has been added'),
367 'response' => $responseData['response'],
368 'ticket' => $responseData['ticket'],
369 'update_data' => $responseData['update_data']
370 ];
371 }
372
373 /**
374 * getTicketWidgets method generate additional information for a ticket by customer
375 * @param Request $request
376 * @param $ticketId
377 * @return array
378 */
379 public function getTicketWidgets(Request $request, $ticketId)
380 {
381 //Get ticket with customer by ticket
382 $ticket = Ticket::with('customer')->findOrFail($ticketId);
383
384 //If the logged-in user has permission
385 if (!PermissionManager::hasTicketPermission($ticket)) {
386 return $this->sendError([
387 'message' => __('Sorry, You do not have permission to this ticket', 'fluent-support')
388 ]);
389 }
390
391 //Get last 10 tickets of this customer except this
392 $otherTickets = Ticket::where('id', '!=', $ticketId)
393 ->select(['id', 'title', 'status', 'created_at'])
394 ->where('customer_id', $ticket->customer_id)
395 ->orderBy('id', 'DESC')
396 ->limit(10)
397 ->get();
398
399 return [
400 'other_tickets' => $otherTickets,
401 'extra_widgets' => ProfileInfoService::getProfileExtraWidgets($ticket->customer)
402 ];
403 }
404
405 /**
406 * updateTicketProperty method will update ticket property
407 * @param Request $request
408 * @param $ticketId
409 * @return array
410 */
411 public function updateTicketProperty(Request $request, $ticketId)
412 {
413 $assigner = Helper::getAgentByUserId(get_current_user_id());
414 $ticket = Ticket::findOrFail($ticketId);
415 $propName = $request->get('prop_name');
416 $propValue = $request->get('prop_value');
417
418 if (!PermissionManager::hasTicketPermission($ticket)) {
419 return $this->sendError([
420 'message' => __('Sorry, You do not have permission to this ticket', 'fluent-support')
421 ]);
422 }
423
424 $prevValue = $ticket->{$propName};
425 if ($propName && $propValue && $prevValue != $propValue) {
426 $ticket->{$propName} = $propValue;
427 $ticket->save();
428 }
429
430 $updateData = [];
431
432 if ($propName == 'product_id') {
433 $ticket->load('product');
434 $updateData['product'] = $ticket->product;
435 } else if ($propName == 'agent_id') {
436 $ticket->load('agent');
437 $updateData['agent'] = $ticket->agent;
438 $updateData['assigner'] = (new TicketService())->onAgentChange($ticket, $assigner);
439 if ($prevValue != $ticket->{$propName}) {
440 do_action('fluent_support/agent_assigned_to_ticket', $ticket->agent, $ticket, $assigner);
441 }
442 }
443
444 return [
445 'message' => __(str_replace('_', ' ', ucwords($propName)) . ' has been updated', 'fluent-support'),
446 'update_data' => $updateData
447 ];
448 }
449
450 /**
451 * closeTicket method close the ticket by id
452 * @param Request $request
453 * @param $ticketId
454 * @return array
455 */
456 public function closeTicket(Request $request, $ticketId)
457 {
458 $agent = Helper::getAgentByUserId(get_current_user_id());
459
460 $ticket = Ticket::findOrFail($ticketId);
461
462 if (!PermissionManager::hasTicketPermission($ticket)) {
463 return $this->sendError([
464 'message' => __('Sorry, You do not have permission to this ticket', 'fluent-support')
465 ]);
466 }
467
468 return [
469 'message' => __('Ticket has been closed', 'fluent_support'),
470 'ticket' => (new TicketService())->close($ticket, $agent)
471 ];
472 }
473
474 /**
475 * reOpenTicket method will reopen a closed ticket
476 * @param Request $request
477 * @param $ticketId
478 * @return array
479 */
480 public function reOpenTicket(Request $request, $ticketId)
481 {
482 $agent = Helper::getAgentByUserId(get_current_user_id());
483
484 $ticket = Ticket::findOrFail($ticketId);
485
486 if (!PermissionManager::hasTicketPermission($ticket)) {
487 return $this->sendError([
488 'message' => __('Sorry, You do not have permission to this ticket', 'fluent-support')
489 ]);
490 }
491
492 return [
493 'message' => __('Ticket has been opened again', 'fluent_support'),
494 'ticket' => (new TicketService())->reopen($ticket, $agent)
495 ];
496 }
497
498 /**
499 * doBulkActions method is responsible for bulk action
500 * This function will get ticket ids and action as parameter and perform action based on the selection
501 * @param Request $request
502 * @return array|string[]|void
503 */
504 public function doBulkActions(Request $request)
505 {
506 //Get all ticket ids
507 $ticketIds = $request->get('ticket_ids', []);
508 $action = $request->get('bulk_action');//get action
509 $hasAllPermission = PermissionManager::currentUserCan('fst_manage_other_tickets');
510 $agent = Helper::getAgentByUserId();
511 $query = Ticket::whereIn('id', $ticketIds);
512
513 //If agent do not have permission to manage other tickets
514 if (!$hasAllPermission) {
515 //Filter ticket by agent_id
516 $query->where('agent_id', $agent->id);
517 }
518
519 //If bulk action is close ticket
520 if ($action == 'close_tickets') {
521 $query->where('status', '!=', 'closed');
522 $tickets = $query->get();
523 foreach ($tickets as $ticket) {
524 (new TicketService())->close($ticket, $agent);
525 }
526
527 return [
528 'message' => sprintf(__('%d tickets have been closed', 'fluent-support'), count($tickets))
529 ];
530 } else if ($action == 'delete_tickets') {
531 //If bulk action is delete ticket
532 $tickets = $query->get();
533
534 foreach ($tickets as $ticket) {
535 $ticket->deleteTicket();
536 }
537
538 return [
539 'message' => __(count($tickets) . ' tickets have been deleted', 'fluent-support')
540 ];
541 } else if ($action == 'assign_agent') {
542 //If action is assign agent
543 $agentId = absint($request->get('agent_id'));
544 if (!$agentId) {
545 $this->sendError([
546 'message' => __('agent_id param is required', 'fluent-support')
547 ]);
548 }
549
550 $agent = Agent::findOrFail($agentId);
551
552 //Filter ticket where not assign same agent or none
553 $query->where(function ($q) use ($agent) {
554 $q->where('agent_id', '!=', $agent->id)
555 ->orWhereNull('agent_id');
556 });
557
558 $tickets = $query->get();
559
560 foreach ($tickets as $ticket) {
561 $assigner = Helper::getCurrentAgent();
562 $ticket->agent_id = $agent->id;
563 $ticket->save();
564 do_action('fluent_support/agent_assigned_to_ticket', $agent, $ticket, $assigner);
565 }
566
567 return [
568 'message' => __(count($tickets) . ' tickets has been assigned to', 'fluent-support') . ' ' . $agent->full_name
569 ];
570 } else if ($action == 'assign_tags') {
571 //if action is assign tags
572 $tags = array_filter(array_map('absint', $request->get('tag_ids', [])));
573 if (!$tags) {
574 $this->sendError([
575 'message' => __('tag_ids param is required', 'fluent-support')
576 ]);
577 }
578
579 $tickets = $query->get();
580
581 foreach ($tickets as $ticket) {
582 $ticket->applyTags($tags);
583 }
584
585 return [
586 'message' => __('Selected tags has been added to tickets', 'fluent-support')
587 ];
588
589 }
590
591 $this->sendError([
592 'message' => __('Sorry no action found as available', 'fluent-support')
593 ]);
594 }
595
596 /**
597 * doBulkReplies method will create response for bulk tickets
598 * This function will get ticket ids, content, attachment etc and create response for tickets
599 * @param Request $request
600 * @return array
601 * @throws \FluentSupport\Framework\Validator\ValidationException
602 */
603 public function doBulkReplies(Request $request)
604 {
605 $data = $request->all();
606 $this->validate($data, [
607 'content' => 'required',
608 'ticket_ids' => 'required|array'
609 ]);
610
611 //get all ticket ids
612 $ticketIds = $request->get('ticket_ids');
613 $ticketIds = array_filter($ticketIds, 'absint');
614
615 //Get logged in agent information
616 $agent = Helper::getAgentByUserId();
617
618 $hasAllPermission = PermissionManager::currentUserCan('fst_manage_other_tickets');
619
620 $query = Ticket::whereIn('id', $ticketIds)->where('status', '!=', 'closed');
621
622 //If the agent does not have permission
623 if (!$hasAllPermission) {
624 //Filter ticket by agent_id
625 $query->where('agent_id', $agent->id);
626 }
627
628 $tickets = $query->get();
629
630 //if not ticket found
631 if ($tickets->isEmpty()) {
632 $this->sendError([
633 'message' => __('Sorry no tickets found based on your filter and bulk actions', 'fluent-support')
634 ]);
635 }
636
637 //get response data
638 $responseData = [
639 'content' => $request->get('content'),
640 'conversation_type' => $request->get('conversation_type', 'response'),
641 'close_ticket' => $request->get('close_ticket', 'no')
642 ];
643
644 $attachments = $request->get('attachments', []);
645
646 //If request with file
647 if ($attachments) {
648 $attachments = Attachment::whereNull('ticket_id')
649 ->orderBy('id', 'asc')
650 ->whereIn('file_hash', $attachments)
651 ->get();
652 }
653
654
655 $responseService = new ResponseService();
656
657 foreach ($tickets as $ticket) {
658 if ($attachments) {
659 $responseData['attachments'] = [];
660 foreach ($attachments as $attachment) {
661 $attachedFile = $attachment->replicate();
662 $attachedFile->ticket_id = $ticket->id;
663 $attachedFile->save();
664 $responseData['attachments'][] = $attachedFile->file_hash;
665 }
666 }
667
668 $responseService->createResponse($responseData, $agent, $ticket);
669 }
670
671
672 return [
673 'message' => __('Response has been added to the selected tickets', 'fluent-support')
674 ];
675
676 }
677
678 /**
679 * deleteResponse method will remove a response from ticket by ticket id and response id
680 * @param Request $request
681 * @param $ticketId
682 * @param $responseId
683 * @return array
684 */
685 public function deleteResponse(Request $request, $ticketId, $responseId)
686 {
687 $ticket = Ticket::findOrFail($ticketId);
688 $response = Conversation::findOrFail($responseId);
689 $agent = Helper::getAgentByUserId();
690
691 $hasAllPermission = PermissionManager::currentUserCan('fst_manage_other_tickets');
692
693 if (!$hasAllPermission) {
694 if ($ticket->agent_id != $agent->id) {
695 return $this->sendError([
696 'message' => __('Sorry, You do not have permission to delete this response', 'fluent-support')
697 ]);
698 }
699 }
700
701 Conversation::where('id', $response->id)->delete();
702
703 return [
704 'message' => __('Selected response has been deleted', 'fluent-support')
705 ];
706
707 }
708
709 /**
710 * updateResponse method will update ticket response using ticket and response id
711 * @param Request $request
712 * @param $ticketId
713 * @param $responseId
714 * @return array
715 * @throws \FluentSupport\Framework\Validator\ValidationException
716 */
717 public function updateResponse(Request $request, $ticketId, $responseId)
718 {
719 $data = $request->all();
720
721 $this->validate($data, [
722 'content' => 'required'
723 ]);
724
725 $ticket = Ticket::findOrFail($ticketId);
726 $response = Conversation::findOrFail($responseId);
727 $agent = Helper::getAgentByUserId();
728
729 $hasAllPermission = PermissionManager::currentUserCan('fst_manage_other_tickets');
730
731 if (!$hasAllPermission) {
732 if ($ticket->agent_id != $agent->id) {
733 return $this->sendError([
734 'message' => __('Sorry, You do not have permission to delete this response', 'fluent-support')
735 ]);
736 }
737 }
738
739 $response->content = wp_unslash(wp_kses_post($data['content']));
740 $response->save();
741
742 return [
743 'message' => __('Selected response has been updated', 'fluent-support'),
744 'response' => $response
745 ];
746 }
747
748 /**
749 * getLiveActivity method will return the activity in a ticket by agents
750 * @param Request $request
751 * @param $ticketId
752 * @return array
753 */
754 public function getLiveActivity(Request $request, $ticketId)
755 {
756 $agent = Helper::getAgentByUserId();
757
758 return [
759 'live_activity' => TicketHelper::getActivity($ticketId, $agent->id)
760 ];
761 }
762
763 /**
764 * removeLiveActivity method will remove activities that
765 * @param Request $request
766 * @param $ticketId
767 * @return array
768 */
769 public function removeLiveActivity(Request $request, $ticketId)
770 {
771 $agent = Helper::getAgentByUserId();
772
773 return [
774 'result' => TicketHelper::removeFromActivities($ticketId, $agent->id),
775 'agent_id' => $agent->id
776 ];
777 }
778
779 /**
780 * addTag method will add tag in ticket by ticket id
781 * @param Request $request
782 * @param $ticketId
783 * @return array
784 */
785 public function addTag(Request $request, $ticketId)
786 {
787 $ticket = Ticket::findOrFail($ticketId);
788
789 $tagId = intval($request->get('tag_id'));
790
791 if (!$ticket->hasTag($tagId)) {
792 $ticket->tags()->attach($tagId, ['source_type' => 'ticket_tag']);
793 }
794
795 return [
796 'message' => __('Tag has been added to this ticket', 'fluent-support'),
797 'tags' => $ticket->tags
798 ];
799 }
800
801 /**
802 * detachTag method will remove all tags from tickets
803 * @param $ticketId
804 * @param $tagId
805 * @return array
806 */
807 public function detachTag($ticketId, $tagId)
808 {
809 $ticket = Ticket::findOrFail($ticketId);
810 $ticket->tags()->detach($tagId);
811
812 return [
813 'message' => __('Tag has been removed from this ticket', 'fluent-support'),
814 'tags' => $ticket->tags
815 ];
816 }
817
818 /**
819 * changeTicketCustomer method will update customer in a ticket
820 * This method will get ticket id and customer id as parameter, it will replace existing customer id with new
821 * @param Request $request
822 * @return array
823 */
824 public function changeTicketCustomer(Request $request)
825 {
826 $updateCustomer = Ticket::where('id', $request->get('ticket_id'))
827 ->update(['customer_id' => $request->get('customer')]);
828 return [
829 'message' => __('Customer has been updated', 'fluent-support'),
830 'updatedCustomer' => $updateCustomer
831 ];
832 }
833
834 /**
835 * getTicketCustomData method will return the custom data by ticket id
836 * @param Request $request
837 * @param $ticketId
838 * @return array|array[]
839 */
840 public function getTicketCustomData(Request $request, $ticketId)
841 {
842 if (!defined('FLUENTSUPPORTPRO')) {
843 return [
844 'custom_data' => [],
845 'rendered_fields' => []
846 ];
847 }
848
849 $ticket = Ticket::findOrFail($ticketId);
850
851 return [
852 'custom_data' => (object)$ticket->customData(),
853 'rendered_fields' => \FluentSupportPro\App\Services\CustomFieldsService::getRenderedPublicFields($ticket->customer)
854 ];
855 }
856
857 /**
858 * syncFluentCrmTags method will synchronize the tags with Fluent CRM by contact id
859 *This function will get contact id and tags as parameter, get existing tags from crm and updated added/removed tags
860 * @param Request $request
861 * @return array
862 */
863 public function syncFluentCrmTags(Request $request)
864 {
865
866 if (!defined('FLUENTCRM')) {
867 return $this->sendError([
868 'message' => __('FluentCRM is not installed', 'fluent-support')
869 ]);
870 }
871
872 $contactId = absint($request->get('contact_id'));
873
874 if (!$contactId) {
875 return $this->sendError([
876 'message' => __('Contact could not be found', 'fluent-support')
877 ]);
878 }
879
880 $tagIds = array_filter($request->get('tags', []), 'absint');
881 $canAddTags = \FluentCrm\App\Services\PermissionManager::currentUserCan('fcrm_manage_contacts');
882 $canAddTags = apply_filters('fluent_support/can_user_add_tags_to_customer', $canAddTags);
883
884 if (!$canAddTags) {
885 return $this->sendError([
886 'message' => __('Sorry you do not have permission to add contact tags', 'fluent-support')
887 ]);
888 }
889
890 $contact = \FluentCrm\App\Models\Subscriber::findOrFail($contactId);
891
892 $existingTags = $contact->tags;
893 $existingTagIds = [];
894 foreach ($existingTags as $tag) {
895 $existingTagIds[] = $tag->id;
896 }
897 $newTagIds = array_diff($tagIds, $existingTagIds);
898 $removedTagIds = array_diff($existingTagIds, $tagIds);
899
900 if ($newTagIds) {
901 $contact->attachTags($newTagIds);
902 }
903
904 if ($removedTagIds) {
905 $contact->detachTags($removedTagIds);
906 }
907
908
909 return [
910 'tags' => $contact->tags,
911 'message' => __('FluentCRM contact tags has been updated', 'fluent-support')
912 ];
913
914 }
915 }
916