PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 1.10.2
Fluent Support – Helpdesk & Customer Support Ticket System v1.10.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 / Importer / ZendeskTickets.php

ZendeskTickets.php in Fluent Support – Helpdesk & Customer Support Ticket System 1.10.2, at app/Services/Tickets/Importer/ZendeskTickets.php

271 lines 8.6 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\Importer;
4 class ZendeskTickets extends BaseImporter
5 {
6 protected $handler = 'zendesk';
7 public $accessToken;
8 public $mailbox_id;
9 private $domain;
10 private $email;
11 protected $limit;
12 private $hasMore;
13 private $currentPage;
14 private $totalTickets;
15 private $originId;
16 private $responseCount;
17 private $totalPage;
18
19 public function stats()
20 {
21 return [
22 'name' => esc_html('Zendesk'),
23 'handler' => $this->handler,
24 'type' => 'sass',
25 'last_migrated' => get_option('_fs_migrate_zendesk')
26 ];
27 }
28
29 public function doMigration($page, $handler)
30 {
31
32 $this->currentPage = $page;
33 $this->handler = $handler;
34 $tickets = $this->ticketsWithReply();
35 $results = $this->migrateTickets($tickets);
36
37 $this->totalPage = $this->totalTickets / $this->limit;
38 $this->hasMore = $this->currentPage < $this->totalPage;
39 $completedNow = isset($results['inserts']) ? count($results['inserts']) : 0;
40 $completedTickets = $completedNow + (($this->currentPage - 1) * $this->limit);
41 $remainingTickets = $this->totalTickets - $completedTickets;
42 $completed = intval(($completedTickets / $this->totalTickets) * 100);
43
44 $response = [
45 'handler' => $this->handler,
46 'insert_ids' => $results['inserts'],
47 'skips' => count($results['skips']),
48 'has_more' => $this->hasMore,
49 'completed' => $completed,
50 'imported_page' => $page,
51 'total_pages' => $this->totalPage,
52 'next_page' => $page + 1,
53 'total_tickets' => $this->totalTickets,
54 'remaining' => $remainingTickets
55 ];
56
57 if (!$this->hasMore) {
58 $response['message'] = __('All tickets has been imported successfully', 'fluent-support');
59 update_option('_fs_migrate_zendesk', current_time('mysql'), 'no');
60 }
61
62 return $response;
63 }
64
65 private function ticketsWithReply()
66 {
67 try {
68 $this->totalTickets = $this->countTotalTickets();
69 $url = "{$this->domain}/api/v2/tickets?per_page={$this->limit}&page={$this->currentPage}";
70 $tickets = $this->makeRequest($url);
71
72 $formattedTickets = [];
73 if (empty($tickets)) {
74 $this->hasMore = false;
75 return [];
76 }
77
78 $this->hasMore = true;
79 foreach ($tickets->tickets as $ticket) {
80 $singleTicketUrl = $this->domain . '/api/v2/tickets/' . $ticket->id . '/comments.json?include=attachments,users';
81 $singleTicket = $this->makeRequest($singleTicketUrl);
82 $this->originId = $ticket->id;
83 $ticketAttacments = [];
84 if (!empty($singleTicket->comments[0]->attachments)) {
85 $ticketAttacments = $this->getAttachments($singleTicket->comments[0]->attachments);
86 }
87
88 $formattedTickets[] = [
89 'title' => sanitize_text_field($ticket->subject),
90 'content' => wp_kses_post($ticket->description),
91 'origin_id' => intval($ticket->id),
92 'source' => sanitize_text_field($this->handler),
93 'customer' => $this->fetchPerson($ticket->requester_id),
94 'replies' => $this->getReplies($singleTicket),
95 'status' => $this->getStatus($ticket->status),
96 'client_priority' => $this->getPriority($ticket->priority),
97 'priority' => $this->getPriority($ticket->priority),
98 'created_at' => date('Y-m-d h:i:s', strtotime($ticket->created_at)),
99 'updated_at' => date('Y-m-d h:i:s', strtotime($ticket->updated_at)),
100 'last_customer_response' => NULL,
101 'last_agent_response' => NULL,
102 'attachments' => $ticketAttacments
103 ];
104 }
105
106 return $formattedTickets;
107
108 } catch (\Exception $e) {
109 return [];
110 }
111 }
112
113 private function getReplies($replies)
114 {
115 unset($replies->comments[0]);
116 $formattedReplies = [];
117 foreach ($replies->comments as $reply) {
118 $ticketReply = [
119 'content' => wp_kses_post($reply->body),
120 'conversation_type' => 'response',
121 'created_at' => date('Y-m-d h:i:s', strtotime($reply->created_at)),
122 'updated_at' => isset($reply->updated_at) ? date('Y-m-d h:i:s', strtotime($reply->updated_at)) : NULL,
123 ];
124
125 $ticketReply = $this->populatePersonInfo($ticketReply, $reply, $replies->users);
126
127 if (count($reply->attachments)) {
128 $ticketReply['attachments'] = $this->getAttachments($reply->attachments);
129 }
130
131 $formattedReplies[] = $ticketReply;
132 }
133
134 return $formattedReplies;
135 }
136
137 private function populatePersonInfo($ticketReply,$reply,$users)
138 {
139 foreach ($users as $user) {
140 if ($user->id !== $reply->author_id) {
141 continue;
142 }
143
144 $ticketReply['is_customer_reply'] = $user->role === 'end-user';
145 $type = $user->role === 'end-user' ? 'user' : 'agent';
146 $ticketReply['user'] = Common::formatPersonData($user, $type);
147 break;
148 }
149
150 return $ticketReply;
151 }
152
153 private function makeRequest($url)
154 {
155 $token = base64_encode($this->email . '/token:' . $this->accessToken);
156
157 $request = wp_remote_get($url, [
158 'headers' => [
159 'Authorization' => "Basic {$token}",
160 'Content-Type' => 'application/json'
161 ]
162 ]);
163
164 if (is_wp_error($request)) {
165 throw new \Exception('Error while making request');
166 }
167
168 $response = json_decode(wp_remote_retrieve_body($request));
169
170 return $response;
171 }
172
173 private function fetchPerson($requesterId)
174 {
175 $userUrl = $this->domain . '/api/v2/users/' . $requesterId . '.json';
176 $fetchUser = $this->makeRequest($userUrl);
177
178 $user = (object)[
179 'name' => $fetchUser->user->name,
180 'address' => $fetchUser->user->email
181 ];
182
183 $personArray = Common::formatPersonData($user, 'customer');
184 return Common::updateOrCreatePerson($personArray);
185 }
186
187 private function countTotalTickets()
188 {
189 $url = "{$this->domain}/api/v2/tickets/count.json";
190 $count = $this->makeRequest($url);
191 return $count->count->value;
192 }
193
194 private function getAttachments($attachments)
195 {
196 $wpUploadDir = wp_upload_dir();
197 $baseDir = $wpUploadDir['basedir'] . '/fluent-support/zendesk-ticket-' . $this->originId . '/';
198
199 $formattedAttachments = [];
200 foreach ($attachments as $attachment) {
201 $filePath = Common::downloadFile($attachment->content_url, $baseDir, $attachment->file_name);
202 $fileUrl = $wpUploadDir['baseurl'] . '/fluent-support/zendesk-ticket-' . $this->originId . '/' . $attachment->file_name;
203 $formattedAttachments[] = [
204 'full_url' => $fileUrl,
205 'title' => $attachment->file_name,
206 'file_path' => $filePath,
207 'driver' => 'local',
208 'status' => 'active',
209 'file_type' => $attachment->content_type
210 ];
211 }
212
213 return $formattedAttachments;
214 }
215
216 public function setAccessToken($accessToken)
217 {
218 $this->accessToken = $accessToken;
219 }
220
221 public function setDomain($domain)
222 {
223 $this->domain = $domain;
224 }
225
226 public function setEmail($email)
227 {
228 $this->email = $email;
229 }
230
231 private function setResponseCount($count)
232 {
233 $this->responseCount = $count;
234 }
235
236 private function getStatus($status)
237 {
238 switch ($status) {
239 case 'open':
240 return 'active';
241 case 'pending':
242 return 'waiting';
243 case 'solved':
244 return 'closed';
245 default:
246 return 'active';
247 }
248
249 }
250
251 private function getPriority($priority)
252 {
253 switch ($priority) {
254 case 'low':
255 case 'normal':
256 return 'normal';
257 case 'high':
258 return 'medium';
259 case 'urgent':
260 return 'critical';
261 default:
262 return 'normal';
263 }
264 }
265
266 public function deleteTickets($page)
267 {
268 return;
269 }
270 }
271