PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / trunk
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution vtrunk
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
← All changes | app/Services/EmailNotificationService.php +215 -171 1.5.21trunk View file →
@@ -13,8 +13,9 @@
13 13 * @param \FluentBooking\App\Models\Booking $booking
14 14 * @param $email
15 15 * @param $emailTo
16 16 * @param $actionType
17 + * @param bool $resending
17 18 * @return bool|mixed
18 19 */
19 20 public static function emailOnBooked(Booking $booking, $email, $emailTo, $actionType = 'scheduled', $resending = false)
20 21 {
@@ -21,10 +22,10 @@
21 22 $emailSubject = EditorShortCodeParser::parse($email['subject'], $booking);
22 23 $emailBody = EditorShortCodeParser::parse($email['body'], $booking);
23 24
24 25 $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');
26 + $useHostName = Arr::get($globalSettings, 'emailing.use_host_name', 'no');
27 + $useHostEmailOnReply = Arr::get($globalSettings, 'emailing.use_host_email_on_reply', 'no');
27 28 $attachIcsFile = Arr::get($globalSettings, 'emailing.attach_ics_on_confirmation', 'no');
28 29 $settingsFromName = Arr::get($globalSettings, 'emailing.from_name', '');
29 30 $settingsFromEmail = Arr::get($globalSettings, 'emailing.from_email', '');
30 31 $settingsReplyToName = Arr::get($globalSettings, 'emailing.reply_to_name', '');
@@ -42,64 +43,73 @@
42 43 if ($emailTo == 'guest') {
43 44 $authors = [$authors[0]];
44 45 }
45 46
47 + $to = [];
48 + $from = '';
49 + $replyTo = '';
46 50 $result = false;
47 - foreach ($authors as $author)
48 - {
49 - $hostName = '';
51 +
52 + foreach ($authors as $author) {
53 + $hostName = $author['name'] ?? '';
50 54 $hostAddress = $author['email'];
51 - if ($author['name']) {
52 - $hostName = $author['name'];
53 - $hostAddress = sprintf('%1s <%2s>', $author['name'], $author['email']);
54 - }
55 55
56 56 $settingsFromEmail = $settingsFromEmail ?: $author['email'];
57 57 $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
58 58
59 - $to = $hostAddress;
60 - $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
61 - $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
59 + if ('guest' == $emailTo) {
60 + $to[] = $guestAddress;
61 + $replyName = $useHostName == 'yes' ? $hostName : $settingsReplyToName;
62 + $fromName = $useHostName == 'yes' ? $hostName : $settingsFromName;
62 63
63 - if ('guest' == $emailTo) {
64 - $to = $guestAddress;
65 - $replyName = $useHostName == 'no' ? $settingsReplyToName : $hostName;
66 - $fromName = $useHostName == 'no' ? $settingsFromName : $hostName;
64 + $replyToEmail = $useHostEmailOnReply == 'yes' ? $author['email'] : $settingsReplyToEmail;
65 + $replyFromEmail = $useHostEmailOnReply == 'yes' ? $replyToEmail : $settingsFromEmail;
67 66
68 - $replayToEmail = $useHostEmailOnReply == 'no' ? $settingsReplyToEmail : $author['email'];
69 - $replyFromEmail = $useHostEmailOnReply == 'no' ? $settingsFromEmail : $replayToEmail;
70 -
71 - $replyTo = sprintf('%1s <%2s>', $replyName, $replayToEmail);
67 + $replyTo = sprintf('%1s <%2s>', $replyName, $replyToEmail);
72 68 $from = sprintf('%1s <%2s>', $fromName, $replyFromEmail);
69 + } else {
70 + $to[] = $hostName ? sprintf('%1$s <%2$s>', $hostName, $hostAddress) : $hostAddress;
73 71 }
72 + }
74 73
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);
74 + $to = implode(', ', array_unique($to));
75 +
76 + if ('guest' != $emailTo) {
77 + $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
78 + $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
87 79 }
88 80
89 - if ($attachments) {
90 - wp_delete_file($attachments[0]);
81 + $headers = self::prepareEmailHeaders($replyTo, $from, $email);
82 +
83 + $body = (string)App::make('view')->make('emails.template', [
84 + 'email_body' => $emailBody,
85 + 'email_footer' => self::getGlobalEmailFooter(),
86 + ]);
87 +
88 + $emogrifier = new Emogrifier($body);
89 + $emogrifier->disableInvisibleNodeRemoval();
90 + $body = (string)$emogrifier->emogrify();
91 +
92 + $result = Mailer::send($to, $emailSubject, $body, $headers, $attachments);
93 +
94 + foreach ($attachments as $attachment) {
95 + wp_delete_file($attachment);
91 96 }
92 97
93 - $status = $result ? 'sent' : 'sending failed';
98 + $actionTypeLabel = $actionType == 'request' ? __('request', 'fluent-booking') : __('scheduled', 'fluent-booking');
99 + $recipientLabel = $emailTo == 'guest' ? __('guest', 'fluent-booking') : __('host', 'fluent-booking');
100 + $statusLabel = $result ? __('sent', 'fluent-booking') : __('sending failed', 'fluent-booking');
101 + $logType = $result ? 'activity' : 'error';
94 102
95 - $title = sprintf(__('Booking %s email %s to %s', 'fluent-booking'), $actionType, $status, $emailTo);
103 + $title = sprintf(
104 + /* translators: %1$s: Action type, %2$s: Status, %3$s: Recipient */
105 + __('Booking %1$s email %2$s to %3$s', 'fluent-booking'),
106 + $actionTypeLabel,
107 + $statusLabel,
108 + $recipientLabel
109 + );
96 110
97 - if ($result) {
98 - self::addLog($title, $title, $booking->id);
99 - } else {
100 - self::addLog($title, $title, $booking->id, 'error');
101 - }
111 + self::addLog($title, $title, $booking->id, $logType);
102 112
103 113 return $result;
104 114 }
105 115
@@ -111,10 +121,10 @@
111 121 */
112 122 public static function reminderEmail(Booking $booking, $email, $emailTo)
113 123 {
114 124 $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');
125 + $useHostName = Arr::get($globalSettings, 'emailing.use_host_name', 'no');
126 + $useHostEmailOnReply = Arr::get($globalSettings, 'emailing.use_host_email_on_reply', 'no');
117 127 $settingsFromName = Arr::get($globalSettings, 'emailing.from_name', '');
118 128 $settingsFromEmail = Arr::get($globalSettings, 'emailing.from_email', '');
119 129 $settingsReplyToName = Arr::get($globalSettings, 'emailing.reply_to_name', '');
120 130 $settingsReplyToEmail = Arr::get($globalSettings, 'emailing.reply_to_email', '');
@@ -126,62 +136,75 @@
126 136 if ($emailTo == 'guest') {
127 137 $authors = [$authors[0]];
128 138 }
129 139
140 + $to = [];
141 + $from = '';
142 + $replyTo = '';
130 143 $result = false;
144 +
131 145 foreach ($authors as $author) {
132 146 $hostAddress = $author['email'];
133 - $hostName = '';
134 - if ($author['name']) {
135 - $hostName = $author['name'];
136 - $hostAddress = sprintf('%1s <%2s>', $author['name'], $author['email']);
137 - }
147 + $hostName = $author['name'] ?? '';
138 148
139 149 $settingsFromEmail = $settingsFromEmail ?: $author['email'];
140 150 $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
141 151
142 - $to = $hostAddress;
143 - $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
144 - $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
152 + if ('guest' == $emailTo) {
153 + $to[] = $guestAddress;
154 + $replyName = $useHostName == 'yes' ? $hostName : $settingsReplyToName;
155 + $fromName = $useHostName == 'yes' ? $hostName : $settingsFromName;
145 156
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);
157 + $replyToEmail = $useHostEmailOnReply == 'yes' ? $author['email'] : $settingsReplyToEmail;
158 + $fromEmail = $useHostEmailOnReply == 'yes' ? $replyToEmail : $settingsFromEmail;
159 +
160 + $replyTo = sprintf('%1$s <%2$s>', $replyName, $replyToEmail);
161 + $from = sprintf('%1$s <%2$s>', $fromName, $fromEmail);
162 + } else {
163 + $to[] = $hostName ? sprintf('%1$s <%2$s>', $hostName, $hostAddress) : $hostAddress;
156 164 }
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 165 }
174 166
175 - if (!$result) {
176 - return false;
167 + $to = implode(', ', array_unique($to));
168 +
169 + if ('guest' != $emailTo) {
170 + $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
171 + $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
177 172 }
178 173
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);
174 + $headers = self::prepareEmailHeaders($replyTo, $from, $email);
182 175
183 - return true;
176 + $subject = EditorShortCodeParser::parse($email['subject'], $booking);
177 + $html = EditorShortCodeParser::parse($email['body'], $booking);
178 +
179 + $body = (string)App::make('view')->make('emails.template', [
180 + 'email_body' => $html,
181 + 'email_footer' => self::getGlobalEmailFooter()
182 + ]);
183 +
184 + $emogrifier = new Emogrifier($body);
185 + $emogrifier->disableInvisibleNodeRemoval();
186 + $body = (string)$emogrifier->emogrify();
187 +
188 + $result = Mailer::send($to, $subject, $body, $headers);
189 +
190 + $recipientLabel = $emailTo == 'guest' ? __('guest', 'fluent-booking') : __('host', 'fluent-booking');
191 + $statusLabel = $result ? __('sent', 'fluent-booking') : __('sending failed', 'fluent-booking');
192 + $logType = $result ? 'activity' : 'error';
193 +
194 + $title = sprintf(
195 + /* translators: %1$s: Status, %2$s: Recipient */
196 + __('Booking reminder email %1$s to %2$s', 'fluent-booking'),
197 + $statusLabel,
198 + $recipientLabel
199 + );
200 +
201 + /* translators: %1$s: Status, %2$s: Recipient */
202 + $description = sprintf(__('Reminder email %1$s to %2$s.', 'fluent-booking'), $statusLabel, $recipientLabel);
203 +
204 + self::addLog($title, $description, $booking->id, $logType);
205 +
206 + return $result;
184 207 }
185 208
186 209 /**
187 210 * @param \FluentBooking\App\Models\Booking $booking
@@ -192,10 +215,10 @@
192 215 */
193 216 public static function bookingCancelOrRejectEmail(Booking $booking, $email, $emailTo, $actionType = 'cancel')
194 217 {
195 218 $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');
219 + $useHostName = Arr::get($globalSettings, 'emailing.use_host_name', 'no');
220 + $useHostEmailOnReply = Arr::get($globalSettings, 'emailing.use_host_email_on_reply', 'no');
198 221 $settingsFromName = Arr::get($globalSettings, 'emailing.from_name', '');
199 222 $settingsFromEmail = Arr::get($globalSettings, 'emailing.from_email', '');
200 223 $settingsReplyToName = Arr::get($globalSettings, 'emailing.reply_to_name', '');
201 224 $settingsReplyToEmail = Arr::get($globalSettings, 'emailing.reply_to_email', '');
@@ -207,65 +230,73 @@
207 230 if ($emailTo == 'guest') {
208 231 $authors = [$authors[0]];
209 232 }
210 233
234 + $to = [];
235 + $from = '';
236 + $replyTo = '';
211 237 $result = false;
238 +
212 239 foreach ($authors as $author) {
213 240 $hostAddress = $author['email'];
214 - $hostName = '';
215 - if ($author['name']) {
216 - $hostName = $author['name'];
217 - $hostAddress = sprintf('%1s <%2s>', $author['name'], $author['email']);
241 + $hostName = $author['name'] ?? '';
242 +
243 + $settingsFromEmail = $settingsFromEmail ?: $author['email'];
244 + $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
245 +
246 + if ('guest' == $emailTo) {
247 + $to[] = $guestAddress;
248 + $replyName = $useHostName == 'yes' ? $hostName : $settingsReplyToName;
249 + $fromName = $useHostName == 'yes' ? $hostName : $settingsFromName;
250 +
251 + $replyToEmail = $useHostEmailOnReply == 'yes' ? $author['email'] : $settingsReplyToEmail;
252 + $replyFromEmail = $useHostEmailOnReply == 'yes' ? $replyToEmail : $settingsFromEmail;
253 +
254 + $replyTo = sprintf('%1s <%2s>', $replyName, $replyToEmail);
255 + $from = sprintf('%1s <%2s>', $fromName, $replyFromEmail);
256 + } else {
257 + $to[] = $hostName ? sprintf('%1s <%2s>', $hostName, $hostAddress) : $hostAddress;
218 258 }
259 + }
219 260
220 - $settingsFromEmail = $settingsFromEmail ?: $author['email'];
221 - $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
261 + $to = implode(', ', array_unique($to));
222 262
223 - $to = $hostAddress;
263 + if ('guest' != $emailTo) {
224 264 $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
225 265 $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
266 + }
226 267
227 - if ('guest' == $emailTo) {
228 - $to = $guestAddress;
229 - $replyName = $useHostName == 'no' ? $settingsReplyToName : $hostName;
230 - $formName = $useHostName == 'no' ? $settingsFromName : $hostName;
268 + $headers = self::prepareEmailHeaders($replyTo, $from, $email);
231 269
232 - $replayToEmail = $useHostEmailOnReply == 'no' ? $settingsReplyToEmail : $author['email'];
233 - $replyFromEmail = $useHostEmailOnReply == 'no' ? $settingsFromEmail : $replayToEmail;
270 + $subject = EditorShortCodeParser::parse($email['subject'], $booking);
271 + $html = EditorShortCodeParser::parse($email['body'], $booking);
234 272
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 - }
273 + $body = (string)App::make('view')->make('emails.template', [
274 + 'email_body' => $html,
275 + 'email_footer' => self::getGlobalEmailFooter()
276 + ]);
255 277
256 - $actionType = $actionType == 'reject' ? __('Rejection', 'fluent-booking') : __('Cancellation', 'fluent-booking');
278 + $emogrifier = new Emogrifier($body);
279 + $emogrifier->disableInvisibleNodeRemoval();
280 + $body = (string)$emogrifier->emogrify();
257 281
258 - $status = $result ? 'sent' : 'sending failed';
282 + $result = Mailer::send($to, $subject, $body, $headers);
259 283
260 - $title = sprintf(__('%s email %s to %s', 'fluent-booking'), $actionType, $status, $emailTo);
284 + $actionTypeLabel = $actionType == 'reject' ? __('Rejection', 'fluent-booking') : __('Cancellation', 'fluent-booking');
285 + $recipientLabel = $emailTo == 'guest' ? __('guest', 'fluent-booking') : __('host', 'fluent-booking');
286 + $statusLabel = $result ? __('sent', 'fluent-booking') : __('sending failed', 'fluent-booking');
287 + $logType = $result ? 'activity' : 'error';
261 288
262 - if ($result) {
263 - self::addLog($title, $title, $booking->id);
264 - } else {
265 - self::addLog($title, $title, $booking->id, 'error');
266 - }
289 + $title = sprintf(
290 + /* translators: %1$s: Action type, %2$s: Status, %3$s: Recipient */
291 + __('Booking %1$s email %2$s to %3$s', 'fluent-booking'),
292 + $actionTypeLabel,
293 + $statusLabel,
294 + $recipientLabel
295 + );
267 296
297 + self::addLog($title, $title, $booking->id, $logType);
298 +
268 299 return $result;
269 300 }
270 301
271 302 /**
@@ -276,10 +307,10 @@
276 307 */
277 308 public static function bookingRescheduledEmail(Booking $booking, $email, $emailTo)
278 309 {
279 310 $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');
311 + $useHostName = Arr::get($globalSettings, 'emailing.use_host_name', 'no');
312 + $useHostEmailOnReply = Arr::get($globalSettings, 'emailing.use_host_email_on_reply', 'no');
282 313 $attachIcsFile = Arr::get($globalSettings, 'emailing.attach_ics_on_confirmation', 'no');
283 314 $settingsFromName = Arr::get($globalSettings, 'emailing.from_name', '');
284 315 $settingsFromEmail = Arr::get($globalSettings, 'emailing.from_email', '');
285 316 $settingsReplyToName = Arr::get($globalSettings, 'emailing.reply_to_name', '');
@@ -288,9 +319,9 @@
288 319 $attachments = [];
289 320 if ($attachIcsFile == 'yes') {
290 321 $attachments = self::prepareAttachments($booking);
291 322 }
292 -
323 +
293 324 $guestAddress = self::getGuestAddress($booking);
294 325
295 326 $authors = $booking->getHostsDetails(false);
296 327
@@ -297,68 +328,77 @@
297 328 if ($emailTo == 'guest') {
298 329 $authors = [$authors[0]];
299 330 }
300 331
332 + $to = [];
333 + $from = '';
334 + $replyTo = '';
301 335 $result = false;
336 +
302 337 foreach ($authors as $author) {
303 338 $hostAddress = $author['email'];
304 - $hostName = '';
305 - if ($author['name']) {
306 - $hostName = $author['name'];
307 - $hostAddress = sprintf('%1s <%2s>', $author['name'], $author['email']);
308 - }
339 + $hostName = $author['name'] ?? '';
309 340
310 341 $settingsFromEmail = $settingsFromEmail ?: $author['email'];
311 342 $settingsReplyToEmail = $settingsReplyToEmail ?: $author['email'];
312 343
313 - $to = $hostAddress;
314 - $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
315 - $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
316 -
317 344 if ('guest' == $emailTo) {
318 - $to = $guestAddress;
319 - $replyName = $useHostName == 'no' ? $settingsReplyToName : $hostName;
320 - $formName = $useHostName == 'no' ? $settingsFromName : $hostName;
345 + $to[] = $guestAddress;
346 + $replyName = $useHostName == 'yes' ? $hostName : $settingsReplyToName;
347 + $fromName = $useHostName == 'yes' ? $hostName : $settingsFromName;
321 348
322 - $replayToEmail = $useHostEmailOnReply == 'no' ? $settingsReplyToEmail : $author['email'];
323 - $replyFromEmail = $useHostEmailOnReply == 'no' ? $settingsFromEmail : $replayToEmail;
349 + $replyToEmail = $useHostEmailOnReply == 'yes' ? $author['email'] : $settingsReplyToEmail;
350 + $replyFromEmail = $useHostEmailOnReply == 'yes' ? $replyToEmail : $settingsFromEmail;
324 351
325 - $replyTo = sprintf('%1s <%2s>', $replyName, $replayToEmail);
326 - $from = sprintf('%1s <%2s>', $formName, $replyFromEmail);
352 + $replyTo = sprintf('%1s <%2s>', $replyName, $replyToEmail);
353 + $from = sprintf('%1s <%2s>', $fromName, $replyFromEmail);
354 + } else {
355 + $to[] = $hostName ? sprintf('%1$s <%2$s>', $hostName, $hostAddress) : $hostAddress;
327 356 }
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();
357 + }
342 358
343 - $result = Mailer::send($to, $subject, $body, $headers, $attachments);
359 + $to = implode(', ', array_unique($to));
360 +
361 + if ('guest' != $emailTo) {
362 + $replyTo = sprintf('%1s <%2s>', $settingsReplyToName, $settingsReplyToEmail ?: $settingsFromEmail);
363 + $from = sprintf('%1s <%2s>', $settingsFromName, $settingsFromEmail);
344 364 }
345 365
366 + $headers = self::prepareEmailHeaders($replyTo, $from, $email);
367 +
368 + $subject = EditorShortCodeParser::parse($email['subject'], $booking);
369 + $html = EditorShortCodeParser::parse($email['body'], $booking);
370 +
371 + $body = (string)App::make('view')->make('emails.template', [
372 + 'email_body' => $html,
373 + 'email_footer' => self::getGlobalEmailFooter()
374 + ]);
375 +
376 + $emogrifier = new Emogrifier($body);
377 + $emogrifier->disableInvisibleNodeRemoval();
378 + $body = (string)$emogrifier->emogrify();
379 +
380 + $result = Mailer::send($to, $subject, $body, $headers, $attachments);
381 +
346 382 if ($attachments) {
347 383 wp_delete_file($attachments[0]);
348 384 }
349 385
350 - $status = $result ? 'sent' : 'sending failed';
386 + $statusLabel = $result ? __('sent', 'fluent-booking') : __('sending failed', 'fluent-booking');
387 + $recipientLabel = $emailTo == 'guest' ? __('guest', 'fluent-booking') : __('host', 'fluent-booking');
388 + $logType = $result ? 'activity' : 'error';
351 389
352 - $title = sprintf(__('Rescheduled booking email %s to $s', 'fluent-booking'), $status, $emailTo);
390 + $title = sprintf(
391 + /* translators: %1$s: Status, %2$s: Recipient */
392 + __('Rescheduled booking email %1$s to %2$s', 'fluent-booking'),
393 + $statusLabel,
394 + $recipientLabel
395 + );
353 396
354 - $description = sprintf(__('Rescheduling email %s to %s', 'fluent-booking'), $status, $emailTo);
397 + /* translators: %1$s: Status, %2$s: Recipient */
398 + $description = sprintf(__('Rescheduling email %1$s to %2$s', 'fluent-booking'), $statusLabel, $recipientLabel);
355 399
356 - if ($result) {
357 - self::addLog($title, $description, $booking->id);
358 - } else {
359 - self::addLog($title, $description, $booking->id, 'error');
360 - }
400 + self::addLog($title, $description, $booking->id, $logType);
361 401
362 402 return $result;
363 403 }
364 404
@@ -395,18 +435,22 @@
395 435 }
396 436
397 437 private static function prepareAttachments($booking)
398 438 {
439 + require_once ABSPATH . 'wp-admin/includes/file.php';
440 +
399 441 if (!WP_Filesystem()) {
400 442 return [];
401 443 }
402 444
403 445 $icsContent = BookingService::generateBookingICS($booking);
404 -
405 - $filePath = wp_tempnam(null, 'event') . '.ics';
406 -
446 +
447 + $icsFileName = 'fcal-' . md5(wp_generate_uuid4()) . '.ics';
448 + $filePath = trailingslashit(wp_upload_dir()['path']) . $icsFileName;
449 +
407 450 global $wp_filesystem;
408 451 $wp_filesystem->put_contents($filePath, $icsContent);
452 +
409 453 return [$filePath];
410 454 }
411 455
412 456 protected static function addLog($title, $description, $bookingId, $type = 'activity')