cakephp2-php8/lib/Cake/Network/Email/SmtpTransport.php

222 lines
5.3 KiB
PHP
Raw Normal View History

2011-03-01 16:47:05 +00:00
<?php
/**
* Send mail using SMTP protocol
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.Network.Email
2011-03-01 16:47:05 +00:00
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
2011-04-13 03:29:34 +00:00
App::uses('CakeSocket', 'Network');
2011-03-01 16:47:05 +00:00
/**
* SendEmail class
*
* @package Cake.Network.Email
2011-03-01 16:47:05 +00:00
*/
class SmtpTransport extends AbstractTransport {
/**
* Socket to SMTP server
*
* @var object CakeScoket
*/
protected $_socket;
/**
* CakeEmail
*
* @var object CakeEmail
*/
protected $_cakeEmail;
/**
* Send mail
*
* @params object $email CakeEmail
* @return boolean
2011-04-29 01:25:18 +00:00
* @throws SocketException
2011-03-01 16:47:05 +00:00
*/
public function send(CakeEmail $email) {
$this->_cakeEmail = $email;
$this->_connect();
$this->_auth();
$this->_sendRcpt();
$this->_sendData();
$this->_disconnect();
return true;
}
/**
* Set the configuration
*
* @param array $config
* @return object $this
*/
public function config($config = array()) {
$default = array(
'host' => 'localhost',
'port' => 25,
'timeout' => 30,
'username' => null,
'password' => null,
'client' => null
);
$this->_config = $config + $default;
}
2011-03-01 16:47:05 +00:00
/**
* Connect to SMTP Server
*
* @return void
2011-04-29 01:25:18 +00:00
* @throws SocketException
2011-03-01 16:47:05 +00:00
*/
protected function _connect() {
$this->_generateSocket();
if (!$this->_socket->connect()) {
throw new SocketException(__d('cake', 'Unable to connect in SMTP server.'));
2011-03-01 16:47:05 +00:00
}
$this->_smtpSend(null, '220');
if (isset($this->_config['client'])) {
$host = $this->_config['client'];
} elseif ($httpHost = env('HTTP_HOST')) {
list($host) = explode(':', $httpHost);
} else {
$host = 'localhost';
}
try {
$this->_smtpSend("EHLO {$host}", '250');
} catch (SocketException $e) {
try {
$this->_smtpSend("HELO {$host}", '250');
} catch (SocketException $e2) {
throw new SocketException(__d('cake', 'SMTP server not accepted the connection.'));
2011-03-01 16:47:05 +00:00
}
}
}
/**
* Send authentication
*
* @return void
2011-04-29 01:25:18 +00:00
* @throws SocketException
2011-03-01 16:47:05 +00:00
*/
protected function _auth() {
if (isset($this->_config['username']) && isset($this->_config['password'])) {
$authRequired = $this->_smtpSend('AUTH LOGIN', '334|503');
if ($authRequired == '334') {
if (!$this->_smtpSend(base64_encode($this->_config['username']), '334')) {
throw new SocketException(__d('cake', 'SMTP server not accepted the username.'));
2011-03-01 16:47:05 +00:00
}
if (!$this->_smtpSend(base64_encode($this->_config['password']), '235')) {
throw new SocketException(__d('cake', 'SMTP server not accepted the password.'));
2011-03-01 16:47:05 +00:00
}
} elseif ($authRequired != '503') {
throw new SocketException(__d('cake', 'SMTP do not require authentication.'));
2011-03-01 16:47:05 +00:00
}
}
}
/**
* Send emails
*
* @return void
2011-04-29 01:25:18 +00:00
* @throws SocketException
2011-03-01 16:47:05 +00:00
*/
protected function _sendRcpt() {
$from = $this->_cakeEmail->from();
$this->_smtpSend('MAIL FROM:<' . key($from) . '>');
2011-03-01 16:47:05 +00:00
$to = $this->_cakeEmail->to();
$cc = $this->_cakeEmail->cc();
$bcc = $this->_cakeEmail->bcc();
2011-03-01 16:47:05 +00:00
$emails = array_merge(array_keys($to), array_keys($cc), array_keys($bcc));
foreach ($emails as $email) {
$this->_smtpSend('RCPT TO:<' . $email . '>');
2011-03-01 16:47:05 +00:00
}
}
/**
* Send Data
*
* @return void
2011-04-29 01:25:18 +00:00
* @throws SocketException
2011-03-01 16:47:05 +00:00
*/
protected function _sendData() {
$this->_smtpSend('DATA', '354');
$headers = $this->_cakeEmail->getHeaders(array_fill_keys(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), true));
$headers = $this->_headersToString($headers);
$message = implode("\r\n", $this->_cakeEmail->message());
$this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n.");
2011-03-01 16:47:05 +00:00
}
/**
* Disconnect
*
* @return void
2011-04-29 01:25:18 +00:00
* @throws SocketException
2011-03-01 16:47:05 +00:00
*/
protected function _disconnect() {
$this->_smtpSend('QUIT', false);
$this->_socket->disconnect();
}
/**
* Helper method to generate socket
*
* @return void
2011-04-29 01:25:18 +00:00
* @throws SocketException
2011-03-01 16:47:05 +00:00
*/
protected function _generateSocket() {
$this->_socket = new CakeSocket($this->_config);
}
/**
* Protected method for sending data to SMTP connection
*
* @param string $data data to be sent to SMTP server
* @param mixed $checkCode code to check for in server response, false to skip
* @return void
2011-04-29 01:25:18 +00:00
* @throws SocketException
2011-03-01 16:47:05 +00:00
*/
protected function _smtpSend($data, $checkCode = '250') {
2011-03-01 16:47:05 +00:00
if (!is_null($data)) {
$this->_socket->write($data . "\r\n");
}
while ($checkCode !== false) {
$response = '';
$startTime = time();
2011-04-04 02:41:40 +00:00
while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->_config['timeout'])) {
2011-03-01 16:47:05 +00:00
$response .= $this->_socket->read();
}
if (substr($response, -2) !== "\r\n") {
throw new SocketException(__d('cake', 'SMTP timeout.'));
2011-03-01 16:47:05 +00:00
}
$response = end(explode("\r\n", rtrim($response, "\r\n")));
if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) {
if ($code[2] === '-') {
continue;
}
return $code[1];
}
throw new SocketException(__d('cake', 'SMTP Error: %s', $response));
2011-03-01 16:47:05 +00:00
}
}
}