<?php

/* MAIL CLASS FILE
----------------------------------*/

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

define('INSTALL_PATH', __dir__ . '/../../../');
include(INSTALL_PATH . 'control/html-mail-tags.php');

class mailr extends PHPMailer {

  // Protocol..
  public $mailpref = 'smtp';

  // Host..
  public $smtp_host = 'localhost';

  // Port..
  public $smtp_port = 587;

  // User/Pass..
  public $smtp_user = '';
  public $smtp_pass = '';

  // Security..
  public $smtp_sec = '';

  // HTML only tags..
  public $htmltags = [];

  // Subject prefix
  public $sbjpref = '';

  // Mail switch..
  public $mailSwitch = 'yes';

  // Mail tags array...
  public $vars = [];

  // Custom mail headers..
  public $xheaders = [];

  // Attachments..
  public $attachments = [];

  // Settings..
  public $config = [];

  // Parser..
  public $parser;

  // Debug..
  public $debug = 'no';
  private $debug_log_file = 'mail-debug-log.log';

  // HTML elements
  public $htmlelements = array(
    'lang' => 'en',
    'dir' => 'ltr',
    'charset' => 'utf-8'
  );

  // Bypass SSL certs
  public $smtp_insec = 'no';
  
  // Read and parse HTML only tags...
  private function htmlTagParser($data, $plain = 'no') {
    if (!empty($this->htmltags)) {
      foreach ($this->htmltags AS $k => $v) {
        switch($plain) {
          case 'yes':
            $data = str_replace($k, '', $data);
            break;
          case 'no':
            $data = str_replace($k, $v, $data);
            break;
        }
      }
    }
    return trim($data);
  }

  // Converts entities..plain text only..
  private function convertChar($data, $type = 'html') {
    $f_r = array(
      '&#039;' => '\'',
      '&quot;' => '"',
      '&amp;' => '&',
      '&lt;' => '<',
      '&gt;' => '>'
    );
    $data = htmlspecialchars_decode($data);
    if ($type == 'plain') {
      return strtr(mswCD($data), $f_r);
    } else {
      return mswCD($data);
    }
  }

  // Loads tags into array..
  public function addTag($placeholder, $data, $type = 'none') {
    switch($type) {
      case 'none':
        $this->vars[$placeholder] = mswQT($data);
        break;
      default:
        if (in_array($type, array('plain','html'))) {
          $this->vars[$type][$placeholder] = mswQT($data);
        }
        break;
    }
  }

  // Clears data vars..
  public function clearVars() {
    $this->vars = [];
  }

  // Converts tags..
  private function convertTags($data, $type = 'none') {
    if (!empty($this->vars)) {
      switch($type) {
        case 'none':
          foreach ($this->vars AS $tags => $value) {
            $data = str_replace($tags, $value, $data);
          }
          break;
        default:
          if (in_array($type, array('plain','html'))) {
            foreach ($this->vars[$type] AS $tags => $value) {
              $data = str_replace($tags, $value, $data);
            }
          }
          break;
      }
    }
    return $data;
  }

  // Cleans spam/form injection input..
  private function mailRep($data) {
    $find = array(
      "\r","\n","%0a",
      "%0d","content-type:",
      "Content-Type:","BCC:",
      "CC:","boundary=",
      "TO:","bcc:","to:","cc:"
    );
    $replace = [];
    return str_replace($find, $replace, $data);
  }

  // Loads email template..
  public function template($file) {
    // Is this a template or just text?
    if (substr(strtolower($file), -4) == '.txt') {
      return trim(mswTmp($file));
    }
    return $file;
  }

