<?php

require_once ("vmlib/logUtil.inc");
//require_once ("PEAR/Mail.php");
//require_once ("PEAR/Mail/mime.php");
require_once ("vmlib/EmailTemplate.class.inc");

require_once 'vmlib/error.inc';

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

require_once 'PHPMailer/src/Exception.php';
require_once 'PHPMailer/src/PHPMailer.php';
require_once 'PHPMailer/src/SMTP.php';

class Email {

    protected $to;
    protected $cc;
    protected $cci;
    protected $subject;
    protected $body;
    protected $bUseHTML;
    protected $aAttachments;
    protected $mimeVersion = '1.0';
    protected $contentType = 'text/html; charset=utf-8';
    protected $from;
    protected $replyTo;
    protected $xMailer;
    protected $date;
    protected $aObjects;
    protected $aProperties;
    protected $oBd;
    public $oEmailTemplate;
    public $aValues;
    protected $logFileName;

    /*     * ****************************************************

     * **************************************************** */
    /**
	*@construct
	*@param $oBd Database access object
	*@param $iEmailTemplateId ID of the template
	*@param $aProperties Properties of the application
	*@param aObjects Object that initialyze the sending
    *@todo Si vous utilisez cette classe avec chargement par mailStruct : $oBd = null, $iEmailTemaplteId = null, $aObjects = null
	*/
    function __construct($oBd, $iEmailTemplateId, $aProperties, $aObjects) {
        //error_log("contructor start");
        $this->oBd = $oBd;
        $this->aProperties = $aProperties;
        $this->aObjects = $aObjects;
        $this->xMailer = array('PHP/' => phpversion());
        //$this->from = $this->aProperties['nickname_sender'] . '<' . $this->aProperties['mail_sender'] . '>';
        //$this->replyTo = '<>';
        //$this->date = date("D, j M Y H:i:s ");
        $this->aValues = array();
        $this->bUseHTML = true;
        //error_log("before if");
        if(isset($this->aProperties['mail_log_file'])){
            //error_log("if1.1");
            $this->logFileName = $this->aProperties['mail_log_file'];
        } else if (!isset($this->aProperties['mail_log_file']) && isset($this->aProperties['error_log_file'])){
          //error_log("if1.2");
          $this->logFileName = $this->aProperties['error_log_file'];
        } else {
          //error_log("if1.3");
          $this->logFileName = $properties['log_dir'] . "/mail.log";
        }
        //error_log("before if 2");
        if (!empty($iEmailTemplateId)) {
            //error_log("if2");
            $this->loadFromMailTemplate($iEmailTemplateId);
        }
        //error_log("contructor end");
    }

    /*     * ****************************************************
      Envoi un email.
      /Retour : message
     * **************************************************** */

    /* function send() {
      $sErrorMessage = '';
      $crlf = ""; // \n
      //
      $oMime = new Mail_mime(array('eol' => $crlf));
      // Pièce jointe ?
      if (is_array($this->aAttachments) && !empty($this->aAttachments)) {
      foreach ($this->aAttachments as $sAttachment) {
      if (file_exists($sAttachment))
      $oMime->addAttachment($sAttachment, 'application/octet-stream');
      }
      }
      //
      $oMime->setHTMLBody('<html><body>' . $this->body . '</body></html>');
      $aMimeParams = array(
      'text_encoding' => '7bit',
      'text_charset' => 'UTF-8',
      'html_charset' => 'UTF-8',
      'head_charset' => 'UTF-8'
      );
      $sBody = $oMime->get($aMimeParams);
      //
      $aHeaders = array(
      'From' => $this->from,
      'Date' => $this->date,
      'To' => $this->to,
      'Subject' => $this->subject,
      'cc' => $this->cc,
      );
      $aHeaders = $oMime->headers($aHeaders);
      //
      $oMail = new Mail();
      $aSmtp = $oMail->factory('smtp', array(
      'host' => $this->aProperties["smtp_host"],
      'port' => $this->aProperties["smtp_port"],
      'auth' => $this->aProperties["smtp_authentification"],
      'username' => $this->aProperties["smtp_login"],
      'password' => $this->aProperties["smtp_password"]));
      //
      if ($this->to != '') {
      $sDestinataire = $this->to;
      if (!empty($this->cc))
      $sDestinataire .= ',' . $this->cc;
      if (!empty($this->cci))
      $sDestinataire .= ',' . $this->cci;
      $sMail = $aSmtp->send($sDestinataire, $aHeaders, $sBody);
      if (PEAR::isError($sMail)) {
      writeToErrorLog(ERROR_0023 . $this->to . '.');
      writeToErrorLog("Error message : " . $sMail->getMessage() . ".");
      writeToLog("Failed sending email to the following address : " . $this->to . ' et ' . $this->cc, $this->aProperties['mail_log_file']);
      writeToLog("Error message : " . $sMail->getMessage() . '.', $this->aProperties['mail_log_file']);
      $sErrorMessage = $sMail->getMessage();
      } else
      writeToLog("|INFORM|PHP| An email has been sent to the following address : $sDestinataire", $this->aProperties['mail_log_file']);
      }
      //
      return $sErrorMessage;
      } */

