Expose last SMTP response.

This commit is contained in:
ndm2 2014-03-13 16:28:54 +01:00
parent 5326073c80
commit c1824071c9
2 changed files with 147 additions and 1 deletions

View file

@ -46,6 +46,42 @@ class SmtpTransport extends AbstractTransport {
*/
protected $_content;
/**
* The response of the last sent SMTP command.
*
* @var array
*/
protected $_lastResponse = array();
/**
* Returns the response of the last sent SMTP command.
*
* A response consists of one or more lines containing a response
* code and an optional response message text:
* {{{
* array(
* array(
* 'code' => '250',
* 'message' => 'mail.example.com'
* ),
* array(
* 'code' => '250',
* 'message' => 'PIPELINING'
* ),
* array(
* 'code' => '250',
* 'message' => '8BITMIME'
* ),
* // etc...
* )
* }}}
*
* @return array
*/
public function getLastResponse() {
return $this->_lastResponse;
}
/**
* Send mail
*
@ -88,6 +124,25 @@ class SmtpTransport extends AbstractTransport {
return $this->_config;
}
/**
* Parses and stores the reponse lines in `'code' => 'message'` format.
*
* @param array $responseLines
* @return void
*/
protected function _bufferResponseLines(array $responseLines) {
$response = array();
foreach ($responseLines as $responseLine) {
if (preg_match('/^(\d{3})(?:[\s\-]+(.*))?$/', $responseLine, $match)) {
$response[] = array(
'code' => $match[1],
'message' => isset($match[2]) ? $match[2] : null
);
}
}
$this->_lastResponse = array_merge($this->_lastResponse, $response);
}
/**
* Connect to SMTP Server
*
@ -286,6 +341,8 @@ class SmtpTransport extends AbstractTransport {
* @throws SocketException
*/
protected function _smtpSend($data, $checkCode = '250') {
$this->_lastResponse = array();
if ($data !== null) {
$this->_socket->write($data . "\r\n");
}
@ -301,6 +358,8 @@ class SmtpTransport extends AbstractTransport {
$responseLines = explode("\r\n", rtrim($response, "\r\n"));
$response = end($responseLines);
$this->_bufferResponseLines($responseLines);
if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) {
if ($code[2] === '-') {
continue;

View file

@ -63,7 +63,7 @@ class SmtpTestTransport extends SmtpTransport {
*/
public function __call($method, $args) {
$method = '_' . $method;
return $this->$method();
return call_user_func_array(array($this, $method), $args);
}
}
@ -362,4 +362,91 @@ class SmtpTransportTest extends CakeTestCase {
$this->assertEquals($expected, $result);
}
/**
* testGetLastResponse method
*
* @return void
*/
public function testGetLastResponse() {
$this->assertEmpty($this->SmtpTransport->getLastResponse());
$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250-PIPELINING\r\n"));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250-SIZE 102400000\r\n"));
$this->socket->expects($this->at(6))->method('read')->will($this->returnValue("250-VRFY\r\n"));
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250-ETRN\r\n"));
$this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250-STARTTLS\r\n"));
$this->socket->expects($this->at(9))->method('read')->will($this->returnValue("250-AUTH PLAIN LOGIN\r\n"));
$this->socket->expects($this->at(10))->method('read')->will($this->returnValue("250-AUTH=PLAIN LOGIN\r\n"));
$this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250-ENHANCEDSTATUSCODES\r\n"));
$this->socket->expects($this->at(12))->method('read')->will($this->returnValue("250-8BITMIME\r\n"));
$this->socket->expects($this->at(13))->method('read')->will($this->returnValue("250 DSN\r\n"));
$this->SmtpTransport->connect();
$expected = array(
array('code' => '250', 'message' => 'PIPELINING'),
array('code' => '250', 'message' => 'SIZE 102400000'),
array('code' => '250', 'message' => 'VRFY'),
array('code' => '250', 'message' => 'ETRN'),
array('code' => '250', 'message' => 'STARTTLS'),
array('code' => '250', 'message' => 'AUTH PLAIN LOGIN'),
array('code' => '250', 'message' => 'AUTH=PLAIN LOGIN'),
array('code' => '250', 'message' => 'ENHANCEDSTATUSCODES'),
array('code' => '250', 'message' => '8BITMIME'),
array('code' => '250', 'message' => 'DSN')
);
$result = $this->SmtpTransport->getLastResponse();
$this->assertEquals($expected, $result);
$email = new CakeEmail();
$email->from('noreply@cakephp.org', 'CakePHP Test');
$email->to('cake@cakephp.org', 'CakePHP');
$this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(3))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->setCakeEmail($email);
$this->SmtpTransport->sendRcpt();
$expected = array(
array('code' => '250', 'message' => 'OK'),
);
$result = $this->SmtpTransport->getLastResponse();
$this->assertEquals($expected, $result);
}
/**
* testBufferResponseLines method
*
* @return void
*/
public function testBufferResponseLines() {
$reponseLines = array(
'123',
'FOOBAR',
'250-PIPELINING',
'250-ENHANCEDSTATUSCODES',
'250-8BITMIME',
'250 DSN',
);
$this->SmtpTransport->bufferResponseLines($reponseLines);
$expected = array(
array('code' => '123', 'message' => null),
array('code' => '250', 'message' => 'PIPELINING'),
array('code' => '250', 'message' => 'ENHANCEDSTATUSCODES'),
array('code' => '250', 'message' => '8BITMIME'),
array('code' => '250', 'message' => 'DSN')
);
$result = $this->SmtpTransport->getLastResponse();
$this->assertEquals($expected, $result);
}
}