From f95dd31ad3d2fecf11ae0201b45cf1cc5eb91393 Mon Sep 17 00:00:00 2001 From: Alex Tselegidis Date: Sat, 16 Jul 2016 16:33:34 +0200 Subject: [PATCH] Created new Email notifications class with dynamic mail system configuration. --- src/engine/Notifications/Email.php | 253 +++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 src/engine/Notifications/Email.php diff --git a/src/engine/Notifications/Email.php b/src/engine/Notifications/Email.php new file mode 100644 index 00000000..3c7ed1bd --- /dev/null +++ b/src/engine/Notifications/Email.php @@ -0,0 +1,253 @@ + + * @copyright Copyright (c) 2013 - 2016, Alex Tselegidis + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link http://easyappointments.org + * @since v1.2.0 + * ---------------------------------------------------------------------------- */ + +namespace EA\Engine\Notifications; + +use \EA\Engine\Types\String; +use \EA\Engine\Types\Url; +use \EA\Engine\Types\Email as EmailAddress; + +/** + * Email Notifications Class + * + * This library handles all the notification email deliveries on the system. + * + * Important: The email configuration settings are located at: /application/config/email.php + */ +class Email { + /** + * Framework Instance + * + * @var CI_Controller + */ + protected $framework; + + /** + * PHPMailer Instance + * + * @var PHPMailer + */ + protected $mailer; + + /** + * Class Constructor + * + * @param CI_Controller $framework + * @param array $config Contains the email configuration to be used. + */ + public function __construct(\CI_Controller $framework, array $config) { + $this->framework = $framework; + + $mailer = new \PHPMailer; + + if ($config['protocol'] === 'smtp') { + $mailer->isSMTP(); + $mailer->Host = $config['smtp_host']; + $mailer->SMTPAuth = true; + $mailer->Username = $config['smtp_user']; + $mailer->Password = $config['smtp_pass']; + $mailer->SMTPSecure = $config['smtp_crypto']; + $mailer->Port = $config['smtp_port']; + } + + $mailer->IsHTML($config['mailtype'] === 'html'); + $mailer->CharSet = $config['charset']; + + $this->mailer = $mailer; + } + + /** + * Replace the email template variables. + * + * This method finds and replaces the html variables of an email template. It is used to + * generate dynamic HTML emails that are send as notifications to the system users. + * + * @param array $replaceArray Array that contains the variables to be replaced. + * @param string $templateHtml The email template HTML. + * + * @return string Returns the new email html that contain the variables of the $replaceArray. + */ + protected function _replaceTemplateVariables(array $replaceArray, $templateHtml) { + foreach($replaceArray as $name => $value) { + $templateHtml = str_replace($name, $value, $templateHtml); + } + + return $templateHtml; + } + + /** + * Send an email with the appointment details. + * + * This email template also needs an email title and an email text in order to complete + * the appointment details. + * + * @param array $appointment Contains the appointment data. + * @param array $provider Contains the provider data. + * @param array $service Contains the service data. + * @param array $customer Contains the customer data. + * @param array $company Contains settings of the company. By the time the + * "company_name", "company_link" and "company_email" values are required in the array. + * @param \EA\Engine\Types\String $title The email title may vary depending the receiver. + * @param \EA\Engine\Types\String $message The email message may vary depending the receiver. + * @param \EA\Engine\Types\Url $appointmentLink This link is going to enable the receiver to make changes + * to the appointment record. + * @param \EA\Engine\Types\Email $recipientEmail The recipient email address. + */ + public function sendAppointmentDetails(array $appointment, array $provider, array $service, + array $customer, array $company, String $title, String $message, Url $appointmentLink, + EmailAddress $recipientEmail) { + + // Prepare template replace array. + $replaceArray = array( + '$email_title' => $title->get(), + '$email_message' => $message->get(), + '$appointment_service' => $service['name'], + '$appointment_provider' => $provider['first_name'] . ' ' . $provider['last_name'], + '$appointment_start_date' => date('d/m/Y H:i', strtotime($appointment['start_datetime'])), + '$appointment_end_date' => date('d/m/Y H:i', strtotime($appointment['end_datetime'])), + '$appointment_link' => $appointmentLink->get(), + '$company_link' => $company['company_link'], + '$company_name' => $company['company_name'], + '$customer_name' => $customer['first_name'] . ' ' . $customer['last_name'], + '$customer_email' => $customer['email'], + '$customer_phone' => $customer['phone_number'], + '$customer_address' => $customer['address'], + + // Translations + 'Appointment Details' => $this->framework->lang->line('appointment_details_title'), + 'Service' => $this->framework->lang->line('service'), + 'Provider' => $this->framework->lang->line('provider'), + 'Start' => $this->framework->lang->line('start'), + 'End' => $this->framework->lang->line('end'), + 'Customer Details' => $this->framework->lang->line('customer_details_title'), + 'Name' => $this->framework->lang->line('name'), + 'Email' => $this->framework->lang->line('email'), + 'Phone' => $this->framework->lang->line('phone'), + 'Address' => $this->framework->lang->line('address'), + 'Appointment Link' => $this->framework->lang->line('appointment_link_title') + ); + + $html = file_get_contents(__DIR__ . '/../../application/views/emails/appointment_details.php'); + $html = $this->_replaceTemplateVariables($replaceArray, $html); + + $this->mailer->From = $company['company_email']; + $this->mailer->FromName = $company['company_name']; + $this->mailer->AddAddress($recipientEmail->get()); + $this->mailer->Subject = $title->get(); + $this->mailer->Body = $html; + + if (!$this->mailer->Send()) { + throw new \RuntimeException('Email could not been sent. Mailer Error (Line ' . __LINE__ . '): ' + . $this->mailer->ErrorInfo); + } + } + + /** + * Send an email notification to both provider and customer on appointment removal. + * + * Whenever an appointment is cancelled or removed, both the provider and customer + * need to be informed. This method sends the same email twice. + * + * IMPORTANT! This method's arguments should be taken + * from database before the appointment record is deleted. + * + * @param array $appointment The record data of the removed appointment. + * @param array $provider The record data of the appointment provider. + * @param array $service The record data of the appointment service. + * @param array $customer The record data of the appointment customer. + * @param array $company Some settings that are required for this function. By now this array must contain + * the following values: "company_link", "company_name", "company_email". + * @param \EA\Engine\Types\Email $recipientEmail The email address of the email recipient. + * @param \EA\Engine\Tyeps\String $reason The reason why the appointment is deleted. + */ + public function sendDeleteAppointment(array $appointment, array $provider, + array $service, array $customer, array $company, EmailAddress $recipientEmail, + String $reason) { + // Prepare email template data. + $replaceArray = array( + '$email_title' => $this->framework->lang->line('appointment_cancelled_title'), + '$email_message' => $this->framework->lang->line('appointment_removed_from_schedule'), + '$appointment_service' => $service['name'], + '$appointment_provider' => $provider['first_name'] . ' ' . $provider['last_name'], + '$appointment_date' => date('d/m/Y H:i', strtotime($appointment['start_datetime'])), + '$appointment_duration' => $service['duration'] . ' minutes', + '$company_link' => $company['company_link'], + '$company_name' => $company['company_name'], + '$customer_name' => $customer['first_name'] . ' ' . $customer['last_name'], + '$customer_email' => $customer['email'], + '$customer_phone' => $customer['phone_number'], + '$customer_address' => $customer['address'], + '$reason' => $reason->get(), + + // Translations + 'Appointment Details' => $this->framework->lang->line('appointment_details_title'), + 'Service' => $this->framework->lang->line('service'), + 'Provider' => $this->framework->lang->line('provider'), + 'Date' => $this->framework->lang->line('start'), + 'Duration' => $this->framework->lang->line('duration'), + 'Customer Details' => $this->framework->lang->line('customer_details_title'), + 'Name' => $this->framework->lang->line('name'), + 'Email' => $this->framework->lang->line('email'), + 'Phone' => $this->framework->lang->line('phone'), + 'Address' => $this->framework->lang->line('address'), + 'Reason' => $this->framework->lang->line('reason') + ); + + $html = file_get_contents(__DIR__ . '/../../application/views/emails/delete_appointment.php'); + $html = $this->_replaceTemplateVariables($replaceArray, $html); + + // Send email to recipient. + $this->mailer->From = $company['company_email']; + $this->mailer->FromName = $company['company_name']; + $this->mailer->AddAddress($recipientEmail->get()); // "Name" argument crushes the phpmailer class. + $this->mailer->Subject = $this->framework->lang->line('appointment_cancelled_title'); + $this->mailer->Body = $html; + + if (!$this->mailer->Send()) { + throw new \RuntimeException('Email could not been sent. Mailer Error (Line ' . __LINE__ . '): ' + . $this->mailer->ErrorInfo); + } + } + + /** + * This method sends an email with the new password of a user. + * + * @param \EA\Engine\Types\String $password Contains the new password. + * @param \EA\Engine\Types\Email $email The receiver's email address. + * @param array $company The company settings to be included in the email. + */ + public function sendPassword(String $password, EmailAddress $recipientEmail, array $company) { + $replaceArray = array( + '$email_title' => $this->framework->lang->line('new_account_password'), + '$email_message' => $this->framework->lang->line('new_password_is'), + '$company_name' => $company['company_name'], + '$company_email' => $company['company_email'], + '$company_link' => $company['company_link'], + '$password' => '' . $password->get() . '' + ); + + $html = file_get_contents(__DIR__ . '/../../application/views/emails/new_password.php'); + $html = $this->_replaceTemplateVariables($replaceArray, $html); + + $this->mailer->From = $company['company_email']; + $this->mailer->FromName = $company['company_name']; + $this->mailer->AddAddress($recipientEmail->get()); // "Name" argument crushes the phpmailer class. + $this->mailer->Subject = $this->framework->lang->line('new_account_password'); + $this->mailer->Body = $html; + + if (!$this->mailer->Send()) { + throw new \RuntimeException('Email could not been sent. Mailer Error (Line ' . __LINE__ . '): ' + . $this->mailer->ErrorInfo); + } + } +}