    /** 
	*Load an email from an external structure.
	*@param $aMailstruct Structure of the email.
	*	$aMailstruct = [
	*		'to'			=>	(string) comma separated,
	*		'cc'			=>	(string) comma separated,
	*		'cci'			=>	(string) comma separated,
	*		'subject'		=>	(string)
	*		'body'			=>	(string)
	*		'aAttachments'	=>	(array) <path|string>
	*		'bUseHTML'		=>	(boolean) if not explicit is true
	*		]
	*
    */
    function loadFromExernalDataStruct($aMailstruct) {
        //error_log(print_r("start", true));
        //$this->to = $aMailstruct["to"];
        //$this->cc = $aMailstruct["cc"];
        //$this->cci = $aMailstruct["cci"];
        $this->subject = $aMailstruct["subject"];
        $this->body = $aMailstruct["body"];
        $this->aAttachments = $aMailstruct["aAttachments"];
        
        if(isset($aMailstruct["bUseHTML"])){
            $this->bUseHTML = $aMailstruct["bUseHTML"];
        }

        $aMailstruct["to"] = str_replace(chr(13), ',', $aMailstruct["to"]);
        $aMailstruct["cc"] = str_replace(chr(13), ',', $aMailstruct["cc"]);
        $aMailstruct["cci"] = str_replace(chr(13), ',', $aMailstruct["cci"]);
        $this->to = str_replace(';', ',', $aMailstruct["to"]);
        $this->cc = str_replace(';', ',', $aMailstruct["cc"]);
        $this->cci = str_replace(';', ',', $aMailstruct["cci"]);
        //error_log(print_r("end", true));
    }
	
	/**
	*Load an email from a template gtf.
	*@param $iTemplateId Id of the template
	*/
    function loadFromMailTemplate($iTemplateId) {
        require_once("gtf_lib/gtf_object/Order.class.inc");
        $this->oEmailTemplate = new EmailTemplateLib($this->oBd, $iTemplateId, $this->aProperties, $this->aObjects);
        if (!empty($this->oEmailTemplate->name)) {
            if (!empty($this->aObjects)) {
                // Si édition simple : génère le code de l'email
                if (!$this->oEmailTemplate->use_advanced)
                    $this->oEmailTemplate->code = $this->oEmailTemplate->generateCode();
                //	
                eval($this->oEmailTemplate->code);
            }
            $this->to = str_replace(chr(13), ',', $this->to);
            $this->cc = str_replace(chr(13), ',', $this->cc);
            $this->cci = str_replace(chr(13), ',', $this->cci);
            $this->to = str_replace(';', ',', $this->to);
            $this->cc = str_replace(';', ',', $this->cc);
            $this->cci = str_replace(';', ',', $this->cci);
        }
    }

