- 框架初始化
 - 安装插件
 - 修复PHP8.4报错
This commit is contained in:
2025-04-19 17:21:20 +08:00
commit c6a4e1f5f6
5306 changed files with 967782 additions and 0 deletions

View File

@@ -0,0 +1,209 @@
<?php
/***************************************************\
*
* Mailer (https://github.com/txthinking/Mailer)
*
* A lightweight PHP SMTP mail sender.
* Implement RFC0821, RFC0822, RFC1869, RFC2045, RFC2821
*
* Support html body, don't worry that the receiver's
* mail client can't support html, because Mailer will
* send both text/plain and text/html body, so if the
* mail client can't support html, it will display the
* text/plain body.
*
* Create Date 2012-07-25.
* Under the MIT license.
*
\***************************************************/
namespace Tx;
use Psr\Log\LoggerInterface;
use \Tx\Mailer\Message;
use \Tx\Mailer\SMTP;
/**
* Class Mailer
*
* This class provides the Mailer public methods for backwards compatibility, but it is recommended
* that you use the Tx\Mailer\SMTP and Tx\Mailer\Message classes going forward
*
* @package Tx
*/
class Mailer
{
/**
* SMTP Class
* @var SMTP
*/
protected $smtp;
/**
* Mail Message
* @var Message
*/
protected $message;
/**
* construct function
* @param LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger=null)
{
$this->smtp = new SMTP($logger);
$this->message = new Message();
}
/**
* set server and port
* @param string $host server
* @param int $port port
* @param string $secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2
* @return $this
*/
public function setServer($host, $port, $secure=null)
{
$this->smtp->setServer($host, $port, $secure);
return $this;
}
/**
* auth with server
* @param string $username
* @param string $password
* @return $this
*/
public function setAuth($username, $password)
{
$this->smtp->setAuth($username, $password);
return $this;
}
/**
* auth oauthbearer with server
* @param string $accessToken
* @return $this
*/
public function setOAuth($accessToken)
{
$this->smtp->setOAuth($accessToken);
return $this;
}
/**
* set mail from
* @param string $name
* @param string $email
* @return $this
*/
public function setFrom($name, $email)
{
$this->message->setFrom($name, $email);
return $this;
}
/**
* set fake mail from
* @param string $name
* @param string $email
* @return $this
*/
public function setFakeFrom($name, $email)
{
$this->message->setFakeFrom($name, $email);
return $this;
}
/**
* add mail receiver
* @param string $name
* @param string $email
* @return $this
*/
public function addTo($name, $email)
{
$this->message->addTo($name, $email);
return $this;
}
/**
* add cc mail receiver
* @param string $name
* @param string $email
* @return $this
*/
public function addCc($name, $email)
{
$this->message->addCc($name, $email);
return $this;
}
/**
* add bcc mail receiver
* @param string $name
* @param string $email
* @return $this
*/
public function addBcc($name, $email)
{
$this->message->addBcc($name, $email);
return $this;
}
/**
* set mail subject
* @param string $subject
* @return $this
*/
public function setSubject($subject)
{
$this->message->setSubject($subject);
return $this;
}
/**
* set mail body
* @param string $body
* @return $this
*/
public function setBody($body)
{
$this->message->setBody($body);
return $this;
}
/**
* add mail attachment
* @param $name
* @param $path
* @return $this
*/
public function addAttachment($name, $path)
{
$this->message->addAttachment($name, $path);
return $this;
}
/**
* set mail reply-to
* @param string $name
* @param string $email
* @return $this
*/
public function setReplyTo($name, $email)
{
$this->message->setReplyTo($name, $email);
return $this;
}
/**
* Send the message...
* @return boolean
*/
public function send()
{
return $this->smtp->send($this->message);
}
}

View File

