PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / trunk
Fluent Support – Helpdesk & Customer Support Ticket System vtrunk
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 / Hooks / Handlers / EmailNotificationHandler.php

EmailNotificationHandler.php in Fluent Support – Helpdesk & Customer Support Ticket System trunk, at app/Hooks/Handlers/EmailNotificationHandler.php

529 lines 19.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\Hooks\Handlers;
4
5 use FluentSupport\App\App;
6 use FluentSupport\App\Models\Agent;
7 use FluentSupport\App\Models\Meta;
8 use FluentSupport\App\Models\Ticket;
9 use FluentSupport\App\Services\EmailNotification\Settings;
10 use FluentSupport\App\Services\Emogrifier;
11 use FluentSupport\App\Services\Helper;
12 use FluentSupport\App\Services\Mailer;
13 use FluentSupport\App\Services\Tickets\AgentTicketAccess;
14 use FluentSupport\Framework\Support\Arr;
15
16 class EmailNotificationHandler
17 {
18 public function ticketCreated($ticket, $customer)
19 {
20 $mailbox = $ticket->mailbox;
21
22 if (!$mailbox) {
23 return;
24 }
25
26 // Let's send welcome email to customer if enabled
27 $emailSettings = (new Settings())->getBoxEmailSettings($mailbox, 'ticket_created_email_to_customer');
28
29 if ($this->shouldSendEmail($emailSettings, 'ticket_created_email_to_customer', $ticket, $customer)) {
30 $subject = apply_filters('fluent_support/parse_smartcode_data', $emailSettings['email_subject'], [
31 'customer' => $customer,
32 'business' => $mailbox,
33 'ticket' => $ticket
34 ]);
35
36 $subject = apply_filters('fluent_support/ticket_email_subject', $subject, $ticket, 'ticket_created_email_to_customer');
37
38 $emailBody = $this->parseEmailBody($emailSettings['email_body'], [
39 'customer' => $customer,
40 'business' => $mailbox,
41 'ticket' => $ticket,
42 'email_type' => 'ticket_created_email_to_customer'
43 ]);
44
45 $headers = $mailbox->getMailerHeader();
46
47 $headers = apply_filters('fluent_support/mail_to_customer_header', $headers, [
48 'cc_email' => $ticket->getSettingsValue('cc_email', []),
49 'hook_type' => 'ticket_created_email_to_customer'
50 ]);
51
52 $attachments = [];
53
54 if ($emailSettings['send_attachments'] == 'yes' && ($files = $ticket->attachments)) {
55 foreach ($files as $file) {
56 if ($file->driver == 'local') {
57 $filePath = $file->file_path;
58 } else {
59 $filePath = Arr::get($file->settings, 'local_temp_path');
60 }
61 if (file_exists($filePath)) {
62 $attachments[] = $filePath;
63 }
64 }
65 }
66
67 Mailer::send($customer->email, $subject, $emailBody, $headers, $attachments);
68 }
69
70 // let's send email to admin if enabled
71 $emailSettings = (new Settings())->getBoxEmailSettings($mailbox, 'ticket_created_email_to_admin');
72 if ($this->shouldSendEmail($emailSettings, 'ticket_created_email_to_admin', $ticket, $customer)
73 && is_email($mailbox->settings['admin_email_address'])
74 ) {
75
76 $mailTo = Arr::get($mailbox->settings, 'admin_email_address');
77
78 if (!$mailTo || !is_email($mailTo)) {
79 return;
80 }
81
82 $subject = apply_filters('fluent_support/parse_smartcode_data', $emailSettings['email_subject'], [
83 'customer' => $customer,
84 'business' => $mailbox,
85 'ticket' => $ticket
86 ]);
87
88 $subject = apply_filters('fluent_support/ticket_email_subject', $subject, $ticket, 'ticket_created_email_to_admin');
89
90 $emailBody = $this->parseEmailBody($emailSettings['email_body'], [
91 'customer' => $customer,
92 'business' => $mailbox,
93 'ticket' => $ticket,
94 'email_type' => 'ticket_created_email_to_admin'
95 ]);
96
97 $headers = $mailbox->getMailerHeader();
98
99 $attachments = [];
100
101 if ($emailSettings['send_attachments'] == 'yes' && ($files = $ticket->attachments)) {
102 foreach ($files as $file) {
103
104 if ($file->driver == 'local') {
105 $filePath = $file->file_path;
106 } else {
107 $filePath = Arr::get($file->settings, 'local_temp_path');
108 }
109 if (file_exists($filePath)) {
110 $attachments[] = $filePath;
111 }
112
113 }
114 }
115
116 Mailer::send($mailTo, $subject, $emailBody, $headers, $attachments);
117 }
118 }
119
120 public function agentReplied($response, $ticket, $agent)
121 {
122 $mailbox = $ticket->mailbox;
123
124
125 if (!$mailbox) {
126 return false;
127 }
128
129 // Let's send welcome email to customer if enabled
130 $emailSettings = (new Settings())->getBoxEmailSettings($mailbox, 'ticket_replied_by_agent_email_to_customer');
131
132
133 if ($emailSettings && $emailSettings['status'] == 'yes') {
134
135 $ticket->load('customer');
136 $customer = $ticket->customer;
137
138 if (!$customer->canReceiveNotifications()) {
139 return false;
140 }
141
142 if (!$this->shouldSendEmail($emailSettings, 'ticket_replied_by_agent_email_to_customer', $ticket, $customer)) {
143 return false;
144 }
145
146 $subject = apply_filters('fluent_support/parse_smartcode_data', $emailSettings['email_subject'], [
147 'customer' => $customer,
148 'business' => $mailbox,
149 'ticket' => $ticket,
150 'response' => $response,
151 'agent' => $agent
152 ]);
153
154 $subject = apply_filters('fluent_support/ticket_email_subject', $subject, $ticket, 'ticket_replied_by_agent_email_to_customer');
155
156 $emailBody = $this->parseEmailBody($emailSettings['email_body'], [
157 'customer' => $customer,
158 'business' => $mailbox,
159 'ticket' => $ticket,
160 'response' => $response,
161 'agent' => $agent,
162 'email_type' => 'ticket_replied_by_agent_email_to_customer'
163 ]);
164
165
166 $headers = $mailbox->getMailerHeader();
167 $headers = apply_filters('fluent_support/mail_to_customer_header', $headers, [
168 'cc_email' => $response->getSettingsValue('cc_email', []),
169 'hook_type' => 'ticket_replied_by_agent_email_to_customer'
170 ]);
171 $attachments = [];
172
173 if ($emailSettings['send_attachments'] == 'yes' && ($files = $response->attachments)) {
174 foreach ($files as $file) {
175 if ($file->driver == 'local') {
176 $filePath = $file->file_path;
177 } else {
178 $filePath = Arr::get($file->settings, 'local_temp_path');
179 }
180 if (file_exists($filePath)) {
181 $attachments[] = $filePath;
182 }
183 }
184 }
185
186 Mailer::send($customer->email, $subject, $emailBody, $headers, $attachments);
187 }
188 }
189
190 public function closedByAgent($ticket, $agent)
191 {
192 $mailbox = $ticket->mailbox;
193 if (!$mailbox) {
194 return;
195 }
196
197 // Let's send welcome email to customer if enabled
198 $emailSettings = (new Settings())->getBoxEmailSettings($mailbox, 'ticket_closed_by_agent_email_to_customer');
199 if ($emailSettings && $emailSettings['status'] == 'yes') {
200
201 $ticket->load('customer');
202 $customer = $ticket->customer;
203
204 if (!$customer->canReceiveNotifications()) {
205 return false;
206 }
207
208 if (!$this->shouldSendEmail($emailSettings, 'ticket_closed_by_agent_email_to_customer', $ticket, $customer)) {
209 return false;
210 }
211
212 $subject = apply_filters('fluent_support/parse_smartcode_data', $emailSettings['email_subject'], [
213 'customer' => $customer,
214 'business' => $mailbox,
215 'ticket' => $ticket,
216 'agent' => $agent,
217 ]);
218
219 $subject = apply_filters('fluent_support/ticket_email_subject', $subject, $ticket, 'ticket_closed_by_agent_email_to_customer');
220
221 $emailBody = $this->parseEmailBody($emailSettings['email_body'], [
222 'customer' => $customer,
223 'business' => $mailbox,
224 'ticket' => $ticket,
225 'agent' => $agent,
226 'email_type' => 'ticket_closed_by_agent_email_to_customer'
227 ]);
228
229 $headers = $mailbox->getMailerHeader();
230 $headers = apply_filters('fluent_support/mail_to_customer_header', $headers, [
231 'cc_email' => $ticket->getSettingsValue('cc_email', []),
232 'hook_type' => 'ticket_closed_by_agent_email_to_customer'
233 ]);
234 Mailer::send($customer->email, $subject, $emailBody, $headers);
235 }
236 }
237
238 public function customerReplied($response, $ticket, $customer)
239 {
240 $mailbox = $ticket->mailbox;
241 if (!$mailbox) {
242 return;
243 }
244
245 // Let's send welcome email to customer if enabled
246 $emailSettings = (new Settings())->getBoxEmailSettings($mailbox, 'ticket_replied_by_customer_email_to_admin');
247 if ($this->shouldSendEmail($emailSettings, 'ticket_replied_by_customer_email_to_admin', $ticket, $customer)) {
248
249 $ticket->load('agent');
250 $agent = $ticket->agent;
251
252 $emailTo = $mailbox->settings['admin_email_address'];
253 if ($agent) {
254 $emailTo = $agent->email;
255 }
256
257 if (!$emailTo || !is_email($emailTo)) {
258 return;
259 }
260
261 $subject = apply_filters('fluent_support/parse_smartcode_data', $emailSettings['email_subject'], [
262 'customer' => $customer,
263 'business' => $mailbox,
264 'ticket' => $ticket,
265 'response' => $response,
266 'agent' => $agent
267 ]);
268
269 $subject = apply_filters('fluent_support/ticket_email_subject', $subject, $ticket, 'ticket_replied_by_customer_email_to_admin');
270
271 $emailBody = $this->parseEmailBody($emailSettings['email_body'], [
272 'customer' => $customer,
273 'business' => $mailbox,
274 'ticket' => $ticket,
275 'response' => $response,
276 'agent' => $agent,
277 'email_type' => 'ticket_replied_by_customer_email_to_admin'
278 ]);
279
280 $headers = $mailbox->getMailerHeader();
281 $attachments = [];
282
283 if ($emailSettings['send_attachments'] == 'yes' && ($files = $response->attachments)) {
284 foreach ($files as $file) {
285 if ($file->driver == 'local') {
286 $filePath = $file->file_path;
287 } else {
288 $filePath = Arr::get($file->settings, 'local_temp_path');
289 }
290 if (file_exists($filePath)) {
291 $attachments[] = $filePath;
292 }
293 }
294 }
295
296 Mailer::send($emailTo, $subject, $emailBody, $headers, $attachments);
297 }
298 }
299
300 public function onAgentAssign(Agent $agent, Ticket $ticket, ?Agent $assigner = null)
301 {
302 if ($agent->status !== 'active' || (int) $ticket->agent_id !== (int) $agent->id) {
303 return;
304 }
305
306 if (!(new AgentTicketAccess())->canAccess($agent, $ticket)) {
307 return;
308 }
309
310 $currentUser = Helper::getAgentByUserId();
311
312 if ($currentUser && $currentUser->user_id == $agent->user_id) {
313 return;
314 }
315
316 $mailbox = $ticket->mailbox;
317
318 if (!$mailbox) {
319 return;
320 }
321
322 // Let's send notification email to agent if enabled
323 $emailSettings = (new Settings())->getBoxEmailSettings($mailbox, 'ticket_agent_on_change');
324
325 if ($this->shouldSendEmail($emailSettings, 'ticket_agent_on_change', $ticket, $agent)) {
326
327 if ($agent) {
328 $emailTo = $agent->email;
329 }
330
331 if (!$emailTo || !is_email($emailTo)) {
332 return;
333 }
334
335 $subject = apply_filters('fluent_support/parse_smartcode_data', $emailSettings['email_subject'], [
336 'business' => $mailbox,
337 'ticket' => $ticket,
338 'agent' => $agent,
339 'assigner' => $assigner
340 ]);
341
342 $subject = apply_filters('fluent_support/ticket_email_subject', $subject, $ticket, 'ticket_agent_on_change');
343
344 $emailBody = $this->parseEmailBody($emailSettings['email_body'], [
345 'business' => $mailbox,
346 'ticket' => $ticket,
347 'agent' => $agent,
348 'assigner' => $assigner,
349 'email_type' => 'ticket_agent_on_change'
350 ]);
351
352 $headers = $mailbox->getMailerHeader();
353
354 Mailer::send($emailTo, $subject, $emailBody, $headers);
355 }
356 }
357
358 public function ticketCreatedByAgent($ticket, $customer, $agent)
359 {
360 $mailbox = $ticket->mailbox;
361
362 if (!$mailbox) {
363 return;
364 }
365
366 // Let's send welcome email to customer if enabled
367 $emailSettings = (new Settings())->getBoxEmailSettings($mailbox, 'ticket_created_by_agent_email_to_customer');
368 if ($this->shouldSendEmail($emailSettings, 'ticket_created_by_agent_email_to_customer', $ticket, $customer)) {
369 $subject = apply_filters('fluent_support/parse_smartcode_data', $emailSettings['email_subject'], [
370 'customer' => $customer,
371 'agent' => $agent,
372 'business' => $mailbox,
373 'ticket' => $ticket
374 ]);
375
376 $subject = apply_filters('fluent_support/ticket_email_subject', $subject, $ticket, 'ticket_created_by_agent_email_to_customer');
377
378 $emailBody = $this->parseEmailBody($emailSettings['email_body'], [
379 'customer' => $customer,
380 'business' => $mailbox,
381 'agent' => $agent,
382 'ticket' => $ticket,
383 'email_type' => 'ticket_created_by_agent_email_to_customer'
384 ]);
385
386 $headers = $mailbox->getMailerHeader();
387
388 $attachments = [];
389
390 if ($emailSettings['send_attachments'] == 'yes' && ($files = $ticket->attachments)) {
391 foreach ($files as $file) {
392 if ($file->driver == 'local') {
393 $filePath = $file->file_path;
394 } else {
395 $filePath = Arr::get($file->settings, 'local_temp_path');
396 }
397 if (file_exists($filePath)) {
398 $attachments[] = $filePath;
399 }
400 }
401 }
402
403 Mailer::send($customer->email, $subject, $emailBody, $headers, $attachments);
404 }
405 }
406
407 public function ticketCreatedByAgentOnBehalf($response, $ticket, $agent)
408 {
409 $mailbox = $ticket->mailbox;
410
411 if (!$mailbox) {
412 return;
413 }
414
415 $emailSettings = (new Settings())->getBoxEmailSettings($mailbox, 'ticket_created_by_agent_on_behalf_email_to_customer');
416 if ($this->shouldSendEmail($emailSettings, 'ticket_created_by_agent_on_behalf_email_to_customer', $ticket)) {
417
418 $ticket->load('customer');
419 $customer = $ticket->customer;
420
421 if (!$customer->canReceiveNotifications()) {
422 return false;
423 }
424
425 $subject = apply_filters('fluent_support/parse_smartcode_data', $emailSettings['email_subject'], [
426 'customer' => $customer,
427 'agent' => $agent,
428 'business' => $mailbox,
429 'ticket' => $ticket,
430 'response' => $response
431 ]);
432
433 $subject = apply_filters('fluent_support/ticket_email_subject', $subject, $ticket, 'ticket_created_by_agent_on_behalf_email_to_customer');
434
435 $emailBody = $this->parseEmailBody($emailSettings['email_body'], [
436 'customer' => $customer,
437 'business' => $mailbox,
438 'agent' => $agent,
439 'ticket' => $ticket,
440 'response' => $response,
441 'email_type' => 'ticket_created_by_agent_on_behalf_email_to_customer'
442 ]);
443
444 $headers = $mailbox->getMailerHeader();
445
446 $attachments = [];
447
448 if ($emailSettings['send_attachments'] == 'yes') {
449 $files = $response->attachments;
450
451 // Agent-initiated ticket uploads are stored on the ticket, while this email
452 // is rendered from the synthetic first response created during ticket creation.
453 if ((!$files || $files->isEmpty()) && $ticket->attachments) {
454 $files = $ticket->attachments;
455 }
456
457 foreach ($files as $file) {
458 if ($file->driver == 'local') {
459 $filePath = $file->file_path;
460 } else {
461 $filePath = Arr::get($file->settings, 'local_temp_path');
462 }
463 if (file_exists($filePath)) {
464 $attachments[] = $filePath;
465 }
466 }
467 }
468
469 Mailer::send($customer->email, $subject, $emailBody, $headers, $attachments);
470 }
471 }
472
473 private function emailTemplateCss()
474 {
475 $app = App::getInstance();
476 return $app->view->make('emails.styles');
477 }
478
479 protected function parseEmailBody($emailBody, $data)
480 {
481 $data['email_body'] = apply_filters('fluent_support/parse_smartcode_data', $emailBody, $data);
482
483 $app = App::getInstance();
484
485 if (isset($data['business'])) {
486 $businessName = $data['business']->name;
487 } else {
488 $businessName = get_bloginfo('name');
489 }
490
491 $footerCreditUrl = Helper::getUpgradeUrl('mail_footer', ['base_url' => 'https://fluentsupport.com/']);
492 $footerText = apply_filters('fluent_support/email_footer_credit', 'This email is a service from ' . $businessName . '. Support Plugin is Powered by <a href="' . esc_url($footerCreditUrl) . '" style="color:#9e9e9e;" target="_new">FluentSupport</a>.');
493
494 $data['email_footer'] = $footerText;
495
496 $emailTypeForCustomerFooter = ['ticket_created_email_to_customer', 'ticket_replied_by_agent_email_to_customer', 'ticket_closed_by_agent_email_to_customer'];
497
498 if (defined('FLUENTSUPPORTPRO') && in_array($data['email_type'], $emailTypeForCustomerFooter)
499 && !is_null($data['business']->email_footer)) {
500 $data['email_footer'] = apply_filters('fluent_support/parse_smartcode_data', $data['business']->email_footer, $data);
501 }
502
503 $emailBody = $app->view->make('emails.ticket_template', $data);
504 $emogrifier = new Emogrifier($emailBody, $this->emailTemplateCss());
505 $emogrifier->disableInvisibleNodeRemoval();
506 return $emogrifier->emogrify();
507 }
508
509 protected function shouldSendEmail($emailSettings, $emailType, $ticket, $person = null)
510 {
511 if (!$emailSettings || $emailSettings['status'] != 'yes') {
512 return false;
513 }
514
515 return apply_filters('fluent_support/should_send_notification', true, 'email', $emailType, $ticket, $person);
516 }
517
518 public function getMailerHeaderWithCc($headers, $info)
519 {
520 if (isset($info['cc_email'])) {
521 $CcHeaders = !empty($info['cc_email']) && is_array($info['cc_email']) ? implode(', ', $info['cc_email']) : '';
522 $headers[] = $CcHeaders ? "Cc: $CcHeaders" : '';
523 }
524
525 return $headers;
526 }
527
528 }
529