  // HTML mail wrapper..
  public function htmlWrap($mail = []) {
    $msg   = mailr::convertTags($this->template($mail['template']), 'none');
    $parse = explode('<-{separater}->', $msg);
    $head = (count($parse) == 3 ? trim($parse[0]) : mswCD($this->config['website']));
    $cont = (count($parse) == 3 ? trim($parse[1]) : str_replace('<-{separater}->', '', trim($msg)));
    $foot = (count($parse) == 3 ? trim($parse[2]) : mswCD($this->config['ifolder']));
    // Parse html message with wrapper..
    $f_r = array(
      '{LANG}' => $this->htmlelements['lang'],
      '{DIR}' => $this->htmlelements['dir'],
      '{CHARSET}' => $this->htmlelements['charset'],
      '{TITLE}' => mswQT($this->config['website']),
      '{HEADER}' => mswL2BR(mailr::convertChar($this->parser->autoLinkParser($head))),
      '{CONTENT}' => mswL2BR(mailr::convertChar($this->parser->autoLinkParser($cont))),
      '{FOOTER}' => mswL2BR(mailr::convertChar($this->parser->autoLinkParser($foot))) . mswL2BR(mailr::appendFT('html'))
    );
    // Pass all mail vars to the template
    foreach($mail AS $k => $v) {
      if (is_array($v)) {
        if (!empty($v)) {
          foreach($v AS $k2 => $v2) {
            $f_r['{' . strtoupper($k . '_' . $k2) . '}'] = $v2;
          }
        }
      } else {
        $f_r['{' . strtoupper($k) . '}'] = $v;
      }
    }
	// Language override..
    if (isset($mail['language']) && is_dir(INSTALL_PATH . 'content/language/' . $mail['language'])) {
      $this->config['languagePref'] = $mail['language'];
    }
    $html = strtr(mswTmp(INSTALL_PATH . 'content/language/' . $this->config['languagePref'] . '/' . LANG_FLDR_EM . '/html-wrapper.html'), $f_r);
    return $this->htmlTagParser($html);
  }

  // Plain text separator..
  private function plainTxtSep() {
    return str_repeat('-', 75);
  }

  // Plain text mail wrapper..
  public function plainWrap($mail = []) {
    $msg   = mailr::convertChar(mailr::convertTags($this->template($mail['template']), 'none'));
    $parse = explode('<-{separater}->', $msg);
    $head = (count($parse) == 3 ? trim((string) strip_tags((string) $parse[0])) : mswCD(strip_tags((string) $this->config['website'])));
    $cont = (count($parse) == 3 ? trim((string) strip_tags((string) $parse[1])) : trim((string) strip_tags((string) $msg)));
    $foot = (count($parse) == 3 ? trim((string) strip_tags((string) $parse[2])) : mswCD(strip_tags((string) $this->config['ifolder'])));
    if (isset($mail['no-footer'])) {
      $foot = '';
    }
    // Pass all mail vars to the template
    $f_r = [];
    foreach($mail AS $k => $v) {
      if (is_array($v)) {
        if (!empty($v)) {
          foreach($v AS $k2 => $v2) {
            $f_r['{' . strtoupper($k . '_' . $k2) . '}'] = $v2;
          }
        }
      } else {
        $f_r['{' . strtoupper($k) . '}'] = $v;
      }
    }
    $html = $head . mswNL() . mailr::plainTxtSep() . mswNL(2) . $cont . mswNL(2) . mailr::plainTxtSep() . mswNL() . $foot . mailr::appendFT();
    return $this->htmlTagParser(strtr($html, $f_r), 'yes');
  }

  // Footer for free version..
  // Please don`t remove the footer unless you have purchased a licence..
  private function appendFT($type = 'plain') {
    $string = '';
    if (!defined('LICENCE_VER') || LICENCE_VER == 'unlocked') {
      return '';
    }
    switch($type) {
      case 'plain':
        $string  = mswNL(2);
        $string .= 'Free ' . SCRIPT_DESC . ' Powered by ' . SCRIPT_NAME . mswNL();
        $string .= 'https://www.' . SCRIPT_URL;
        break;
      case 'html':
        $string  = mswNL(2);
        $string .= 'Free ' . SCRIPT_DESC . ' Powered by ' . SCRIPT_NAME . mswNL();
        $string .= '<a href="https://www.' . SCRIPT_URL . '">https://www.' . SCRIPT_URL . '</a>';
        break;
    }
    return $string;
  }

