* @copyright Since 2013 Ovidiu Cimpean * @license Do not edit, modify or copy this file * * @version Release: 4 */ /* Swfit Version 5.3.1 */ require_once dirname(__FILE__).'/../libraries/swift/swift_required.php'; if ((int) pqnp_ini_config('swift_init')) { require_once dirname(__FILE__).'/../libraries/swift/swift_init.php'; } require_once dirname(__FILE__).'/NewsletterProTemplateDecoratorReplacements.php'; class NewsletterProMail extends NewsletterProMailSwift implements NewsletterProMailInterface { public $failed_recipients = []; public $charset = 'UTF-8'; private $message; private $template_name; private $attachment_exists; public function __construct($id = null) { parent::__construct($id); $this->context = Context::getContext(); $this->module = NewsletterPro::getInstance(); $this->attachment_exists = false; if ('tls' != Tools::strtolower($this->encryption) && 'ssl' != Tools::strtolower($this->encryption)) { $this->encryption = false; } if ('' == trim($this->from_name)) { $this->from_name = (string) $this->context->shop->name; } if ('' == trim($this->reply_to)) { $this->reply_to = (string) $this->from_email; } } public function mimeEncodeTo($to) { if (is_array($to)) { foreach ($to as $address => $name) { if (!is_int($address)) { $to[$address] = self::mimeEncode($name); } } } return $to; } private function validateEmail(&$email) { $invalid_to_email_message = $this->module->l('The email address "%s" is not valid.'); if (is_array($email)) { foreach ($email as $address => $name) { if (is_int($address)) { // in this case name is email if (!NewsletterPro_Swift_Validate::email($name)) { if (1 == count($email)) { $this->addError(sprintf($invalid_to_email_message, $name)); return false; } else { $this->failed_recipients[] = $name; unset($email[$address]); } } } else { if (!NewsletterPro_Swift_Validate::email($address)) { if (1 == count($email)) { $this->addError(sprintf($invalid_to_email_message, $address)); return false; } else { $this->failed_recipients[] = $address; unset($email[$address]); } } } } } elseif (!NewsletterPro_Swift_Validate::email($email)) { $this->addError(sprintf($invalid_to_email_message, $email)); return false; } return true; } private function validateSubject($subject) { if (!Validate::isMailSubject($subject)) { $this->addError($this->module->l('Invalid email subject.')); return false; } return true; } public function newSwiftTransport() { if (self::METHOD_MAIL == $this->method) { return NewsletterPro_Swift_MailTransport::newInstance(); } elseif (self::METHOD_SMTP == $this->method) { return NewsletterPro_Swift_SmtpTransport::newInstance() ->setHost($this->server) ->setPort($this->port) ->setEncryption($this->getEncryption()) ->setUsername($this->user) ->setPassword($this->passwd); } throw new Exception(NewsletterPro::getInstance()->l('Invalid mail method.')); } public function newSwiftMessage() { $message = NewsletterPro_Swift_Message::newInstance()->setCharset($this->charset)->setFrom([$this->from_email => $this->from_name])->setSender([$this->from_email => $this->from_name])->setReplyTo([$this->reply_to => $this->from_name]); $type = $message->getHeaders()->get('Content-Type'); $type->setValue('text/html'); $type->setParameter('charset', 'utf-8'); return $message; } public function newSwiftMailer($transport = null) { return NewsletterPro_Swift_Mailer::newInstance(isset($transport) ? $transport : $this->newSwiftTransport()); } public function getSentFaildRecipients() { return $this->failed_recipients; } public function setTemplateNameForAttachment($template_name) { $this->template_name = $template_name; } /** * Send one email * This method accept also multiple to emails, but is not recommended. * * @param string $subject Email subject * @param string $template Email html template * @param array/string $to Email to * * @return bool Retrun true if the email was successfuly sent */ public function send($subject, $template, $to, &$failed_recipients = []) { $this->failed_recipients = $failed_recipients; $num_sent = 0; try { if (!$this->validateSubject($subject)) { return 0; } if (!$this->validateEmail($to)) { return 0; } $to = $this->mimeEncodeTo($to); $transport = $this->newSwiftTransport(); $message = $this->message = NewsletterPro_Swift_Message::newInstance()->setCharset($this->charset)->setContentType('text/html')->setFrom([$this->from_email => $this->from_name])->setSender([$this->from_email => $this->from_name])->setReplyTo([$this->reply_to => $this->from_name])->setTo($to)->setSubject($subject); if ((int) $this->list_unsubscribe_active) { self::setHeaderListUnsubscribe($message, self::getEmailFromTo($to), null, null, $this->list_unsubscribe_email); } $content = []; $embed = new NewsletterProEmbedImages($template); $template = $embed->getTemplate(); $attachments = NewsletterProMailAttachment::get($this->template_name); $content[] = NewsletterPro_Swift_MimePart::newInstance($template, 'text/html'); if ((bool) pqnp_config('EMAIL_MIME_TEXT')) { $content[] = NewsletterPro_Swift_MimePart::newInstance(NewsletterProHtmlToText::convert($template), 'text/plain'); } $message->setChildren(array_merge($content, $embed->getImages(), $attachments)); $mailer = NewsletterPro_Swift_Mailer::newInstance($transport); $num_sent = $mailer->send($message, $this->failed_recipients); if (!$num_sent) { if (self::METHOD_MAIL == $this->method) { $this->addError(sprintf($this->module->l('Failed to send the email. The problem can be related with the %s function.'), 'php mail()')); } else { if (!function_exists('proc_open') && self::METHOD_SMTP == $this->method) { $this->addError(sprintf($this->module->l('Failed to send the email. The problem is related with the %s function and is happen only if you use the SMTP method. You need to contact your hosting provider to solve the problem with that function.'), 'php proc_open')); } else { $this->addError($this->module->l('Failed to send the email.')); } } } } catch (NewsletterPro_Swift_RfcComplianceException $e) { $this->addError($e->getMessage()); } return (int) $num_sent; } /** * Send the newsletter to the forwarders * If a forwarder exists in the database, will be deleted from the forwarder list. * * @param array/string $from The forwarder email * * @return bool Retrun true if the email was successfuly sent */ public function sendForward($data, $type, $from, $sleep = 1) { $errors_status = []; try { if ($forwards = NewsletterProForward::getForwarders($from)) { $email_info = self::getEmailInfo($from); $fwd_recipients = new NewsletterProForwardRecipients(); $fwd_recipients->add([$email_info['name'] => $email_info['email']], $forwards); $fwd_recipients->buildForwardersRecursive($email_info['email']); $recipients = $fwd_recipients->getRecipients(); foreach ($recipients as $parent_email => $child_emails) { $this->from_name = $fwd_recipients->getRecipientName($parent_email); $this->from_email = $parent_email; foreach ($child_emails as $email) { if ($template = $this->getTemplate($email, $data, $type)) { $template->setForwarder(true); $template->setForwarderData([ 'is_forwarder' => 1, 'forwarder_email' => $email_info['email'], ]); $template_content = $template->getContent(); $subject = $template_content['render']['title']; $render = $template_content['render']['full']; if (pqnp_config('DEBUG_MODE')) { $send = $this->send($subject, $render, $email); } else { $send = @$this->send($subject, $render, $email); } if ($send) { $this->addSuccessFwd($email); } else { $errors_status[] = true; } sleep($sleep); } } } return empty($errors_status); } } catch (Exception $e) { $this->addError($e->getMessage()); } return !$this->hasErrors(); } /** * Get email info. * * @param array/string $email Name and Email address * * @return array */ public static function getEmailInfo($email) { if (is_array($email)) { reset($email); $from_email = key($email); $from_name = $email[$from_email]; if (!Validate::isMailName($from_name)) { $from_name = ''; } } else { $from_name = ''; $from_email = $email; } return [ 'name' => $from_name, 'email' => $from_email, ]; } /** * Extract the full name and email from the user object. * * @param object $user The user object * * @return array/string User full name and email address */ public static function getToFromUser($user) { $to = $user->email; if (Tools::strlen($user->firstname) > 0) { $current_encode_fn = mb_detect_encoding($user->firstname, 'UTF-8, ISO-8859-1, ISO-8859-15, HTML-ENTITIES', true); $firstname = mb_convert_encoding($user->firstname, 'UTF-8', $current_encode_fn); $current_encode_ln = mb_detect_encoding($user->lastname, 'UTF-8, ISO-8859-1, ISO-8859-15, HTML-ENTITIES', true); $lastname = mb_convert_encoding($user->lastname, 'UTF-8', $current_encode_ln); $to = [$user->email => self::mimeEncode($firstname.' '.$lastname)]; } return $to; } public static function mimeEncode($string, $charset = 'UTF-8', $newline = "\r\n") { if (function_exists('mb_encode_mimeheader')) { return mb_encode_mimeheader($string, $charset); } return Mail::mimeEncode($string, $charset, $newline); } public static function getEmailFromTo($to) { if (is_array($to)) { $kyes = array_keys($to); $to_email = $kyes[0]; if (is_int($to_email)) { $values = array_values($to); $to_email = $values[0]; } } else { $to_email = $to; } return $to_email; } public static function setHeaderListUnsubscribe(&$message, $email, $id_lang, $id_shop = null, $mail_to = null) { $context = Context::getContext(); $module = NewsletterPro::getInstance(); $unsubscribe_link = urldecode($context->link->getModuleLink($module->name, 'unsubscribe', [ 'email' => $email, 'u_token' => Tools::encrypt($email), 'msg' => false, ], null, $id_lang, $id_shop)); $headers = &$message->getHeaders(); $u_header = ''; if (isset($mail_to) && Tools::strlen(trim($mail_to)) > 0) { $u_header = ', <'.$unsubscribe_link.'>'; } else { $u_header = '<'.$unsubscribe_link.'>'; } $li_un = $headers->get('List-Unsubscribe'); if (!$li_un) { $headers->addTextHeader('List-Unsubscribe', $u_header); } else { $li_un->setValue($u_header); } } public function toTerminalInfo($default = false) { $output = []; $data = []; if (!$default) { $data = [ 'ID' => $this->id, 'Name' => $this->name, ]; } $data = array_merge($data, [ 'Method' => (self::METHOD_MAIL == $this->method ? 'MAIL' : 'SMTP'), 'From Name' => $this->from_name, 'From Email' => $this->from_email, 'From Reply To' => $this->reply_to, ]); if (self::METHOD_SMTP == $this->method) { $data = array_merge($data, [ 'Domain' => $this->domain, 'Server' => $this->server, 'User' => $this->user, 'Encryption' => Tools::strtoupper($this->encryption), 'Port' => $this->port, 'List-Unsubscribe Active' => $this->list_unsubscribe_active, 'List-Unsubscribe Email' => $this->list_unsubscribe_email, ]); } $max_len = 0; $keys = array_keys($data); foreach ($keys as $key) { if (Tools::strlen($key) > $max_len) { $max_len = Tools::strlen($key); } } foreach ($data as $key => $value) { $diff = $max_len - Tools::strlen($key); if ($diff < 0) { $diff = 0; } $output[] = $key.': '.str_repeat(' ', $diff).$value; } return $output; } }