PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.20
VikAppointments Services Booking Calendar v1.2.20
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / mail / templates / admin.php
vikappointments / site / helpers / libraries / mail / templates Last commit date
admin.php 1 month ago cancellation.php 1 month ago customer.php 1 month ago employee.php 1 month ago index.html 1 month ago packadmin.php 1 month ago package.php 1 month ago stock.php 1 month ago waitlist.php 1 month ago
admin.php
446 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 VAPLoader::import('libraries.mail.template');
15 VAPLoader::import('libraries.order.factory');
16
17 /**
18 * Wrapper used to handle mail notifications for the
19 * administrators after a purchase of an appointment.
20 *
21 * @since 1.7
22 */
23 class VAPMailTemplateAdmin implements VAPMailTemplate
24 {
25 /**
26 * The order object.
27 *
28 * @var VAPOrderAppointment
29 */
30 protected $order;
31
32 /**
33 * An optional template file to use.
34 *
35 * @var string
36 */
37 protected $templateFile;
38
39 /**
40 * An array of options.
41 *
42 * @var array
43 */
44 protected $options;
45
46 /**
47 * Class constructor.
48 *
49 * @param mixed $order Either the order ID or the order object.
50 * @param array $options An array of options.
51 */
52 public function __construct($order, array $options = array())
53 {
54 if (empty($options['lang']))
55 {
56 // always use default language in case it is not specified
57 $options['lang'] = VikAppointments::getDefaultLanguage();
58 }
59
60 if (is_numeric($order))
61 {
62 // recover order details for the given language
63 $this->order = VAPOrderFactory::getAppointments($order, $options['lang']);
64 }
65 else
66 {
67 // use order as provided
68 $this->order = $order;
69 }
70
71 // register options
72 $this->options = $options;
73
74 // load given language to translate template contents
75 VikAppointments::loadLanguage($this->options['lang'], JPATH_SITE);
76 }
77
78 /**
79 * Returns the code of the template before being parsed.
80 *
81 * @param string $file An optional template file to use. If not specified,
82 * the one set in configuration will be used.
83 *
84 * @return void
85 */
86 public function setFile($file)
87 {
88 // use specified template file
89 $this->templateFile = $file;
90
91 // check if a filename or a path was passed
92 if ($file && !is_file($file))
93 {
94 // make sure we have a valid file path
95 $this->templateFile = VAPHELPERS . DIRECTORY_SEPARATOR . 'mail_tmpls' . DIRECTORY_SEPARATOR . $file;
96 }
97 }
98
99 /**
100 * Returns the code of the template before being parsed.
101 *
102 * @return string
103 */
104 public function getTemplate()
105 {
106 // copy order details in a local variable for being used directly
107 // within the template file
108 $order = $this->order;
109
110 if (!$this->templateFile)
111 {
112 // get template file from configuration
113 $file = VAPFactory::getConfig()->get('adminmailtmpl');
114
115 // build template path
116 $this->templateFile = VAPHELPERS . DIRECTORY_SEPARATOR . 'mail_tmpls' . DIRECTORY_SEPARATOR . $file;
117 }
118
119 // make sure the file exists
120 if (!is_file($this->templateFile))
121 {
122 // missing file, return empty string
123 return '';
124 }
125
126 // start output buffering
127 ob_start();
128 // include file to catch its contents
129 include $this->templateFile;
130 // write template contents within a variable
131 $content = ob_get_contents();
132 // clear output buffer
133 ob_end_clean();
134
135 // free space
136 unset($order);
137
138 return $content;
139 }
140
141 /**
142 * Fetches the subject to be used in the e-mail.
143 *
144 * @return string
145 */
146 public function getSubject()
147 {
148 // get company name
149 $fromname = VAPFactory::getConfig()->getString('agencyname');
150
151 /**
152 * Fetch subject.
153 *
154 * @since 1.7.7 Added the possibility to use a custom subject.
155 */
156 $subject = !empty($this->options['subject']) ? $this->options['subject'] : 'VAPADMINEMAILSUBJECT';
157 $subject = JText::sprintf($subject, $fromname);
158
159 // let plugins manipulate the subject for this e-mail template
160 $res = VAPMailFactory::letPluginsManipulateMail('admin', 'subject', $subject, $this->order);
161
162 if ($res === false)
163 {
164 // a plugin prevented the e-mail sending
165 return '';
166 }
167
168 /**
169 * Parse e-mail subject to replace tags with the related order details.
170 *
171 * @since 1.6.6
172 */
173 VikAppointments::parseEmailSubject($subject, $this->order);
174
175 return $subject;
176 }
177
178 /**
179 * Parses the HTML of the template and returns it.
180 *
181 * @return string
182 */
183 public function getHtml()
184 {
185 $config = VAPFactory::getConfig();
186 $currency = VAPFactory::getCurrency();
187
188 // load template HTML
189 $tmpl = $this->getTemplate();
190
191 // fetch payment name
192 if ($this->order->payment)
193 {
194 // use payment name
195 $payment_name = $this->order->payment->name;
196 }
197 else
198 {
199 $payment_name = '';
200 }
201
202 // fetch coupon string
203 if ($this->order->coupon)
204 {
205 $coupon_str = $this->order->coupon->code;
206
207 if ($this->order->coupon->amount > 0)
208 {
209 $coupon_str .= ' : ';
210
211 if ($this->order->coupon->type == 1)
212 {
213 $coupon_str .= $this->order->coupon->amount . '%';
214 }
215 else
216 {
217 $coupon_str .= $currency->format($this->order->coupon->amount);
218 }
219 }
220 }
221 else
222 {
223 $coupon_str = '';
224 }
225
226 $vik = VAPApplication::getInstance();
227
228 // fetch order link HREF
229 $order_link_href = "index.php?option=com_vikappointments&view=order&ordnum={$this->order->id}&ordkey={$this->order->sid}";
230 $order_link_href = $vik->routeForExternalUse($order_link_href);
231
232 // fetch confirmation link HREF
233 $confirmation_link_href = "index.php?option=com_vikappointments&view=order&task=order.confirm&id={$this->order->id}&conf_key={$this->order->conf_key}";
234 $confirmation_link_href = $vik->routeForExternalUse($confirmation_link_href);
235
236 // fetch company logo image
237 $logo_str = $config->get('companylogo');
238
239 if ($logo_str && is_file(VAPMEDIA . DIRECTORY_SEPARATOR . $logo_str))
240 {
241 $logo_str = JHtml::fetch('vaphtml.media.display', $logo_str, [
242 'alt' => $config->get('agencyname'),
243 'small' => false,
244 'style' => 'max-width: 100%;',
245 ]);
246 }
247 else
248 {
249 $logo_str = '';
250 }
251
252 // get name chunks
253 $customerNameChunks = preg_split("/\s+/", (string) $this->order->purchaser_nominative);
254
255 // extract last name from the list
256 $customerLastName = array_pop($customerNameChunks);
257 // join remaining chunks into the first name
258 $customerFirstName = implode(' ', $customerNameChunks);
259
260 if (!$customerFirstName)
261 {
262 // only one name provided, use it as first name
263 $customerFirstName = $customerLastName;
264 $customerLastName = '';
265 }
266
267 // build placeholders lookup
268 $placeholders = array(
269 'logo' => $logo_str,
270 'company_name' => $config->get('agencyname'),
271 'order_number' => $this->order->id,
272 'order_key' => $this->order->sid,
273 'order_status' => JHtml::fetch('vaphtml.status.display', $this->order->status),
274 'order_payment' => $payment_name,
275 'order_total_cost' => $currency->format($this->order->totals->gross),
276 'order_total_net' => $currency->format($this->order->totals->net),
277 'order_total_tax' => $currency->format($this->order->totals->tax),
278 'order_total_discount' => $currency->format($this->order->totals->discount),
279 'order_coupon_code' => $coupon_str,
280 'order_link' => $order_link_href,
281 'confirmation_link' => $confirmation_link_href,
282 'user_name' => $this->order->author ? $this->order->author->name : '',
283 'user_username' => $this->order->author ? $this->order->author->username : '',
284 'user_email' => $this->order->author ? $this->order->author->email : '',
285 'customer_full_name' => $this->order->purchaser_nominative,
286 'customer_first_name' => $customerFirstName,
287 'customer_last_name' => $customerLastName,
288 );
289
290 // get e-mail custom text model
291 $model = JModelVAP::getInstance('mailtext');
292
293 // set up options
294 $options = $this->options;
295 $options['file'] = $this->templateFile;
296
297 // parse e-mail template
298 $tmpl = $model->parseTemplate($tmpl, $this->order, $options);
299
300 // parse e-mail template placeholders
301 foreach ($placeholders as $tag => $value)
302 {
303 $tmpl = str_replace("{{$tag}}", $value, $tmpl);
304 }
305
306 // let plugins manipulate the content for this e-mail template
307 $res = VAPMailFactory::letPluginsManipulateMail('admin', 'content', $tmpl, $this->order);
308
309 if ($res === false)
310 {
311 // a plugin prevented the e-mail sending
312 return '';
313 }
314
315 return $tmpl;
316 }
317
318 /**
319 * Sends the HTML contents via e-mail.
320 *
321 * @return boolean
322 */
323 public function send()
324 {
325 $config = VAPFactory::getConfig();
326
327 // get administrators e-mail
328 $adminmails = VikAppointments::getAdminMailList();
329 // get sender e-mail address
330 $sendermail = VikAppointments::getSenderMail();
331 // get company name
332 $fromname = $config->getString('agencyname');
333
334 // fetch subject
335 $subject = $this->getSubject();
336
337 // parse e-mail template
338 $html = $this->getHtml();
339
340 if (empty($subject) || empty($html))
341 {
342 // do not send e-mail in case the subject or
343 // the content are empty
344 return false;
345 }
346
347 $attachments = array();
348
349 /**
350 * ICS attachment is included only for confirmed appointments.
351 *
352 * @since 1.7
353 */
354 if ($this->order->statusRole == 'APPROVED' && VikAppointments::getAttachmentPropertiesICS('admin'))
355 {
356 // get export ICS file
357 $file = VikAppointments::composeFileICS($this->order->id, $is_admin = true);
358
359 if ($file)
360 {
361 // register into the list with status 0, meaning that
362 // the file is volatile and should be deleted
363 $attachments[$file] = 0;
364 }
365 }
366
367 /**
368 * CSV attachment is included only for confirmed appointments.
369 *
370 * @since 1.7
371 */
372 if ($this->order->statusRole == 'APPROVED' && VikAppointments::getAttachmentPropertiesCSV('admin'))
373 {
374 // get export CSV file
375 $file = VikAppointments::composeFileCSV($this->order->id, $is_admin = true);
376
377 if ($file)
378 {
379 // register into the list with status 0, meaning that
380 // the file is volatile and should be deleted
381 $attachments[$file] = 0;
382 }
383 }
384
385 // iterate files uploaded by the customer
386 foreach (VikAppointments::includeMailAttachments($this->order) as $file)
387 {
388 // Register into the list with status 0, meaning that
389 // the file is volatile and should be deleted. This
390 // because we are attaching a copy of the original file,
391 // which owns a more readable file name.
392 $attachments[$file] = 0;
393 }
394
395 // let plugins manipulate the attachments for this e-mail template
396 $res = VAPMailFactory::letPluginsManipulateMail('admin', 'attachment', $attachments, $this->order);
397
398 $sent = false;
399
400 // make sure the plugin didn't prevent e-mail sending
401 if ($res !== false)
402 {
403 foreach ($adminmails as $recipient)
404 {
405 // send the e-mail notification
406 $sent = VAPApplication::getInstance()->sendMail(
407 $sendermail,
408 $fromname,
409 $recipient,
410 $this->order->purchaser_mail,
411 $subject,
412 $html,
413 array_keys($attachments)
414 ) || $sent;
415 }
416 }
417
418 // destroy any temporary attachment here
419 foreach ($attachments as $file => $keep)
420 {
421 // check if the file exists and it should be deleted
422 if (!$keep && is_file($file))
423 {
424 // permanently delete file
425 unlink($file);
426 }
427 }
428
429 return $sent;
430 }
431
432 /**
433 * Checks whether the notification should be sent.
434 *
435 * @return boolean
436 */
437 public function shouldSend()
438 {
439 // get list of statuses for which the notification should be sent
440 $list = VAPFactory::getConfig()->getArray('mailadminwhen');
441
442 // make sure the order status is contained within the list
443 return in_array($this->order->status, $list);
444 }
445 }
446