<?php
/* =================================================================================
 * License: GPL-2.0 license
 * Author: 众产®  https://ciy.cn/code
 * Version: 0.1.1
 * 

$mail = new \ciy\smtp();
$mail->smtp_server = 'ssl://smtp.xxx.com';
$mail->smtp_port = 465;
$mail->user = 'xxx@ciy.cn';
$mail->pass = '123456';
$param = array();
$param['mailto'] = '345345345@qq.com';
$param['title'] = '邮件标题xxx';
$param['content'] = '支持html的邮件内容';
$retmail = $mail->sendmail($param);
//clog($mail->log);
if(is_string($retmail))
    return errjson($retmail);
====================================================================================*/

namespace ciy;

class smtp {
    public $smtp_server = '';
    public $smtp_port = 465;
    public $timeout = 30;
    public $user = '';
    public $pass = '';
    public $log = '';
    private $sock = false;
    function __construct() {
    }
    function sendmail($param) {
        $mailto = $param['mailto']; // a@b.c,d@b.c
        $title = $param['title'];
        $content = $param['content'];
        $cc = isset($param['cc']) ? $param['cc'] : ''; // a@b.c,d@b.c
        $bcc = isset($param['bcc']) ? $param['bcc'] : ''; // a@b.c,d@b.c
        $content = preg_replace("/(^|(\r\n))(\.)/", "\1.\3", $content);
        $header = "MIME-Version:1.0\r\n";
        $header .= "Content-Type:text/html; charset=utf-8\r\n";
        $header .= 'To: ' . $mailto . "\r\n";
        if ($cc != '')
            $header .= 'Cc: ' . $cc . "\r\n";
        $header .= 'From: <' . $this->user . ">\r\n";
        $header .= "Subject: =?UTF-8?B?" . base64_encode($title) . "?=\r\n";
        $header .= 'Reply-To: ' . $this->user . "\r\n";
        //$header .= $additional_headers;
        $header .= 'Date: ' . date('r') . "\r\n";
        $header .= "X-Mailer:By Ciyon 1.0\r\n";
        list($msec, $sec) = explode(' ', microtime());
        $header .= 'Message-ID: <' . date('YmdHis', $sec) . '.' . ($msec * 1000000) . '.' . $this->user . ">\r\n";
        //$header .= "Content-Transfer-Encoding: quoted-printable\r\n";
        //$header .= "X-AliDM-Trace: ". base64_encode(json_encode(['TagName'=>'用户创建的Tag','OpenTrace'=>"1"]))."\r\n";
        $TO = explode(',', $mailto);
        if ($cc != '')
            $TO = array_merge($TO, explode(',', $cc));
        if ($bcc != '')
            $TO = array_merge($TO, explode(',', $bcc));
        foreach ($TO as $rcpt_to) {
            $this->log('Connect ' . $this->smtp_server . ':' . $this->smtp_port);
            $this->sock = @fsockopen($this->smtp_server, $this->smtp_port, $errno, $errstr, $this->timeout);
            if (!($this->sock && $this->checksuccess()))
                return $this->log('connenct fail: ' . $errstr . ' (' . $errno . ')');
            if (!$this->sendcmd('HELO', 'localhost'))
                return $this->log('sending HELO fail');
            if (!$this->sendcmd('AUTH LOGIN', base64_encode($this->user)))
                return $this->log('mail user fail');
            if (!$this->sendcmd(base64_encode($this->pass)))
                return $this->log('password fail');
            if (!$this->sendcmd('MAIL', 'FROM:<' . $this->user . '>'))
                return $this->log('sending MAIL fail');
            if (!$this->sendcmd('RCPT', 'TO:<' . $rcpt_to . '>'))
                return $this->log('sending RCPT fail');
            if (!$this->sendcmd('DATA'))
                return $this->log('sending DATA fail');
            fputs($this->sock, $header . "\r\n" . $content);
            $this->log('>  ' . str_replace("\r\n", "\n" . '>  ', $header . "\n> " . $content . "\n> "));
            fputs($this->sock, "\r\n.\r\n");
            $this->log('. [EOM]');
            if (!$this->checksuccess())
                return $this->log('sending [EOM] fail');
            $this->sendcmd('QUIT');
            fclose($this->sock);
            $this->log('Send OK');
        }
        return true;
    }

    function checksuccess() {
        $response = str_replace("\r\n", '', fgets($this->sock, 512));
        $this->log('<  ' . $response);
        if (!preg_match("/^[23]/", $response)) {
            fputs($this->sock, "QUIT\r\n");
            fgets($this->sock, 512);
            $this->log('Remote host returned: ' . $response);
            return false;
        }
        return true;
    }

    function sendcmd($cmd, $arg = '') {
        if (!empty($arg))
            $cmd .= ' ' . $arg;
        fputs($this->sock, $cmd . "\r\n");
        $this->log('>  ' . $cmd);
        return $this->checksuccess();
    }

    function log($message) {
        $this->log .= $message . "\n";
        return $message;
    }
}
