123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- <?php
- /**
- *
- * Cube Framework $Id$ e6pUWQQEujuO/qzzCywy7l5NUnPu06eGkFtSjAhxspk=
- *
- * @link http://codecu.be/framework
- * @copyright Copyright (c) 2017 CodeCube SRL
- * @license http://codecu.be/framework/license Commercial License
- *
- * @version 1.9 [rev.1.9.01]
- */
- namespace Cube\Mail\Transport;
- /**
- * mailer transport class - using smtp protocol
- *
- * Class Smtp
- *
- * @package Cube\Mail\Transport
- */
- class Smtp extends AbstractTransport
- {
- /**
- * SMTP line break constant.
- *
- * @var string
- */
- const CRLF = "\r\n";
- /**
- *
- * SMTP server connection
- *
- * @var mixed
- */
- protected $_connection = null;
- /**
- *
- * Local client hostname or i.p.
- *
- * @var string
- */
- protected $_name = 'localhost';
- /**
- *
- * Remote smtp hostname or i.p.
- *
- * @var string
- */
- protected $_host;
- /**
- * smtp server port
- *
- * @var int
- */
- protected $_port = 25;
- /**
- *
- * connection protocol "tcp" or "ssl"
- *
- * @var string
- */
- protected $_protocol = 'tcp';
- /**
- *
- * tls
- *
- * @var bool
- */
- protected $_tls = false;
- /**
- *
- * SMTP username
- *
- * @var string
- */
- protected $_username;
- /**
- *
- * SMTP password
- *
- * @var string
- */
- protected $_password;
- /**
- *
- * debug messages
- *
- * @var string
- */
- protected $_debug;
- /**
- *
- * class constructor
- *
- * @param string $host
- * @param array $config
- */
- public function __construct($host = 'localhost', array $config = array())
- {
- parent::__construct($config);
- $this->setHost($host);
- }
- /**
- *
- * get local server name
- *
- * @return string
- */
- public function getName()
- {
- return $this->_name;
- }
- /**
- *
- * set local server name
- *
- * @param string $name
- */
- public function setName($name)
- {
- $this->_name = $name;
- }
- /**
- *
- * get remote smtp hostname
- *
- * @return string
- */
- public function getHost()
- {
- return $this->_host;
- }
- /**
- *
- * set remote smtp hostname
- *
- * @param string $host
- *
- * @return $this
- */
- public function setHost($host)
- {
- $this->_host = $host;
- return $this;
- }
- /**
- *
- * get smtp port
- *
- * @return int
- */
- public function getPort()
- {
- return $this->_port;
- }
- /**
- *
- * set remote smtp port
- *
- * 7.8: if port is 465, use ssl
- *
- * @param int $port
- *
- * @return $this
- */
- public function setPort($port)
- {
- $this->_port = $port;
- if ($port == '465') {
- $this->setProtocol('ssl');
- }
- return $this;
- }
- /**
- *
- * get secure string
- *
- * @return string
- */
- public function getProtocol()
- {
- return $this->_protocol;
- }
- /**
- *
- * set protocol
- *
- * @param string $protocol
- *
- * @return $this
- */
- public function setProtocol($protocol)
- {
- if ('tls' == $protocol) {
- $this->_protocol = 'tcp';
- $this->_tls = true;
- }
- else {
- $this->_protocol = $protocol;
- $this->_tls = false;
- }
- return $this;
- }
- /**
- *
- * get smtp username
- *
- * @return string
- */
- public function getUsername()
- {
- return $this->_username;
- }
- /**
- *
- * set smtp username
- *
- * @param string $username
- *
- * @return $this
- */
- public function setUsername($username)
- {
- $this->_username = $username;
- return $this;
- }
- /**
- *
- * get smtp password
- *
- * @return string
- */
- public function getPassword()
- {
- return $this->_password;
- }
- /**
- *
- * set smtp password
- *
- * @param string $password
- *
- * @return $this
- */
- public function setPassword($password)
- {
- $this->_password = $password;
- return $this;
- }
- /**
- *
- * get output messages from the smtp server
- *
- * @return string
- */
- public function getDebug()
- {
- return (string)$this->_debug;
- }
- /**
- *
- * connect method
- *
- * @return bool
- */
- public function connect()
- {
- $hostname = (($this->_protocol == 'ssl') ? 'ssl://' : '') . $this->_host;
- $this->_connection = fsockopen($hostname, $this->_port, $errno, $errstr, 30);
- // response
- if ($this->_getCode() !== 220) {
- return false;
- }
- fputs($this->_connection, 'EHLO ' . $this->_name . "\r\n");
- if ($this->_getCode() !== 250) {
- fputs($this->_connection, 'HELO ' . $this->_name . "\r\n");
- if ($this->_getCode() !== 250) {
- return false;
- }
- }
- if ($this->_tls === true) {
- fputs($this->_connection, 'STARTTLS' . "\r\n");
- if ($this->_getCode() !== 220) {
- return false;
- }
- stream_socket_enable_crypto($this->_connection, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
- fputs($this->_connection, 'EHLO ' . $this->_name . "\r\n");
- if ($this->_getCode() !== 250) {
- fputs($this->_connection, 'HELO ' . $this->_name . "\r\n");
- if ($this->_getCode() !== 250) {
- return false;
- }
- }
- }
- if ($this->_host != 'localhost') {
- fputs($this->_connection, 'AUTH LOGIN' . "\r\n");
- if ($this->_getCode() !== 334) {
- return false;
- }
- fputs($this->_connection, base64_encode($this->_username) . "\r\n");
- if ($this->_getCode() !== 334) {
- return false;
- }
- fputs($this->_connection, base64_encode($this->_password) . "\r\n");
- if ($this->_getCode() !== 235) {
- return false;
- }
- }
- return true;
- }
- /**
- *
- * disconnect method
- *
- * @return $this
- */
- public function disconnect()
- {
- if ($this->isConnection()) {
- $this->_command('QUIT');
- fclose($this->_connection);
- }
- return $this;
- }
- /**
- *
- * check if we have an open connection
- *
- * @1.9: add additional headers
- * @1.9: if message is in html, generate text/plain version as well
- *
- * @return bool
- */
- public function isConnection()
- {
- return ($this->_connection) ? true : false;
- }
- /**
- *
- * send mail method
- *
- * @return bool
- */
- public function send()
- {
- $result = false;
- if ($this->connect()) {
- // deliver the email
- $mail = $this->getMail();
- $from = $mail->getFrom();
- $replyTo = $mail->getReplyTo();
- $cc = $mail->getCc();
- $bcc = $mail->getBcc();
- $contentType = $mail->getContentType();
- $charset = $mail->getCharset();
- $body = $mail->getBody();
- foreach ($mail->getTo() as $to) {
- $this->_command("MAIL FROM:<{$from['address']}>");
- $this->_command("RCPT TO:<" . $to['address'] . ">");
- $this->_command("DATA");
- fputs($this->_connection, "To: " . $this->_formatAddress($to) . self::CRLF
- . "From: " . $this->_formatAddress($from) . self::CRLF
- . "Subject: " . $mail->getSubject() . self::CRLF);
- if (count($cc) > 0) {
- fputs($this->_connection, "Cc: {$cc['address']}" . self::CRLF);
- }
- if (count($bcc) > 0) {
- fputs($this->_connection, "Bcc: {$cc['address']}" . self::CRLF);
- }
- if (count($replyTo) > 0) {
- fputs($this->_connection, "Reply-to: {$replyTo['address']}" . self::CRLF);
- }
- fputs($this->_connection, "X-Sender: <{$from['address']}>" . self::CRLF
- . "Return-Path: <{$from['address']}>" . self::CRLF
- . "Errors-To: <{$from['address']}>" . self::CRLF
- . "Date: " . $mail->getDate() . self::CRLF
- . "Message-ID: " . $mail->getMessageId() . self::CRLF
- . "X-Mailer: Cube Framework/SMTP" . self::CRLF
- . "X-Priority: 3" . self::CRLF
- . "MIME-Version: 1.0" . self::CRLF
- . "Content-Type: " . sprintf('%s; charset="%s"', $contentType, $charset) . self::CRLF
- . self::CRLF
- . $body . self::CRLF
- . "." . self::CRLF);
- $this->_getServerResponse();
- }
- $result = true;
- }
- // disconnect
- $this->disconnect();
- // return
- return $result;
- }
- protected function _command($command, $description = null, $result = null)
- {
- $code = null;
- if ($this->isConnection()) {
- fputs($this->_connection, $command . self::CRLF);
- if ($description === null) {
- $description = $command;
- }
- $this->_debug .= '<code>' . $description . '</code>';
- $code = $this->_getCode();
- }
- return ($code === $result) ? true : false;
- }
- /**
- *
- * format an address field
- *
- * @param array $data array of data
- *
- * @return string formatted address
- */
- protected function _formatAddress($data)
- {
- $address = array();
- if (array_key_exists('address', $data)) {
- $data = array($data);
- }
- foreach ((array)$data as $field) {
- if (isset($field['name'])) {
- $address[] = $field['name'] . ' <' . $field['address'] . '>';
- }
- else {
- $address[] = $field['address'];
- }
- }
- return implode('; ', $address);
- }
- /**
- *
- * get server response
- *
- * @return string
- */
- protected function _getServerResponse()
- {
- $response = "";
- while ($str = fgets($this->_connection, 4096)) {
- $response .= $str;
- if (substr($str, 3, 1) == " ") {
- break;
- }
- }
- $this->_debug .= '<code>' . $response . '</code><br/>';
- return $response;
- }
- /**
- *
- * get the code from the server response
- *
- * @return int
- */
- protected function _getCode()
- {
- // filter code from response
- return (int)substr($this->_getServerResponse(), 0, 3);
- }
- }
|