PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 1.10.4
Fluent Support – Helpdesk & Customer Support Ticket System v1.10.4
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.10.4, at app/Http/Controllers/TicketController.php

647 lines 20.2 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\Meta;
6 use FluentSupport\Framework\Support\Arr;
7 use FluentSupport\App\Http\Requests\TicketRequest;
8 use FluentSupport\App\Http\Requests\TicketResponseRequest;
9 use FluentSupport\App\Models\Conversation;
10 use FluentSupport\App\Models\Ticket;
11 use FluentSupport\App\Services\FluentBoardsService;
12 use FluentSupport\App\Services\FluentCRMServices;
13 use FluentSupport\App\Services\Helper;
14 use FluentSupport\App\Services\ProfileInfoService;
15 use FluentSupport\App\Services\TicketHelper;
16 use FluentSupport\Framework\Request\Request;
17 use FluentSupport\App\Modules\PermissionManager;
18 use FluentSupport\App\Services\Tickets\TicketService;
19
20 /**
21 * TicketController class for REST API related to ticket
22 * This class is responsible for getting / inserting/ modifying data for all request related to ticket
23 * @package FluentSupport\App\Http\Controllers
24 *
25 * @version 1.0.0
26 */
27 class TicketController extends Controller
28 {
29 /**
30 * This `me` method will return the current user profile info
31 * @param Request $request
32 * @param ProfileInfoService $profileInfoService
33 * @return array
34 */
35 public function me(Request $request, ProfileInfoService $profileInfoService)
36 {
37 $user = wp_get_current_user();
38 $settings = [
39 'user_id' => $user->ID,
40 'email' => $user->user_email,
41 'person' => Helper::getAgentByUserId($user->ID),
42 'permissions' => PermissionManager::currentUserPermissions(),
43 'request' => $request->all()
44 ];
45
46 $withPortalSettings = $request->getSafe('with_portal_settings');
47
48 return $profileInfoService->me($settings, $withPortalSettings);
49 }
50
51 /**
52 * index method will return the list of ticket based on the selected filter
53 * @param Request $request
54 * @return array
55 */
56 public function index(Request $request, TicketService $ticketService)
57 {
58 //Selected filter type, either simple or Advanced
59 $filterType = $request->getText('filter_type', 'simple');
60 $data = $request->all();
61 return $ticketService->getTickets($data, $filterType);
62 }
63
64 /**
65 * createTicket method will create new ticket as well as customer or WP user
66 * @param Request $request
67 * @param Ticket $ticket
68 * @return array
69 * @throws \Exception
70 */
71 public function createTicket(TicketRequest $request, Ticket $ticket)
72 {
73 $data = $request->sanitize();
74
75 $ticketData = $data['ticket'];
76
77 if (!empty($data['attachments'])) {
78 $ticketData['attachments'] = $data['attachments'];
79 }
80
81 $maybeNewCustomer = $data['newCustomer'];
82
83 $createdTicket = $ticket->createTicket($ticketData, $maybeNewCustomer);
84
85 if (is_wp_error($createdTicket)) {
86 return $this->sendError([
87 'message' => $createdTicket->get_error_message()
88 ]);
89 }
90
91 return [
92 'message' => 'Ticket has been successfully created',
93 'ticket' => $createdTicket
94 ];
95 }
96
97 /**
98 * getTicket method will return ticket information by ticket id
99 * @param Request $request
100 * @param $ticket_id
101 * @return array
102 */
103 public function getTicket(Request $request, Ticket $ticket, $ticket_id)
104 {
105 try {
106 $ticketWith = $request->getSafe('with', 'sanitize_text_field');
107 if (!$ticketWith) {
108 $ticketWith = ['customer', 'agent', 'product', 'mailbox', 'tags', 'attachments' => function ($q) {
109 $q->whereIn('status', ['active', 'inline']);
110 }];
111 }
112 $withCrmData = in_array('fluentcrm_profile', $request->query('with_data', []));
113
114 return $ticket->getTicket($ticketWith, $withCrmData, $ticket_id);
115 } catch (\Exception $e) {
116 return $this->sendError($e->getMessage());
117 }
118 }
119
120 /**
121 * createResponse method will create response by agent for the ticket
122 * @param Request $request
123 * @param Ticket $ticket
124 * @param int $ticket_id
125 * @return array
126 * @throws \FluentSupport\Framework\Validator\ValidationException
127 */
128 public function createResponse(TicketResponseRequest $request, Ticket $ticket, $ticket_id)
129 {
130
131 $data = $request->sanitize();
132
133 try {
134 return $ticket->createResponse($data, $ticket_id);
135 } catch (\Exception $e) {
136 return $this->sendError($e->getMessage());
137 }
138 }
139
140 /**
141 * createDraft method will create draft by agent for the ticket
142 * @param Request $request
143 * @param Ticket $ticket
144 * @param int $ticket_id
145 * @return array
146 * @throws \FluentSupport\Framework\Validator\ValidationException
147 */
148 public function createOrUpdatDraft(TicketResponseRequest $request, Ticket $ticket, $ticket_id)
149 {
150
151 $data = $request->sanitize();
152
153 try {
154 return $ticket->addOrUpdatDraft($data, $ticket_id);
155 } catch (\Exception $e) {
156 return $this->sendError($e->getMessage());
157 }
158 }
159
160 public function getDraft(Ticket $ticket, $ticket_id)
161 {
162 try {
163 return $ticket->fetchDraft($ticket_id);
164 } catch (\Exception $e) {
165 return $this->sendError($e->getMessage());
166 }
167 }
168
169 public function deleteDraft(Ticket $ticket, $draft_id)
170 {
171 $draft_id = intval($draft_id);
172
173 try {
174 return $ticket->removeDraft($draft_id);
175 } catch (\Exception $e) {
176 return $this->sendError($e->getMessage());
177 }
178 }
179
180 /**
181 * getTicketWidgets method generate additional information for a ticket by customer
182 * @param Ticket $ticket
183 * @param $ticket_id
184 * @return array
185 */
186 public function getTicketWidgets(Ticket $ticket, $ticket_id)
187 {
188 try {
189 return $ticket->getTicketWidgets($ticket_id);
190 } catch (\Exception $e) {
191 return $this->sendError($e->getMessage());
192 }
193 }
194
195 /**
196 * updateTicketProperty method will update ticket property
197 * @param Request $request
198 * @param Ticket $ticket
199 * @param $ticket_id
200 * @return array
201 */
202 public function updateTicketProperty(Request $request, Ticket $ticket, $ticket_id)
203 {
204 $propName = $request->getSafe('prop_name', 'sanitize_text_field');
205 $propValue = $request->getSafe('prop_value', 'sanitize_text_field');
206
207 try {
208 return $ticket->updateTicketProperty($propName, $propValue, $ticket_id);
209 } catch (\Exception $e) {
210 return $this->sendError($e->getMessage());
211 }
212 }
213
214 /**
215 * closeTicket method close the ticket by id
216 * @param Ticket $ticket
217 * @param int $ticket_id
218 * @return array
219 */
220 public function closeTicket(Ticket $ticket, $ticket_id)
221 {
222 try {
223 return $ticket->closeTicket($ticket_id, $this->request->getSafe('close_ticket_silently'));
224 } catch (\Exception $e) {
225 return $this->sendError($e->getMessage());
226 }
227 }
228
229 /**
230 * reOpenTicket method will reopen a closed ticket
231 * @param Request $request
232 * @param $ticket_id
233 * @return array
234 */
235 public function reOpenTicket(Ticket $ticket, $ticket_id)
236 {
237 try {
238 return $ticket->reOpenTicket($ticket_id);
239 } catch (\Exception $e) {
240 return $this->sendError($e->getMessage());
241 }
242 }
243
244 /**
245 * doBulkActions method is responsible for bulk action
246 * This function will get ticket ids and action as parameter and perform action based on the selection
247 * @param Request $request
248 * @param Ticket $ticket
249 * @return array|string[]|void
250 * @throws \Exception
251 */
252 public function doBulkActions(Request $request, Ticket $ticket)
253 {
254 $action = $request->getSafe('bulk_action', 'sanitize_text_field'); //get action
255 $ticket_ids = $request->get('ticket_ids', []);
256 $sanitizedTicketIds = array_map('intval', $ticket_ids);
257
258 try {
259 return $ticket->handleBulkActions($action, $sanitizedTicketIds);
260 } catch (\Exception $e) {
261 return $this->sendError($e->getMessage());
262 }
263 }
264
265 /**
266 * deleteTicket method will delete a ticket
267 * @param Request $request
268 * @param TicketService $ticketService
269 * @return array
270 */
271 public function deleteTicket(TicketService $ticketService, $ticket_id)
272 {
273 $ticket = Ticket::findOrFail($ticket_id);
274 try {
275 return $ticketService->delete($ticket);
276 } catch (\Exception $e) {
277 return $this->sendError($e->getMessage());
278 }
279 }
280
281 /**
282 * doBulkReplies method will create response for bulk tickets
283 * This function will get ticket ids, content, attachment etc and create response for tickets
284 * @param Request $request
285 * @param Conversation $conversation
286 * @return array
287 * @throws \Exception
288 */
289 public function doBulkReplies(Request $request, Conversation $conversation)
290 {
291 $data = $request->get();
292 $this->validate($data, [
293 'content' => 'required',
294 'ticket_ids' => 'required|array'
295 ]);
296
297 try {
298 return $conversation->doBulkReplies($data);
299 } catch (\Exception $e) {
300 return $this->sendError($e->getMessage());
301 }
302 }
303
304 /**
305 * deleteResponse method will remove a response from ticket by ticket id and response id
306 * @param Request $request
307 * @param Conversation $conversation
308 * @param $ticket_id
309 * @param $response_id
310 * @return array
311 */
312 public function deleteResponse(Conversation $conversation, $ticket_id, $response_id)
313 {
314 try {
315 return $conversation->deleteResponse($ticket_id, $response_id);
316 } catch (\Exception $e) {
317 return $this->sendError($e->getMessage());
318 }
319 }
320
321 /**
322 * updateResponse method will update ticket response using ticket and response id
323 * @param Request $request
324 * @param Conversation $conversation
325 * @param int $ticket_id
326 * @param int $response_id
327 * @return array
328 * @throws \Exception
329 */
330 public function updateResponse(TicketResponseRequest $request, Conversation $conversation, $ticket_id, $response_id)
331 {
332 $data = $request->getSafe(['content', 'ticket_id', 'response_id']);
333
334 try {
335 return $conversation->updateResponse($data, $ticket_id, $response_id);
336 } catch (\Exception $e) {
337 return $this->sendError($e->getMessage());
338 }
339 }
340
341 public function approveDraftResponse(TicketResponseRequest $request, Conversation $conversation, $ticket_id, $response_id)
342 {
343 $data = [
344 'content' => $request->getSafe('content', 'sanitize_text_field')
345 ];
346 $conversationType = 'response';
347
348 try {
349 return $conversation->publishDraftResponse($data, $ticket_id, $response_id, $conversationType);
350 } catch (\Exception $e) {
351 return $this->sendError($e->getMessage());
352 }
353 }
354
355 /**
356 * getLiveActivity method will return the activity in a ticket by agents
357 * @param Request $request
358 * @param $ticket_id
359 * @return array
360 */
361 public function getLiveActivity(Request $request, $ticket_id)
362 {
363 $agent = Helper::getAgentByUserId();
364
365 return [
366 'live_activity' => TicketHelper::getActivity($ticket_id, $agent->id)
367 ];
368 }
369
370 /**
371 * removeLiveActivity method will remove activities that
372 * @param Request $request
373 * @param $ticket_id
374 * @return array
375 */
376 public function removeLiveActivity(Request $request, $ticket_id)
377 {
378 $agent = Helper::getAgentByUserId();
379
380 return [
381 'result' => TicketHelper::removeFromActivities($ticket_id, $agent->id),
382 'agent_id' => $agent->id
383 ];
384 }
385
386 /**
387 * addTag method will add tag in ticket by ticket id
388 * @param Request $request
389 * @param $ticket_id
390 * @return array
391 */
392 public function addTag(Request $request, $ticket_id)
393 {
394 $ticket = Ticket::findOrFail($ticket_id);
395
396 $ticket->applyTags($request->getSafe('tag_id', 'intval'));
397
398 return [
399 'message' => __('Tag has been added to this ticket', 'fluent-support'),
400 'tags' => $ticket->tags
401 ];
402 }
403
404 /**
405 * detachTag method will remove all tags from tickets
406 * @param $ticket_id
407 * @param $tag_id
408 * @return array
409 */
410 public function detachTag($ticket_id, $tag_id)
411 {
412 $ticket = Ticket::findOrFail($ticket_id);
413 $ticket->detachTags($tag_id);
414
415 return [
416 'message' => __('Tag has been removed from this ticket', 'fluent-support'),
417 'tags' => $ticket->tags
418 ];
419 }
420
421 /**
422 * changeTicketCustomer method will update customer in a ticket
423 * This method will get ticket id and customer id as parameter, it will replace existing customer id with new
424 * @param Request $request
425 * @return array
426 */
427 public function changeTicketCustomer(Request $request)
428 {
429 $ticketId = $request->getSafe('ticket_id', 'intval');
430 $newCustomerId = $request->getSafe('customer', 'intval');
431
432 if (!$newCustomerId) {
433 return $this->sendError(__('Invalid customer selected.', 'fluent-support'));
434 }
435
436 try {
437 $updated = Ticket::where('id', $ticketId)
438 ->where('customer_id', '!=', $newCustomerId)
439 ->update(['customer_id' => $newCustomerId]);
440
441 return $updated
442 ? ['message' => __('Customer has been updated', 'fluent-support')]
443 : $this->sendError(__('Ticket not found or customer already assigned.', 'fluent-support'));
444
445 } catch (\Exception $e) {
446 return $this->sendError($e->getMessage());
447 }
448 }
449
450 /**
451 * getTicketCustomData method will return the custom data by ticket id
452 * @param Request $request
453 * @param $ticket_id
454 * @return array|array[]
455 */
456 public function getTicketCustomData(Request $request, $ticket_id)
457 {
458 if (!defined('FLUENTSUPPORTPRO')) {
459 return [
460 'custom_data' => [],
461 'rendered_fields' => []
462 ];
463 }
464
465 $ticket = Ticket::findOrFail($ticket_id);
466
467 return [
468 'custom_data' => (object)$ticket->customData(),
469 'rendered_fields' => \FluentSupportPro\App\Services\CustomFieldsService::getRenderedPublicFields($ticket->customer, 'admin')
470 ];
471 }
472
473 /**
474 * syncFluentCrmTags method will synchronize the tags with Fluent CRM by contact id
475 *This function will get contact id and tags as parameter, get existing tags from crm and updated added/removed tags
476 * @param Request $request
477 * @param FluentCRMServices $fluentCRMServices
478 * @return array
479 */
480 public function syncFluentCrmTags(Request $request, FluentCRMServices $fluentCRMServices)
481 {
482 $data = $request->only(['contact_id', 'tags']);
483 try {
484 return $fluentCRMServices->syncCrmTags($data);
485 } catch (\Exception $e) {
486 return $this->sendError($e->getMessage());
487 }
488 }
489
490 /**
491 * This `syncFluentCrmLists` method will synchronize the lists with Fluent CRM by contact id
492 * This method will get contact id and lists as parameter, get existing lists from crm and updated added/removed lists
493 * @param Request $request
494 * @param FluentCRMServices $fluentCRMServices
495 * @return array
496 */
497
498 public function syncFluentCrmLists(Request $request, FluentCRMServices $fluentCRMServices)
499 {
500 $data = $request->only(['contact_id', 'lists']);
501 try {
502 return $fluentCRMServices->syncCrmLists($data);
503 } catch (\Exception $e) {
504 return $this->sendError($e->getMessage());
505 }
506 }
507
508 /**
509 * Retrieve boards from Fluent Boards API.
510 *
511 * @return array Formatted array of boards.
512 */
513 public function getBoards()
514 {
515 $boards = FluentBoardsApi('boards')->getBoards();
516 $formattedBoards = [];
517
518 foreach ($boards as $board) {
519 $formattedBoard = [
520 'id' => $board->id,
521 'title' => $board->title,
522 'tasks' => [],
523 ];
524
525 $formattedBoards[] = $formattedBoard;
526 }
527
528 return ['boards' => $formattedBoards];
529 }
530
531 /**
532 * Retrieve stages for a specific board from Fluent Boards API.
533 *
534 * @param Request $request Request object containing 'board_id'.
535 * @return array Formatted array of stages.
536 */
537 public function getStages(Request $request)
538 {
539 $boardId = $request->input('board_id');
540 $boardStages = FluentBoardsApi('boards')->getStagesByBoard($boardId);
541
542 $formattedStages = [];
543 if (!empty($boardStages)) {
544 foreach ($boardStages[0]->stages as $stage) {
545 $formattedStages[] = [
546 'id' => $stage->id,
547 'title' => $stage->title,
548 ];
549 }
550 }
551
552 return ['stages' => $formattedStages];
553 }
554
555 /**
556 * Create a task using data provided in the request.
557 *
558 * @param Request $request Request object containing task data.
559 * @return array Response containing message and task data.
560 */
561 public function createTask(Request $request, FluentBoardsService $fluentBoardsService)
562 {
563 try {
564 $taskData = [
565 'source_id' => $request->getSafe('source_id', 'intval'),
566 'board_id' => $request->getSafe('board_id', 'intval'),
567 'stage_id' => $request->getSafe('stage_id', 'intval'),
568 'crm_contact_id' => $request->getSafe('crm_contact_id', 'intval') ?: null,
569 'title' => $request->getSafe('title', 'sanitize_text_field'),
570 'description' => $request->getSafe('description', 'wp_kses_post'),
571 'source' => $request->getSafe('source', 'sanitize_text_field'),
572 'started_at' => $request->getSafe('started_at', 'sanitize_text_field'),
573 'due_at' => $request->getSafe('due_at', 'sanitize_text_field'),
574 ];
575
576 $task = FluentBoardsApi('tasks')->create($taskData);
577
578 if (!$task) {
579 return $this->sendError(__('Failed to create task.', 'fluent-support'));
580 }
581
582 $fluentBoardsService->addInternalNote($task);
583 $fluentBoardsService->addComment($task);
584
585 return [
586 'message' => __('Task successfully added to Fluent Boards', 'fluent-support'),
587 'task' => $task
588 ];
589 } catch (\Exception $e) {
590 return $this->sendError($e->getMessage());
591 }
592 }
593
594 /**
595 * Get ticket essentials data based on the provided types.
596 *
597 * @param \Illuminate\Http\Request $request
598 * @return array The ticket essentials data.
599 */
600 public function getTicketEssentials(Request $request)
601 {
602 $type = $request->get('type');
603
604 return TicketHelper::getTicketEssentials($type);
605 }
606
607 public function fetchLabelSearch(Ticket $ticket)
608 {
609 try {
610 $agent_id = get_current_user_id();
611 return TicketHelper::getLabelSearch($agent_id);
612 } catch (\Exception $e) {
613 return $this->sendError($e->getMessage());
614 }
615 }
616
617 public function storeOrUpdateLabelSearch(Request $request)
618 {
619 try {
620 $agent_id = get_current_user_id();
621 $searchData = $request->get('query');
622 $filterType = Arr::get($searchData, 'filter_type', '');
623 if ($filterType == 'advanced') {
624 return TicketHelper::saveSearchLabel($agent_id,$searchData,$filterType);
625 }
626
627 return [
628 'message' => __('Invalid filter type.', 'fluent-support'),
629 ];
630
631 } catch (\Exception $e) {
632 return $this->sendError($e->getMessage());
633 }
634 }
635
636 public function deleteLabelSearch(Request $request, $search_id)
637 {
638 try {
639 $agent_id = get_current_user_id();
640 return TicketHelper::deleteSavedSearch($search_id);
641 } catch (\Exception $e) {
642 return $this->sendError($e->getMessage());
643 }
644 }
645 }
646
647