  // Sends mail..
  public function sendMail($mail = []) {
    if ($this->mailSwitch == 'yes') {
      try {
        switch($this->mailpref) {
          case 'php':
            $this->isMail();
            break;
          default:
            $this->IsSMTP();
            $this->SMTPAuth   = ($this->smtp_user && $this->smtp_pass ? true : false);
            $this->SMTPSecure = (in_array($this->smtp_sec, array(
              '',
              'tls',
              'ssl'
            )) ? $this->smtp_sec : '');
            // Keep connection alive..
            if (isset($mail['alive'])) {
              $this->SMTPKeepAlive = true;
            }
            // Allow insecure connections?
            if ($this->smtp_insec == 'yes') {
              $this->SMTPOptions = array(
                'ssl' => array(
                  'verify_peer' => false,
                  'verify_peer_name' => false,
                  'allow_self_signed' => true
                )
              );
            }
            // Enable debug..
            if ($this->debug == 'yes') {
              $this->SMTPDebug = 2;
              $this->Debugoutput = function($str, $level) {
                mswPUT(INSTALL_PATH . 'logs/' . $this->debug_log_file, '[' . $level . '] ' . $str . (function_exists('mswNL') ? mswNL() : PHP_EOL));
              };
            }
            break;
        }
        $this->Port = $this->smtp_port;
        $this->Host = $this->smtp_host;
        $this->Username = $this->smtp_user;
        $this->Password = $this->smtp_pass;
        $this->CharSet  = ($this->htmlelements['charset'] ? $this->htmlelements['charset'] : 'utf-8');
        // Custom mail headers..
        if (!empty($this->xheaders)) {
          foreach ($this->xheaders AS $k => $v) {
            $this->addCustomHeader($k . ':' . $v);
          }
        }
        // From/to headers..
        switch($this->mailpref) {
          case 'php':
            $this->setFrom(mailr::mailRep($mail['from_email']), mailr::mailRep(mailr::convertChar($mail['from_name'])));
            $this->addAddress(mailr::mailRep($mail['to_email']), mailr::mailRep(mailr::convertChar($mail['to_name'])));
            break;
          default:
            $this->From     = mailr::mailRep($mail['from_email']);
            $this->FromName = mailr::mailRep(mailr::convertChar($mail['from_name']));
            $this->addAddress(mailr::mailRep($mail['to_email']), mailr::mailRep(mailr::convertChar($mail['to_name'])));
            break;
        }
        // Reply to..
        if (!empty($mail['replyto'])) {
          $this->addReplyTo($mail['replyto']['email'], $mail['replyto']['name']);
        }
        // Additional standard addresses..
        if (isset($mail['add-emails']) && $mail['add-emails']) {
          $addEmails = array_map('trim', explode(',', $mail['add-emails']));
          if (!empty($addEmails)) {
            foreach ($addEmails AS $aAddresses) {
              $this->addAddress(mailr::mailRep($aAddresses), mailr::mailRep(mailr::convertChar($mail['to_name'])));
            }
          }
        }
        // Carbon copy addresses..
        if (!empty($mail['cc'])) {
          foreach ($mail['cc'] AS $cc_email => $cc_name) {
            $this->addCC($cc_email, $cc_name);
          }
        }
        // Blind carbon copy addresses..
        if (!empty($mail['bcc'])) {
          foreach ($mail['bcc'] AS $bcc_email => $bcc_name) {
            $this->addBCC($bcc_email, $bcc_name);
          }
        }
        $this->WordWrap = 1000;
        // X Mailer..
        if (defined('MAIL_X_MAIL_HEADER') && MAIL_X_MAIL_HEADER) {
          $this->XMailer = MAIL_X_MAIL_HEADER;
        }
        // Attachments..
        if (!empty($this->attachments)) {
          foreach ($this->attachments AS $f => $n) {
            $this->addAttachment($f, $n);
          }
        }
        switch($this->mailpref) {
          case 'php':
            $this->Subject  = mailr::convertChar($this->sbjpref . $mail['subject']);
            $this->Body     = mailr::plainWrap($mail);
            break;
          default:
            // Subject..
            $this->Subject  = mailr::convertChar($this->sbjpref . $mail['subject']);
            // Message body..
            $this->msgHTML((isset($mail['template']['html']) ? $mail['template']['html'] : mailr::htmlWrap($mail)));
            $this->AltBody = (isset($mail['template']['plain']) ? $mail['template']['plain'] : mailr::plainWrap($mail));
            break;
        }
        // Send mail..
        $this->send();
        // Clear all recipient data..
        $this->clearReplyTos();
        $this->clearAllRecipients();
      } catch(ErrorException $e) {
        if ($this->debug == 'yes') {
          mswPUT(INSTALL_PATH . 'logs/' . $this->debug_log_file, (isset($this->ErrorInfo) ? (string) $this->ErrorInfo : $e->getMessage()) . (function_exists('mswNL') ? mswNL() : PHP_EOL));
        }
      }
    }
  }

}

//---------------------------------------------------
// Check licence ver - please do not alter or change
//---------------------------------------------------

if (!defined('LICENCE_VER') || !class_exists('mswLic')) {
  die(@base64_decode('U3lzdGVtIGVycm9yLCBwbGVhc2UgY29udGFjdCBNYWlhbk1lZGlhIEAgPGEgaHJlZj0iaHR0cHM6Ly93d3cubWFpYW5tZWRpYS5jb20vY29udGFjdCI+aHR0cHM6Ly93d3cubWFpYW5tZWRpYS5jb20vY29udGFjdDwvYT48YnI+PGJyPlNvcnJ5IGZvciB0aGUgaW5jb252ZW5pZW5jZS4='));
}

?>