@@ -0,0 +1,40 @@
<?php
/***************************************************\
*
* Mailer (https://github.com/txthinking/Mailer)
*
* A lightweight PHP SMTP mail sender.
* Implement RFC0821, RFC0822, RFC1869, RFC2045, RFC2821
*
* Support html body, don't worry that the receiver's
* mail client can't support html, because Mailer will
* send both text/plain and text/html body, so if the
* mail client can't support html, it will display the
* text/plain body.
*
* Create Date 2012-07-25.
* Under the MIT license.
*
\***************************************************/
/**
* Created by PhpStorm.
* User: msowers
* Date: 3/30/15
* Time: 2:42 PM
*/
namespace Tx\Mailer\Exceptions;
class CodeException extends SMTPException
{
public function __construct($expected, $received, $serverMessage = null)
{
$message = "Unexpected return code - Expected: {$expected}, Got: {$received}";
if (isset($serverMessage)) {
$message .= " | " . $serverMessage;
}
parent::__construct($message);
}
}

View File

@@ -0,0 +1,32 @@
<?php
/***************************************************\
*
* Mailer (https://github.com/txthinking/Mailer)
*
* A lightweight PHP SMTP mail sender.
* Implement RFC0821, RFC0822, RFC1869, RFC2045, RFC2821
*
* Support html body, don't worry that the receiver's
* mail client can't support html, because Mailer will
* send both text/plain and text/html body, so if the
* mail client can't support html, it will display the
* text/plain body.
*
* Create Date 2012-07-25.
* Under the MIT license.
*
\***************************************************/
/**
* Created by PhpStorm.
* User: msowers
* Date: 3/30/15
* Time: 2:48 PM
*/
namespace Tx\Mailer\Exceptions;
class CryptoException extends SMTPException
{
}

View File

@@ -0,0 +1,35 @@
<?php
/***************************************************\
*
* Mailer (https://github.com/txthinking/Mailer)
*
* A lightweight PHP SMTP mail sender.
* Implement RFC0821, RFC0822, RFC1869, RFC2045, RFC2821
*
* Support html body, don't worry that the receiver's
* mail client can't support html, because Mailer will
* send both text/plain and text/html body, so if the
* mail client can't support html, it will display the
* text/plain body.
*
* Create Date 2012-07-25.
* Under the MIT license.
*
\***************************************************/
/**
* Created by PhpStorm.
* User: msowers
* Date: 3/30/15
* Time: 1:51 PM
*/
namespace Tx\Mailer\Exceptions;
class SMTPException extends \Exception
{
public function __construct($message)
{
parent::__construct($message);
}
}

View File

@@ -0,0 +1,31 @@
<?php
/***************************************************\
*
* Mailer (https://github.com/txthinking/Mailer)
*
* A lightweight PHP SMTP mail sender.
* Implement RFC0821, RFC0822, RFC1869, RFC2045, RFC2821
*
* Support html body, don't worry that the receiver's
* mail client can't support html, because Mailer will
* send both text/plain and text/html body, so if the
* mail client can't support html, it will display the
* text/plain body.
*
* Create Date 2012-07-25.
* Under the MIT license.
*
\***************************************************/
/**
* Created by PhpStorm.
* User: msowers
* Date: 3/30/15
* Time: 1:47 PM
*/
namespace Tx\Mailer\Exceptions;
class SendException extends SMTPException
{
}

View File

