PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.1.2
Fluent Support – Helpdesk & Customer Support Ticket System v2.1.2
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 2.1.2, at app/Services/Tickets/ResponseService.php

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