	/**
     * Send an email.
     * @return $sErrorMessage Le message d'erreur
     */
    function send() {
        $mail = new PHPMailer(null);                                    // create instance with try catch
        $sErrorMessage = null;

        $mail->isSMTP();                                                // Set mailer to use SMTP
        //$mail->SMTPDebug = 3;                                         // debugger level (3 all with connection)
        $mail->Debugoutput = function($str, $level) {
            error_log("debug level $level; message: $str");
        };
        $mail->Host = $this->aProperties["smtp_host"];                  // Specify main and backup SMTP servers
        $mail->Port = $this->aProperties["smtp_port"];                  // TCP port to connect to
        $mail->SMTPAuth = $this->aProperties["smtp_authentification"];  // Enable SMTP authentication
        // if authentication add parameter to connect SMTP
        if ($this->aProperties["smtp_authentification"] === true) {
            $mail->AuthType = 'LOGIN';
            $mail->Username = $this->aProperties["smtp_login"];             // SMTP username
            $mail->Password = $this->aProperties["smtp_password"];          // SMTP password
            $mail->SMTPSecure = 'tls';                                      // Enable TLS encryption, `ssl` also accepted (deprecated)
        }
        //error_log("defintion mail");
        $mail->SetFrom($this->aProperties['mail_sender'], $this->aProperties['nickname_sender']);
        //error_log("sender");
        //error_log(print_r($this->to, true));
        // add recipients
        $aTo = array($this->to);
        //error_log("br1");
        if(strpos($this->to, ",") !== false){
          //error_log("br2");
          $aTo = explode(",", $this->to);
        }
        //error_log(print_r($aTo, true));
        if (is_array($aTo) && !empty($aTo)) {
            foreach ($aTo as $sTo) {
                $mail->AddAddress($sTo);
            }
        }
        //error_log("to");
        // add copy recipient
        $aCC = array($this->cc);
        if(strpos($this->cc, ",") !== false){
          $aCC = explode(",", $this->cc);
        }
        if (is_array($aCC) && !empty($aCC)) {
            foreach ($aCC as $sCC) {
                $mail->AddCC($sCC);
            }
        }
        //error_log("cc");
        // add CCI recipient
        $aCCI = array($this->cci);
        if(strpos($this->cci, ",") === false){
          $aCCI = explode(",", $this->cci);
        }
        if (is_array($aCCI) && !empty($aCCI)) {
            foreach ($aCCI as $sCCI) {
                $mail->AddBCC($sCCI);
            }
        }
        //error_log("cci");
        $mail->AddReplyTo($this->aProperties["mail_sender"], $this->aProperties["nickname_sender"]);

        $mail->IsHTML($this->bUseHTML);                                            // Set email format to HTML
        $mail->CharSet = 'UTF-8';

        $mail->Subject = $this->subject;
        //error_log("subject");
        if($this->bUseHTML){
            $this->body = '<html><body>' . $this->body . '</body></html>';
        }
        
        $mail->Body = /* utf8_decode */($this->body);
        //error_log("body");
        // Pièce jointe ?   
        if (is_array($this->aAttachments) && !empty($this->aAttachments)) {
            foreach ($this->aAttachments as $sAttachment) {
                if (file_exists($sAttachment)) {
                    //$mail->addAttachment($path, $name, $encoding = 'base64', $type = 'application/octet-stream');
                    $mail->addAttachment($sAttachment);
                }
            }
        }
        //error_log("pj");
        // Depuis PHP 5.6 -> vérification du certificat SSL.
        if (!$this->aProperties['proxy_check_ssl']) {
            $mail->SMTPOptions = array(
                'ssl' => array(
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                    'allow_self_signed' => true
                )
            );
        }
        //error_log("send");
        //
        if (!$mail->send()) {
            writeToErrorLog(ERROR_0023 . $this->to . '.');
            writeToErrorLog("Error message : " . $mail->ErrorInfo);
            writeToLog("|WARN|PHP|Failed sending email to the following address : " . $this->to . ' and copy to : ' . $this->cc, $this->logFileName);
            $sErrorMessage = $mail->ErrorInfo;
        } else {
            writeToLog("|INFORM|PHP| An email has been sent to the following address : " . $this->to . ' and copy to : ' . $this->cc, $this->logFileName);

            if ($this->aProperties['SaveSentMail'] === true) {
                require_once("gtf_lib/Imap.php");
                $imap = new Imap($this->aProperties['imapBotSender_host'], $this->aProperties['imapBotSender_port'], $this->aProperties['imapBotSender_login'], $this->aProperties['imapBotSender_pwd'], $this->aProperties['imapBotSender_encrypt']);

                if ($imap->isConnected() === false) {
                    writeToLog("|WARN|PHP| can't connect to the IMAP at hostname : " . $this->aProperties['imapBotSender_host'], $this->logFileName);
                } else {
                    $imap->selectFolder("Sent");
                    $imap->saveMessageInSent($mail->getSentMIMEMessage(), "");
                }
            }
        }

        return $sErrorMessage;
    }

}

?>