@@ -0,0 +1,456 @@
<?php
/***************************************************\
*
* Mailer (https://github.com/txthinking/Mailer)
*
* A lightweight PHP SMTP mail sender.
* Implement RFC0821, RFC0822, RFC1869, RFC2045, RFC2821
*
* Support html body, don't worry that the receiver's
* mail client can't support html, because Mailer will
* send both text/plain and text/html body, so if the
* mail client can't support html, it will display the
* text/plain body.
*
* Create Date 2012-07-25.
* Under the MIT license.
*
\***************************************************/
namespace Tx\Mailer;
class Message
{
/**
* from name
*/
protected $fromName;
/**
* from email
*/
protected $fromEmail;
/**
* fake from name
*/
protected $fakeFromName;
/**
* fake from email
*/
protected $fakeFromEmail;
/**
* to email
*/
protected $to = array();
/**
* cc email
*/
protected $cc = array();
/**
* bcc email
*/
protected $bcc = array();
/**
* mail subject
*/
protected $subject;
/**
* mail body
*/
protected $body;
/**
*mail attachment
*/
protected $attachment = array();
/**
* message header
*/
protected $header = array();
/**
* charset
*/
protected $charset = "UTF-8";
/**
* header multipart boundaryMixed
*/
protected $boundaryMixed;
/**
* header multipart alternative
*/
protected $boundaryAlternative;
/**
* $this->CRLF
* @var string
*/
protected $CRLF = "\r\n";
/**
* Address for the reply-to header
* @var string
*/
protected $replyToName;
/**
* Address for the reply-to header
* @var string
*/
protected $replyToEmail;
public function setReplyTo($name, $email)
{
$this->replyToName = $name;
$this->replyToEmail = $email;
return $this;
}
/**
* set mail from
* @param string $name
* @param string $email
* @return $this
*/
public function setFrom($name, $email)
{
$this->fromName = $name;
$this->fromEmail = $email;
return $this;
}
/**
* set mail fake from
* @param string $name
* @param string $email
* @return $this
*/
public function setFakeFrom($name, $email)
{
$this->fakeFromName = $name;
$this->fakeFromEmail = $email;
return $this;
}
/**
* add mail receiver
* @param string $name
* @param string $email
* @return $this
*/
public function addTo($name, $email)
{
$this->to[$email] = $name;
return $this;
}
/**
* add cc mail receiver
* @param string $name
* @param string $email
* @return $this
*/
public function addCc($name, $email)
{
$this->cc[$email] = $name;
return $this;
}
/**
* add bcc mail receiver
* @param string $name
* @param string $email
* @return $this
*/
public function addBcc($name, $email)
{
$this->bcc[$email] = $name;
return $this;
}
/**
* set mail subject
* @param string $subject
* @return $this
*/
public function setSubject($subject)
{
$this->subject = $subject;
return $this;
}
/**
* set mail body
* @param string $body
* @return $this
*/
public function setBody($body)
{
$this->body = $body;
return $this;
}
/**
* add mail attachment
* @param $name
* @param $path
* @return $this
*/
public function addAttachment($name, $path)
{
$this->attachment[$name] = $path;
return $this;
}
/**
* @return string
*/
public function getFromName()
{
return $this->fromName;
}
/**
* @return string
*/
public function getFromEmail()
{
return $this->fromEmail;
}
/**
* @return string
*/
public function getFakeFromName()
{
return $this->fakeFromName;
}
/**
* @return string
*/
public function getFakeFromEmail()
{
return $this->fakeFromEmail;
}
/**
* @return mixed
*/
public function getTo()
{
return $this->to;
}
/**
* @return mixed
*/
public function getCc()
{
return $this->cc;
}
/**
* @return mixed
*/
public function getBcc()
{
return $this->bcc;
}
/**
* @return mixed
*/
public function getSubject()
{
return $this->subject;
}
/**
* @return mixed
*/
public function getBody()
{
return $this->body;
}
/**
* @return array
*/
public function getAttachment()
{
return $this->attachment;
}
/**
* Create mail header
* @return $this
*/
protected function createHeader()
{
$this->header['Date'] = date('r');
$fromName = "";
$fromEmail = $this->fromEmail;
if(!empty($this->fromName)){
$fromName = sprintf("=?utf-8?B?%s?= ", base64_encode($this->fromName));
}
if(!empty($this->fakeFromEmail)){
if(!empty($this->fakeFromName)){
$fromName = sprintf("=?utf-8?B?%s?= ", base64_encode($this->fakeFromName));
}
$fromEmail = $this->fakeFromEmail;
}
$this->header['Return-Path'] = $fromEmail;
$this->header['From'] = $fromName . "<" . $fromEmail .">";
$this->header['To'] = '';
foreach ($this->to as $toEmail => $toName) {
if(!empty($toName)){
$toName = sprintf("=?utf-8?B?%s?= ", base64_encode($toName));
}
$this->header['To'] .= $toName . "<" . $toEmail . ">, ";
}
$this->header['To'] = substr($this->header['To'], 0, -2);
$this->header['Cc'] = '';
foreach ($this->cc as $toEmail => $toName) {
if(!empty($toName)){
$toName = sprintf("=?utf-8?B?%s?= ", base64_encode($toName));
}
$this->header['Cc'] .= $toName . "<" . $toEmail . ">, ";
}
$this->header['Cc'] = substr($this->header['Cc'], 0, -2);
$this->header['Bcc'] = '';
foreach ($this->bcc as $toEmail => $toName) {
if(!empty($toName)){
$toName = sprintf("=?utf-8?B?%s?= ", base64_encode($toName));
}
$this->header['Bcc'] .= $toName . "<" . $toEmail . ">, ";
}
$this->header['Bcc'] = substr($this->header['Bcc'], 0, -2);
$replyToName = "";
if(!empty($this->replyToEmail)){
if(!empty($this->replyToName)){
$replyToName = sprintf("=?utf-8?B?%s?= ", base64_encode($this->replyToName));
}
$this->header['Reply-To'] = $replyToName . "<" . $this->replyToEmail . ">";
}
if(empty($this->subject)){
$subject = '';
}else{
$subject = sprintf("=?utf-8?B?%s?= ", base64_encode($this->subject));
}
$this->header['Subject'] = $subject;
$this->header['Message-ID'] = '<' . md5(uniqid()) . $this->fromEmail . '>';
$this->header['X-Priority'] = '3';
$this->header['X-Mailer'] = 'Mailer (https://github.com/txthinking/Mailer)';
$this->header['MIME-Version'] = '1.0';
if (!empty($this->attachment)){
$this->boundaryMixed = md5(md5(time().'TxMailer').uniqid());
$this->header['Content-Type'] = "multipart/mixed; \r\n\tboundary=\"" . $this->boundaryMixed . "\"";
}
$this->boundaryAlternative = md5(md5(time().'TXMailer').uniqid());
return $this;
}
/**
* @brief createBody create body
*
* @return string
*/
protected function createBody()
{
$in = "";
$in .= "Content-Type: multipart/alternative; boundary=\"$this->boundaryAlternative\"" . $this->CRLF;
$in .= $this->CRLF;
$in .= "--" . $this->boundaryAlternative . $this->CRLF;
$in .= "Content-Type: text/plain; charset=\"" . $this->charset . "\"" . $this->CRLF;
$in .= "Content-Transfer-Encoding: base64" . $this->CRLF;
$in .= $this->CRLF;
$in .= chunk_split(base64_encode($this->body)) . $this->CRLF;
$in .= $this->CRLF;
$in .= "--" . $this->boundaryAlternative . $this->CRLF;
$in .= "Content-Type: text/html; charset=\"" . $this->charset ."\"" . $this->CRLF;
$in .= "Content-Transfer-Encoding: base64" . $this->CRLF;
$in .= $this->CRLF;
$in .= chunk_split(base64_encode($this->body)) . $this->CRLF;
$in .= $this->CRLF;
$in .= "--" . $this->boundaryAlternative . "--" . $this->CRLF;
return $in;
}
/**
* @brief createBodyWithAttachment create body with attachment
*
* @return string
*/
protected function createBodyWithAttachment()
{
$in = "";
$in .= $this->CRLF;
$in .= $this->CRLF;
$in .= '--' . $this->boundaryMixed . $this->CRLF;
$in .= "Content-Type: multipart/alternative; boundary=\"$this->boundaryAlternative\"" . $this->CRLF;
$in .= $this->CRLF;
$in .= "--" . $this->boundaryAlternative . $this->CRLF;
$in .= "Content-Type: text/plain; charset=\"" . $this->charset . "\"" . $this->CRLF;
$in .= "Content-Transfer-Encoding: base64" . $this->CRLF;
$in .= $this->CRLF;
$in .= chunk_split(base64_encode($this->body)) . $this->CRLF;
$in .= $this->CRLF;
$in .= "--" . $this->boundaryAlternative . $this->CRLF;
$in .= "Content-Type: text/html; charset=\"" . $this->charset ."\"" . $this->CRLF;
$in .= "Content-Transfer-Encoding: base64" . $this->CRLF;
$in .= $this->CRLF;
$in .= chunk_split(base64_encode($this->body)) . $this->CRLF;
$in .= $this->CRLF;
$in .= "--" . $this->boundaryAlternative . "--" . $this->CRLF;
foreach ($this->attachment as $name => $path){
$in .= $this->CRLF;
$in .= '--' . $this->boundaryMixed . $this->CRLF;
$in .= "Content-Type: application/octet-stream; name=\"". $name ."\"" . $this->CRLF;
$in .= "Content-Transfer-Encoding: base64" . $this->CRLF;
$in .= "Content-Disposition: attachment; filename=\"" . $name . "\"" . $this->CRLF;
$in .= $this->CRLF;
$in .= chunk_split(base64_encode(file_get_contents($path))) . $this->CRLF;
}
$in .= $this->CRLF;
$in .= $this->CRLF;
$in .= '--' . $this->boundaryMixed . '--' . $this->CRLF;
return $in;
}
public function toString()
{
$in = '';
$this->createHeader();
foreach ($this->header as $key => $value) {
$in .= $key . ': ' . $value . $this->CRLF;
}
if (empty($this->attachment)) {
$in .= $this->createBody();
} else {
$in .= $this->createBodyWithAttachment();
}
$in .= $this->CRLF . $this->CRLF . "." . $this->CRLF;
return $in;
}
}

