PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 1.10.5
Fluent Support – Helpdesk & Customer Support Ticket System v1.10.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 / Services / Tickets / ResponseService.php

ResponseService.php in Fluent Support – Helpdesk & Customer Support Ticket System 1.10.5, at app/Services/Tickets/ResponseService.php

234 lines 8.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\Services\Tickets;
4
5 use FluentSupport\App\Models\Attachment;
6 use FluentSupport\App\Models\Conversation;
7 use FluentSupport\App\Services\Helper;
8 use FluentSupport\App\Services\Includes\UploadService;
9 use FluentSupport\Framework\Support\Arr;
10
11 class ResponseService
12 {
13 /**
14 * createResponse method is responsible for create responses to ticket by agent or customer
15 * @param $data
16 * @param $person
17 * @param $ticket
18 * @return array|false
19 */
20 public function createResponse($data, $person, $ticket, $silently = false)
21 {
22 if (empty($data['content'])) {
23 return false;
24 }
25
26 $cc_emails = Arr::get($data, 'cc_emails', []);
27
28 $informationalReply = Arr::get($data, 'informational_reply', false);
29 // Adding support for shortcode in agent response
30 if ($person->person_type == 'agent') {
31 $data['content'] = apply_filters('fluent_support/parse_smartcode_data', $data['content'], [
32 'customer' => $ticket->customer,
33 'agent' => $person
34 ]);
35 }
36
37 $convoType = Arr::get($data, 'conversation_type', 'response');
38
39 $content = wp_unslash(wp_kses_post($data['content']));
40 $resetWaitingSince = apply_filters('fluent_support/reset_waiting_since', true, $content);
41 $content = apply_filters('fluent_support/response_content_before_use_anywhere', $content);
42 $response = [
43 'person_id' => $person->id,
44 'ticket_id' => $ticket->id,
45 'conversation_type' => $convoType,
46 'content' => $content,
47 'source' => Arr::get($data, 'source', 'web'),
48 'content_hash' => md5($content)
49 ];
50
51 if (!empty($data['message_id'])) {
52 $response['message_id'] = sanitize_text_field($data['message_id']);
53 }
54
55 $response = apply_filters('fluent_support/new_' . $person->person_type . '_' . $convoType, $response, $ticket, $person);
56
57 $createdResponse = \FluentSupport\App\Models\Conversation::create($response);
58
59 if (!empty($cc_emails)) {
60 //Store cc emails in meta settings for the response
61 $createdResponse->updateSettingsValue('cc_email', $cc_emails);
62
63 //Store all the carbon copy customers under the ticket
64 $existingCcEmails = $ticket->getSettingsValue('all_cc_email', []);
65 $newData = array_merge($existingCcEmails, $cc_emails);
66 $ticket->updateSettingsValue('all_cc_email', array_unique($newData));
67 }
68
69 $createdResponse->load('person');
70
71 if ($person->person_type == 'agent' && $ticket->status == 'new' && $convoType == 'response') {
72 $ticket->status = 'active';
73 if ($ticket->created_at) {
74 $ticket->first_response_time = strtotime(current_time('mysql')) - strtotime($ticket->created_at);
75 } else {
76 $ticket->first_response_time = 300;
77 }
78 }
79
80 $agentAdded = false;
81 $updateData = [];
82
83 if ($person->person_type == 'agent') {
84 if (!$ticket->agent_id && $convoType == 'response') {
85 $ticket->agent_id = $person->id;
86 $agentAdded = true;
87 $updateData = [
88 'agent_id' => $person->id
89 ];
90 }
91
92 if ($convoType == 'response') {
93 if ($resetWaitingSince && !$informationalReply) {
94 $ticket->last_agent_response = current_time('mysql');
95 $ticket->waiting_since = current_time('mysql');
96 }
97 }
98 } else {
99
100 if ($ticket->last_agent_response && strtotime($ticket->last_agent_response) > strtotime($ticket->last_customer_response)) {
101 $ticket->waiting_since = current_time('mysql');
102 }
103
104 $ticket->last_customer_response = current_time('mysql');
105 }
106
107 if ($convoType == 'response') {
108 $ticket->response_count += 1;
109 }
110
111 $closed = false;
112 if (Arr::get($data, 'close_ticket') == 'yes' && $ticket->status != 'closed') {
113 $ticket->status = 'closed';
114 $ticket->resolved_at = current_time('mysql');
115 $ticket->closed_by = $person->id;
116 $ticket->total_close_time = current_time('timestamp') - strtotime($ticket->created_at);
117 $closed = true;
118
119 $internalNote = __('Ticket has been closed', 'fluent-support');
120
121 $internalNote = apply_filters('fluent_support/ticket_close_internal_note', $internalNote, $ticket);
122
123 if ($internalNote) {
124 Conversation::create([
125 'ticket_id' => $ticket->id,
126 'person_id' => $person->id,
127 'conversation_type' => 'internal_info',
128 'content' => $internalNote
129 ]);
130 }
131 }
132
133 $ticket->save();
134
135 Helper::tempImageMoveUploadDir($ticket->id, 'conversation', $createdResponse->id);
136
137 //If file upload failed to local during create response
138 if ($attachmentHashes = Arr::get($data, 'attachments', [])) {
139 $attachments = Attachment::where('ticket_id', $ticket->id)
140 ->whereIn('file_hash', $attachmentHashes)
141 ->where('status', 'in-active')
142 ->get();
143
144 if (!$attachments->isEmpty()) {
145 $storageDriver = Helper::getUploadDriverKey();
146 foreach ($attachments as $attachment) {
147 if ($storageDriver != 'local') {
148 do_action_ref_array('fluent_support/finalize_file_upload_' . $storageDriver, [&$attachment, $ticket->id]);
149 }
150
151 if ($attachment->driver == 'local') {
152 $newFileInfo = UploadService::copyFileTicketFolder($attachment->file_path, $ticket->id);
153 if ($newFileInfo && !empty($newFileInfo['file_path'])) {
154 $attachment->file_path = $newFileInfo['file_path'];
155 $attachment->full_url = $newFileInfo['url'];
156 }
157 }
158
159 $attachment->ticket_id = $ticket->id;
160 $attachment->person_id = $createdResponse->person_id;
161 $attachment->conversation_id = $createdResponse->id;
162 $attachment->status = 'active';
163 $attachment->save();
164 }
165 $createdResponse->load('attachments');
166 }
167 }
168
169 if ($silently) {
170 return [
171 'response' => $createdResponse,
172 'ticket' => $ticket,
173 'update_data' => $updateData
174 ];
175 }
176
177 if ($agentAdded) {
178 $assigner = Helper::getCurrentAgent();
179 $ticket->load('agent');
180
181 /*
182 * Action on ticket assign to an agent
183 *
184 * @since v1.0.0
185 * @param object $person
186 * @param object $ticket
187 * @param object $assigner
188 */
189 do_action('fluent_support/agent_assigned_to_ticket', $person, $ticket, $assigner);
190 $updateData['agent'] = $ticket->agent;
191 }
192
193 /*
194 * Action on conversation
195 *
196 * @since v1.0.0
197 * @param string $convoType
198 * @param string $personType
199 * @param object $createdResponse
200 * @param object $ticket
201 * @param object $person
202 */
203 do_action('fluent_support/' . $convoType . '_added_by_' . $person->person_type, $createdResponse, $ticket, $person);
204
205
206 if ($closed) {
207 /*
208 * Action on ticket close
209 *
210 * @since v1.0.0
211 * @param object $ticket
212 * @param object $person
213 */
214 do_action('fluent_support/ticket_closed', $ticket, $person);
215
216 /*
217 * Action on ticket close
218 *
219 * @since v1.0.0
220 * @param string $personType
221 * @param object $ticket
222 * @param object $person
223 */
224 do_action('fluent_support/ticket_closed_by_' . $person->person_type, $ticket, $person);
225 }
226
227 return [
228 'response' => $createdResponse,
229 'ticket' => $ticket,
230 'update_data' => $updateData
231 ];
232 }
233 }
234