PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 1.5.10
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v1.5.10
2.4.0 2.3.0 2.2.5 2.2.0 2.1.2 2.1.1 trunk 1.10.0 1.10.01 1.10.02 1.5.0 1.5.01 1.5.02 1.5.1 1.5.10 1.5.20 1.5.21 1.5.22 1.5.23 1.5.24 1.5.25 1.6.0 1.7.0 1.7.1 1.7.2 All 33 releases
fluent-booking / app / Services / EmailNotificationService.php

EmailNotificationService.php in Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution 1.5.10, at app/Services/EmailNotificationService.php

430 lines 16.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBooking\App\Services;
4
5 use FluentBooking\App\App;
6 use FluentBooking\App\Models\Booking;
7 use FluentBooking\App\Services\Libs\Emogrifier\Emogrifier;
8 use FluentBooking\Framework\Support\Arr;
9
10 class EmailNotificationService
11 {
12 /**
13 * @param \FluentBooking\App\Models\Booking $booking
14 * @param $email
15 * @param $emailTo
16 * @param $actionType
17 * @return bool|mixed
18 */
19 public static function emailOnBooked(Booking $booking, $email, $emailTo, $actionType = 'scheduled', $resending = false)
20 {
21 $emailSubject = EditorShortCodeParser::parse($email['subject'], $booking);
22 $emailBody = EditorShortCodeParser::parse($email['body'], $booking);
23
24 $globalSettings = Helper::getGlobalSettings();
25 $useHostName = Arr::get($globalSettings, 'emailing.use_host_name', 'yes');
26 $useHostEmailOnReply = Arr::get($globalSettings, 'emailing.use_host_email_on_reply', 'yes');
27 $attachIcsFile = Arr::get($globalSettings, 'emailing.attach_ics_on_confirmation', 'no');
28 $settingsFromName = Arr::get($globalSettings, 'emailing.from_name', '');
29 $settingsFromEmail = Arr::get($globalSettings, 'emailing.from_email', '');
30 $settingsReplyToName = Arr::get($globalSettings, 'emailing.reply_to_name', '');
31 $settingsReplyToEmail = Arr::get($globalSettings, 'emailing.reply_to_email', '');
32
33 $attachments = [];
34 if ($attachIcsFile == 'yes' && $actionType == 'scheduled' && !$resending) {
35 $attachments = self::prepareAttachments($booking);
36 }
37
38 $guestAddress = self::getGuestAddress($booking);
39
40 $authors = $booking->getHostsDetails(false);
41
42 if ($emailTo == 'guest') {
43 $authors = [$authors[0]];
44 }
45
46 $result = false;
47 foreach ($authors as $author)
48 {
49 $hostName = '';
50 $hostAddress = $author['email'];
51 if ($author['name']) {
52 $hostName = $author['name'];
53 $hostAddress = sprintf('%1s <%2s>', $author['name'], $author['email']);
54 }
55
56 $settingsFromEmail = $settingsFromEmail ?: $author['email'];
57 $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
58
59 $to = $hostAddress;
60 $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
61 $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
62
63 if ('guest' == $emailTo) {
64 $to = $guestAddress;
65 $replyName = $useHostName == 'no' ? $settingsReplyToName : $hostName;
66 $fromName = $useHostName == 'no' ? $settingsFromName : $hostName;
67
68 $replayToEmail = $useHostEmailOnReply == 'no' ? $settingsReplyToEmail : $author['email'];
69 $replyFromEmail = $useHostEmailOnReply == 'no' ? $settingsFromEmail : $replayToEmail;
70
71 $replyTo = sprintf('%1s <%2s>', $replyName, $replayToEmail);
72 $from = sprintf('%1s <%2s>', $fromName, $replyFromEmail);
73 }
74
75 $headers = self::prepareEmailHeaders($replyTo, $from, $email);
76
77 $body = (string)App::make('view')->make('emails.template', [
78 'email_body' => $emailBody,
79 'email_footer' => self::getGlobalEmailFooter(),
80 ]);
81
82 $emogrifier = new Emogrifier($body);
83 $emogrifier->disableInvisibleNodeRemoval();
84 $body = (string)$emogrifier->emogrify();
85
86 $result = Mailer::send($to, $emailSubject, $body, $headers, $attachments);
87 }
88
89 if ($attachments) {
90 wp_delete_file($attachments[0]);
91 }
92
93 $status = $result ? 'sent' : 'sending failed';
94
95 $title = sprintf(__('Booking %s email %s to %s', 'fluent-booking'), $actionType, $status, $emailTo);
96
97 if ($result) {
98 self::addLog($title, $title, $booking->id);
99 } else {
100 self::addLog($title, $title, $booking->id, 'error');
101 }
102
103 return $result;
104 }
105
106 /**
107 * @param \FluentBooking\App\Models\Booking $booking
108 * @param $email
109 * @param $emailTo
110 * @return bool|mixed
111 */
112 public static function reminderEmail(Booking $booking, $email, $emailTo)
113 {
114 $globalSettings = Helper::getGlobalSettings();
115 $useHostName = Arr::get($globalSettings, 'emailing.use_host_name', 'yes');
116 $useHostEmailOnReply = Arr::get($globalSettings, 'emailing.use_host_email_on_reply', 'yes');
117 $settingsFromName = Arr::get($globalSettings, 'emailing.from_name', '');
118 $settingsFromEmail = Arr::get($globalSettings, 'emailing.from_email', '');
119 $settingsReplyToName = Arr::get($globalSettings, 'emailing.reply_to_name', '');
120 $settingsReplyToEmail = Arr::get($globalSettings, 'emailing.reply_to_email', '');
121
122 $guestAddress = self::getGuestAddress($booking);
123
124 $authors = $booking->getHostsDetails(false);
125
126 if ($emailTo == 'guest') {
127 $authors = [$authors[0]];
128 }
129
130 $result = false;
131 foreach ($authors as $author) {
132 $hostAddress = $author['email'];
133 $hostName = '';
134 if ($author['name']) {
135 $hostName = $author['name'];
136 $hostAddress = sprintf('%1s <%2s>', $author['name'], $author['email']);
137 }
138
139 $settingsFromEmail = $settingsFromEmail ?: $author['email'];
140 $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
141
142 $to = $hostAddress;
143 $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
144 $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
145
146 if ('guest' == $emailTo) {
147 $to = $guestAddress;
148 $replyName = $useHostName == 'no' ? $settingsReplyToName : $hostName;
149 $formName = $useHostName == 'no' ? $settingsFromName : $hostName;
150
151 $replayToEmail = $useHostEmailOnReply == 'no' ? $settingsReplyToEmail : $author['email'];
152 $replyFromEmail = $useHostEmailOnReply == 'no' ? $settingsFromEmail : $replayToEmail;
153
154 $replyTo = sprintf('%1s <%2s>', $replyName, $replayToEmail);
155 $from = sprintf('%1s <%2s>', $formName, $replyFromEmail);
156 }
157
158 $headers = self::prepareEmailHeaders($replyTo, $from, $email);
159
160 $subject = EditorShortCodeParser::parse($email['subject'], $booking);
161 $html = EditorShortCodeParser::parse($email['body'], $booking);
162
163 $body = (string)App::make('view')->make('emails.template', [
164 'email_body' => $html,
165 'email_footer' => self::getGlobalEmailFooter()
166 ]);
167
168 $emogrifier = new Emogrifier($body);
169 $emogrifier->disableInvisibleNodeRemoval();
170 $body = (string)$emogrifier->emogrify();
171
172 $result = Mailer::send($to, $subject, $body, $headers);
173 }
174
175 if (!$result) {
176 return false;
177 }
178
179 $title = __('Reminder Email Sent', 'fluent-booking');
180 $description = sprintf(__('Reminder email sent to %s.', 'fluent-booking'), $emailTo);
181 self::addLog($title, $description, $booking->id);
182
183 return true;
184 }
185
186 /**
187 * @param \FluentBooking\App\Models\Booking $booking
188 * @param $email
189 * @param $emailTo
190 * @param $actionType
191 * @return bool|mixed
192 */
193 public static function bookingCancelOrRejectEmail(Booking $booking, $email, $emailTo, $actionType = 'cancel')
194 {
195 $globalSettings = Helper::getGlobalSettings();
196 $useHostName = Arr::get($globalSettings, 'emailing.use_host_name', 'yes');
197 $useHostEmailOnReply = Arr::get($globalSettings, 'emailing.use_host_email_on_reply', 'yes');
198 $settingsFromName = Arr::get($globalSettings, 'emailing.from_name', '');
199 $settingsFromEmail = Arr::get($globalSettings, 'emailing.from_email', '');
200 $settingsReplyToName = Arr::get($globalSettings, 'emailing.reply_to_name', '');
201 $settingsReplyToEmail = Arr::get($globalSettings, 'emailing.reply_to_email', '');
202
203 $guestAddress = self::getGuestAddress($booking);
204
205 $authors = $booking->getHostsDetails(false);
206
207 if ($emailTo == 'guest') {
208 $authors = [$authors[0]];
209 }
210
211 $result = false;
212 foreach ($authors as $author) {
213 $hostAddress = $author['email'];
214 $hostName = '';
215 if ($author['name']) {
216 $hostName = $author['name'];
217 $hostAddress = sprintf('%1s <%2s>', $author['name'], $author['email']);
218 }
219
220 $settingsFromEmail = $settingsFromEmail ?: $author['email'];
221 $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
222
223 $to = $hostAddress;
224 $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
225 $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
226
227 if ('guest' == $emailTo) {
228 $to = $guestAddress;
229 $replyName = $useHostName == 'no' ? $settingsReplyToName : $hostName;
230 $formName = $useHostName == 'no' ? $settingsFromName : $hostName;
231
232 $replayToEmail = $useHostEmailOnReply == 'no' ? $settingsReplyToEmail : $author['email'];
233 $replyFromEmail = $useHostEmailOnReply == 'no' ? $settingsFromEmail : $replayToEmail;
234
235 $replyTo = sprintf('%1s <%2s>', $replyName, $replayToEmail);
236 $from = sprintf('%1s <%2s>', $formName, $replyFromEmail);
237 }
238
239 $headers = self::prepareEmailHeaders($replyTo, $from, $email);
240
241 $subject = EditorShortCodeParser::parse($email['subject'], $booking);
242 $html = EditorShortCodeParser::parse($email['body'], $booking);
243
244 $body = (string)App::make('view')->make('emails.template', [
245 'email_body' => $html,
246 'email_footer' => self::getGlobalEmailFooter()
247 ]);
248
249 $emogrifier = new Emogrifier($body);
250 $emogrifier->disableInvisibleNodeRemoval();
251 $body = (string)$emogrifier->emogrify();
252
253 $result = Mailer::send($to, $subject, $body, $headers);
254 }
255
256 $actionType = $actionType == 'reject' ? __('Rejection', 'fluent-booking') : __('Cancellation', 'fluent-booking');
257
258 $status = $result ? 'sent' : 'sending failed';
259
260 $title = sprintf(__('%s email %s to %s', 'fluent-booking'), $actionType, $status, $emailTo);
261
262 if ($result) {
263 self::addLog($title, $title, $booking->id);
264 } else {
265 self::addLog($title, $title, $booking->id, 'error');
266 }
267
268 return $result;
269 }
270
271 /**
272 * @param \FluentBooking\App\Models\Booking $booking
273 * @param $email
274 * @param $emailTo
275 * @return bool|mixed
276 */
277 public static function bookingRescheduledEmail(Booking $booking, $email, $emailTo)
278 {
279 $globalSettings = Helper::getGlobalSettings();
280 $useHostName = Arr::get($globalSettings, 'emailing.use_host_name', 'yes');
281 $useHostEmailOnReply = Arr::get($globalSettings, 'emailing.use_host_email_on_reply', 'yes');
282 $attachIcsFile = Arr::get($globalSettings, 'emailing.attach_ics_on_confirmation', 'no');
283 $settingsFromName = Arr::get($globalSettings, 'emailing.from_name', '');
284 $settingsFromEmail = Arr::get($globalSettings, 'emailing.from_email', '');
285 $settingsReplyToName = Arr::get($globalSettings, 'emailing.reply_to_name', '');
286 $settingsReplyToEmail = Arr::get($globalSettings, 'emailing.reply_to_email', '');
287
288 $attachments = [];
289 if ($attachIcsFile == 'yes') {
290 $attachments = self::prepareAttachments($booking);
291 }
292
293 $guestAddress = self::getGuestAddress($booking);
294
295 $authors = $booking->getHostsDetails(false);
296
297 if ($emailTo == 'guest') {
298 $authors = [$authors[0]];
299 }
300
301 $result = false;
302 foreach ($authors as $author) {
303 $hostAddress = $author['email'];
304 $hostName = '';
305 if ($author['name']) {
306 $hostName = $author['name'];
307 $hostAddress = sprintf('%1s <%2s>', $author['name'], $author['email']);
308 }
309
310 $settingsFromEmail = $settingsFromEmail ?: $author['email'];
311 $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
312
313 $to = $hostAddress;
314 $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
315 $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
316
317 if ('guest' == $emailTo) {
318 $to = $guestAddress;
319 $replyName = $useHostName == 'no' ? $settingsReplyToName : $hostName;
320 $formName = $useHostName == 'no' ? $settingsFromName : $hostName;
321
322 $replayToEmail = $useHostEmailOnReply == 'no' ? $settingsReplyToEmail : $author['email'];
323 $replyFromEmail = $useHostEmailOnReply == 'no' ? $settingsFromEmail : $replayToEmail;
324
325 $replyTo = sprintf('%1s <%2s>', $replyName, $replayToEmail);
326 $from = sprintf('%1s <%2s>', $formName, $replyFromEmail);
327 }
328
329 $headers = self::prepareEmailHeaders($replyTo, $from, $email);
330
331 $subject = EditorShortCodeParser::parse($email['subject'], $booking);
332 $html = EditorShortCodeParser::parse($email['body'], $booking);
333
334 $body = (string)App::make('view')->make('emails.template', [
335 'email_body' => $html,
336 'email_footer' => self::getGlobalEmailFooter()
337 ]);
338
339 $emogrifier = new Emogrifier($body);
340 $emogrifier->disableInvisibleNodeRemoval();
341 $body = (string)$emogrifier->emogrify();
342
343 $result = Mailer::send($to, $subject, $body, $headers, $attachments);
344 }
345
346 if ($attachments) {
347 wp_delete_file($attachments[0]);
348 }
349
350 $status = $result ? 'sent' : 'sending failed';
351
352 $title = sprintf(__('Rescheduled booking email %s to $s', 'fluent-booking'), $status, $emailTo);
353
354 $description = sprintf(__('Rescheduling email %s to %s', 'fluent-booking'), $status, $emailTo);
355
356 if ($result) {
357 self::addLog($title, $description, $booking->id);
358 } else {
359 self::addLog($title, $description, $booking->id, 'error');
360 }
361
362 return $result;
363 }
364
365 private static function getGuestAddress($booking)
366 {
367 $guestAddress = $booking->email;
368 if ($booking->first_name && $booking->last_name) {
369 $guestAddress = sprintf('%1s %2s <%3s>', $booking->first_name, $booking->last_name, $booking->email);
370 } else if ($booking->first_name) {
371 $guestAddress = sprintf('%1s <%2s>', $booking->first_name, $booking->email);
372 }
373
374 if ($additionalGuests = $booking->getAdditionalGuests()) {
375 $guestAddress .= ', ' . implode(', ', $additionalGuests);
376 }
377 return $guestAddress;
378 }
379
380 private static function prepareEmailHeaders($replyTo, $from, $email)
381 {
382 $headers = [
383 'Reply-To: ' . $replyTo
384 ];
385
386 if ($from) {
387 $headers[] = 'From: ' . $from;
388 }
389
390 if (isset($email['recipients'])) {
391 $headers[] = 'bcc: ' . implode(', ', $email['recipients']);
392 }
393
394 return $headers;
395 }
396
397 private static function prepareAttachments($booking)
398 {
399 if (!WP_Filesystem()) {
400 return [];
401 }
402
403 $icsContent = BookingService::generateBookingICS($booking);
404
405 $filePath = wp_tempnam(null, 'event') . '.ics';
406
407 global $wp_filesystem;
408 $wp_filesystem->put_contents($filePath, $icsContent);
409 return [$filePath];
410 }
411
412 protected static function addLog($title, $description, $bookingId, $type = 'activity')
413 {
414 do_action('fluent_booking/log_booking_note', [
415 'title' => $title,
416 'description' => $description,
417 'booking_id' => $bookingId,
418 'type' => $type,
419 ]);
420 }
421
422 public static function getGlobalEmailFooter()
423 {
424 $globalSettings = Helper::getGlobalSettings();
425
426 return Arr::get($globalSettings, 'emailing.email_footer', '');
427 }
428
429 }
430