View File

@@ -0,0 +1,492 @@
<?php
/***************************************************\
*
* Mailer (https://github.com/txthinking/Mailer)
*
* A lightweight PHP SMTP mail sender.
* Implement RFC0821, RFC0822, RFC1869, RFC2045, RFC2821
*
* Support html body, don't worry that the receiver's
* mail client can't support html, because Mailer will
* send both text/plain and text/html body, so if the
* mail client can't support html, it will display the
* text/plain body.
*
* Create Date 2012-07-25.
* Under the MIT license.
*
\***************************************************/
namespace Tx\Mailer;
use Psr\Log\LoggerInterface;
use Tx\Mailer\Exceptions\CodeException;
use Tx\Mailer\Exceptions\CryptoException;
use Tx\Mailer\Exceptions\SMTPException;
class SMTP
{
/**
* smtp socket
*/
protected $smtp;
/**
* smtp server
*/
protected $host;
/**
* smtp server port
*/
protected $port;
/**
* smtp secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2
*/
protected $secure;
/**
* smtp allow insecure ssl
*/
protected $allowInsecure;
/**
* EHLO message
*/
protected $ehlo;
/**
* smtp username
*/
protected $username;
/**
* smtp password
*/
protected $password;
/**
* oauth access token
*/
protected $oauthToken;
/**
* $this->CRLF
* @var string
*/
protected $CRLF = "\r\n";
/**
* @var Message
*/
protected $message;
/**
* @var LoggerInterface - Used to make things prettier than self::$logger
*/
protected $logger;
/**
* Stack of all commands issued to SMTP
* @var array
*/
protected $commandStack = array();
/**
* Stack of all results issued to SMTP
* @var array
*/
protected $resultStack = array();
public function __construct(LoggerInterface $logger=null)
{
$this->logger = $logger;
}
/**
* set server and port
* @param string $host server
* @param int $port port
* @param string $secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2
* @return $this
*/
public function setServer($host, $port, $secure=null, $allowInsecure=null)
{
$this->host = $host;
$this->port = $port;
$this->secure = $secure;
$this->allowInsecure = $allowInsecure;
if(!$this->ehlo) $this->ehlo = $host;
$this->logger && $this->logger->debug("Set: the server");
return $this;
}
/**
* auth login with server
* @param string $username
* @param string $password
* @return $this
*/
public function setAuth($username, $password)
{
$this->username = $username;
$this->password = $password;
$this->logger && $this->logger->debug("Set: the auth login");
return $this;
}
/**
* auth oauthbearer with server
* @param string $accessToken
* @return $this
*/
public function setOAuth($accessToken)
{
$this->oauthToken = $accessToken;
$this->logger && $this->logger->debug("Set: the auth oauthbearer");
return $this;
}
/**
* set the EHLO message
* @param $ehlo
* @return $this
*/
public function setEhlo($ehlo)
{
$this->ehlo = $ehlo;
return $this;
}
/**
* Send the message
*
* @param Message $message
* @return bool
* @throws CodeException
* @throws CryptoException
* @throws SMTPException
*/
public function send(Message $message)
{
$this->logger && $this->logger->debug('Set: a message will be sent');
$this->message = $message;
$this->connect()
->ehlo();
if ($this->secure === 'tls' || $this->secure === 'tlsv1.0' || $this->secure === 'tlsv1.1' | $this->secure === 'tlsv1.2') {
$this->starttls()
->ehlo();
}
if ($this->username !== null || $this->password !== null) {
$this->authLogin();
} elseif ($this->oauthToken !== null) {
$this->authOAuthBearer();
}
$this->mailFrom()
->rcptTo()
->data()
->quit();
return fclose($this->smtp);
}
/**
* connect the server
* SUCCESS 220
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function connect()
{
$this->logger && $this->logger->debug("Connecting to {$this->host} at {$this->port}");
$host = ($this->secure == 'ssl') ? 'ssl://' . $this->host : $this->host;
// Create connection
$context = null;
if ($this->allowInsecure) {
$context = stream_context_create([
'ssl' => [
'security_level' => 0,
'verify_peer' => false,
'verify_peer_name' => false
]
]);
} else {
$context = stream_context_create();
}
$this->smtp = stream_socket_client(
$host.':'.$this->port,
$error_code,
$error_message,
ini_get('default_socket_timeout'),
STREAM_CLIENT_CONNECT,
$context
);
//set block mode
// stream_set_blocking($this->smtp, 1);
if (!$this->smtp){
throw new SMTPException("Could not open SMTP Port.");
}
$code = $this->getCode();
if ($code !== '220'){
throw new CodeException('220', $code, array_pop($this->resultStack));
}
return $this;
}
/**
* SMTP STARTTLS
* SUCCESS 220
* @return $this
* @throws CodeException
* @throws CryptoException
* @throws SMTPException
*/
protected function starttls()
{
$in = "STARTTLS" . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '220'){
throw new CodeException('220', $code, array_pop($this->resultStack));
}
if ($this->secure !== 'tls' && version_compare(phpversion(), '5.6.0', '<')) {
throw new CryptoException('Crypto type expected PHP 5.6 or greater');
}
switch ($this->secure) {
case 'tlsv1.0':
$crypto_type = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT;
break;
case 'tlsv1.1':
$crypto_type = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
break;
case 'tlsv1.2':
$crypto_type = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
break;
default:
$crypto_type = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT |
STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT |
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
break;
}
if(!\stream_socket_enable_crypto($this->smtp, true, $crypto_type)) {
throw new CryptoException("Start TLS failed to enable crypto");
}
return $this;
}
/**
* SMTP EHLO
* SUCCESS 250
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function ehlo()
{
$in = "EHLO " . $this->ehlo . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '250'){
throw new CodeException('250', $code, array_pop($this->resultStack));
}
return $this;
}
/**
* SMTP AUTH LOGIN
* SUCCESS 334
* SUCCESS 334
* SUCCESS 235
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function authLogin()
{
$in = "AUTH LOGIN" . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '334'){
throw new CodeException('334', $code, array_pop($this->resultStack));
}
$in = base64_encode($this->username) . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '334'){
throw new CodeException('334', $code, array_pop($this->resultStack));
}
$in = base64_encode($this->password) . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '235'){
throw new CodeException('235', $code, array_pop($this->resultStack));
}
return $this;
}
/**
* SMTP AUTH OAUTHBEARER
* SUCCESS 235
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function authOAuthBearer()
{
$authStr = sprintf("n,a=%s,%shost=%s%sport=%s%sauth=Bearer %s%s%s",
$this->message->getFromEmail(),
chr(1),
$this->host,
chr(1),
$this->port,
chr(1),
$this->oauthToken,
chr(1),
chr(1)
);
$authStr = base64_encode($authStr);
$in = "AUTH OAUTHBEARER $authStr" . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '235'){
throw new CodeException('235', $code, array_pop($this->resultStack));
}
return $this;
}
/**
* SMTP AUTH XOAUTH2
* SUCCESS 235
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function authXOAuth2()
{
$authStr = sprintf("user=%s%sauth=Bearer %s%s%s",
$this->message->getFromEmail(),
chr(1),
$this->oauthToken,
chr(1),
chr(1)
);
$authStr = base64_encode($authStr);
$in = "AUTH XOAUTH2 $authStr" . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '235'){
throw new CodeException('235', $code, array_pop($this->resultStack));
}
return $this;
}
/**
* SMTP MAIL FROM
* SUCCESS 250
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function mailFrom()
{
$in = "MAIL FROM:<{$this->message->getFromEmail()}>" . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '250') {
throw new CodeException('250', $code, array_pop($this->resultStack));
}
return $this;
}
/**
* SMTP RCPT TO
* SUCCESS 250
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function rcptTo()
{
$to = array_merge(
$this->message->getTo(),
$this->message->getCc(),
$this->message->getBcc()
);
foreach ($to as $toEmail=>$_) {
$in = "RCPT TO:<" . $toEmail . ">" . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '250') {
throw new CodeException('250', $code, array_pop($this->resultStack));
}
}
return $this;
}
/**
* SMTP DATA
* SUCCESS 354
* SUCCESS 250
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function data()
{
$in = "DATA" . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '354') {
throw new CodeException('354', $code, array_pop($this->resultStack));
}
$in = $this->message->toString();
$code = $this->pushStack($in);
if ($code !== '250'){
throw new CodeException('250', $code, array_pop($this->resultStack));
}
return $this;
}
/**
* SMTP QUIT
* SUCCESS 221
* @return $this
* @throws CodeException
* @throws SMTPException
*/
protected function quit()
{
$in = "QUIT" . $this->CRLF;
$code = $this->pushStack($in);
if ($code !== '221'){
throw new CodeException('221', $code, array_pop($this->resultStack));
}
return $this;
}
protected function pushStack($string)
{
$this->commandStack[] = $string;
fputs($this->smtp, $string, strlen($string));
$this->logger && $this->logger->debug('Sent: '. $string);
return $this->getCode();
}
/**
* get smtp response code
* once time has three digital and a space
* @return string
* @throws SMTPException
*/
protected function getCode()
{
while ($str = fgets($this->smtp, 515)) {
$this->logger && $this->logger->debug("Got: ". $str);
$this->resultStack[] = $str;
$str = ltrim($str);
if(substr($str,3,1) == " ") {
$code = substr($str,0,3);
return $code;
}
}
throw new SMTPException("SMTP Server did not respond with anything I recognized");
}
}