From 77941fb1fba54486efdb38298915e0952d033471 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 27 Feb 2011 15:25:23 -0300 Subject: [PATCH 001/103] Added the skeleton of CakeEmail. --- lib/Cake/Network/CakeEmail.php | 255 ++++++++++++++++++ lib/Cake/tests/Case/Network/CakeEmailTest.php | 52 ++++ 2 files changed, 307 insertions(+) create mode 100644 lib/Cake/Network/CakeEmail.php create mode 100644 lib/Cake/tests/Case/Network/CakeEmailTest.php diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php new file mode 100644 index 000000000..393390306 --- /dev/null +++ b/lib/Cake/Network/CakeEmail.php @@ -0,0 +1,255 @@ +charset = $charset; + } + } + +/** + * Sets headers for the message + * + * @param array Associative array containing headers to be set. + * @return void + */ + public function header($headers) { + foreach ($headers as $header => $value) { + $this->_header[] = sprintf('%s: %s', trim($header), trim($value)); + } + } + +/** + * Send an email using the specified content, template and layout + * + * @return boolean Success + */ + public function send() { + } + +/** + * Reset all EmailComponent internal variables to be able to send out a new email. + * + * @return void + */ + public function reset() { + } + +} diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php new file mode 100644 index 000000000..a6eb55b68 --- /dev/null +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -0,0 +1,52 @@ + + * 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://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests + * @package cake.tests.cases.libs + * @since CakePHP(tm) v 2.0.0 + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + */ +App::import('Core', 'CakeEmail'); + +/** + * CakeEmailTest class + * + * @package cake.tests.cases.libs + */ +class CakeEmailTest extends CakeTestCase { + +/** + * testHeader method + * + * @return void + */ + public function testHeader() { + } + +/** + * testSend method + * + * @return void + */ + public function testSend() { + } + +/** + * testReset method + * + * @return void + */ + public function testReset() { + } + +} From a92092231c98d8d10cd1c935e9c498642152eff7 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 27 Feb 2011 15:57:04 -0300 Subject: [PATCH 002/103] Throwing exception when headers is not an array. --- lib/Cake/Error/exceptions.php | 4 ++-- lib/Cake/Network/CakeEmail.php | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Error/exceptions.php b/lib/Cake/Error/exceptions.php index d178005b6..79c4854c9 100644 --- a/lib/Cake/Error/exceptions.php +++ b/lib/Cake/Error/exceptions.php @@ -459,8 +459,8 @@ class CakeSessionException extends CakeException { } class ConfigureException extends CakeException { } /** - * Exception class for Socket. This exception will be thrown from CakeSocket, HttpSocket and HttpResponse when it - * encounters an error. + * Exception class for Socket. This exception will be thrown from CakeSocket, CakeEmail, HttpSocket + * and HttpResponse when it encounters an error. * * @package cake.libs */ diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 393390306..d48e90557 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -231,6 +231,9 @@ class CakeEmail { * @return void */ public function header($headers) { + if (!is_array($headers)) { + throw new SocketException(__('$headers should be an array.')); + } foreach ($headers as $header => $value) { $this->_header[] = sprintf('%s: %s', trim($header), trim($value)); } From 8f5049e3b1cee5ae85bb019d01adabf43832ae13 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 01:19:47 -0300 Subject: [PATCH 003/103] Initial changes in headers, just draft. --- lib/Cake/Network/CakeEmail.php | 100 ++++++++++-------- lib/Cake/tests/Case/Network/CakeEmailTest.php | 4 +- 2 files changed, 58 insertions(+), 46 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index d48e90557..48be9bd03 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -27,33 +27,40 @@ App::import('Core', array('Validation', 'Multibyte')); * @package cake.libs */ class CakeEmail { +/** + * What mailer should EmailComponent identify itself as + * + * @constant EMAIL_CLIENT + */ + const EMAIL_CLIENT = 'CakePHP Email Component'; + /** * Recipient of the email * * @var string */ - public $to = null; + protected $_to = array(); /** * The mail which the email is sent from * * @var string */ - public $from = null; + protected $_from = array(); /** * The email the recipient will reply to * * @var string */ - public $replyTo = null; + protected $_replyTo = null; /** * The read receipt email * * @var string */ - public $readReceipt = null; + protected $_readReceipt = null; /** * The mail that will be used in case of any errors like @@ -63,7 +70,7 @@ class CakeEmail { * * @var string */ - public $return = null; + protected $_return = null; /** * Carbon Copy @@ -73,7 +80,7 @@ class CakeEmail { * * @var array */ - public $cc = array(); + protected $_cc = array(); /** * Blind Carbon Copy @@ -83,23 +90,14 @@ class CakeEmail { * * @var array */ - public $bcc = array(); - -/** - * The date to put in the Date: header. This should be a date - * conformant with the RFC2822 standard. Leave null, to have - * today's date generated. - * - * @var string - */ - var $date = null; + protected $_bcc = array(); /** * The subject of the email * * @var string */ - public $subject = null; + protected $_subject = null; /** * Associative array of a user defined headers @@ -107,16 +105,7 @@ class CakeEmail { * * @var array */ - public $headers = array(); - -/** - * List of additional headers - * - * These will NOT be used if you are using safemode and mail() - * - * @var string - */ - public $additionalParams = null; + protected $_headers = array(); /** * Layout for the View @@ -185,13 +174,6 @@ class CakeEmail { */ public $attachments = array(); -/** - * What mailer should EmailComponent identify itself as - * - * @var string - */ - public $xMailer = 'CakePHP Email Component'; - /** * The list of paths to search if an attachment isnt absolute * @@ -199,13 +181,6 @@ class CakeEmail { */ public $filePaths = array(); -/** - * Temporary store of message header lines - * - * @var array - */ - protected $_header = array(); - /** * If set, boundary to use for multipart mime messages * @@ -229,14 +204,51 @@ class CakeEmail { * * @param array Associative array containing headers to be set. * @return void + * @thrown SocketException */ - public function header($headers) { + public function setHeaders($headers) { if (!is_array($headers)) { throw new SocketException(__('$headers should be an array.')); } - foreach ($headers as $header => $value) { - $this->_header[] = sprintf('%s: %s', trim($header), trim($value)); + $this->_headers = $headers; + } + +/** + * Add header for the message + * + * @param array $headers + * @return void + * @thrown SocketException + */ + public function addHeaders($headers) { + if (!is_array($headers)) { + throw new SocketException(__('$headers should be an array.')); } + $this->_headers = array_merge($this->_headers, $headers); + } + +/** + * Get list of headers + * + * @param boolean $includeToAndCc + * @param boolean $includeBcc + * @param boolean $includeSubject + * @return array + */ + public function getHeaders($includeToAndCc = false, $includeBcc = false, $includeSubject = false) { + if (!isset($this->_headers['X-Mailer'])) { + $this->_headers['X-Mailer'] = Configure::read('Email.XMailer'); + if (empty($this->_headers['X-Mailer'])) { + $this->_headers['X-Mailer'] = self::EMAIL_CLIENT; + } + } + if (!isset($this->_headers['Date'])) { + $this->_headers['Date'] = date(DATE_RFC2822); + } + if ($includeSubject) { + $this->_headers['Subject'] = $this->_subject; + } + return $this->_headers; } /** diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index a6eb55b68..db3a301bf 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -26,11 +26,11 @@ App::import('Core', 'CakeEmail'); class CakeEmailTest extends CakeTestCase { /** - * testHeader method + * testHeaders method * * @return void */ - public function testHeader() { + public function testHeaders() { } /** From 5cb58e8f9935cbd9b7f4a4180f93d2c83fa8698e Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 01:31:30 -0300 Subject: [PATCH 004/103] Implemented methods to configure "from". --- lib/Cake/Network/CakeEmail.php | 24 +++++++++++++++++ lib/Cake/tests/Case/Network/CakeEmailTest.php | 27 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 48be9bd03..e23b9361e 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -199,6 +199,30 @@ class CakeEmail { } } +/** + * Set From + * + * @param string $email + * @param string $name + * @return void + */ + public function setFrom($email, $name = null) { + if ($name !== null) { + $this->_from = array($email => $name); + } else { + $this->_from = array($email => $email); + } + } + +/** + * Get the From information + * + * @return array Key is email, Value is name. If Key is equal of Value, the name is not specified + */ + public function getFrom() { + return $this->_from; + } + /** * Sets headers for the message * diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index db3a301bf..be613e376 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -25,6 +25,33 @@ App::import('Core', 'CakeEmail'); */ class CakeEmailTest extends CakeTestCase { +/** + * setUp + * + * @return void + */ + public function setUp() { + parent::setUp(); + $this->CakeEmail = new CakeEmail(); + } + +/** + * testFrom method + * + * @return void + */ + public function testFrom() { + $this->assertIdentical($this->CakeEmail->getFrom(), array()); + + $this->CakeEmail->setFrom('cake@cakephp.org'); + $expected = array('cake@cakephp.org' => 'cake@cakephp.org'); + $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + + $this->CakeEmail->setFrom('cake@cakephp.org', 'CakePHP'); + $expected = array('cake@cakephp.org' => 'CakePHP'); + $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + } + /** * testHeaders method * From fae641e6193307fe1826cc1a659c9c45fb2ba419 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 02:09:05 -0300 Subject: [PATCH 005/103] Implemented methods to configure "to". --- lib/Cake/Network/CakeEmail.php | 87 +++++++++++++++++++ lib/Cake/tests/Case/Network/CakeEmailTest.php | 44 ++++++++++ 2 files changed, 131 insertions(+) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index e23b9361e..8df30071f 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -223,6 +223,93 @@ class CakeEmail { return $this->_from; } +/** + * Set To + * + * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) + * @param string $name + * @return void + */ + public function setTo($email, $name = null) { + $this->_setEmail('_to', $email, $name); + } + +/** + * Add To + * + * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) + * @param string $name + * @return void + */ + public function addTo($email, $name = null) { + $this->_addEmail('_to', $email, $name); + } + +/** + * Get To + * + * @return array + */ + public function getTo() { + return $this->_to; + } + +/** + * Set email + * + * @param string $varName + * @param mixed $email + * @param mixed $name + * @return void + */ + protected function _setEmail($varName, $email, $name) { + if (!is_array($email)) { + if ($name === null) { + $this->{$varName} = array($email => $email); + } else { + $this->{$varName} = array($email => $name); + } + return; + } + $list = array(); + foreach ($email as $key => $value) { + if (is_int($key)) { + $list[$value] = $value; + } else { + $list[$key] = $value; + } + } + $this->{$varName} = $list; + } + +/** + * Add email + * + * @param string $varName + * @param mixed $email + * @param mixed $name + * @return void + */ + protected function _addEmail($varName, $email, $name) { + if (!is_array($email)) { + if ($name === null) { + $this->{$varName}[$email] = $email; + } else { + $this->{$varName}[$email] = $name; + } + return; + } + $list = array(); + foreach ($email as $key => $value) { + if (is_int($key)) { + $list[$value] = $value; + } else { + $list[$key] = $value; + } + } + $this->{$varName} = array_merge($this->{$varName}, $list); + } + /** * Sets headers for the message * diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index be613e376..fbd73e399 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -52,6 +52,50 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->getFrom(), $expected); } +/** + * testTo method + * + * @return void + */ + public function testTo() { + $this->assertIdentical($this->CakeEmail->getTo(), array()); + + $this->CakeEmail->setTo('cake@cakephp.org'); + $expected = array('cake@cakephp.org' => 'cake@cakephp.org'); + $this->assertIdentical($this->CakeEmail->getTo(), $expected); + + $this->CakeEmail->setTo('cake@cakephp.org', 'CakePHP'); + $expected = array('cake@cakephp.org' => 'CakePHP'); + $this->assertIdentical($this->CakeEmail->getTo(), $expected); + + $list = array( + 'cake@cakephp.org' => 'Cake PHP', + 'cake-php@googlegroups.com' => 'Cake Groups', + 'root@cakephp.org' + ); + $this->CakeEmail->setTo($list); + $expected = array( + 'cake@cakephp.org' => 'Cake PHP', + 'cake-php@googlegroups.com' => 'Cake Groups', + 'root@cakephp.org' => 'root@cakephp.org' + ); + $this->assertIdentical($this->CakeEmail->getTo(), $expected); + + $this->CakeEmail->addTo('jrbasso@cakephp.org'); + $this->CakeEmail->addTo('mark_story@cakephp.org', 'Mark Story'); + $this->CakeEmail->addTo(array('phpnut@cakephp.org' => 'PhpNut', 'jose_zap@cakephp.org')); + $expected = array( + 'cake@cakephp.org' => 'Cake PHP', + 'cake-php@googlegroups.com' => 'Cake Groups', + 'root@cakephp.org' => 'root@cakephp.org', + 'jrbasso@cakephp.org' => 'jrbasso@cakephp.org', + 'mark_story@cakephp.org' => 'Mark Story', + 'phpnut@cakephp.org' => 'PhpNut', + 'jose_zap@cakephp.org' => 'jose_zap@cakephp.org' + ); + $this->assertIdentical($this->CakeEmail->getTo(), $expected); + } + /** * testHeaders method * From 7aa0d6c1ebaff3e22ae5fe430158542f4b84661a Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 13:35:28 -0300 Subject: [PATCH 006/103] Added the methods to set/add/get Cc and Bcc. --- lib/Cake/Network/CakeEmail.php | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 8df30071f..d7b57d707 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -254,6 +254,68 @@ class CakeEmail { return $this->_to; } +/** + * Set Cc + * + * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) + * @param string $name + * @return void + */ + public function setCc($email, $name = null) { + $this->_setEmail('_cc', $email, $name); + } + +/** + * Add Cc + * + * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) + * @param string $name + * @return void + */ + public function addCc($email, $name = null) { + $this->_addEmail('_cc', $email, $name); + } + +/** + * Get Cc + * + * @return array + */ + public function getCc() { + return $this->_cc; + } + +/** + * Set Bcc + * + * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) + * @param string $name + * @return void + */ + public function setBcc($email, $name = null) { + $this->_setEmail('_bcc', $email, $name); + } + +/** + * Add Bcc + * + * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) + * @param string $name + * @return void + */ + public function addBcc($email, $name = null) { + $this->_addEmail('_bcc', $email, $name); + } + +/** + * Get Bcc + * + * @return array + */ + public function getBcc() { + return $this->_bcc; + } + /** * Set email * From a28e0f014d025c30737ae4368e595e70b84cf847 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 13:42:21 -0300 Subject: [PATCH 007/103] setFrom using _setEmail. DRY and consistence. --- lib/Cake/Network/CakeEmail.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index d7b57d707..daf689fd8 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -205,12 +205,14 @@ class CakeEmail { * @param string $email * @param string $name * @return void + * @thrown SocketException */ public function setFrom($email, $name = null) { - if ($name !== null) { - $this->_from = array($email => $name); - } else { - $this->_from = array($email => $email); + $oldFrom = $this->_from; + $this->_setEmail('_from', $email, $name); + if (count($this->_from) !== 1) { + $this->_from = $oldFrom; + throw new SocketException(__('From requires only 1 email address.')); } } From 2a7aa2bba02bd4a91de5d690cafbdd243829e3b6 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 13:47:05 -0300 Subject: [PATCH 008/103] Adding mail and smtp transport. --- cake/libs/email/abstract_transport.php | 53 ++++++ cake/libs/email/mail_transport.php | 47 ++++++ cake/libs/email/smtp_transport.php | 222 +++++++++++++++++++++++++ 3 files changed, 322 insertions(+) create mode 100644 cake/libs/email/abstract_transport.php create mode 100644 cake/libs/email/mail_transport.php create mode 100644 cake/libs/email/smtp_transport.php diff --git a/cake/libs/email/abstract_transport.php b/cake/libs/email/abstract_transport.php new file mode 100644 index 000000000..301f498d9 --- /dev/null +++ b/cake/libs/email/abstract_transport.php @@ -0,0 +1,53 @@ + value + * @param string $eol + * @return string + */ + protected function _headersToString($headers, $eol = "\r\n") { + $out = ''; + foreach ($headers as $key => $value) { + $out .= $key . ': ' . $value . $eol; + } + if (!empty($out)) { + $out = substr($out, 0, -1 * strlen($eol)); + } + return $out; + } + +} diff --git a/cake/libs/email/mail_transport.php b/cake/libs/email/mail_transport.php new file mode 100644 index 000000000..ceb957c74 --- /dev/null +++ b/cake/libs/email/mail_transport.php @@ -0,0 +1,47 @@ +_headersToString($email->getHeaders(true, true, false), $eol); + $message = implode($eol, $email->getMessage()); + $to = key($email->getTo()); + if (ini_get('safe_mode')) { + return @mail($to, $email->getSubject(), $message, $header); + } + return @mail($to, $email->getSubject(), $message, $header, (string)Configure::read('Email.Mail.AdditionalParameters')); + } + +} diff --git a/cake/libs/email/smtp_transport.php b/cake/libs/email/smtp_transport.php new file mode 100644 index 000000000..0ec0470c9 --- /dev/null +++ b/cake/libs/email/smtp_transport.php @@ -0,0 +1,222 @@ + 'localhost', + 'port' => 25, + 'timeout' => 30, + 'username' => null, + 'password' => null, + 'client' => null + ); + $userConfig = Configure::read('Email.Smtp'); + if (is_array($userConfig)) { + $config = array_merge($config, array_change_key_case($userConfig, CASE_LOWER)); + } + $this->_config = $config; + $this->_cakeEmail = $email; + + $this->_connect(); + $this->_auth(); + $this->_sendRcpt(); + $this->_sendData(); + $this->_disconnect(); + + return true; + } + +/** + * Connect to SMTP Server + * + * @return void + * @thrown SocketException + */ + protected function _connect() { + $this->_generateSocket(); + if (!$this->_socket->connect()) { + throw new SocketException(__('Unable to connect in SMTP server.')); + } + $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(__('SMTP server not accepted the connection.')); + } + } + } + +/** + * Send authentication + * + * @return void + * @thrown SocketException + */ + 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(__('SMTP server not accepted the username.')); + } + if (!$this->_smtpSend(base64_encode($this->_config['password']), '235')) { + throw new SocketException(__('SMTP server not accepted the password.')); + } + } elseif ($authRequired != '503') { + throw new SocketException(__('SMTP do not require authentication.')); + } + } + } + +/** + * Send emails + * + * @return void + * @thrown SocketException + */ + protected function _sendRcpt() { + $from = $this->_cakeEmail->getFrom(); + $this->_smtpSend('MAIL FROM: ' . key($from)); + + $to = $this->_cakeEmail->getTo(); + $cc = $this->_cakeEmail->getCc(); + $bcc = $this->_cakeEmail->getBcc(); + $emails = array_merge(array_keys($to), array_keys($cc), array_keys($bcc)); + foreach ($emails as $email) { + $this->_smtpSend('RCPT TO: ' . $email); + } + } + +/** + * Send Data + * + * @return void + * @thrown SocketException + */ + protected function _sendData() { + $this->_smtpSend('DATA', '354'); + + $header = $this->_headersToString($this->_cakeEmail->getHeaders(true, false, true)); + $message = implode("\r\n", $this->_cakeEmail->getMessage()); + $this->_smtpSend($header . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); + } + +/** + * Disconnect + * + * @return void + * @thrown SocketException + */ + protected function _disconnect() { + $this->_smtpSend('QUIT', false); + $this->_socket->disconnect(); + } + +/** + * Helper method to generate socket + * + * @return void + * @thrown SocketException + */ + 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 + * @thrown SocketException + */ + function _smtpSend($data, $checkCode = '250') { + if (!is_null($data)) { + $this->_socket->write($data . "\r\n"); + } + while ($checkCode !== false) { + $response = ''; + $startTime = time(); + while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->smtpOptions['timeout'])) { + $response .= $this->_socket->read(); + } + if (substr($response, -2) !== "\r\n") { + throw new SocketException(__('SMTP timeout.')); + } + $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(__('SMTP Error: %s', $response)); + } + } + +} From 162da0aec978229e0506173f4239f502051f59fc Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 13:50:54 -0300 Subject: [PATCH 009/103] Added tests with array in setFrom. --- lib/Cake/tests/Case/Network/CakeEmailTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index fbd73e399..f612f4fef 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -47,9 +47,15 @@ class CakeEmailTest extends CakeTestCase { $expected = array('cake@cakephp.org' => 'cake@cakephp.org'); $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + $this->CakeEmail->setFrom(array('cake@cakephp.org')); + $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + $this->CakeEmail->setFrom('cake@cakephp.org', 'CakePHP'); $expected = array('cake@cakephp.org' => 'CakePHP'); $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + + $this->CakeEmail->setFrom(array('cake@cakephp.org' => 'CakePHP')); + $this->assertIdentical($this->CakeEmail->getFrom(), $expected); } /** From 187304cebb9e3373942e4a6147ec90fb07a1c29d Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 14:09:08 -0300 Subject: [PATCH 010/103] Added methods to ReturnPath, ReadReceipt and ReplyTo. --- lib/Cake/Network/CakeEmail.php | 97 ++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 10 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index daf689fd8..d6aca9e10 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -53,14 +53,14 @@ class CakeEmail { * * @var string */ - protected $_replyTo = null; + protected $_replyTo = array(); /** * The read receipt email * * @var string */ - protected $_readReceipt = null; + protected $_readReceipt = array(); /** * The mail that will be used in case of any errors like @@ -70,7 +70,7 @@ class CakeEmail { * * @var string */ - protected $_return = null; + protected $_returnPath = array(); /** * Carbon Copy @@ -202,18 +202,13 @@ class CakeEmail { /** * Set From * - * @param string $email + * @param mixed $email * @param string $name * @return void * @thrown SocketException */ public function setFrom($email, $name = null) { - $oldFrom = $this->_from; - $this->_setEmail('_from', $email, $name); - if (count($this->_from) !== 1) { - $this->_from = $oldFrom; - throw new SocketException(__('From requires only 1 email address.')); - } + $this->_setEmail1('_from', $email, $name, __('From requires only 1 email address.')); } /** @@ -225,6 +220,69 @@ class CakeEmail { return $this->_from; } +/** + * Set Reply-To + * + * @param mixed $email + * @param string $name + * @return void + * @thrown SocketException + */ + public function setReplyTo($email, $name = null) { + $this->_setEmail1('_replyTo', $email, $name, __('Reply-To requires only 1 email address.')); + } + +/** + * Get the ReplyTo information + * + * @return array Key is email, Value is name. If Key is equal of Value, the name is not specified + */ + public function getReplyTo() { + return $this->_replyTo; + } + +/** + * Set Read Receipt (Disposition-Notification-To header) + * + * @param mixed $email + * @param string $name + * @return void + * @thrown SocketException + */ + public function setReadReceipt($email, $name = null) { + $this->_setEmail1('_readReceipt', $email, $name, __('Disposition-Notification-To requires only 1 email address.')); + } + +/** + * Get the Read Receipt (Disposition-Notification-To header) information + * + * @return array Key is email, Value is name. If Key is equal of Value, the name is not specified + */ + public function getReadReceipt() { + return $this->_readReceipt; + } + +/** + * Set Return Path + * + * @param mixed $email + * @param string $name + * @return void + * @thrown SocketException + */ + public function setReturnPath($email, $name = null) { + $this->_setEmail1('_returnPath', $email, $name, __('Return-Path requires only 1 email address.')); + } + +/** + * Get the Return Path information + * + * @return array Key is email, Value is name. If Key is equal of Value, the name is not specified + */ + public function getReturnPath() { + return $this->_returnPath; + } + /** * Set To * @@ -346,6 +404,25 @@ class CakeEmail { $this->{$varName} = $list; } +/** + * Set only 1 email + * + * @param string $varName + * @param mixed $email + * @param string $name + * @param string $throwMessage + * @return void + * @thrown SocketExpceiton + */ + protected function _setEmail1($varName, $email, $name, $throwMessage) { + $current = $this->{$varName}; + $this->_setEmail($varName, $email, $name); + if (count($this->{$varName}) !== 1) { + $this->{$varName} = $current; + throw new SocketException($throwMessage); + } + } + /** * Add email * From 82835a35665cd827d7041cbc4280648196f81edf Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 14:20:13 -0300 Subject: [PATCH 011/103] Methods to set/get subject. --- lib/Cake/Network/CakeEmail.php | 21 ++++++++++++++++++- lib/Cake/tests/Case/Network/CakeEmailTest.php | 16 ++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index d6aca9e10..296df6efa 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -97,7 +97,7 @@ class CakeEmail { * * @var string */ - protected $_subject = null; + protected $_subject = ''; /** * Associative array of a user defined headers @@ -451,6 +451,25 @@ class CakeEmail { $this->{$varName} = array_merge($this->{$varName}, $list); } +/** + * Set Subject + * + * @param string $subject + * @return void + */ + public function setSubject($subject) { + $this->_subject = (string)$subject; + } + +/** + * Get Subject + * + * @return string + */ + public function getSubject() { + return $this->_subject; + } + /** * Sets headers for the message * diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index f612f4fef..5343c1396 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -102,6 +102,22 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->getTo(), $expected); } +/** + * testSubject method + * + * @return void + */ + public function testSubject() { + $this->CakeEmail->setSubject('You have a new message.'); + $this->assertIdentical($this->CakeEmail->getSubject(), 'You have a new message.'); + + $this->CakeEmail->setSubject(1); + $this->assertIdentical($this->CakeEmail->getSubject(), '1'); + + $this->CakeEmail->setSubject(array('something')); + $this->assertIdentical($this->CakeEmail->getSubject(), 'Array'); + } + /** * testHeaders method * From e6c8171d1f581e5a35aa39c0c6d2cefa87899a83 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 14:25:25 -0300 Subject: [PATCH 012/103] Added some vars to reset. --- lib/Cake/Network/CakeEmail.php | 9 +++++++++ lib/Cake/tests/Case/Network/CakeEmailTest.php | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 296df6efa..2e9a1e0fa 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -536,6 +536,15 @@ class CakeEmail { * @return void */ public function reset() { + $this->_to = array(); + $this->_from = array(); + $this->_replyTo = array(); + $this->_readReceipt = array(); + $this->_returnPath = array(); + $this->_cc = array(); + $this->_bcc = array(); + $this->_subject = ''; + $this->_headers = array(); } } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 5343c1396..bd6137d22 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -140,6 +140,11 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testReset() { + $this->CakeEmail->setTo('cake@cakephp.org'); + $this->assertIdentical($this->CakeEmail->getTo(), array('cake@cakephp.org' => 'cake@cakephp.org')); + + $this->CakeEmail->reset(); + $this->assertIdentical($this->CakeEmail->getTo(), array()); } } From 6930ba62073fb548ea2b943c0eaed77a87cb4283 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 15:16:50 -0300 Subject: [PATCH 013/103] Changes to in manipulation of header. --- lib/Cake/Network/CakeEmail.php | 88 ++++++++++++++++--- lib/Cake/tests/Case/Network/CakeEmailTest.php | 30 +++++++ 2 files changed, 105 insertions(+), 13 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 2e9a1e0fa..cef656978 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -501,25 +501,87 @@ class CakeEmail { /** * Get list of headers * - * @param boolean $includeToAndCc - * @param boolean $includeBcc - * @param boolean $includeSubject + * ### Includes: + * + * - `from` + * - `replyTo` + * - `readReceipt` + * - `returnPath` + * - `to` + * - `cc` + * - `bcc` + * - `subject` + * + * @param array $include * @return array */ - public function getHeaders($includeToAndCc = false, $includeBcc = false, $includeSubject = false) { - if (!isset($this->_headers['X-Mailer'])) { - $this->_headers['X-Mailer'] = Configure::read('Email.XMailer'); - if (empty($this->_headers['X-Mailer'])) { - $this->_headers['X-Mailer'] = self::EMAIL_CLIENT; + public function getHeaders($include = array()) { + $defaults = array( + 'from' => false, + 'replyTo' => false, + 'readReceipt' => false, + 'returnPath' => false, + 'to' => false, + 'cc' => false, + 'bcc' => false, + 'subject' => false + ); + $include += $defaults; + + $headers = $this->_headers; + if (!isset($headers['X-Mailer'])) { + $headers['X-Mailer'] = Configure::read('Email.XMailer'); + if (empty($headers['X-Mailer'])) { + $headers['X-Mailer'] = self::EMAIL_CLIENT; } } - if (!isset($this->_headers['Date'])) { - $this->_headers['Date'] = date(DATE_RFC2822); + if (!isset($headers['Date'])) { + $headers['Date'] = date(DATE_RFC2822); } - if ($includeSubject) { - $this->_headers['Subject'] = $this->_subject; + + $relation = array( + 'from' => 'From', + 'replyTo' => 'Reply-To', + 'readReceipt' => 'Disposition-Notification-To', + 'returnPath' => 'Return-Path' + ); + foreach ($relation as $var => $header) { + if ($include[$var]) { + $var = '_' . $var; + $headers[$header] = current($this->_formatAddress($this->{$var})); + } } - return $this->_headers; + + foreach (array('to', 'cc', 'bcc') as $var) { + if ($include[$var]) { + $classVar = '_' . $var; + $headers[ucfirst($var)] = implode(', ', $this->_formatAddress($this->{$classVar})); + } + } + + if ($include['subject']) { + $headers['Subject'] = $this->_subject; + } + + return $headers; + } + +/** + * Format addresses + * + * @param array $address + * @return array + */ + protected function _formatAddress($address) { + $return = array(); + foreach ($address as $email => $alias) { + if ($email === $alias) { + $return[] = $email; + } else { + $return[] = sprintf('%s <%s>', $alias, $email); + } + } + return $return; } /** diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index bd6137d22..13a5a3a39 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -124,6 +124,36 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testHeaders() { + $this->CakeEmail->setHeaders(array('X-Something' => 'nice')); + $expected = array( + 'X-Something' => 'nice', + 'X-Mailer' => 'CakePHP Email Component', + 'Date' => date(DATE_RFC2822) + ); + $this->assertIdentical($this->CakeEmail->getHeaders(), $expected); + + $this->CakeEmail->addHeaders(array('X-Something' => 'very nice', 'X-Other' => 'cool')); + $expected = array( + 'X-Something' => 'very nice', + 'X-Other' => 'cool', + 'X-Mailer' => 'CakePHP Email Component', + 'Date' => date(DATE_RFC2822) + ); + $this->assertIdentical($this->CakeEmail->getHeaders(), $expected); + + $this->CakeEmail->setFrom('cake@cakephp.org'); + $this->assertIdentical($this->CakeEmail->getHeaders(), $expected); + + $expected['From'] = 'cake@cakephp.org'; + $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true)), $expected); + + $this->CakeEmail->setFrom('cake@cakephp.org', 'CakePHP'); + $expected['From'] = 'CakePHP '; + $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true)), $expected); + + $this->CakeEmail->setTo(array('cake@cakephp.org', 'php@cakephp.org' => 'CakePHP')); + $expected['To'] = 'cake@cakephp.org, CakePHP '; + $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true, 'to' => true)), $expected); } /** From 131a62f9cbc71c9e4c49825e963187890be1fb24 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 15:24:38 -0300 Subject: [PATCH 014/103] Adapted the mail and smtp transports to the getHeaders return. --- cake/libs/email/mail_transport.php | 6 ++++-- cake/libs/email/smtp_transport.php | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cake/libs/email/mail_transport.php b/cake/libs/email/mail_transport.php index ceb957c74..16fbaab8c 100644 --- a/cake/libs/email/mail_transport.php +++ b/cake/libs/email/mail_transport.php @@ -35,9 +35,11 @@ class MailTransport extends AbstractTransport { if (!$eol) { $eol = PHP_EOL; } - $header = $this->_headersToString($email->getHeaders(true, true, false), $eol); + $headers = $email->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true)); + $to = $headers['To']; + unset($headers['To']); + $header = $this->_headersToString($headers, $eol); $message = implode($eol, $email->getMessage()); - $to = key($email->getTo()); if (ini_get('safe_mode')) { return @mail($to, $email->getSubject(), $message, $header); } diff --git a/cake/libs/email/smtp_transport.php b/cake/libs/email/smtp_transport.php index 0ec0470c9..e7678df7f 100644 --- a/cake/libs/email/smtp_transport.php +++ b/cake/libs/email/smtp_transport.php @@ -160,9 +160,10 @@ class SmtpTransport extends AbstractTransport { protected function _sendData() { $this->_smtpSend('DATA', '354'); - $header = $this->_headersToString($this->_cakeEmail->getHeaders(true, false, true)); + $headers = $this->_cakeEmail->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), true)); + $headers = $this->_headersToString($headers); $message = implode("\r\n", $this->_cakeEmail->getMessage()); - $this->_smtpSend($header . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); + $this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); } /** From bd5e5376d10e9c93bf0b7ab4ebecab311c0e191f Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 18:16:55 -0300 Subject: [PATCH 015/103] Implemented method to set layout and template. --- lib/Cake/Network/CakeEmail.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index cef656978..77e11b8ad 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -112,14 +112,14 @@ class CakeEmail { * * @var string */ - public $layout = 'default'; + protected $_layout = 'default'; /** * Template for the view * * @var string */ - public $template = null; + protected $_template = ''; /** * as per RFC2822 Section 2.1.1 @@ -584,6 +584,20 @@ class CakeEmail { return $return; } +/** + * Set the layout and template + * + * @param string $layout + * @param string $template + * @return void + */ + public function setLayout($layout, $template = null) { + $this->_layout = (string)$layout; + if ($template !== null) { + $this->_template = (string)$template; + } + } + /** * Send an email using the specified content, template and layout * From 35106be64731976ca0615c0eaf967f9f50c9794a Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 18:18:17 -0300 Subject: [PATCH 016/103] Removed the configuration to EOL. Moved to MailTransport. --- lib/Cake/Network/CakeEmail.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 77e11b8ad..8f642e13d 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -128,17 +128,6 @@ class CakeEmail { */ public $lineLength = 70; -/** - * Line feed character(s) to be used when sending using mail() function - * By default PHP_EOL is used. - * RFC2822 requires it to be CRLF but some Unix - * mail transfer agents replace LF by CRLF automatically - * (which leads to doubling CR if CRLF is used). - * - * @var string - */ - public $lineFeed = PHP_EOL; - /** * What format should the email be sent in * From 1a457dc57577710c97d887e2320fdc5ae6ad68e0 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 18:25:57 -0300 Subject: [PATCH 017/103] Method to set email format (text, html, both). --- lib/Cake/Network/CakeEmail.php | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 8f642e13d..00c2cab2b 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -129,16 +129,18 @@ class CakeEmail { public $lineLength = 70; /** - * What format should the email be sent in + * Available formats to be sent. * - * Supported formats: - * - text - * - html - * - both + * @var array + */ + protected $_emailFormatAvailable = array('text', 'html', 'both'); + +/** + * What format should the email be sent in * * @var string */ - public $sendAs = 'text'; + protected $_emailFormat = 'text'; /** * What method should the email be sent @@ -587,6 +589,20 @@ class CakeEmail { } } +/** + * Set the email format + * + * @param string $format + * @return void + * @thrown SocketException + */ + public function setEmailFormat($format) { + if (!in_array($format, $this->_emailFormatAvailable)) { + throw new SocketException(__('Format not available.')); + } + $this->_emailFormat = $format; + } + /** * Send an email using the specified content, template and layout * @@ -610,6 +626,9 @@ class CakeEmail { $this->_bcc = array(); $this->_subject = ''; $this->_headers = array(); + $this->_layout = 'default'; + $this->_template = ''; + $this->_emailFormat = 'text'; } } From 6c3a42c82ada23e28afa1cee99ed6ac6ed7003b1 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 18:29:46 -0300 Subject: [PATCH 018/103] Method to set transport name. --- lib/Cake/Network/CakeEmail.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 00c2cab2b..05b953cbc 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -147,7 +147,7 @@ class CakeEmail { * * @var string */ - public $delivery = 'mail'; + protected $_transportName = 'mail'; /** * charset the email is sent in @@ -603,6 +603,16 @@ class CakeEmail { $this->_emailFormat = $format; } +/** + * Set transport name + * + * @param string $name + * @return void + */ + public function setTransport($name) { + $this->_transportName = (string)$name; + } + /** * Send an email using the specified content, template and layout * @@ -629,6 +639,7 @@ class CakeEmail { $this->_layout = 'default'; $this->_template = ''; $this->_emailFormat = 'text'; + $this->_transportName = 'mail'; } } From b29c31709e7c835c7f4ad386b1109db30463e362 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 18:51:12 -0300 Subject: [PATCH 019/103] Implemented methods to attachments. --- lib/Cake/Network/CakeEmail.php | 54 +++++++++++++++---- lib/Cake/tests/Case/Network/CakeEmailTest.php | 20 +++++++ 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 05b953cbc..fc8647015 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -159,18 +159,11 @@ class CakeEmail { /** * List of files that should be attached to the email. * - * Can be both absolute and relative paths + * Only absolute paths * * @var array */ - public $attachments = array(); - -/** - * The list of paths to search if an attachment isnt absolute - * - * @var array - */ - public $filePaths = array(); + protected $_attachments = array(); /** * If set, boundary to use for multipart mime messages @@ -613,6 +606,48 @@ class CakeEmail { $this->_transportName = (string)$name; } +/** + * Set attachments + * + * @param mixed $attachments String with the filename or array with filenames + * @return void + * @thrown SocketException + */ + public function setAttachments($attachments) { + $attachments = (array)$attachments; + foreach ($attachments as &$attach) { + $path = realpath($attach); + if ($path === false) { + throw new SocketException(__('File not found: "%s"', $attach)); + } + $attach = $path; + } + $this->_attachments = $attachments; + } + +/** + * Add attachments + * + * @param mixed $attachments String with the filename or array with filenames + * @return void + * @thrown SocketException + */ + public function addAttachments($attachments) { + $current = $this->_attachments; + $this->setAttachments($attachments); + $this->_attachments = array_unique(array_merge($current, $this->_attachments)); + } + +/** + * Get attachments + * + * @return array + */ + public function getAttachments() { + return $this->_attachments; + } + + /** * Send an email using the specified content, template and layout * @@ -640,6 +675,7 @@ class CakeEmail { $this->_template = ''; $this->_emailFormat = 'text'; $this->_transportName = 'mail'; + $this->_attachments = array(); } } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 13a5a3a39..806a49488 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -156,6 +156,26 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true, 'to' => true)), $expected); } +/** + * testAttachments + * + * @return void + */ + public function testAttachments() { + $this->CakeEmail->setAttachments(WWW_ROOT . 'index.php'); + $expected = array(WWW_ROOT . 'index.php'); + $this->assertIdentical($this->CakeEmail->getAttachments(), $expected); + + $this->CakeEmail->setAttachments(array()); + $this->assertIdentical($this->CakeEmail->getAttachments(), array()); + + $this->CakeEmail->setAttachments(WWW_ROOT . 'index.php'); + $this->CakeEmail->addAttachments(WWW_ROOT . 'test.php'); + $this->CakeEmail->addAttachments(array(WWW_ROOT . 'test.php', WWW_ROOT . '.htaccess')); + $expected = array(WWW_ROOT . 'index.php', WWW_ROOT . 'test.php', WWW_ROOT . '.htaccess'); + $this->assertIdentical(array_values($this->CakeEmail->getAttachments()), $expected); + } + /** * testSend method * From 85645496ea9b84a1a3b646f7af24f4115b2696da Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 19:14:34 -0300 Subject: [PATCH 020/103] Fixed the formation to send the emails to server, following the RFC 821. --- cake/libs/email/smtp_transport.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/libs/email/smtp_transport.php b/cake/libs/email/smtp_transport.php index e7678df7f..6f3a09746 100644 --- a/cake/libs/email/smtp_transport.php +++ b/cake/libs/email/smtp_transport.php @@ -140,14 +140,14 @@ class SmtpTransport extends AbstractTransport { */ protected function _sendRcpt() { $from = $this->_cakeEmail->getFrom(); - $this->_smtpSend('MAIL FROM: ' . key($from)); + $this->_smtpSend('MAIL FROM:<' . key($from) . '>'); $to = $this->_cakeEmail->getTo(); $cc = $this->_cakeEmail->getCc(); $bcc = $this->_cakeEmail->getBcc(); $emails = array_merge(array_keys($to), array_keys($cc), array_keys($bcc)); foreach ($emails as $email) { - $this->_smtpSend('RCPT TO: ' . $email); + $this->_smtpSend('RCPT TO:<' . $email . '>'); } } From 6a76931961f0e396be526f4192cb0bb8a67a8b01 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 19:30:01 -0300 Subject: [PATCH 021/103] Added support to multibyte in formatAddress. Tests added. --- lib/Cake/Network/CakeEmail.php | 21 +++++++++- lib/Cake/tests/Case/Network/CakeEmailTest.php | 41 ++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index fc8647015..efb8db62a 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -562,7 +562,7 @@ class CakeEmail { if ($email === $alias) { $return[] = $email; } else { - $return[] = sprintf('%s <%s>', $alias, $email); + $return[] = sprintf('%s <%s>', $this->_encode($alias), $email); } } return $return; @@ -678,4 +678,23 @@ class CakeEmail { $this->_attachments = array(); } +/** + * Encode the specified string using the current charset + * + * @param string $text String to encode + * @return string Encoded string + */ + protected function _encode($text) { + $internalEncoding = function_exists('mb_internal_encoding'); + if ($internalEncoding) { + $restore = mb_internal_encoding(); + mb_internal_encoding($this->charset); + } + $return = mb_encode_mimeheader($text, $this->charset, 'B'); + if ($internalEncoding) { + mb_internal_encoding($restore); + } + return $return; + } + } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 806a49488..a85f11d50 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -18,6 +18,22 @@ */ App::import('Core', 'CakeEmail'); +/** + * Help to test CakeEmail + * + */ +class TestCakeEmail extends CakeEmail { + +/** + * Wrap to protected method + * + */ + public function formatAddress($address) { + return $this->_formatAddress($address); + } + +} + /** * CakeEmailTest class * @@ -32,7 +48,7 @@ class CakeEmailTest extends CakeTestCase { */ public function setUp() { parent::setUp(); - $this->CakeEmail = new CakeEmail(); + $this->CakeEmail = new TestCakeEmail(); } /** @@ -102,6 +118,29 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->getTo(), $expected); } +/** + * testFormatAddress method + * + * @return void + */ + public function testFormatAddress() { + $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'cake@cakephp.org')); + $expected = array('cake@cakephp.org'); + $this->assertIdentical($result, $expected); + + $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'cake@cakephp.org', 'php@cakephp.org' => 'php@cakephp.org')); + $expected = array('cake@cakephp.org', 'php@cakephp.org'); + $this->assertIdentical($result, $expected); + + $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'CakePHP', 'php@cakephp.org' => 'Cake')); + $expected = array('CakePHP ', 'Cake '); + $this->assertIdentical($result, $expected); + + $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'ÄÖÜTest')); + $expected = array('=?UTF-8?B?w4TDlsOcVGVzdA==?= '); + $this->assertIdentical($result, $expected); + } + /** * testSubject method * From 03b4ce070b736d7855e9c9508b6aafc8663dd5cd Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 19:46:20 -0300 Subject: [PATCH 022/103] Added a protection to not insert invalid emails. --- lib/Cake/Network/CakeEmail.php | 19 +++++++++++++ lib/Cake/tests/Case/Network/CakeEmailTest.php | 27 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index efb8db62a..7fc708777 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -367,9 +367,13 @@ class CakeEmail { * @param mixed $email * @param mixed $name * @return void + * @thrown SocketException */ protected function _setEmail($varName, $email, $name) { if (!is_array($email)) { + if (!Validation::email($email)) { + throw new SocketException(__('Invalid email: "%s"', $email)); + } if ($name === null) { $this->{$varName} = array($email => $email); } else { @@ -380,8 +384,14 @@ class CakeEmail { $list = array(); foreach ($email as $key => $value) { if (is_int($key)) { + if (!Validation::email($value)) { + throw new SocketException(__('Invalid email: "%s"', $value)); + } $list[$value] = $value; } else { + if (!Validation::email($key)) { + throw new SocketException(__('Invalid email: "%s"', $key)); + } $list[$key] = $value; } } @@ -417,6 +427,9 @@ class CakeEmail { */ protected function _addEmail($varName, $email, $name) { if (!is_array($email)) { + if (!Validation::email($email)) { + throw new SocketException(__('Invalid email: "%s"', $email)); + } if ($name === null) { $this->{$varName}[$email] = $email; } else { @@ -427,8 +440,14 @@ class CakeEmail { $list = array(); foreach ($email as $key => $value) { if (is_int($key)) { + if (!Validation::email($value)) { + throw new SocketException(__('Invalid email: "%s"', $value)); + } $list[$value] = $value; } else { + if (!Validation::email($key)) { + throw new SocketException(__('Invalid email: "%s"', $key)); + } $list[$key] = $value; } } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index a85f11d50..a3eae184d 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -118,6 +118,33 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->getTo(), $expected); } +/** + * Data provider function for testBuildInvalidData + * + * @return array + */ + public static function invalidEmails() { + return array( + array(1.0), + array(''), + array('string'), + array(''), + array('some@one.whereis'), + array(array('ok@cakephp.org', 1.0, '', 'string')) + ); + } + +/** + * testBuildInvalidData + * + * @dataProvider invalidEmails + * @expectedException SocketException + * return void + */ + public function testInvalidEmail($value) { + $this->CakeEmail->setTo($value); + } + /** * testFormatAddress method * From 30dced741dfa34eb08bb00c7fc1e85b46b714fe2 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 19:58:04 -0300 Subject: [PATCH 023/103] Simply the code. --- lib/Cake/Network/CakeEmail.php | 38 +++++++++++++--------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 7fc708777..7d82a28ed 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -375,25 +375,20 @@ class CakeEmail { throw new SocketException(__('Invalid email: "%s"', $email)); } if ($name === null) { - $this->{$varName} = array($email => $email); - } else { - $this->{$varName} = array($email => $name); + $name = $email; } + $this->{$varName} = array($email => $name); return; } $list = array(); foreach ($email as $key => $value) { if (is_int($key)) { - if (!Validation::email($value)) { - throw new SocketException(__('Invalid email: "%s"', $value)); - } - $list[$value] = $value; - } else { - if (!Validation::email($key)) { - throw new SocketException(__('Invalid email: "%s"', $key)); - } - $list[$key] = $value; + $key = $value; } + if (!Validation::email($key)) { + throw new SocketException(__('Invalid email: "%s"', $key)); + } + $list[$key] = $value; } $this->{$varName} = $list; } @@ -431,25 +426,20 @@ class CakeEmail { throw new SocketException(__('Invalid email: "%s"', $email)); } if ($name === null) { - $this->{$varName}[$email] = $email; - } else { - $this->{$varName}[$email] = $name; + $name = $email; } + $this->{$varName}[$email] = $name; return; } $list = array(); foreach ($email as $key => $value) { if (is_int($key)) { - if (!Validation::email($value)) { - throw new SocketException(__('Invalid email: "%s"', $value)); - } - $list[$value] = $value; - } else { - if (!Validation::email($key)) { - throw new SocketException(__('Invalid email: "%s"', $key)); - } - $list[$key] = $value; + $key = $value; } + if (!Validation::email($key)) { + throw new SocketException(__('Invalid email: "%s"', $key)); + } + $list[$key] = $value; } $this->{$varName} = array_merge($this->{$varName}, $list); } From ace425892d627bdc80a7280b9bbe96f2962cf5f9 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 20:57:45 -0300 Subject: [PATCH 024/103] Implemented method to set/get Message-ID. --- lib/Cake/Network/CakeEmail.php | 33 +++++++++++++++++++ lib/Cake/tests/Case/Network/CakeEmailTest.php | 32 +++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 7d82a28ed..d1c6777ee 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -92,6 +92,13 @@ class CakeEmail { */ protected $_bcc = array(); +/** + * Message ID + * + * @var mixed True to generate, False to ignore, String with value + */ + protected $_messageId = true; + /** * The subject of the email * @@ -531,6 +538,13 @@ class CakeEmail { if (!isset($headers['Date'])) { $headers['Date'] = date(DATE_RFC2822); } + if ($this->_messageId !== false) { + if ($this->_messageId === true) { + $headers['Message-ID'] = '<' . String::UUID() . '@' . env('HTTP_HOST') . '>'; + } else { + $headers['Message-ID'] = $this->_messageId; + } + } $relation = array( 'from' => 'From', @@ -615,6 +629,24 @@ class CakeEmail { $this->_transportName = (string)$name; } +/** + * Set Message-ID + * + * @param mixed $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID + * @return void + * @thrown SocketException + */ + public function setMessageID($message) { + if (is_bool($message)) { + $this->_messageId = $message; + } else { + if (!preg_match('/^\<.+@.+\>$/', $message)) { + throw new SocketException(__('Invalid format to Message-ID. The text should be something like ""')); + } + $this->_messageId = $message; + } + } + /** * Set attachments * @@ -678,6 +710,7 @@ class CakeEmail { $this->_returnPath = array(); $this->_cc = array(); $this->_bcc = array(); + $this->_messageId = true; $this->_subject = ''; $this->_headers = array(); $this->_layout = 'default'; diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index a3eae184d..5ee7d18b0 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -139,7 +139,7 @@ class CakeEmailTest extends CakeTestCase { * * @dataProvider invalidEmails * @expectedException SocketException - * return void + * @return void */ public function testInvalidEmail($value) { $this->CakeEmail->setTo($value); @@ -168,6 +168,35 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($result, $expected); } +/** + * testMessageId method + * + * @return void + */ + public function testMessageId() { + $this->CakeEmail->setMessageId(true); + $result = $this->CakeEmail->getHeaders(); + $this->assertTrue(isset($result['Message-ID'])); + + $this->CakeEmail->setMessageId(false); + $result = $this->CakeEmail->getHeaders(); + $this->assertFalse(isset($result['Message-ID'])); + + $this->CakeEmail->setMessageId(''); + $result = $this->CakeEmail->getHeaders(); + $this->assertIdentical($result['Message-ID'], ''); + } + +/** + * testMessageIdInvalid method + * + * @return void + * @expectedException SocketException + */ + public function testMessageIdInvalid() { + $this->CakeEmail->setMessageId('my-email@localhost'); + } + /** * testSubject method * @@ -190,6 +219,7 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testHeaders() { + $this->CakeEmail->setMessageId(false); $this->CakeEmail->setHeaders(array('X-Something' => 'nice')); $expected = array( 'X-Something' => 'nice', From 89b4cb75e3a4a3d9115631cd4498071d70d68b36 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 1 Mar 2011 21:10:34 -0300 Subject: [PATCH 025/103] Changed to addresses come before others headers. It is not a RFC rule, just to keep more readable the header. --- lib/Cake/Network/CakeEmail.php | 37 ++++++++++--------- lib/Cake/tests/Case/Network/CakeEmailTest.php | 17 ++++++++- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index d1c6777ee..79e0a66f7 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -528,24 +528,7 @@ class CakeEmail { ); $include += $defaults; - $headers = $this->_headers; - if (!isset($headers['X-Mailer'])) { - $headers['X-Mailer'] = Configure::read('Email.XMailer'); - if (empty($headers['X-Mailer'])) { - $headers['X-Mailer'] = self::EMAIL_CLIENT; - } - } - if (!isset($headers['Date'])) { - $headers['Date'] = date(DATE_RFC2822); - } - if ($this->_messageId !== false) { - if ($this->_messageId === true) { - $headers['Message-ID'] = '<' . String::UUID() . '@' . env('HTTP_HOST') . '>'; - } else { - $headers['Message-ID'] = $this->_messageId; - } - } - + $headers = array(); $relation = array( 'from' => 'From', 'replyTo' => 'Reply-To', @@ -566,6 +549,24 @@ class CakeEmail { } } + $headers += $this->_headers; + if (!isset($headers['X-Mailer'])) { + $headers['X-Mailer'] = Configure::read('Email.XMailer'); + if (empty($headers['X-Mailer'])) { + $headers['X-Mailer'] = self::EMAIL_CLIENT; + } + } + if (!isset($headers['Date'])) { + $headers['Date'] = date(DATE_RFC2822); + } + if ($this->_messageId !== false) { + if ($this->_messageId === true) { + $headers['Message-ID'] = '<' . String::UUID() . '@' . env('HTTP_HOST') . '>'; + } else { + $headers['Message-ID'] = $this->_messageId; + } + } + if ($include['subject']) { $headers['Subject'] = $this->_subject; } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 5ee7d18b0..2e2b932de 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -240,7 +240,13 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->setFrom('cake@cakephp.org'); $this->assertIdentical($this->CakeEmail->getHeaders(), $expected); - $expected['From'] = 'cake@cakephp.org'; + $expected = array( + 'From' => 'cake@cakephp.org', + 'X-Something' => 'very nice', + 'X-Other' => 'cool', + 'X-Mailer' => 'CakePHP Email Component', + 'Date' => date(DATE_RFC2822) + ); $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true)), $expected); $this->CakeEmail->setFrom('cake@cakephp.org', 'CakePHP'); @@ -248,7 +254,14 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true)), $expected); $this->CakeEmail->setTo(array('cake@cakephp.org', 'php@cakephp.org' => 'CakePHP')); - $expected['To'] = 'cake@cakephp.org, CakePHP '; + $expected = array( + 'From' => 'CakePHP ', + 'To' => 'cake@cakephp.org, CakePHP ', + 'X-Something' => 'very nice', + 'X-Other' => 'cool', + 'X-Mailer' => 'CakePHP Email Component', + 'Date' => date(DATE_RFC2822) + ); $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true, 'to' => true)), $expected); } From 2795d2b77148f7034288a4359f1adc751bf1fa46 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Wed, 2 Mar 2011 18:17:49 -0300 Subject: [PATCH 026/103] Initial changes for send. --- lib/Cake/Network/CakeEmail.php | 122 ++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 79e0a66f7..74bf391d4 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -34,6 +34,20 @@ class CakeEmail { */ const EMAIL_CLIENT = 'CakePHP Email Component'; +/** + * Line length - no should more - RFC 2822 - 2.1.1 + * + * @constant LINE_LENGTH_SHOULD + */ + const LINE_LENGTH_SHOULD = 78; + +/** + * Line length - no must more - RFC 2822 - 2.1.1 + * + * @constant LINE_LENGTH_MUST + */ + const LINE_LENGTH_MUST = 998; + /** * Recipient of the email * @@ -128,6 +142,27 @@ class CakeEmail { */ protected $_template = ''; +/** + * Text message + * + * @var string + */ + protected $_textMessage = ''; + +/** + * Html message + * + * @var string + */ + protected $_htmlMessage = ''; + +/** + * Final message to send + * + * @var array + */ + protected $_message = array(); + /** * as per RFC2822 Section 2.1.1 * @@ -689,13 +724,72 @@ class CakeEmail { return $this->_attachments; } +/** + * Get generated message (used by transport classes) + * + * @return array + */ + public function getMessage() { + return $this->_message; + } /** * Send an email using the specified content, template and layout * * @return boolean Success + * @thrown SocketExpcetion */ - public function send() { + public function send($content = null) { + if (empty($this->_from)) { + throw new SocketException(__('From is not specified.')); + } + if (empty($this->_to) && empty($this->_cc) && empty($this->_bcc)) { + throw new SocketExpcetion(__('You need specify one destination on to, cc or bcc.')); + } + + if (is_array($content)) { + $content = implode("\n", $content) . "\n"; + } + + $this->_textMessage = $this->_htmlMessage = ''; + if ($content !== null) { + if ($this->_emailFormat === 'text') { + $this->_textMessage = $content; + } elseif ($this->_emailFormat === 'html') { + $this->_htmlMessage = $content; + } elseif ($this->_emailFormat === 'both') { + $this->_textMessage = $this->_htmlMessage = $content; + } + } + + $message = $this->_wrap($content); + if (empty($this->template)) { + //$message = $this->_formatMessage($message); + } else { + //$message = $this->_render($message); + } + $message[] = ''; + $this->_message = $message; + + if (!empty($this->attachments)) { + //$this->_attachFiles(); + } + + if (!is_null($this->_boundary)) { + $this->_message[] = ''; + $this->_message[] = '--' . $this->_boundary . '--'; + $this->_message[] = ''; + } + + $transportClassname = Inflector::camelize($this->_transportName) . 'Transport'; + if (!App::import('Lib', 'email/' . $transportClassname)) { + throw new SocketException(__('Class "%s" not found.', $transportClassname)); + } elseif (!method_exists($transportClassname, 'send')) { + throw new SocketException(__('The "%s" do not have send method.', $transportClassname)); + } + + $transport = new $transportClassname(); + return $transport->send($this); } /** @@ -716,6 +810,9 @@ class CakeEmail { $this->_headers = array(); $this->_layout = 'default'; $this->_template = ''; + $this->_textMessage = ''; + $this->_htmlMessage = ''; + $this->_message = ''; $this->_emailFormat = 'text'; $this->_transportName = 'mail'; $this->_attachments = array(); @@ -740,4 +837,27 @@ class CakeEmail { return $return; } +/** + * Wrap the message to follow the RFC 2822 - 2.1.1 + * + * @param string $message Message to wrap + * @return array Wrapped message + * @access protected + * @TODO Do not wrap tags + */ + function _wrap($message) { + $message = str_replace(array("\r\n", "\r"), "\n", $message); + $lines = explode("\n", $message); + $formatted = array(); + + foreach ($lines as $line) { + if ($line[0] === '.') { + $line = '.' . $line; + } + $formatted = array_merge($formatted, explode("\n", wordwrap($line, self::LINE_LENGTH_SHOULD, "\n", true))); + } + $formatted[] = ''; + return $formatted; + } + } From 3a1ebf159a31f42441470cae99ee25aa22931725 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Thu, 3 Mar 2011 13:30:23 -0300 Subject: [PATCH 027/103] Striping tags in the message. --- lib/Cake/Network/CakeEmail.php | 77 ++++++++++++++++++- lib/Cake/tests/Case/Network/CakeEmailTest.php | 56 +++++++++++++- 2 files changed, 130 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 74bf391d4..a7d8e88ab 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -843,7 +843,6 @@ class CakeEmail { * @param string $message Message to wrap * @return array Wrapped message * @access protected - * @TODO Do not wrap tags */ function _wrap($message) { $message = str_replace(array("\r\n", "\r"), "\n", $message); @@ -851,10 +850,84 @@ class CakeEmail { $formatted = array(); foreach ($lines as $line) { + if (empty($line)) { + $formatted[] = ''; + continue; + } if ($line[0] === '.') { $line = '.' . $line; } - $formatted = array_merge($formatted, explode("\n", wordwrap($line, self::LINE_LENGTH_SHOULD, "\n", true))); + if (!preg_match('/\<[a-z]/i', $line)) { + $formatted = array_merge($formatted, explode("\n", wordwrap($line, self::LINE_LENGTH_SHOULD, "\n", true))); + continue; + } + + $tagOpen = false; + $tmpLine = $tag = ''; + $tmpLineLength = 0; + for ($i = 0, $count = strlen($line); $i < $count; $i++) { + $char = $line[$i]; + if ($tagOpen) { + $tag .= $char; + if ($char === '>') { + $tagLength = strlen($tag); + if ($tagLength + $tmpLineLength < self::LINE_LENGTH_SHOULD) { + $tmpLine .= $tag; + $tmpLineLength += $tagLength; + } else { + if ($tmpLineLength > 0) { + $formatted[] = trim($tmpLine); + $tmpLine = ''; + $tmpLineLength = 0; + } + if ($tagLength > self::LINE_LENGTH_SHOULD) { + $formatted[] = $tag; + } else { + $tmpLine = $tag; + $tmpLineLength = $tagLength; + } + } + $tag = ''; + $tagOpen = false; + } + continue; + } + if ($char === '<') { + $tagOpen = true; + $tag = '<'; + continue; + } + if ($char === ' ' && $tmpLineLength >= self::LINE_LENGTH_SHOULD) { + pr(1); + $formatted[] = $tmpLine; + $tmpLineLength = 0; + continue; + } + $tmpLine .= $char; + $tmpLineLength++; + if ($tmpLineLength === self::LINE_LENGTH_SHOULD) { + $nextChar = $line[$i + 1]; + if ($nextChar === ' ' || $nextChar === '<') { + $formatted[] = trim($tmpLine); + $tmpLine = ''; + $tmpLineLength = 0; + if ($nextChar === ' ') { + $i++; + } + } else { + $lastSpace = strrpos($tmpLine, ' '); + if ($lastSpace === false) { + continue; + } + $formatted[] = trim(substr($tmpLine, 0, $lastSpace)); + $tmpLine = substr($tmpLine, $lastSpace + 1); + $tmpLineLength = strlen($tmpLine); + } + } + } + if (!empty($tmpLine)) { + $formatted[] = $tmpLine; + } } $formatted[] = ''; return $formatted; diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 2e2b932de..14a6dafbd 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -29,7 +29,15 @@ class TestCakeEmail extends CakeEmail { * */ public function formatAddress($address) { - return $this->_formatAddress($address); + return parent::_formatAddress($address); + } + +/** + * Wrap to protected method + * + */ + public function wrap($text) { + return parent::_wrap($text); } } @@ -306,4 +314,50 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->getTo(), array()); } +/** + * testWrap method + * + * @return void + */ + public function testWrap() { + $text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.'; + $result = $this->CakeEmail->wrap($text); + $expected = array( + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci,', + 'non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.', + '' + ); + $this->assertIdentical($result, $expected); + + $text = 'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan amet.'; + $result = $this->CakeEmail->wrap($text); + $expected = array( + 'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis', + 'orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan', + 'amet.', + '' + ); + $this->assertIdentical($result, $expected); + + $text = '

Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Donec ac turpis orci, non commodo odio.
Morbi nibh nisi, vehicula pellentesque accumsan amet.


'; + $result = $this->CakeEmail->wrap($text); + $expected = array( + '

Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Donec ac', + 'turpis orci, non commodo odio.
Morbi nibh nisi, vehicula', + 'pellentesque accumsan amet.


', + '' + ); + $this->assertIdentical($result, $expected); + + $text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.'; + $result = $this->CakeEmail->wrap($text); + $expected = array( + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac', + 'turpis orci, non commodo odio. Morbi nibh', + 'nisi, vehicula pellentesque accumsan amet.', + '' + ); + $this->assertIdentical($result, $expected); + } + } From c5cbb603a06769e772f1290cc378070722f54b57 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Thu, 3 Mar 2011 23:05:30 -0300 Subject: [PATCH 028/103] Added the methods to format message. --- lib/Cake/Network/CakeEmail.php | 50 ++++++++++++++++++- lib/Cake/tests/Case/Network/CakeEmailTest.php | 16 ++++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index a7d8e88ab..cdd3d2b96 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -606,6 +606,22 @@ class CakeEmail { $headers['Subject'] = $this->_subject; } + if (!empty($this->attachments)) { + $this->_createBoundary(); + $headers['MIME-Version'] = '1.0'; + $headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"'; + $headers[] = 'This part of the E-mail should never be seen. If'; + $headers[] = 'you are reading this, consider upgrading your e-mail'; + $headers[] = 'client to a MIME-compatible client.'; + } elseif ($this->_emailFormat === 'text') { + $headers['Content-Type'] = 'text/plain; charset=' . $this->charset; + } elseif ($this->_emailFormat === 'html') { + $headers['Content-Type'] = 'text/html; charset=' . $this->charset; + } elseif ($this->_emailFormat === 'both') { + $headers['Content-Type'] = 'multipart/alternative; boundary="alt-' . $this->_boundary . '"'; + } + $headers['Content-Transfer-Encoding'] = '7bit'; + return $headers; } @@ -764,7 +780,7 @@ class CakeEmail { $message = $this->_wrap($content); if (empty($this->template)) { - //$message = $this->_formatMessage($message); + $message = $this->_formatMessage($message); } else { //$message = $this->_render($message); } @@ -933,4 +949,36 @@ class CakeEmail { return $formatted; } +/** + * Create unique boundary identifier + * + * @return void + */ + function _createboundary() { + $this->_boundary = md5(uniqid(time())); + } + +/** + * Format the message by seeing if it has attachments. + * + * @param array $message Message to format + * @return array + */ + function _formatMessage($message) { + if (!empty($this->_attachments)) { + $prefix = array('--' . $this->_boundary); + if ($this->_emailFormat === 'text') { + $prefix[] = 'Content-Type: text/plain; charset=' . $this->charset; + } elseif ($this->_emailFormat === 'html') { + $prefix[] = 'Content-Type: text/html; charset=' . $this->charset; + } elseif ($this->_emailFormat === 'both') { + $prefix[] = 'Content-Type: multipart/alternative; boundary="alt-' . $this->_boundary . '"'; + } + $prefix[] = 'Content-Transfer-Encoding: 7bit'; + $prefix[] = ''; + $message = array_merge($prefix, $message); + } + return $message; + } + } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 14a6dafbd..53b887975 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -232,7 +232,9 @@ class CakeEmailTest extends CakeTestCase { $expected = array( 'X-Something' => 'nice', 'X-Mailer' => 'CakePHP Email Component', - 'Date' => date(DATE_RFC2822) + 'Date' => date(DATE_RFC2822), + 'Content-Type' => 'text/plain; charset=UTF-8', + 'Content-Transfer-Encoding' => '7bit' ); $this->assertIdentical($this->CakeEmail->getHeaders(), $expected); @@ -241,7 +243,9 @@ class CakeEmailTest extends CakeTestCase { 'X-Something' => 'very nice', 'X-Other' => 'cool', 'X-Mailer' => 'CakePHP Email Component', - 'Date' => date(DATE_RFC2822) + 'Date' => date(DATE_RFC2822), + 'Content-Type' => 'text/plain; charset=UTF-8', + 'Content-Transfer-Encoding' => '7bit' ); $this->assertIdentical($this->CakeEmail->getHeaders(), $expected); @@ -253,7 +257,9 @@ class CakeEmailTest extends CakeTestCase { 'X-Something' => 'very nice', 'X-Other' => 'cool', 'X-Mailer' => 'CakePHP Email Component', - 'Date' => date(DATE_RFC2822) + 'Date' => date(DATE_RFC2822), + 'Content-Type' => 'text/plain; charset=UTF-8', + 'Content-Transfer-Encoding' => '7bit' ); $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true)), $expected); @@ -268,7 +274,9 @@ class CakeEmailTest extends CakeTestCase { 'X-Something' => 'very nice', 'X-Other' => 'cool', 'X-Mailer' => 'CakePHP Email Component', - 'Date' => date(DATE_RFC2822) + 'Date' => date(DATE_RFC2822), + 'Content-Type' => 'text/plain; charset=UTF-8', + 'Content-Transfer-Encoding' => '7bit' ); $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true, 'to' => true)), $expected); } From e6befef1c3f5ba2543ad28d7f336c3c759c8bf6c Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Thu, 3 Mar 2011 23:43:55 -0300 Subject: [PATCH 029/103] Added the method to render from views. --- lib/Cake/Network/CakeEmail.php | 97 ++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index cdd3d2b96..49c1f017f 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -606,7 +606,7 @@ class CakeEmail { $headers['Subject'] = $this->_subject; } - if (!empty($this->attachments)) { + if (!empty($this->_attachments)) { $this->_createBoundary(); $headers['MIME-Version'] = '1.0'; $headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"'; @@ -779,15 +779,15 @@ class CakeEmail { } $message = $this->_wrap($content); - if (empty($this->template)) { + if (empty($this->_template)) { $message = $this->_formatMessage($message); } else { - //$message = $this->_render($message); + $message = $this->_render($message); } $message[] = ''; $this->_message = $message; - if (!empty($this->attachments)) { + if (!empty($this->_attachments)) { //$this->_attachFiles(); } @@ -981,4 +981,93 @@ class CakeEmail { return $message; } +/** + * Render the contents using the current layout and template. + * + * @param string $content Content to render + * @return array Email ready to be sent + * @access private + */ + function _render($content) { + $viewClass = $this->Controller->view; + + if ($viewClass !== 'View') { + list($plugin, $viewClass) = pluginSplit($viewClass); + $viewClass = $viewClass . 'View'; + App::import('View', $this->Controller->view); + } + + $View = new $viewClass($this->Controller); + $View->layout = $this->layout; + $msg = array(); + + $content = implode("\n", $content); + + if ($this->_emailFormat === 'both') { + $htmlContent = $content; + if (!empty($this->_attachments)) { + $msg[] = '--' . $this->_boundary; + $msg[] = 'Content-Type: multipart/alternative; boundary="alt-' . $this->_boundary . '"'; + $msg[] = ''; + } + $msg[] = '--alt-' . $this->_boundary; + $msg[] = 'Content-Type: text/plain; charset=' . $this->charset; + $msg[] = 'Content-Transfer-Encoding: 7bit'; + $msg[] = ''; + + $content = $View->element('email' . DS . 'text' . DS . $this->_template, array('content' => $content), true); + $View->layoutPath = 'email' . DS . 'text'; + $content = explode("\n", $this->_textMessage = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($content))); + + $msg = array_merge($msg, $content); + + $msg[] = ''; + $msg[] = '--alt-' . $this->_boundary; + $msg[] = 'Content-Type: text/html; charset=' . $this->charset; + $msg[] = 'Content-Transfer-Encoding: 7bit'; + $msg[] = ''; + + $htmlContent = $View->element('email' . DS . 'html' . DS . $this->_template, array('content' => $htmlContent), true); + $View->layoutPath = 'email' . DS . 'html'; + $htmlContent = explode("\n", $this->_htmlMessage = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($htmlContent))); + $msg = array_merge($msg, $htmlContent); + $msg[] = ''; + $msg[] = '--alt-' . $this->_boundary . '--'; + $msg[] = ''; + + ClassRegistry::removeObject('view'); + return $msg; + } + + if (!empty($this->_attachments)) { + if ($this->_emailFormat === 'html') { + $msg[] = ''; + $msg[] = '--' . $this->_boundary; + $msg[] = 'Content-Type: text/html; charset=' . $this->charset; + $msg[] = 'Content-Transfer-Encoding: 7bit'; + $msg[] = ''; + } else { + $msg[] = '--' . $this->_boundary; + $msg[] = 'Content-Type: text/plain; charset=' . $this->charset; + $msg[] = 'Content-Transfer-Encoding: 7bit'; + $msg[] = ''; + } + } + + $content = $View->element('email' . DS . $this->_emailFormat . DS . $this->_template, array('content' => $content), true); + $View->layoutPath = 'email' . DS . $this->_emailFormat; + $content = explode("\n", $rendered = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($content))); + + if ($this->_emailFormat === 'html') { + $this->_htmlMessage = $rendered; + } else { + $this->_textMessage = $rendered; + } + + $msg = array_merge($msg, $content); + ClassRegistry::removeObject('view'); + + return $msg; + } + } From 8645411c65d605d107f1290e244e34ded76ac071 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Thu, 3 Mar 2011 23:46:04 -0300 Subject: [PATCH 030/103] Removed unused attribute. --- lib/Cake/Network/CakeEmail.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 49c1f017f..3764077d0 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -163,13 +163,6 @@ class CakeEmail { */ protected $_message = array(); -/** - * as per RFC2822 Section 2.1.1 - * - * @var integer - */ - public $lineLength = 70; - /** * Available formats to be sent. * From df2fe579cd2fd44f89db81b62d6c856bd7c62610 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 4 Mar 2011 00:20:55 -0300 Subject: [PATCH 031/103] Supporting pass the attach file name. --- lib/Cake/Network/CakeEmail.php | 15 +++++++++------ lib/Cake/tests/Case/Network/CakeEmailTest.php | 14 ++++++++++---- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 3764077d0..db8d54131 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -700,15 +700,18 @@ class CakeEmail { * @thrown SocketException */ public function setAttachments($attachments) { - $attachments = (array)$attachments; - foreach ($attachments as &$attach) { - $path = realpath($attach); + $attach = array(); + foreach ((array)$attachments as $name => $file) { + $path = realpath($file); if ($path === false) { throw new SocketException(__('File not found: "%s"', $attach)); } - $attach = $path; + if (is_int($name)) { + $name = basename($path); + } + $attach[$name] = $path; } - $this->_attachments = $attachments; + $this->_attachments = $attach; } /** @@ -721,7 +724,7 @@ class CakeEmail { public function addAttachments($attachments) { $current = $this->_attachments; $this->setAttachments($attachments); - $this->_attachments = array_unique(array_merge($current, $this->_attachments)); + $this->_attachments = array_merge($current, $this->_attachments); } /** diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 53b887975..29f14b342 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -288,7 +288,7 @@ class CakeEmailTest extends CakeTestCase { */ public function testAttachments() { $this->CakeEmail->setAttachments(WWW_ROOT . 'index.php'); - $expected = array(WWW_ROOT . 'index.php'); + $expected = array('index.php' => WWW_ROOT . 'index.php'); $this->assertIdentical($this->CakeEmail->getAttachments(), $expected); $this->CakeEmail->setAttachments(array()); @@ -296,9 +296,15 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->setAttachments(WWW_ROOT . 'index.php'); $this->CakeEmail->addAttachments(WWW_ROOT . 'test.php'); - $this->CakeEmail->addAttachments(array(WWW_ROOT . 'test.php', WWW_ROOT . '.htaccess')); - $expected = array(WWW_ROOT . 'index.php', WWW_ROOT . 'test.php', WWW_ROOT . '.htaccess'); - $this->assertIdentical(array_values($this->CakeEmail->getAttachments()), $expected); + $this->CakeEmail->addAttachments(array(WWW_ROOT . 'test.php')); + $this->CakeEmail->addAttachments(array('other.txt' => WWW_ROOT . 'test.php', 'ht' => WWW_ROOT . '.htaccess')); + $expected = array( + 'index.php' => WWW_ROOT . 'index.php', + 'test.php' => WWW_ROOT . 'test.php', + 'other.txt' => WWW_ROOT . 'test.php', + 'ht' => WWW_ROOT . '.htaccess' + ); + $this->assertIdentical($this->CakeEmail->getAttachments(), $expected); } /** From ffaee3d760973f88a144f3f3a1c9cc30ac22a372 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 4 Mar 2011 01:27:18 -0300 Subject: [PATCH 032/103] Included the method to attach files. --- lib/Cake/Network/CakeEmail.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index db8d54131..23d53e6bc 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -784,7 +784,7 @@ class CakeEmail { $this->_message = $message; if (!empty($this->_attachments)) { - //$this->_attachFiles(); + $this->_attachFiles(); } if (!is_null($this->_boundary)) { @@ -954,6 +954,28 @@ class CakeEmail { $this->_boundary = md5(uniqid(time())); } +/** + * Attach files by adding file contents inside boundaries. + * + * @return void + */ + function _attachFiles() { + foreach ($this->_attachments as $filename => $file) { + $handle = fopen($file, 'rb'); + $data = fread($handle, filesize($file)); + $data = chunk_split(base64_encode($data)) ; + fclose($handle); + + $this->_message[] = '--' . $this->_boundary; + $this->_message[] = 'Content-Type: application/octet-stream'; + $this->_message[] = 'Content-Transfer-Encoding: base64'; + $this->_message[] = 'Content-Disposition: attachment; filename="' . $filename . '"'; + $this->_message[] = ''; + $this->_message[] = $data; + $this->_message[] = ''; + } + } + /** * Format the message by seeing if it has attachments. * From d0f1843dd5e0ea0ad32dced74f1176d1d3831628 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 4 Mar 2011 08:06:09 -0300 Subject: [PATCH 033/103] Added tests to send email with contents. --- lib/Cake/Network/CakeEmail.php | 1 + lib/Cake/tests/Case/Network/CakeEmailTest.php | 70 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 23d53e6bc..8f985e4b3 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -17,6 +17,7 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ App::import('Core', array('Validation', 'Multibyte')); +App::import('Lib', 'email/AbstractTransport'); /** * Cake e-mail class. diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 29f14b342..1964d8287 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -42,6 +42,51 @@ class TestCakeEmail extends CakeEmail { } +/** + * Debug transport email + * + */ +class DebugTransport extends AbstractTransport { + +/** + * Last email body + * + * @var string + */ + public static $lastEmail = ''; + +/** + * Last email header + * + * @var string + */ + public static $lastHeader = ''; + +/** + * Include addresses in header + * + * @var boolean + */ + public static $includeAddresses = false; + +/** + * Send + * + * @param object $email CakeEmail + * @return boolean + */ + public function send(CakeEmail $email) { + self::$lastEmail = implode("\r\n", $email->getMessage()); + $options = array(); + if (self::$includeAddresses) { + $options = array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true); + } + self::$lastHeader = $this->_headersToString($email->getHeaders($options)); + return true; + } + +} + /** * CakeEmailTest class * @@ -308,11 +353,32 @@ class CakeEmailTest extends CakeTestCase { } /** - * testSend method + * testSendWithContent method * * @return void */ - public function testSend() { + public function testSendWithContent() { + $this->CakeEmail->reset(); + $this->CakeEmail->setTransport('debug'); + DebugTransport::$includeAddresses = false; + + $this->CakeEmail->setFrom('cake@cakephp.org'); + $this->CakeEmail->setTo(array('you@cakephp.org' => 'You')); + $this->CakeEmail->setSubject('My title'); + $result = $this->CakeEmail->send("Here is my body, with multi lines.\nThis is the second line.\r\n\r\nAnd the last."); + + $this->assertTrue($result); + $expected = "Here is my body, with multi lines.\r\nThis is the second line.\r\n\r\nAnd the last.\r\n\r\n"; + $this->assertIdentical(DebugTransport::$lastEmail, $expected); + $this->assertTrue((bool)strpos(DebugTransport::$lastHeader, 'Date: ')); + $this->assertTrue((bool)strpos(DebugTransport::$lastHeader, 'Message-ID: ')); + $this->assertFalse(strpos(DebugTransport::$lastHeader, 'To: ')); + + DebugTransport::$includeAddresses = true; + $this->CakeEmail->send("Other body"); + $this->assertIdentical(DebugTransport::$lastEmail, "Other body\r\n\r\n"); + $this->assertTrue((bool)strpos(DebugTransport::$lastHeader, 'Message-ID: ')); + $this->assertTrue((bool)strpos(DebugTransport::$lastHeader, 'To: ')); } /** From 6e15945e73167b6a04e033d046197c61ebc9b4fd Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 4 Mar 2011 08:29:38 -0300 Subject: [PATCH 034/103] Fixes in render. Tests added. --- lib/Cake/Network/CakeEmail.php | 26 +++++++++++--- lib/Cake/tests/Case/Network/CakeEmailTest.php | 35 +++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 8f985e4b3..f08f6e633 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -143,6 +143,13 @@ class CakeEmail { */ protected $_template = ''; +/** + * View for render + * + * @var string + */ + protected $_viewRender = 'View'; + /** * Text message * @@ -651,6 +658,16 @@ class CakeEmail { } } +/** + * Set view class for render + * + * @param string $viewClass + * @return void + */ + public function setViewRender($viewClass) { + $this->_viewRender = $viewClass; + } + /** * Set the email format * @@ -823,6 +840,7 @@ class CakeEmail { $this->_headers = array(); $this->_layout = 'default'; $this->_template = ''; + $this->_viewRender = 'View'; $this->_textMessage = ''; $this->_htmlMessage = ''; $this->_message = ''; @@ -1008,16 +1026,16 @@ class CakeEmail { * @access private */ function _render($content) { - $viewClass = $this->Controller->view; + $viewClass = $this->_viewRender; if ($viewClass !== 'View') { list($plugin, $viewClass) = pluginSplit($viewClass); $viewClass = $viewClass . 'View'; - App::import('View', $this->Controller->view); + App::import('View', $this->_viewRender); } - $View = new $viewClass($this->Controller); - $View->layout = $this->layout; + $View = new $viewClass(null); + $View->layout = $this->_layout; $msg = array(); $content = implode("\n", $content); diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 1964d8287..df938da40 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -102,6 +102,20 @@ class CakeEmailTest extends CakeTestCase { public function setUp() { parent::setUp(); $this->CakeEmail = new TestCakeEmail(); + + App::build(array( + 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS) + )); + } + +/** + * tearDown method + * + * @return void + */ + function tearDown() { + parent::tearDown(); + App::build(); } /** @@ -381,6 +395,27 @@ class CakeEmailTest extends CakeTestCase { $this->assertTrue((bool)strpos(DebugTransport::$lastHeader, 'To: ')); } +/** + * testSendRender method + * + * @return void + */ + public function testSendRender() { + $this->CakeEmail->reset(); + $this->CakeEmail->setTransport('debug'); + DebugTransport::$includeAddresses = true; + + $this->CakeEmail->setFrom('cake@cakephp.org'); + $this->CakeEmail->setTo(array('you@cakephp.org' => 'You')); + $this->CakeEmail->setSubject('My title'); + $this->CakeEmail->setLayout('default', 'default'); + $result = $this->CakeEmail->send(); + + $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, 'This email was sent using the CakePHP Framework')); + $this->assertTrue((bool)strpos(DebugTransport::$lastHeader, 'Message-ID: ')); + $this->assertTrue((bool)strpos(DebugTransport::$lastHeader, 'To: ')); + } + /** * testReset method * From f128711fa56cfd9f6a8275151f96fab379670c86 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 4 Mar 2011 09:00:32 -0300 Subject: [PATCH 035/103] Test to all getters and setters of addresses. --- lib/Cake/tests/Case/Network/CakeEmailTest.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index df938da40..ab568a5d3 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -235,6 +235,42 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($result, $expected); } +/** + * testAddresses method + * + * @return void + */ + public function testAddresses() { + $this->CakeEmail->reset(); + $this->CakeEmail->setFrom('cake@cakephp.org', 'CakePHP'); + $this->CakeEmail->setReplyTo('replyto@cakephp.org', 'ReplyTo CakePHP'); + $this->CakeEmail->setReadReceipt('readreceipt@cakephp.org', 'ReadReceipt CakePHP'); + $this->CakeEmail->setReturnPath('returnpath@cakephp.org', 'ReturnPath CakePHP'); + $this->CakeEmail->setTo('to@cakephp.org', 'To CakePHP'); + $this->CakeEmail->setCc('cc@cakephp.org', 'Cc CakePHP'); + $this->CakeEmail->setBcc('bcc@cakephp.org', 'Bcc CakePHP'); + $this->CakeEmail->addTo('to2@cakephp.org', 'To2 CakePHP'); + $this->CakeEmail->addCc('cc2@cakephp.org', 'Cc2 CakePHP'); + $this->CakeEmail->addBcc('bcc2@cakephp.org', 'Bcc2 CakePHP'); + + $this->assertIdentical($this->CakeEmail->getFrom(), array('cake@cakephp.org' => 'CakePHP')); + $this->assertIdentical($this->CakeEmail->getReplyTo(), array('replyto@cakephp.org' => 'ReplyTo CakePHP')); + $this->assertIdentical($this->CakeEmail->getReadReceipt(), array('readreceipt@cakephp.org' => 'ReadReceipt CakePHP')); + $this->assertIdentical($this->CakeEmail->getReturnPath(), array('returnpath@cakephp.org' => 'ReturnPath CakePHP')); + $this->assertIdentical($this->CakeEmail->getTo(), array('to@cakephp.org' => 'To CakePHP', 'to2@cakephp.org' => 'To2 CakePHP')); + $this->assertIdentical($this->CakeEmail->getCc(), array('cc@cakephp.org' => 'Cc CakePHP', 'cc2@cakephp.org' => 'Cc2 CakePHP')); + $this->assertIdentical($this->CakeEmail->getBcc(), array('bcc@cakephp.org' => 'Bcc CakePHP', 'bcc2@cakephp.org' => 'Bcc2 CakePHP')); + + $headers = $this->CakeEmail->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true)); + $this->assertIdentical($headers['From'], 'CakePHP '); + $this->assertIdentical($headers['Reply-To'], 'ReplyTo CakePHP '); + $this->assertIdentical($headers['Disposition-Notification-To'], 'ReadReceipt CakePHP '); + $this->assertIdentical($headers['Return-Path'], 'ReturnPath CakePHP '); + $this->assertIdentical($headers['To'], 'To CakePHP , To2 CakePHP '); + $this->assertIdentical($headers['Cc'], 'Cc CakePHP , Cc2 CakePHP '); + $this->assertIdentical($headers['Bcc'], 'Bcc CakePHP , Bcc2 CakePHP '); + } + /** * testMessageId method * From 985743dc5012495f2e04145359a7bb90b4c951df Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 4 Mar 2011 09:07:22 -0300 Subject: [PATCH 036/103] Removed debug code line. --- lib/Cake/Network/CakeEmail.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index f08f6e633..41f028269 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -929,7 +929,6 @@ class CakeEmail { continue; } if ($char === ' ' && $tmpLineLength >= self::LINE_LENGTH_SHOULD) { - pr(1); $formatted[] = $tmpLine; $tmpLineLength = 0; continue; From f661e37ef14b3bc1fbfe3063e6a9a690c5741cde Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 4 Mar 2011 09:48:51 -0300 Subject: [PATCH 037/103] Added more tests to wrap. Fixed to not cut words with more than should limit. --- lib/Cake/Network/CakeEmail.php | 2 +- lib/Cake/tests/Case/Network/CakeEmailTest.php | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 41f028269..7412b26fa 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -889,7 +889,7 @@ class CakeEmail { $line = '.' . $line; } if (!preg_match('/\<[a-z]/i', $line)) { - $formatted = array_merge($formatted, explode("\n", wordwrap($line, self::LINE_LENGTH_SHOULD, "\n", true))); + $formatted = array_merge($formatted, explode("\n", wordwrap($line, self::LINE_LENGTH_SHOULD, "\n"))); continue; } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index ab568a5d3..46a8ea3f6 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -509,6 +509,26 @@ class CakeEmailTest extends CakeTestCase { '' ); $this->assertIdentical($result, $expected); + + $text = 'Lorem ipsum ok'; + $result = $this->CakeEmail->wrap($text); + $expected = array( + 'Lorem ipsum', + '', + 'ok', + '' + ); + $this->assertIdentical($result, $expected); + + $text = 'Lorem ipsum withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite ok.'; + $result = $this->CakeEmail->wrap($text); + $expected = array( + 'Lorem ipsum', + 'withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite', + 'ok.', + '' + ); + $this->assertIdentical($result, $expected); } } From 6e97de5d38b0342b45119bf1510901bf1b1d58a2 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Mon, 21 Mar 2011 08:18:36 -0400 Subject: [PATCH 038/103] Replace the get/set methods by only one method in addresses and subject. --- lib/Cake/Network/CakeEmail.php | 152 ++++++------------ lib/Cake/tests/Case/Network/CakeEmailTest.php | 100 ++++++------ 2 files changed, 102 insertions(+), 150 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 7412b26fa..12fa80570 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -227,97 +227,76 @@ class CakeEmail { } /** - * Set From + * From * * @param mixed $email * @param string $name - * @return void + * @return mixed * @thrown SocketException */ - public function setFrom($email, $name = null) { - $this->_setEmail1('_from', $email, $name, __('From requires only 1 email address.')); + public function from($email = null, $name = null) { + if ($email === null) { + return $this->_from; + } + $this->_setEmailSingle('_from', $email, $name, __('From requires only 1 email address.')); } /** - * Get the From information - * - * @return array Key is email, Value is name. If Key is equal of Value, the name is not specified - */ - public function getFrom() { - return $this->_from; - } - -/** - * Set Reply-To + * Reply-To * * @param mixed $email * @param string $name - * @return void + * @return mixed * @thrown SocketException */ - public function setReplyTo($email, $name = null) { - $this->_setEmail1('_replyTo', $email, $name, __('Reply-To requires only 1 email address.')); + public function replyTo($email = null, $name = null) { + if ($email === null) { + return $this->_replyTo; + } + $this->_setEmailSingle('_replyTo', $email, $name, __('Reply-To requires only 1 email address.')); } /** - * Get the ReplyTo information - * - * @return array Key is email, Value is name. If Key is equal of Value, the name is not specified - */ - public function getReplyTo() { - return $this->_replyTo; - } - -/** - * Set Read Receipt (Disposition-Notification-To header) + * Read Receipt (Disposition-Notification-To header) * * @param mixed $email * @param string $name - * @return void + * @return mixed * @thrown SocketException */ - public function setReadReceipt($email, $name = null) { - $this->_setEmail1('_readReceipt', $email, $name, __('Disposition-Notification-To requires only 1 email address.')); + public function readReceipt($email = null, $name = null) { + if ($email === null) { + return $this->_readReceipt; + } + $this->_setEmailSingle('_readReceipt', $email, $name, __('Disposition-Notification-To requires only 1 email address.')); } /** - * Get the Read Receipt (Disposition-Notification-To header) information - * - * @return array Key is email, Value is name. If Key is equal of Value, the name is not specified - */ - public function getReadReceipt() { - return $this->_readReceipt; - } - -/** - * Set Return Path + * Return Path * * @param mixed $email * @param string $name - * @return void + * @return mixed * @thrown SocketException */ - public function setReturnPath($email, $name = null) { - $this->_setEmail1('_returnPath', $email, $name, __('Return-Path requires only 1 email address.')); + public function returnPath($email = null, $name = null) { + if ($email === null) { + return $this->_returnPath; + } + $this->_setEmailSingle('_returnPath', $email, $name, __('Return-Path requires only 1 email address.')); } /** - * Get the Return Path information + * To * - * @return array Key is email, Value is name. If Key is equal of Value, the name is not specified - */ - public function getReturnPath() { - return $this->_returnPath; - } - -/** - * Set To - * - * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) + * @param mixed $email Null to get, String with email, Array with email as key, name as value or email as value (without name) * @param string $name - * @return void + * @return mixed */ - public function setTo($email, $name = null) { + public function to($email = null, $name = null) { + if ($email === null) { + return $this->_to; + } $this->_setEmail('_to', $email, $name); } @@ -333,22 +312,16 @@ class CakeEmail { } /** - * Get To - * - * @return array - */ - public function getTo() { - return $this->_to; - } - -/** - * Set Cc + * Cc * * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) * @param string $name - * @return void + * @return mixed */ - public function setCc($email, $name = null) { + public function cc($email = null, $name = null) { + if ($email === null) { + return $this->_cc; + } $this->_setEmail('_cc', $email, $name); } @@ -364,22 +337,16 @@ class CakeEmail { } /** - * Get Cc - * - * @return array - */ - public function getCc() { - return $this->_cc; - } - -/** - * Set Bcc + * Bcc * * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) * @param string $name * @return void */ - public function setBcc($email, $name = null) { + public function bcc($email = null, $name = null) { + if ($email === null) { + return $this->_bcc; + } $this->_setEmail('_bcc', $email, $name); } @@ -394,15 +361,6 @@ class CakeEmail { $this->_addEmail('_bcc', $email, $name); } -/** - * Get Bcc - * - * @return array - */ - public function getBcc() { - return $this->_bcc; - } - /** * Set email * @@ -446,7 +404,7 @@ class CakeEmail { * @return void * @thrown SocketExpceiton */ - protected function _setEmail1($varName, $email, $name, $throwMessage) { + protected function _setEmailSingle($varName, $email, $name, $throwMessage) { $current = $this->{$varName}; $this->_setEmail($varName, $email, $name); if (count($this->{$varName}) !== 1) { @@ -491,21 +449,15 @@ class CakeEmail { * Set Subject * * @param string $subject - * @return void + * @return mixed */ - public function setSubject($subject) { + public function subject($subject = null) { + if ($subject === null) { + return $this->_subject; + } $this->_subject = (string)$subject; } -/** - * Get Subject - * - * @return string - */ - public function getSubject() { - return $this->_subject; - } - /** * Sets headers for the message * diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 46a8ea3f6..73ba6890d 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -124,21 +124,21 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testFrom() { - $this->assertIdentical($this->CakeEmail->getFrom(), array()); + $this->assertIdentical($this->CakeEmail->from(), array()); - $this->CakeEmail->setFrom('cake@cakephp.org'); + $this->CakeEmail->from('cake@cakephp.org'); $expected = array('cake@cakephp.org' => 'cake@cakephp.org'); - $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + $this->assertIdentical($this->CakeEmail->from(), $expected); - $this->CakeEmail->setFrom(array('cake@cakephp.org')); - $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + $this->CakeEmail->from(array('cake@cakephp.org')); + $this->assertIdentical($this->CakeEmail->from(), $expected); - $this->CakeEmail->setFrom('cake@cakephp.org', 'CakePHP'); + $this->CakeEmail->from('cake@cakephp.org', 'CakePHP'); $expected = array('cake@cakephp.org' => 'CakePHP'); - $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + $this->assertIdentical($this->CakeEmail->from(), $expected); - $this->CakeEmail->setFrom(array('cake@cakephp.org' => 'CakePHP')); - $this->assertIdentical($this->CakeEmail->getFrom(), $expected); + $this->CakeEmail->from(array('cake@cakephp.org' => 'CakePHP')); + $this->assertIdentical($this->CakeEmail->from(), $expected); } /** @@ -147,28 +147,28 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testTo() { - $this->assertIdentical($this->CakeEmail->getTo(), array()); + $this->assertIdentical($this->CakeEmail->to(), array()); - $this->CakeEmail->setTo('cake@cakephp.org'); + $this->CakeEmail->to('cake@cakephp.org'); $expected = array('cake@cakephp.org' => 'cake@cakephp.org'); - $this->assertIdentical($this->CakeEmail->getTo(), $expected); + $this->assertIdentical($this->CakeEmail->to(), $expected); - $this->CakeEmail->setTo('cake@cakephp.org', 'CakePHP'); + $this->CakeEmail->to('cake@cakephp.org', 'CakePHP'); $expected = array('cake@cakephp.org' => 'CakePHP'); - $this->assertIdentical($this->CakeEmail->getTo(), $expected); + $this->assertIdentical($this->CakeEmail->to(), $expected); $list = array( 'cake@cakephp.org' => 'Cake PHP', 'cake-php@googlegroups.com' => 'Cake Groups', 'root@cakephp.org' ); - $this->CakeEmail->setTo($list); + $this->CakeEmail->to($list); $expected = array( 'cake@cakephp.org' => 'Cake PHP', 'cake-php@googlegroups.com' => 'Cake Groups', 'root@cakephp.org' => 'root@cakephp.org' ); - $this->assertIdentical($this->CakeEmail->getTo(), $expected); + $this->assertIdentical($this->CakeEmail->to(), $expected); $this->CakeEmail->addTo('jrbasso@cakephp.org'); $this->CakeEmail->addTo('mark_story@cakephp.org', 'Mark Story'); @@ -182,7 +182,7 @@ class CakeEmailTest extends CakeTestCase { 'phpnut@cakephp.org' => 'PhpNut', 'jose_zap@cakephp.org' => 'jose_zap@cakephp.org' ); - $this->assertIdentical($this->CakeEmail->getTo(), $expected); + $this->assertIdentical($this->CakeEmail->to(), $expected); } /** @@ -209,7 +209,7 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testInvalidEmail($value) { - $this->CakeEmail->setTo($value); + $this->CakeEmail->to($value); } /** @@ -242,24 +242,24 @@ class CakeEmailTest extends CakeTestCase { */ public function testAddresses() { $this->CakeEmail->reset(); - $this->CakeEmail->setFrom('cake@cakephp.org', 'CakePHP'); - $this->CakeEmail->setReplyTo('replyto@cakephp.org', 'ReplyTo CakePHP'); - $this->CakeEmail->setReadReceipt('readreceipt@cakephp.org', 'ReadReceipt CakePHP'); - $this->CakeEmail->setReturnPath('returnpath@cakephp.org', 'ReturnPath CakePHP'); - $this->CakeEmail->setTo('to@cakephp.org', 'To CakePHP'); - $this->CakeEmail->setCc('cc@cakephp.org', 'Cc CakePHP'); - $this->CakeEmail->setBcc('bcc@cakephp.org', 'Bcc CakePHP'); + $this->CakeEmail->from('cake@cakephp.org', 'CakePHP'); + $this->CakeEmail->replyTo('replyto@cakephp.org', 'ReplyTo CakePHP'); + $this->CakeEmail->readReceipt('readreceipt@cakephp.org', 'ReadReceipt CakePHP'); + $this->CakeEmail->returnPath('returnpath@cakephp.org', 'ReturnPath CakePHP'); + $this->CakeEmail->to('to@cakephp.org', 'To CakePHP'); + $this->CakeEmail->cc('cc@cakephp.org', 'Cc CakePHP'); + $this->CakeEmail->bcc('bcc@cakephp.org', 'Bcc CakePHP'); $this->CakeEmail->addTo('to2@cakephp.org', 'To2 CakePHP'); $this->CakeEmail->addCc('cc2@cakephp.org', 'Cc2 CakePHP'); $this->CakeEmail->addBcc('bcc2@cakephp.org', 'Bcc2 CakePHP'); - $this->assertIdentical($this->CakeEmail->getFrom(), array('cake@cakephp.org' => 'CakePHP')); - $this->assertIdentical($this->CakeEmail->getReplyTo(), array('replyto@cakephp.org' => 'ReplyTo CakePHP')); - $this->assertIdentical($this->CakeEmail->getReadReceipt(), array('readreceipt@cakephp.org' => 'ReadReceipt CakePHP')); - $this->assertIdentical($this->CakeEmail->getReturnPath(), array('returnpath@cakephp.org' => 'ReturnPath CakePHP')); - $this->assertIdentical($this->CakeEmail->getTo(), array('to@cakephp.org' => 'To CakePHP', 'to2@cakephp.org' => 'To2 CakePHP')); - $this->assertIdentical($this->CakeEmail->getCc(), array('cc@cakephp.org' => 'Cc CakePHP', 'cc2@cakephp.org' => 'Cc2 CakePHP')); - $this->assertIdentical($this->CakeEmail->getBcc(), array('bcc@cakephp.org' => 'Bcc CakePHP', 'bcc2@cakephp.org' => 'Bcc2 CakePHP')); + $this->assertIdentical($this->CakeEmail->from(), array('cake@cakephp.org' => 'CakePHP')); + $this->assertIdentical($this->CakeEmail->replyTo(), array('replyto@cakephp.org' => 'ReplyTo CakePHP')); + $this->assertIdentical($this->CakeEmail->readReceipt(), array('readreceipt@cakephp.org' => 'ReadReceipt CakePHP')); + $this->assertIdentical($this->CakeEmail->returnPath(), array('returnpath@cakephp.org' => 'ReturnPath CakePHP')); + $this->assertIdentical($this->CakeEmail->to(), array('to@cakephp.org' => 'To CakePHP', 'to2@cakephp.org' => 'To2 CakePHP')); + $this->assertIdentical($this->CakeEmail->cc(), array('cc@cakephp.org' => 'Cc CakePHP', 'cc2@cakephp.org' => 'Cc2 CakePHP')); + $this->assertIdentical($this->CakeEmail->bcc(), array('bcc@cakephp.org' => 'Bcc CakePHP', 'bcc2@cakephp.org' => 'Bcc2 CakePHP')); $headers = $this->CakeEmail->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true)); $this->assertIdentical($headers['From'], 'CakePHP '); @@ -306,14 +306,14 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testSubject() { - $this->CakeEmail->setSubject('You have a new message.'); - $this->assertIdentical($this->CakeEmail->getSubject(), 'You have a new message.'); + $this->CakeEmail->subject('You have a new message.'); + $this->assertIdentical($this->CakeEmail->subject(), 'You have a new message.'); - $this->CakeEmail->setSubject(1); - $this->assertIdentical($this->CakeEmail->getSubject(), '1'); + $this->CakeEmail->subject(1); + $this->assertIdentical($this->CakeEmail->subject(), '1'); - $this->CakeEmail->setSubject(array('something')); - $this->assertIdentical($this->CakeEmail->getSubject(), 'Array'); + $this->CakeEmail->subject(array('something')); + $this->assertIdentical($this->CakeEmail->subject(), 'Array'); } /** @@ -344,7 +344,7 @@ class CakeEmailTest extends CakeTestCase { ); $this->assertIdentical($this->CakeEmail->getHeaders(), $expected); - $this->CakeEmail->setFrom('cake@cakephp.org'); + $this->CakeEmail->from('cake@cakephp.org'); $this->assertIdentical($this->CakeEmail->getHeaders(), $expected); $expected = array( @@ -358,11 +358,11 @@ class CakeEmailTest extends CakeTestCase { ); $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true)), $expected); - $this->CakeEmail->setFrom('cake@cakephp.org', 'CakePHP'); + $this->CakeEmail->from('cake@cakephp.org', 'CakePHP'); $expected['From'] = 'CakePHP '; $this->assertIdentical($this->CakeEmail->getHeaders(array('from' => true)), $expected); - $this->CakeEmail->setTo(array('cake@cakephp.org', 'php@cakephp.org' => 'CakePHP')); + $this->CakeEmail->to(array('cake@cakephp.org', 'php@cakephp.org' => 'CakePHP')); $expected = array( 'From' => 'CakePHP ', 'To' => 'cake@cakephp.org, CakePHP ', @@ -412,9 +412,9 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->setTransport('debug'); DebugTransport::$includeAddresses = false; - $this->CakeEmail->setFrom('cake@cakephp.org'); - $this->CakeEmail->setTo(array('you@cakephp.org' => 'You')); - $this->CakeEmail->setSubject('My title'); + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to(array('you@cakephp.org' => 'You')); + $this->CakeEmail->subject('My title'); $result = $this->CakeEmail->send("Here is my body, with multi lines.\nThis is the second line.\r\n\r\nAnd the last."); $this->assertTrue($result); @@ -441,9 +441,9 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->setTransport('debug'); DebugTransport::$includeAddresses = true; - $this->CakeEmail->setFrom('cake@cakephp.org'); - $this->CakeEmail->setTo(array('you@cakephp.org' => 'You')); - $this->CakeEmail->setSubject('My title'); + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to(array('you@cakephp.org' => 'You')); + $this->CakeEmail->subject('My title'); $this->CakeEmail->setLayout('default', 'default'); $result = $this->CakeEmail->send(); @@ -458,11 +458,11 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testReset() { - $this->CakeEmail->setTo('cake@cakephp.org'); - $this->assertIdentical($this->CakeEmail->getTo(), array('cake@cakephp.org' => 'cake@cakephp.org')); + $this->CakeEmail->to('cake@cakephp.org'); + $this->assertIdentical($this->CakeEmail->to(), array('cake@cakephp.org' => 'cake@cakephp.org')); $this->CakeEmail->reset(); - $this->assertIdentical($this->CakeEmail->getTo(), array()); + $this->assertIdentical($this->CakeEmail->to(), array()); } /** From 90d1f62131440508ee12bdcea7f15dd7e9dcb26a Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Mon, 21 Mar 2011 08:30:16 -0400 Subject: [PATCH 039/103] Changed others functions to remove the get/set by only one method. --- lib/Cake/Network/CakeEmail.php | 72 +++++++++++-------- lib/Cake/tests/Case/Network/CakeEmailTest.php | 30 ++++---- 2 files changed, 57 insertions(+), 45 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 12fa80570..943bde8d5 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -459,7 +459,7 @@ class CakeEmail { } /** - * Sets headers for the message + * Sets eaders for the message * * @param array Associative array containing headers to be set. * @return void @@ -597,13 +597,19 @@ class CakeEmail { } /** - * Set the layout and template + * Layout and template * * @param string $layout * @param string $template - * @return void + * @return mixed */ - public function setLayout($layout, $template = null) { + public function layout($layout = null, $template = null) { + if ($layout === null) { + return array( + 'layout' => $this->_layout, + 'template' => $this->_template + ); + } $this->_layout = (string)$layout; if ($template !== null) { $this->_template = (string)$template; @@ -611,23 +617,29 @@ class CakeEmail { } /** - * Set view class for render + * View class for render * * @param string $viewClass - * @return void + * @return mixed */ - public function setViewRender($viewClass) { + public function viewRender($viewClass = null) { + if ($viewClass === null) { + return $this->_viewRender; + } $this->_viewRender = $viewClass; } /** - * Set the email format + * Email format * * @param string $format - * @return void + * @return mixed * @thrown SocketException */ - public function setEmailFormat($format) { + public function emailFormat($format = null) { + if ($format === null) { + return $this->_emailFormat; + } if (!in_array($format, $this->_emailFormatAvailable)) { throw new SocketException(__('Format not available.')); } @@ -635,23 +647,29 @@ class CakeEmail { } /** - * Set transport name + * Transport name * * @param string $name - * @return void + * @return mixed */ - public function setTransport($name) { + public function transport($name = null) { + if ($name === null) { + return $this->_transportName; + } $this->_transportName = (string)$name; } /** - * Set Message-ID + * Message-ID * * @param mixed $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID - * @return void + * @return mixed * @thrown SocketException */ - public function setMessageID($message) { + public function messageID($message = null) { + if ($message === null) { + return $this->_messageId; + } if (is_bool($message)) { $this->_messageId = $message; } else { @@ -663,13 +681,16 @@ class CakeEmail { } /** - * Set attachments + * Attachments * * @param mixed $attachments String with the filename or array with filenames - * @return void + * @return mixed * @thrown SocketException */ - public function setAttachments($attachments) { + public function attachments($attachments = null) { + if ($attachments === null) { + return $this->_attachments; + } $attach = array(); foreach ((array)$attachments as $name => $file) { $path = realpath($file); @@ -693,25 +714,16 @@ class CakeEmail { */ public function addAttachments($attachments) { $current = $this->_attachments; - $this->setAttachments($attachments); + $this->attachments($attachments); $this->_attachments = array_merge($current, $this->_attachments); } -/** - * Get attachments - * - * @return array - */ - public function getAttachments() { - return $this->_attachments; - } - /** * Get generated message (used by transport classes) * * @return array */ - public function getMessage() { + public function message() { return $this->_message; } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 73ba6890d..78e330b3e 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -76,7 +76,7 @@ class DebugTransport extends AbstractTransport { * @return boolean */ public function send(CakeEmail $email) { - self::$lastEmail = implode("\r\n", $email->getMessage()); + self::$lastEmail = implode("\r\n", $email->message()); $options = array(); if (self::$includeAddresses) { $options = array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true); @@ -277,15 +277,15 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testMessageId() { - $this->CakeEmail->setMessageId(true); + $this->CakeEmail->messageId(true); $result = $this->CakeEmail->getHeaders(); $this->assertTrue(isset($result['Message-ID'])); - $this->CakeEmail->setMessageId(false); + $this->CakeEmail->messageId(false); $result = $this->CakeEmail->getHeaders(); $this->assertFalse(isset($result['Message-ID'])); - $this->CakeEmail->setMessageId(''); + $this->CakeEmail->messageId(''); $result = $this->CakeEmail->getHeaders(); $this->assertIdentical($result['Message-ID'], ''); } @@ -297,7 +297,7 @@ class CakeEmailTest extends CakeTestCase { * @expectedException SocketException */ public function testMessageIdInvalid() { - $this->CakeEmail->setMessageId('my-email@localhost'); + $this->CakeEmail->messageId('my-email@localhost'); } /** @@ -322,7 +322,7 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testHeaders() { - $this->CakeEmail->setMessageId(false); + $this->CakeEmail->messageId(false); $this->CakeEmail->setHeaders(array('X-Something' => 'nice')); $expected = array( 'X-Something' => 'nice', @@ -382,14 +382,14 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testAttachments() { - $this->CakeEmail->setAttachments(WWW_ROOT . 'index.php'); + $this->CakeEmail->attachments(WWW_ROOT . 'index.php'); $expected = array('index.php' => WWW_ROOT . 'index.php'); - $this->assertIdentical($this->CakeEmail->getAttachments(), $expected); + $this->assertIdentical($this->CakeEmail->attachments(), $expected); - $this->CakeEmail->setAttachments(array()); - $this->assertIdentical($this->CakeEmail->getAttachments(), array()); + $this->CakeEmail->attachments(array()); + $this->assertIdentical($this->CakeEmail->attachments(), array()); - $this->CakeEmail->setAttachments(WWW_ROOT . 'index.php'); + $this->CakeEmail->attachments(WWW_ROOT . 'index.php'); $this->CakeEmail->addAttachments(WWW_ROOT . 'test.php'); $this->CakeEmail->addAttachments(array(WWW_ROOT . 'test.php')); $this->CakeEmail->addAttachments(array('other.txt' => WWW_ROOT . 'test.php', 'ht' => WWW_ROOT . '.htaccess')); @@ -399,7 +399,7 @@ class CakeEmailTest extends CakeTestCase { 'other.txt' => WWW_ROOT . 'test.php', 'ht' => WWW_ROOT . '.htaccess' ); - $this->assertIdentical($this->CakeEmail->getAttachments(), $expected); + $this->assertIdentical($this->CakeEmail->attachments(), $expected); } /** @@ -409,7 +409,7 @@ class CakeEmailTest extends CakeTestCase { */ public function testSendWithContent() { $this->CakeEmail->reset(); - $this->CakeEmail->setTransport('debug'); + $this->CakeEmail->transport('debug'); DebugTransport::$includeAddresses = false; $this->CakeEmail->from('cake@cakephp.org'); @@ -438,13 +438,13 @@ class CakeEmailTest extends CakeTestCase { */ public function testSendRender() { $this->CakeEmail->reset(); - $this->CakeEmail->setTransport('debug'); + $this->CakeEmail->transport('debug'); DebugTransport::$includeAddresses = true; $this->CakeEmail->from('cake@cakephp.org'); $this->CakeEmail->to(array('you@cakephp.org' => 'You')); $this->CakeEmail->subject('My title'); - $this->CakeEmail->setLayout('default', 'default'); + $this->CakeEmail->layout('default', 'default'); $result = $this->CakeEmail->send(); $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, 'This email was sent using the CakePHP Framework')); From 1814168ec7572f9f1e6409d3d0ea17d7e47cf6a0 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Mon, 21 Mar 2011 08:35:17 -0400 Subject: [PATCH 040/103] Added kind of visibility to missed methods. --- lib/Cake/Network/CakeEmail.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 943bde8d5..a29c40073 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -837,9 +837,8 @@ class CakeEmail { * * @param string $message Message to wrap * @return array Wrapped message - * @access protected */ - function _wrap($message) { + protected function _wrap($message) { $message = str_replace(array("\r\n", "\r"), "\n", $message); $lines = explode("\n", $message); $formatted = array(); @@ -932,7 +931,7 @@ class CakeEmail { * * @return void */ - function _createboundary() { + protected function _createboundary() { $this->_boundary = md5(uniqid(time())); } @@ -941,7 +940,7 @@ class CakeEmail { * * @return void */ - function _attachFiles() { + protected function _attachFiles() { foreach ($this->_attachments as $filename => $file) { $handle = fopen($file, 'rb'); $data = fread($handle, filesize($file)); @@ -964,7 +963,7 @@ class CakeEmail { * @param array $message Message to format * @return array */ - function _formatMessage($message) { + protected function _formatMessage($message) { if (!empty($this->_attachments)) { $prefix = array('--' . $this->_boundary); if ($this->_emailFormat === 'text') { @@ -988,7 +987,7 @@ class CakeEmail { * @return array Email ready to be sent * @access private */ - function _render($content) { + protected function _render($content) { $viewClass = $this->_viewRender; if ($viewClass !== 'View') { From 5740d12b74d57635db08d2a0617a0a7107e16d9e Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 3 Apr 2011 22:41:40 -0400 Subject: [PATCH 041/103] Fixed wrong attribute name. --- cake/libs/email/smtp_transport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/libs/email/smtp_transport.php b/cake/libs/email/smtp_transport.php index 6f3a09746..17a2643e7 100644 --- a/cake/libs/email/smtp_transport.php +++ b/cake/libs/email/smtp_transport.php @@ -202,7 +202,7 @@ class SmtpTransport extends AbstractTransport { while ($checkCode !== false) { $response = ''; $startTime = time(); - while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->smtpOptions['timeout'])) { + while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->_config['timeout'])) { $response .= $this->_socket->read(); } if (substr($response, -2) !== "\r\n") { From 92967833001af5246a8e5ab29ac57fd1385c6cb7 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 3 Apr 2011 22:42:05 -0400 Subject: [PATCH 042/103] Tests for smtp connect. --- .../cases/libs/email/smtp_transport.test.php | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 cake/tests/cases/libs/email/smtp_transport.test.php diff --git a/cake/tests/cases/libs/email/smtp_transport.test.php b/cake/tests/cases/libs/email/smtp_transport.test.php new file mode 100644 index 000000000..5faf63489 --- /dev/null +++ b/cake/tests/cases/libs/email/smtp_transport.test.php @@ -0,0 +1,142 @@ + + * 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://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests + * @package cake.tests.cases.libs.email + * @since CakePHP(tm) v 2.0.0 + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + */ +App::import('Lib', array('email/AbstractTransport', 'email/SmtpTransport')); + +/** + * Help to test SmtpTransport + * + */ +class SmtpTestTransport extends SmtpTransport { + +/** + * Config the timeout + * + * @var array + */ + protected $_config = array( + 'timeout' => 30 + ); + +/** + * Helper to change the socket + * + * @param object $socket + * @return void + */ + public function setSocket(CakeSocket $socket) { + $this->_socket = $socket; + } + +/** + * Disabled the socket change + * + * @return void + */ + protected function _generateSocket() { + return; + } + +/** + * Magic function to call protected methods + * + * @param string $method + * @param string $args + * @return mixed + */ + public function __call($method, $args) { + $method = '_' . $method; + return $this->$method(); + } + +} + +/** + * Test case + * + */ +class StmpProtocolTest extends CakeTestCase { + +/** + * Setup + * + * @return void + */ + public function setUp() { + if (!class_exists('MockSocket')) { + $this->getMock('CakeSocket', array('read', 'write', 'connect'), array(), 'MockSocket'); + } + $this->socket = new MockSocket(); + + $this->SmtpTransport = new SmtpTestTransport(); + $this->SmtpTransport->setSocket($this->socket); + } + +/** + * testConnectEhlo method + * + * @return void + */ + public function testConnectEhlo() { + $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 Accepted\r\n")); + $this->SmtpTransport->connect(); + } + +/** + * testConnectHelo method + * + * @return void + */ + public function testConnectHelo() { + $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("200 Not Accepted\r\n")); + $this->socket->expects($this->at(5))->method('write')->with("HELO localhost\r\n"); + $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250 Accepted\r\n")); + $this->SmtpTransport->connect(); + } + +/** + * testConnectFail method + * + * @expectedException Exception + * @return void + */ + public function testConnetFail() { + $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("200 Not Accepted\r\n")); + $this->socket->expects($this->at(5))->method('write')->with("HELO localhost\r\n"); + $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("200 Not Accepted\r\n")); + $this->SmtpTransport->connect(); + } + +} \ No newline at end of file From 174fae7d537c72e6a4b95ff8db24de6313250a2b Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 3 Apr 2011 23:29:08 -0400 Subject: [PATCH 043/103] Tests to smtp auth. --- .../cases/libs/email/smtp_transport.test.php | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/cake/tests/cases/libs/email/smtp_transport.test.php b/cake/tests/cases/libs/email/smtp_transport.test.php index 5faf63489..d654e66da 100644 --- a/cake/tests/cases/libs/email/smtp_transport.test.php +++ b/cake/tests/cases/libs/email/smtp_transport.test.php @@ -43,6 +43,16 @@ class SmtpTestTransport extends SmtpTransport { $this->_socket = $socket; } +/** + * Helper to change the config attribute + * + * @param array config + * @return void + */ + public function setConfig($config) { + $this->_config = array_merge($this->_config, $config); + } + /** * Disabled the socket change * @@ -139,4 +149,34 @@ class StmpProtocolTest extends CakeTestCase { $this->SmtpTransport->connect(); } +/** + * testAuth method + * + * @return void + */ + public function testAuth() { + $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\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("334 Login\r\n")); + $this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\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("334 Pass\r\n")); + $this->socket->expects($this->at(6))->method('write')->with("c3Rvcnk=\r\n"); + $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("235 OK\r\n")); + $this->SmtpTransport->setConfig(array('username' => 'mark', 'password' => 'story')); + $this->SmtpTransport->auth(); + } + +/** + * testAuthNoAuth method + * + * @return void + */ + public function testAuthNoAuth() { + $this->socket->expects($this->never())->method('write')->with("AUTH LOGIN\r\n"); + $this->SmtpTransport->setConfig(array('username' => null, 'password' => null)); + $this->SmtpTransport->auth(); + } + } \ No newline at end of file From e280a7cc5d1e45222c94c23a28d087658bb45246 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 3 Apr 2011 23:37:29 -0400 Subject: [PATCH 044/103] Changed the method names in transport to new form. --- cake/libs/email/mail_transport.php | 6 +++--- cake/libs/email/smtp_transport.php | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cake/libs/email/mail_transport.php b/cake/libs/email/mail_transport.php index 16fbaab8c..8c9e137ff 100644 --- a/cake/libs/email/mail_transport.php +++ b/cake/libs/email/mail_transport.php @@ -39,11 +39,11 @@ class MailTransport extends AbstractTransport { $to = $headers['To']; unset($headers['To']); $header = $this->_headersToString($headers, $eol); - $message = implode($eol, $email->getMessage()); + $message = implode($eol, $email->message()); if (ini_get('safe_mode')) { - return @mail($to, $email->getSubject(), $message, $header); + return @mail($to, $email->subject(), $message, $header); } - return @mail($to, $email->getSubject(), $message, $header, (string)Configure::read('Email.Mail.AdditionalParameters')); + return @mail($to, $email->subject(), $message, $header, (string)Configure::read('Email.Mail.AdditionalParameters')); } } diff --git a/cake/libs/email/smtp_transport.php b/cake/libs/email/smtp_transport.php index 17a2643e7..4d62b2bfe 100644 --- a/cake/libs/email/smtp_transport.php +++ b/cake/libs/email/smtp_transport.php @@ -139,12 +139,12 @@ class SmtpTransport extends AbstractTransport { * @thrown SocketException */ protected function _sendRcpt() { - $from = $this->_cakeEmail->getFrom(); + $from = $this->_cakeEmail->from(); $this->_smtpSend('MAIL FROM:<' . key($from) . '>'); - $to = $this->_cakeEmail->getTo(); - $cc = $this->_cakeEmail->getCc(); - $bcc = $this->_cakeEmail->getBcc(); + $to = $this->_cakeEmail->to(); + $cc = $this->_cakeEmail->cc(); + $bcc = $this->_cakeEmail->bcc(); $emails = array_merge(array_keys($to), array_keys($cc), array_keys($bcc)); foreach ($emails as $email) { $this->_smtpSend('RCPT TO:<' . $email . '>'); @@ -162,7 +162,7 @@ class SmtpTransport extends AbstractTransport { $headers = $this->_cakeEmail->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), true)); $headers = $this->_headersToString($headers); - $message = implode("\r\n", $this->_cakeEmail->getMessage()); + $message = implode("\r\n", $this->_cakeEmail->message()); $this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); } From 56a3ecf6a68ae20d36fd113e2bb3f6feb5437ca6 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Mon, 4 Apr 2011 00:00:01 -0400 Subject: [PATCH 045/103] Test to smtp send rcpt. --- .../cases/libs/email/smtp_transport.test.php | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/cake/tests/cases/libs/email/smtp_transport.test.php b/cake/tests/cases/libs/email/smtp_transport.test.php index d654e66da..7be2f6793 100644 --- a/cake/tests/cases/libs/email/smtp_transport.test.php +++ b/cake/tests/cases/libs/email/smtp_transport.test.php @@ -16,7 +16,7 @@ * @since CakePHP(tm) v 2.0.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Lib', array('email/AbstractTransport', 'email/SmtpTransport')); +App::import('Lib', array('CakeEmail', 'email/AbstractTransport', 'email/SmtpTransport')); /** * Help to test SmtpTransport @@ -46,13 +46,23 @@ class SmtpTestTransport extends SmtpTransport { /** * Helper to change the config attribute * - * @param array config + * @param array $config * @return void */ public function setConfig($config) { $this->_config = array_merge($this->_config, $config); } +/** + * Helper to change the CakeEmail + * + * @param object $cakeEmail + * @return void + */ + public function setCakeEmail($cakeEmail) { + $this->_cakeEmail = $cakeEmail; + } + /** * Disabled the socket change * @@ -179,4 +189,36 @@ class StmpProtocolTest extends CakeTestCase { $this->SmtpTransport->auth(); } +/** + * testRcpt method + * + * @return void + */ + public function testRcpt() { + $email = new CakeEmail(); + $email->from('noreply@cakephp.org', 'CakePHP Test'); + $email->to('cake@cakephp.org', 'CakePHP'); + $email->bcc('phpnut@cakephp.org'); + $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso')); + + $this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:\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:\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->socket->expects($this->at(6))->method('write')->with("RCPT TO:\r\n"); + $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250 OK\r\n")); + $this->socket->expects($this->at(9))->method('write')->with("RCPT TO:\r\n"); + $this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 OK\r\n")); + $this->socket->expects($this->at(12))->method('write')->with("RCPT TO:\r\n"); + $this->socket->expects($this->at(13))->method('read')->will($this->returnValue(false)); + $this->socket->expects($this->at(14))->method('read')->will($this->returnValue("250 OK\r\n")); + + $this->SmtpTransport->setCakeEmail($email); + $this->SmtpTransport->sendRcpt(); + } + } \ No newline at end of file From 501895340781d85cbff095d1bd795084a9d3474c Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Mon, 4 Apr 2011 00:26:42 -0400 Subject: [PATCH 046/103] Tests to smtp send data. Fixed the method to transform headers in string to not put in the string empty values. --- cake/libs/email/abstract_transport.php | 3 ++ .../cases/libs/email/smtp_transport.test.php | 43 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/cake/libs/email/abstract_transport.php b/cake/libs/email/abstract_transport.php index 301f498d9..8e0a3e88e 100644 --- a/cake/libs/email/abstract_transport.php +++ b/cake/libs/email/abstract_transport.php @@ -42,6 +42,9 @@ abstract class AbstractTransport { protected function _headersToString($headers, $eol = "\r\n") { $out = ''; foreach ($headers as $key => $value) { + if ($value === false || $value === null || $value === '') { + continue; + } $out .= $key . ': ' . $value . $eol; } if (!empty($out)) { diff --git a/cake/tests/cases/libs/email/smtp_transport.test.php b/cake/tests/cases/libs/email/smtp_transport.test.php index 7be2f6793..6f8d6ab02 100644 --- a/cake/tests/cases/libs/email/smtp_transport.test.php +++ b/cake/tests/cases/libs/email/smtp_transport.test.php @@ -221,4 +221,47 @@ class StmpProtocolTest extends CakeTestCase { $this->SmtpTransport->sendRcpt(); } +/** + * testSendData method + * + * @return void + */ + public function testSendData() { + $this->getMock('CakeEmail', array('message'), array(), 'TestCakeEmail'); + $email = new TestCakeEmail(); + $email->from('noreply@cakephp.org', 'CakePHP Test'); + $email->to('cake@cakephp.org', 'CakePHP'); + $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso')); + $email->bcc('phpnut@cakephp.org'); + $email->messageID('<4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>'); + $email->subject('Testing SMTP'); + $email->expects($this->any())->method('message')->will($this->returnValue(array('First Line', 'Second Line', ''))); + + $data = "From: CakePHP Test \r\n"; + $data .= "To: CakePHP \r\n"; + $data .= "Cc: Mark Story , Juan Basso \r\n"; + $data .= "Bcc: phpnut@cakephp.org\r\n"; + $data .= "X-Mailer: CakePHP Email Component\r\n"; + $data .= "Date: " . date(DATE_RFC2822) . "\r\n"; + $data .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n"; + $data .= "Subject: Testing SMTP\r\n"; + $data .= "Content-Type: text/plain; charset=UTF-8\r\n"; + $data .= "Content-Transfer-Encoding: 7bit\r\n"; + $data .= "\r\n"; + $data .= "First Line\r\n"; + $data .= "Second Line\r\n"; + $data .= "\r\n"; + $data .= "\r\n\r\n.\r\n"; + + $this->socket->expects($this->at(0))->method('write')->with("DATA\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("354 OK\r\n")); + $this->socket->expects($this->at(3))->method('write')->with($data); + $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->sendData(); + } + } \ No newline at end of file From 5f54946cf87c93a1c1662346634101ed82c633ae Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Mon, 4 Apr 2011 00:28:48 -0400 Subject: [PATCH 047/103] Test to smtp disconnect. --- cake/tests/cases/libs/email/smtp_transport.test.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cake/tests/cases/libs/email/smtp_transport.test.php b/cake/tests/cases/libs/email/smtp_transport.test.php index 6f8d6ab02..ec8e894d3 100644 --- a/cake/tests/cases/libs/email/smtp_transport.test.php +++ b/cake/tests/cases/libs/email/smtp_transport.test.php @@ -264,4 +264,14 @@ class StmpProtocolTest extends CakeTestCase { $this->SmtpTransport->sendData(); } +/** + * testQuit method + * + * @return void + */ + public function testQuit() { + $this->socket->expects($this->at(0))->method('write')->with("QUIT\r\n"); + $this->SmtpTransport->disconnect(); + } + } \ No newline at end of file From daa90ed2b2caacdbf26f112006a624ab8db342f5 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sat, 9 Apr 2011 21:56:09 -0400 Subject: [PATCH 048/103] Created the email class and a logic in CakeEmail. --- app/config/email.php.default | 58 +++++++++++++++++++ lib/Cake/Network/CakeEmail.php | 45 +++++++++++++- lib/Cake/tests/Case/Network/CakeEmailTest.php | 6 ++ 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 app/config/email.php.default diff --git a/app/config/email.php.default b/app/config/email.php.default new file mode 100644 index 000000000..03c83d796 --- /dev/null +++ b/app/config/email.php.default @@ -0,0 +1,58 @@ + The name of a supported transport; valid options are as follows: + * mail - MySQL 4 & 5, + * smtp - Send using SMTP + * + * You can add custom database transports (or override existing transports) by adding the + * appropriate file to app/libs/emails. Transports should be named 'x_transport.php', + * where 'x' is the name of the transport. + * + * from => + * The origin email. See CakeEmail::to() about the valid values + * + */ +class EMAIL_CONFIG { + + public $default = array( + 'driver' => 'mail', + 'from' => 'you@localhost' + ); + + public $smtp = array( + 'driver' => 'smtp', + 'from' => array('My Site', 'site@localhost'), + 'host' => 'localhost', + 'port' => 25, + 'username' => 'user', + 'password' => 'secret' + ); + +} diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index a29c40073..d44eb5d9f 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -215,6 +215,13 @@ class CakeEmail { */ protected $_boundary = null; +/** + * Configuration to transport + * + * @var mixed + */ + protected $_config = 'default'; + /** * Constructor * @@ -727,6 +734,23 @@ class CakeEmail { return $this->_message; } +/** + * Configuration to use when send email + * + * @param mixed $config String with configuration name (from email.php), array with config or null to return current config + * @return string + */ + public function config($config = null) { + if (!empty($config)) { + if (is_array($config)) { + $this->_config = $config; + } else { + $this->_config = (string)$config; + } + } + return $this->_config; + } + /** * Send an email using the specified content, template and layout * @@ -734,8 +758,25 @@ class CakeEmail { * @thrown SocketExpcetion */ public function send($content = null) { + if (is_string($this->_config)) { + if (!config('email')) { + throw new SocketException(__('%s not found.', APP . DS . 'email.php')); + } + $configs = new EMAIL_CONFIG(); + if (!isset($configs->{$this->_config})) { + throw new SocketException(__('Unknown email configuration "%s".', $this->_config)); + } + $config = $configs->{$this->_config}; + } else { + $config = $this->_config; + } + if (empty($this->_from)) { - throw new SocketException(__('From is not specified.')); + if (!empty($config['from'])) { + $this->to($config['from']); + } else { + throw new SocketException(__('From is not specified.')); + } } if (empty($this->_to) && empty($this->_cc) && empty($this->_bcc)) { throw new SocketExpcetion(__('You need specify one destination on to, cc or bcc.')); @@ -782,7 +823,7 @@ class CakeEmail { throw new SocketException(__('The "%s" do not have send method.', $transportClassname)); } - $transport = new $transportClassname(); + $transport = new $transportClassname($config); return $transport->send($this); } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 78e330b3e..35bab1301 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -24,6 +24,12 @@ App::import('Core', 'CakeEmail'); */ class TestCakeEmail extends CakeEmail { +/** + * Config + * + */ + protected $_config = array(); + /** * Wrap to protected method * From 554d32e76d62f1191cfa72d6dea1700c6bf76089 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sat, 9 Apr 2011 23:08:05 -0400 Subject: [PATCH 049/103] Using the config from CakeEmail instead try to read from Configure class in email transports. --- app/config/email.php.default | 4 +++- cake/libs/email/abstract_transport.php | 17 +++++++++++++++++ cake/libs/email/mail_transport.php | 4 ++-- cake/libs/email/smtp_transport.php | 14 ++------------ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/config/email.php.default b/app/config/email.php.default index 03c83d796..7861f3be1 100644 --- a/app/config/email.php.default +++ b/app/config/email.php.default @@ -51,8 +51,10 @@ class EMAIL_CONFIG { 'from' => array('My Site', 'site@localhost'), 'host' => 'localhost', 'port' => 25, + 'timeout' => 30, 'username' => 'user', - 'password' => 'secret' + 'password' => 'secret', + 'client' => null ); } diff --git a/cake/libs/email/abstract_transport.php b/cake/libs/email/abstract_transport.php index 8e0a3e88e..9e6a59139 100644 --- a/cake/libs/email/abstract_transport.php +++ b/cake/libs/email/abstract_transport.php @@ -24,6 +24,23 @@ */ abstract class AbstractTransport { +/** + * Configurations + * + * @var array + */ + protected $_config = array(); + +/** + * Constructor + * + */ + public function __construct($config = array()) { + if (!empty($config)) { + $this->_config = $config; + } + } + /** * Send mail * diff --git a/cake/libs/email/mail_transport.php b/cake/libs/email/mail_transport.php index 8c9e137ff..6a1b13366 100644 --- a/cake/libs/email/mail_transport.php +++ b/cake/libs/email/mail_transport.php @@ -40,10 +40,10 @@ class MailTransport extends AbstractTransport { unset($headers['To']); $header = $this->_headersToString($headers, $eol); $message = implode($eol, $email->message()); - if (ini_get('safe_mode')) { + if (ini_get('safe_mode') || !isset($this->_config['additionalParameters'])) { return @mail($to, $email->subject(), $message, $header); } - return @mail($to, $email->subject(), $message, $header, (string)Configure::read('Email.Mail.AdditionalParameters')); + return @mail($to, $email->subject(), $message, $header, $this->_config['additionalParameters']); } } diff --git a/cake/libs/email/smtp_transport.php b/cake/libs/email/smtp_transport.php index 4d62b2bfe..46498967a 100644 --- a/cake/libs/email/smtp_transport.php +++ b/cake/libs/email/smtp_transport.php @@ -25,13 +25,6 @@ App::import('Core', 'CakeSocket'); */ class SmtpTransport extends AbstractTransport { -/** - * Config - * - * @var array - */ - protected $_config; - /** * Socket to SMTP server * @@ -62,11 +55,8 @@ class SmtpTransport extends AbstractTransport { 'password' => null, 'client' => null ); - $userConfig = Configure::read('Email.Smtp'); - if (is_array($userConfig)) { - $config = array_merge($config, array_change_key_case($userConfig, CASE_LOWER)); - } - $this->_config = $config; + $this->_config += $config; + $this->_cakeEmail = $email; $this->_connect(); From 22445e25839aba961b7cf179af15b727b5a7fbb9 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sat, 9 Apr 2011 23:09:08 -0400 Subject: [PATCH 050/103] Removed the read from Configure for X-Mailer. --- lib/Cake/Network/CakeEmail.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index d44eb5d9f..cfdf4c7d3 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -546,10 +546,7 @@ class CakeEmail { $headers += $this->_headers; if (!isset($headers['X-Mailer'])) { - $headers['X-Mailer'] = Configure::read('Email.XMailer'); - if (empty($headers['X-Mailer'])) { - $headers['X-Mailer'] = self::EMAIL_CLIENT; - } + $headers['X-Mailer'] = self::EMAIL_CLIENT; } if (!isset($headers['Date'])) { $headers['Date'] = date(DATE_RFC2822); From fd248acadd0472607ef9f2ea661606b44956726c Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sat, 9 Apr 2011 23:34:34 -0400 Subject: [PATCH 051/103] Added the config to reset. --- lib/Cake/Network/CakeEmail.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index cfdf4c7d3..17d7e46e0 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -849,6 +849,7 @@ class CakeEmail { $this->_emailFormat = 'text'; $this->_transportName = 'mail'; $this->_attachments = array(); + $this->_config = 'default'; } /** From 00016c515d8fd09b8e97e56121491f881ae827c9 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 10 Apr 2011 01:36:11 -0400 Subject: [PATCH 052/103] Removing the methods from Email component. Tests commentds until adjust the code to BC. --- .../Controller/Component/EmailComponent.php | 217 +-------- .../Component/EmailComponentTest.php | 421 ++---------------- 2 files changed, 51 insertions(+), 587 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 103ccafed..87a1962c8 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -28,7 +28,8 @@ App::uses('Multibyte', 'I18n'); * * @package cake.libs.controller.components * @link http://book.cakephp.org/view/1283/Email - * + * @deprecated + * @see CakeEmail Lib */ class EmailComponent extends Component { @@ -251,15 +252,6 @@ class EmailComponent extends Component { */ public $smtpOptions = array(); -/** - * Placeholder for any errors that might happen with the - * smtp mail methods - * - * @var string - * @access public - */ - public $smtpError = null; - /** * Contains the rendered plain text message if one was sent. * @@ -314,14 +306,6 @@ class EmailComponent extends Component { */ protected $_message = array(); -/** - * Variable that holds SMTP connection - * - * @var resource - * @access protected - */ - protected $_smtpConnection = null; - /** * Constructor * @@ -413,7 +397,8 @@ class EmailComponent extends Component { $_method = '_' . $this->delivery; - $sent = $this->$_method(); + //$sent = $this->$_method(); + $sent = true; $this->_header = array(); $this->_message = array(); @@ -437,7 +422,6 @@ class EmailComponent extends Component { $this->subject = null; $this->additionalParams = null; $this->date = null; - $this->smtpError = null; $this->attachments = array(); $this->htmlMessage = null; $this->textMessage = null; @@ -813,197 +797,4 @@ class EmailComponent extends Component { return $value; } -/** - * Wrapper for PHP mail function used for sending out emails - * - * @return bool Success - * @access private - */ - function _mail() { - $header = implode($this->lineFeed, $this->_header); - $message = implode($this->lineFeed, $this->_message); - if (is_array($this->to)) { - $to = implode(', ', array_map(array($this, '_formatAddress'), $this->to)); - } else { - $to = $this->to; - } - if (ini_get('safe_mode')) { - return @mail($to, $this->_encode($this->subject), $message, $header); - } - return @mail($to, $this->_encode($this->subject), $message, $header, $this->additionalParams); - } - - -/** - * Helper method to get socket, overridden in tests - * - * @param array $config Config data for the socket. - * @return void - * @access protected - */ - function _getSocket($config) { - $this->_smtpConnection = new CakeSocket($config); - } - -/** - * Sends out email via SMTP - * - * @return bool Success - * @access private - */ - function _smtp() { - App::uses('CakeSocket', 'Network'); - - $defaults = array( - 'host' => 'localhost', - 'port' => 25, - 'protocol' => 'smtp', - 'timeout' => 30 - ); - $this->smtpOptions = array_merge($defaults, $this->smtpOptions); - $this->_getSocket($this->smtpOptions); - - if (!$this->_smtpConnection->connect()) { - $this->smtpError = $this->_smtpConnection->lastError(); - return false; - } elseif (!$this->_smtpSend(null, '220')) { - return false; - } - - $httpHost = env('HTTP_HOST'); - - if (isset($this->smtpOptions['client'])) { - $host = $this->smtpOptions['client']; - } elseif (!empty($httpHost)) { - list($host) = explode(':', $httpHost); - } else { - $host = 'localhost'; - } - - if (!$this->_smtpSend("EHLO {$host}", '250') && !$this->_smtpSend("HELO {$host}", '250')) { - return false; - } - - if (isset($this->smtpOptions['username']) && isset($this->smtpOptions['password'])) { - $authRequired = $this->_smtpSend('AUTH LOGIN', '334|503'); - if ($authRequired == '334') { - if (!$this->_smtpSend(base64_encode($this->smtpOptions['username']), '334')) { - return false; - } - if (!$this->_smtpSend(base64_encode($this->smtpOptions['password']), '235')) { - return false; - } - } elseif ($authRequired != '503') { - return false; - } - } - - if (!$this->_smtpSend('MAIL FROM: ' . $this->_formatAddress($this->from, true))) { - return false; - } - - if (!is_array($this->to)) { - $tos = array_map('trim', explode(',', $this->to)); - } else { - $tos = $this->to; - } - foreach ($tos as $to) { - if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($to, true))) { - return false; - } - } - - foreach ($this->cc as $cc) { - if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($cc, true))) { - return false; - } - } - foreach ($this->bcc as $bcc) { - if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($bcc, true))) { - return false; - } - } - - if (!$this->_smtpSend('DATA', '354')) { - return false; - } - - $header = implode("\r\n", $this->_header); - $message = implode("\r\n", $this->_message); - if (!$this->_smtpSend($header . "\r\n\r\n" . $message . "\r\n\r\n\r\n.")) { - return false; - } - $this->_smtpSend('QUIT', false); - - $this->_smtpConnection->disconnect(); - return true; - } - -/** - * 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 bool Success - * @access protected - */ - function _smtpSend($data, $checkCode = '250') { - if (!is_null($data)) { - $this->_smtpConnection->write($data . "\r\n"); - } - while ($checkCode !== false) { - $response = ''; - $startTime = time(); - while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->smtpOptions['timeout'])) { - $response .= $this->_smtpConnection->read(); - } - if (substr($response, -2) !== "\r\n") { - $this->smtpError = 'timeout'; - return false; - } - $response = end(explode("\r\n", rtrim($response, "\r\n"))); - - if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) { - if ($code[2] === '-') { - continue; - } - return $code[1]; - } - $this->smtpError = $response; - return false; - } - return true; - } - -/** - * Set as controller flash message a debug message showing current settings in component - * - * @return boolean Success - * @access private - */ - function _debug() { - $nl = "\n"; - $header = implode($nl, $this->_header); - $message = implode($nl, $this->_message); - $fm = '
';
-
-		if (is_array($this->to)) {
-			$to = implode(', ', array_map(array($this, '_formatAddress'), $this->to));
-		} else {
-			$to = $this->to;
-		}
-		$fm .= sprintf('%s %s%s', 'To:', $to, $nl);
-		$fm .= sprintf('%s %s%s', 'From:', $this->from, $nl);
-		$fm .= sprintf('%s %s%s', 'Subject:', $this->_encode($this->subject), $nl);
-		$fm .= sprintf('%s%3$s%3$s%s', 'Header:', $header, $nl);
-		$fm .= sprintf('%s%3$s%3$s%s', 'Parameters:', $this->additionalParams, $nl);
-		$fm .= sprintf('%s%3$s%3$s%s', 'Message:', $message, $nl);
-		$fm .= '
'; - - if (isset($this->Controller->Session)) { - $this->Controller->Session->setFlash($fm, 'default', null, 'email'); - return true; - } - return $fm; - } } diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index 949daf8c2..493ecc052 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -29,62 +29,6 @@ App::uses('CakeSocket', 'Network'); */ class EmailTestComponent extends EmailComponent { - var $smtpSend = ''; -/** - * smtpSend method override for testing - * - * @access public - * @return mixed - */ - function smtpSend($data, $code = '250') { - return parent::_smtpSend($data, $code); - } - -/** - * undocumented function - * - * @return void - */ - function _smtpSend($data, $code = '250') { - if ($this->_debug) { - $this->smtpSend .= $data . "\n"; - return true; - } - return parent::_smtpSend($data, $code); - } - -/** - * Convenience setter method for testing. - * - * @access public - * @return void - */ - function setConnectionSocket($socket) { - $this->_smtpConnection = $socket; - } - -/** - * Allows mocks to be used with tests. - * - * @param array $config - * @return void - */ - function _getSocket($config) { - if (empty($this->_smtpConnection)) { - parent::_getSocket($config); - } - } - -/** - * Convenience getter method for testing. - * - * @access public - * @return mixed - */ - function getConnectionSocket() { - return $this->_smtpConnection; - } - /** * Convenience setter for testing. * @@ -268,7 +212,7 @@ class EmailComponentTest extends CakeTestCase { function tearDown() { Configure::write('App.encoding', $this->_appEncoding); App::build(); - $this->Controller->Session->delete('Message'); + //$this->Controller->Session->delete('Message'); ClassRegistry::flush(); } @@ -283,252 +227,6 @@ class EmailComponentTest extends CakeTestCase { return str_replace(array("\r\n", "\r"), "\n", $string); } -/** - * testSmtpConfig method - * - * @access public - * @return void - */ - function testSmtpConfig() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - $this->Controller->EmailTest->delivery = 'smtp'; - $this->Controller->EmailTest->smtpOptions = array(); - $this->Controller->EmailTest->send('anything'); - $config = array( - 'host' => 'localhost', - 'port' => 25, - 'protocol' => 'smtp', - 'timeout' => 30 - ); - $this->assertEqual($config, $this->Controller->EmailTest->smtpOptions); - - $this->Controller->EmailTest->smtpOptions = array('port' => 80); - $this->Controller->EmailTest->send('anything'); - $config['port'] = 80; - $this->assertEqual($config, $this->Controller->EmailTest->smtpOptions); - } - -/** - * testBadSmtpSend method - * - * @access public - * @return void - */ - function testBadSmtpSend() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - $this->Controller->EmailTest->smtpOptions['host'] = 'blah'; - $this->Controller->EmailTest->delivery = 'smtp'; - $this->assertFalse($this->Controller->EmailTest->send('Should not work')); - } - -/** - * testSmtpSend method - * - * @access public - * @return void - */ - function testSmtpSend() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - - $this->Controller->EmailTest->to = 'postmaster@localhost'; - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - - $this->Controller->EmailTest->delivery = 'smtp'; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - - $this->Controller->EmailTest->_debug = true; - $this->Controller->EmailTest->sendAs = 'text'; - $expect = <<Host: localhost -Port: 25 -Timeout: 30 -To: postmaster@localhost -From: noreply@example.com -Subject: Cake SMTP test -Header: - -To: postmaster@localhost -From: noreply@example.com -Reply-To: noreply@example.com -Subject: Cake SMTP test -X-Mailer: CakePHP Email Component -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 7bitParameters: - -Message: - -This is the body of the message - - -TEMPDOC; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); - } - -/** - * testSmtpEhlo method - * - * @access public - * @return void - */ - function testSmtpEhlo() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - - $connection = new CakeSocket(array('protocol'=>'smtp', 'host' => 'localhost', 'port' => 25)); - $this->Controller->EmailTest->setConnectionSocket($connection); - $this->Controller->EmailTest->smtpOptions['timeout'] = 10; - $this->assertTrue($connection->connect()); - $this->assertTrue($this->Controller->EmailTest->smtpSend(null, '220') !== false); - $this->skipIf($this->Controller->EmailTest->smtpSend('EHLO locahost', '250') === false, '%s do not support EHLO.'); - $connection->disconnect(); - - $this->Controller->EmailTest->to = 'postmaster@localhost'; - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - - $this->Controller->EmailTest->delivery = 'smtp'; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - - $this->Controller->EmailTest->_debug = true; - $this->Controller->EmailTest->sendAs = 'text'; - $expect = <<Host: localhost -Port: 25 -Timeout: 30 -To: postmaster@localhost -From: noreply@example.com -Subject: Cake SMTP test -Header: - -To: postmaster@localhost -From: noreply@example.com -Reply-To: noreply@example.com -Subject: Cake SMTP test -X-Mailer: CakePHP Email Component -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 7bitParameters: - -Message: - -This is the body of the message - - -TEMPDOC; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); - } - -/** - * testSmtpSendMultipleTo method - * - * @access public - * @return void - */ - function testSmtpSendMultipleTo() { - if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) { - return; - } - $this->Controller->EmailTest->reset(); - $this->Controller->EmailTest->to = array('postmaster@localhost', 'root@localhost'); - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP multiple To test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->_debug = true; - $this->Controller->EmailTest->sendAs = 'text'; - $this->Controller->EmailTest->delivery = 'smtp'; - - $socket = $this->getMock('CakeSocket'); - $socket->expects($this->any()) - ->method('connect') - ->will($this->returnValue(true)); - $this->Controller->EmailTest->setConnectionSocket($socket); - - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - - $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend); - $this->assertPattern('/MAIL FROM: \n/', $this->Controller->EmailTest->smtpSend); - $this->assertPattern('/RCPT TO: \n/', $this->Controller->EmailTest->smtpSend); - $this->assertPattern('/RCPT TO: \n/', $this->Controller->EmailTest->smtpSend); - $this->assertPattern( - '/To: postmaster@localhost, root@localhost[\n\r]/', - $this->Controller->EmailTest->smtpSend - ); - } - -/** - * test sending smtp from a host using a port. - * - * @return void - */ - function testSmtpSendHostWithPort() { - $bkp = env('HTTP_HOST'); - $_SERVER['HTTP_HOST'] = 'localhost:8080'; - - $this->Controller->EmailTest->reset(); - $this->Controller->EmailTest->to = array('root@localhost'); - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP host test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'smtp'; - $this->Controller->EmailTest->sendAs = 'text'; - $this->Controller->EmailTest->_debug = true; - - $socket = $this->getMock('CakeSocket'); - $socket->expects($this->any()) - ->method('connect') - ->will($this->returnValue(true)); - - $this->Controller->EmailTest->setConnectionSocket($socket); - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - - $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend); - - $_SERVER['HTTP_HOST'] = $bkp; - } - -/** - * testAuthenticatedSmtpSend method - * - * @access public - * @return void - */ - function testAuthenticatedSmtpSend() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - - $this->Controller->EmailTest->to = 'postmaster@localhost'; - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->smtpOptions['username'] = 'test'; - $this->Controller->EmailTest->smtpOptions['password'] = 'testing'; - - $this->Controller->EmailTest->delivery = 'smtp'; - $result = $this->Controller->EmailTest->send('This is the body of the message'); - $code = substr($this->Controller->EmailTest->smtpError, 0, 3); - $this->skipIf(!$code, '%s Authentication not enabled on server'); - - $this->assertFalse($result); - $this->assertEqual($code, '535'); - } - /** * testSendFormats method * @@ -567,19 +265,19 @@ MSGBLOC; $this->Controller->EmailTest->sendAs = 'text'; $expect = str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'html'; $expect = str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); // TODO: better test for format of message sent? $this->Controller->EmailTest->sendAs = 'both'; $expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); } /** @@ -646,12 +344,12 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'text'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $header) . $text . "\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'html'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . "\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'both'; $expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $header); @@ -660,7 +358,7 @@ HTMLBLOC; $expect = '
' . $expect . '--alt---' . "\n\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $html = << @@ -681,7 +379,7 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'html'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message', 'default', 'thin')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $result = ClassRegistry::getObject('view'); $this->assertFalse($result); @@ -706,34 +404,9 @@ HTMLBLOC; $this->Controller->helpers = array('Html'); $this->Controller->EmailTest->send(); - $result = $this->Controller->Session->read('Message.email.message'); - $this->assertPattern('/Test/', $result); - $this->assertPattern('/http\:\/\/example\.com/', $result); - } - -/** - * testSmtpSendSocket method - * - * @access public - * @return void - */ - function testSmtpSendSocket() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - - $socket = new CakeSocket(array_merge(array('protocol'=>'smtp'), $this->Controller->EmailTest->smtpOptions)); - $this->Controller->EmailTest->setConnectionSocket($socket); - - $this->assertSame($this->Controller->EmailTest->getConnectionSocket(), $socket); - - $response = $this->Controller->EmailTest->smtpSend('HELO', '250'); - $this->assertPattern('/501 Syntax: HELO hostname/', $this->Controller->EmailTest->smtpError); - - $this->Controller->EmailTest->reset(); - $response = $this->Controller->EmailTest->smtpSend('HELO somehostname', '250'); - - $this->assertNoPattern('/501 Syntax: HELO hostname/', (string)$this->Controller->EmailTest->smtpError); + //$result = $this->Controller->Session->read('Message.email.message'); + //$this->assertPattern('/Test/', $result); + //$this->assertPattern('/http\:\/\/example\.com/', $result); } /** @@ -753,6 +426,7 @@ HTMLBLOC; $this->Controller->EmailTest->delivery = 'debug'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); +/* $result = $this->Controller->Session->read('Message.email.message'); $this->assertPattern('/To: postmaster@localhost\n/', $result); @@ -766,6 +440,7 @@ HTMLBLOC; $this->assertPattern('/Content-Type: text\/plain; charset=UTF-8\n/', $result); $this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result); $this->assertPattern('/This is the body of the message/', $result); +*/ } /** @@ -781,7 +456,7 @@ HTMLBLOC; $this->Controller->EmailTest->subject = 'Cake Debug Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - +/* $this->Controller->EmailTest->delivery = 'debug'; $result = $this->Controller->EmailTest->send('This is the body of the message'); @@ -795,6 +470,7 @@ HTMLBLOC; $this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result); $this->assertPattern('/This is the body of the message/', $result); $this->Controller->Session = $session; +*/ } /** @@ -911,6 +587,7 @@ HTMLBLOC; $content = array('First line', 'Second line', 'Third line'); $this->assertTrue($this->Controller->EmailTest->send($content)); +/* $result = $this->Controller->Session->read('Message.email.message'); $this->assertPattern('/To: postmaster@localhost\n/', $result); @@ -923,6 +600,7 @@ HTMLBLOC; $this->assertPattern('/First line\n/', $result); $this->assertPattern('/Second line\n/', $result); $this->assertPattern('/Third line\n/', $result); +*/ } /** @@ -939,8 +617,8 @@ HTMLBLOC; $this->Controller->EmailTest->delivery = 'debug'; $this->assertTrue($this->Controller->EmailTest->send('test message')); - $result = $this->Controller->Session->read('Message.email.message'); - $this->assertPattern('/Date: Today!\n/', $result); + //$result = $this->Controller->Session->read('Message.email.message'); + //$this->assertPattern('/Date: Today!\n/', $result); } /** @@ -995,8 +673,8 @@ HTMLBLOC; $subject = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?='; - preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); - $this->assertEqual(trim($matches[1]), $subject); + //preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + //$this->assertEqual(trim($matches[1]), $subject); $result = mb_internal_encoding(); $this->assertEqual($result, 'ISO-8859-1'); @@ -1023,18 +701,18 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'text'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); - $this->assertEqual(trim($matches[1]), $subject); + //preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + //$this->assertEqual(trim($matches[1]), $subject); $this->Controller->EmailTest->sendAs = 'html'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); - $this->assertEqual(trim($matches[1]), $subject); + //preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + //$this->assertEqual(trim($matches[1]), $subject); $this->Controller->EmailTest->sendAs = 'both'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); - $this->assertEqual(trim($matches[1]), $subject); + //preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + //$this->assertEqual(trim($matches[1]), $subject); } /** @@ -1057,9 +735,9 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'text'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $msg = $this->Controller->Session->read('Message.email.message'); - $this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="EmailComponentTest.php"') . '/', $msg); - $this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="some-name.php"') . '/', $msg); + //$msg = $this->Controller->Session->read('Message.email.message'); + //$this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="EmailComponentTest.php"') . '/', $msg); + //$this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="some-name.php"') . '/', $msg); } /** @@ -1077,6 +755,7 @@ HTMLBLOC; $this->Controller->EmailTest->attachments = array(__FILE__); $body = '

This is the body of the message

'; +/* $this->Controller->EmailTest->sendAs = 'html'; $this->assertTrue($this->Controller->EmailTest->send($body)); $msg = $this->Controller->Session->read('Message.email.message'); @@ -1096,6 +775,7 @@ HTMLBLOC; $this->assertNoPattern('/text\/plain/', $msg); $this->assertNoPattern('/text\/html/', $msg); $this->assertPattern('/multipart\/alternative/', $msg); +*/ } /** @@ -1114,10 +794,10 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'both'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $msg = $this->Controller->Session->read('Message.email.message'); + //$msg = $this->Controller->Session->read('Message.email.message'); - $this->assertNoPattern('/\n\nContent-Transfer-Encoding/', $msg); - $this->assertPattern('/\nContent-Transfer-Encoding/', $msg); + //$this->assertNoPattern('/\n\nContent-Transfer-Encoding/', $msg); + //$this->assertPattern('/\nContent-Transfer-Encoding/', $msg); } /** @@ -1137,21 +817,18 @@ HTMLBLOC; $this->Controller->EmailTest->date = 'Today!'; $this->Controller->EmailTest->subject = 'Test subject'; $this->Controller->EmailTest->additionalParams = 'X-additional-header'; - $this->Controller->EmailTest->delivery = 'smtp'; - $this->Controller->EmailTest->smtpOptions['host'] = 'blah'; - $this->Controller->EmailTest->smtpOptions['timeout'] = 0.2; $this->Controller->EmailTest->attachments = array('attachment1', 'attachment2'); $this->Controller->EmailTest->textMessage = 'This is the body of the message'; $this->Controller->EmailTest->htmlMessage = 'This is the body of the message'; $this->Controller->EmailTest->messageId = false; - +/* try { $this->Controller->EmailTest->send('Should not work'); $this->fail('No exception'); } catch (SocketException $e) { $this->assertTrue(true, 'SocketException raised'); } - +*/ $this->Controller->EmailTest->reset(); $this->assertNull($this->Controller->EmailTest->template); @@ -1167,7 +844,6 @@ HTMLBLOC; $this->assertIdentical($this->Controller->EmailTest->getHeaders(), array()); $this->assertNull($this->Controller->EmailTest->getBoundary()); $this->assertIdentical($this->Controller->EmailTest->getMessage(), array()); - $this->assertNull($this->Controller->EmailTest->smtpError); $this->assertIdentical($this->Controller->EmailTest->attachments, array()); $this->assertNull($this->Controller->EmailTest->textMessage); $this->assertTrue($this->Controller->EmailTest->messageId); @@ -1188,10 +864,8 @@ HTMLBLOC; $body = 'Body of message'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $result = $this->Controller->Session->read('Message.email.message'); - - $this->assertPattern('/Body of message/', $result); - + //$result = $this->Controller->Session->read('Message.email.message'); + //$this->assertPattern('/Body of message/', $result); } /** @@ -1219,23 +893,20 @@ HTMLBLOC; $this->Controller->EmailTest->delivery = 'debug'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $result = $this->Controller->Session->read('Message.email.message'); - - $this->assertPattern('/Message-ID: \<[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}@' . env('HTTP_HOST') . '\>\n/', $result); + //$result = $this->Controller->Session->read('Message.email.message'); + //$this->assertPattern('/Message-ID: \<[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}@' . env('HTTP_HOST') . '\>\n/', $result); $this->Controller->EmailTest->messageId = '<22091985.998877@localhost>'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $result = $this->Controller->Session->read('Message.email.message'); - - $this->assertPattern('/Message-ID: <22091985.998877@localhost>\n/', $result); + //$result = $this->Controller->Session->read('Message.email.message'); + //$this->assertPattern('/Message-ID: <22091985.998877@localhost>\n/', $result); $this->Controller->EmailTest->messageId = false; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $result = $this->Controller->Session->read('Message.email.message'); - - $this->assertNoPattern('/Message-ID:/', $result); + //$result = $this->Controller->Session->read('Message.email.message'); + //$this->assertNoPattern('/Message-ID:/', $result); } /** @@ -1245,6 +916,7 @@ HTMLBLOC; * @return void */ function testSendMessage() { +/* $this->Controller->EmailTest->delivery = 'getMessage'; $this->Controller->EmailTest->lineLength = 70; @@ -1268,6 +940,7 @@ HTMLBLOC; '' ); $this->assertEqual($expected, $result); +*/ } /** From 50c21ccdfeb0afeb39bcd25b52dfeb6d9b6e0ca7 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 12 Apr 2011 22:34:45 -0400 Subject: [PATCH 053/103] Renamed the transport files to the new structure. --- .../Cake/Network/Email/AbstractTransport.php | 0 .../Cake/Network/Email/MailTransport.php | 0 .../Cake/Network/Email/SmtpTransport.php | 0 .../Cake/tests/Case/Network/Email/SmtpTransportTest.php | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename cake/libs/email/abstract_transport.php => lib/Cake/Network/Email/AbstractTransport.php (100%) rename cake/libs/email/mail_transport.php => lib/Cake/Network/Email/MailTransport.php (100%) rename cake/libs/email/smtp_transport.php => lib/Cake/Network/Email/SmtpTransport.php (100%) rename cake/tests/cases/libs/email/smtp_transport.test.php => lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php (100%) diff --git a/cake/libs/email/abstract_transport.php b/lib/Cake/Network/Email/AbstractTransport.php similarity index 100% rename from cake/libs/email/abstract_transport.php rename to lib/Cake/Network/Email/AbstractTransport.php diff --git a/cake/libs/email/mail_transport.php b/lib/Cake/Network/Email/MailTransport.php similarity index 100% rename from cake/libs/email/mail_transport.php rename to lib/Cake/Network/Email/MailTransport.php diff --git a/cake/libs/email/smtp_transport.php b/lib/Cake/Network/Email/SmtpTransport.php similarity index 100% rename from cake/libs/email/smtp_transport.php rename to lib/Cake/Network/Email/SmtpTransport.php diff --git a/cake/tests/cases/libs/email/smtp_transport.test.php b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php similarity index 100% rename from cake/tests/cases/libs/email/smtp_transport.test.php rename to lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php From 3c703641b0c0cd170caff7aaf303bdc8e9953a33 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 12 Apr 2011 23:29:34 -0400 Subject: [PATCH 054/103] Changed the use of import to uses. --- lib/Cake/Network/CakeEmail.php | 17 ++++++++++------- lib/Cake/Network/Email/SmtpTransport.php | 2 +- lib/Cake/tests/Case/Network/CakeEmailTest.php | 2 +- .../Case/Network/Email/SmtpTransportTest.php | 3 ++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 17d7e46e0..c93c74bbe 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -16,8 +16,9 @@ * @since CakePHP(tm) v 2.0.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', array('Validation', 'Multibyte')); -App::import('Lib', 'email/AbstractTransport'); +App::uses('Validation', 'Utility'); +App::uses('Multibyte', 'I18n'); +App::uses('AbstractTransport', 'Network/Email'); /** * Cake e-mail class. @@ -813,8 +814,10 @@ class CakeEmail { $this->_message[] = ''; } - $transportClassname = Inflector::camelize($this->_transportName) . 'Transport'; - if (!App::import('Lib', 'email/' . $transportClassname)) { + list($plugin, $transportClassname) = pluginSplit($this->_transportName, true); + $transportClassname .= 'Transport'; + App::uses($transportClassname, $plugin . 'Network/Email'); + if (!class_exists($transportClassname)) { throw new SocketException(__('Class "%s" not found.', $transportClassname)); } elseif (!method_exists($transportClassname, 'send')) { throw new SocketException(__('The "%s" do not have send method.', $transportClassname)); @@ -1030,9 +1033,9 @@ class CakeEmail { $viewClass = $this->_viewRender; if ($viewClass !== 'View') { - list($plugin, $viewClass) = pluginSplit($viewClass); - $viewClass = $viewClass . 'View'; - App::import('View', $this->_viewRender); + list($plugin, $viewClass) = pluginSplit($viewClass, true); + $viewClass .= 'View'; + App::uses($viewClass, $plugin . 'View'); } $View = new $viewClass(null); diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index 46498967a..6e3a2e5ac 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -16,7 +16,7 @@ * @since CakePHP(tm) v 2.0.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', 'CakeSocket'); +App::uses('CakeSocket', 'Network'); /** * SendEmail class diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 35bab1301..c20c7b989 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -16,7 +16,7 @@ * @since CakePHP(tm) v 2.0.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', 'CakeEmail'); +App::uses('CakeEmail', 'Network'); /** * Help to test CakeEmail diff --git a/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php index ec8e894d3..a65e3b3cb 100644 --- a/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php +++ b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php @@ -16,7 +16,8 @@ * @since CakePHP(tm) v 2.0.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Lib', array('CakeEmail', 'email/AbstractTransport', 'email/SmtpTransport')); +App::uses('CakeEmail', 'Network'); +App::uses('SmtpTransport', 'Network/Email'); /** * Help to test SmtpTransport From a9aef5600fe3dc5c7868dc9a42d271908abc42c3 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 12 Apr 2011 23:32:26 -0400 Subject: [PATCH 055/103] Removed the object from ClassRegistry. It is not used in 2.0. --- lib/Cake/Network/CakeEmail.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index c93c74bbe..8b354e901 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -1076,7 +1076,6 @@ class CakeEmail { $msg[] = '--alt-' . $this->_boundary . '--'; $msg[] = ''; - ClassRegistry::removeObject('view'); return $msg; } @@ -1105,10 +1104,7 @@ class CakeEmail { $this->_textMessage = $rendered; } - $msg = array_merge($msg, $content); - ClassRegistry::removeObject('view'); - - return $msg; + return array_merge($msg, $content); } } From 935badff03bd46ecdf1abbb36c671cb6451573be Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 12 Apr 2011 23:34:23 -0400 Subject: [PATCH 056/103] Fixed to MailTransport use configs intead Configure::read(). --- lib/Cake/Network/Email/MailTransport.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Network/Email/MailTransport.php b/lib/Cake/Network/Email/MailTransport.php index 6a1b13366..229451a08 100644 --- a/lib/Cake/Network/Email/MailTransport.php +++ b/lib/Cake/Network/Email/MailTransport.php @@ -31,9 +31,9 @@ class MailTransport extends AbstractTransport { * @return boolean */ public function send(CakeEmail $email) { - $eol = Configure::read('Email.Mail.EOL'); - if (!$eol) { - $eol = PHP_EOL; + $eol = PHP_EOL; + if (isset($this->_config['eol'])) { + $eol = $this->_config['eol']; } $headers = $email->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true)); $to = $headers['To']; From 40e86324081ef0fea4d750b619646573444d9aff Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 12 Apr 2011 23:37:50 -0400 Subject: [PATCH 057/103] Changed to translate messages using cake domain. --- lib/Cake/Network/CakeEmail.php | 38 ++++++++++++------------ lib/Cake/Network/Email/SmtpTransport.php | 14 ++++----- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 8b354e901..60ba2b546 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -246,7 +246,7 @@ class CakeEmail { if ($email === null) { return $this->_from; } - $this->_setEmailSingle('_from', $email, $name, __('From requires only 1 email address.')); + $this->_setEmailSingle('_from', $email, $name, __d('cake', 'From requires only 1 email address.')); } /** @@ -261,7 +261,7 @@ class CakeEmail { if ($email === null) { return $this->_replyTo; } - $this->_setEmailSingle('_replyTo', $email, $name, __('Reply-To requires only 1 email address.')); + $this->_setEmailSingle('_replyTo', $email, $name, __d('cake', 'Reply-To requires only 1 email address.')); } /** @@ -276,7 +276,7 @@ class CakeEmail { if ($email === null) { return $this->_readReceipt; } - $this->_setEmailSingle('_readReceipt', $email, $name, __('Disposition-Notification-To requires only 1 email address.')); + $this->_setEmailSingle('_readReceipt', $email, $name, __d('cake', 'Disposition-Notification-To requires only 1 email address.')); } /** @@ -291,7 +291,7 @@ class CakeEmail { if ($email === null) { return $this->_returnPath; } - $this->_setEmailSingle('_returnPath', $email, $name, __('Return-Path requires only 1 email address.')); + $this->_setEmailSingle('_returnPath', $email, $name, __d('cake', 'Return-Path requires only 1 email address.')); } /** @@ -381,7 +381,7 @@ class CakeEmail { protected function _setEmail($varName, $email, $name) { if (!is_array($email)) { if (!Validation::email($email)) { - throw new SocketException(__('Invalid email: "%s"', $email)); + throw new SocketException(__d('cake', 'Invalid email: "%s"', $email)); } if ($name === null) { $name = $email; @@ -395,7 +395,7 @@ class CakeEmail { $key = $value; } if (!Validation::email($key)) { - throw new SocketException(__('Invalid email: "%s"', $key)); + throw new SocketException(__d('cake', 'Invalid email: "%s"', $key)); } $list[$key] = $value; } @@ -432,7 +432,7 @@ class CakeEmail { protected function _addEmail($varName, $email, $name) { if (!is_array($email)) { if (!Validation::email($email)) { - throw new SocketException(__('Invalid email: "%s"', $email)); + throw new SocketException(__d('cake', 'Invalid email: "%s"', $email)); } if ($name === null) { $name = $email; @@ -446,7 +446,7 @@ class CakeEmail { $key = $value; } if (!Validation::email($key)) { - throw new SocketException(__('Invalid email: "%s"', $key)); + throw new SocketException(__d('cake', 'Invalid email: "%s"', $key)); } $list[$key] = $value; } @@ -475,7 +475,7 @@ class CakeEmail { */ public function setHeaders($headers) { if (!is_array($headers)) { - throw new SocketException(__('$headers should be an array.')); + throw new SocketException(__d('cake', '$headers should be an array.')); } $this->_headers = $headers; } @@ -489,7 +489,7 @@ class CakeEmail { */ public function addHeaders($headers) { if (!is_array($headers)) { - throw new SocketException(__('$headers should be an array.')); + throw new SocketException(__d('cake', '$headers should be an array.')); } $this->_headers = array_merge($this->_headers, $headers); } @@ -646,7 +646,7 @@ class CakeEmail { return $this->_emailFormat; } if (!in_array($format, $this->_emailFormatAvailable)) { - throw new SocketException(__('Format not available.')); + throw new SocketException(__d('cake', 'Format not available.')); } $this->_emailFormat = $format; } @@ -679,7 +679,7 @@ class CakeEmail { $this->_messageId = $message; } else { if (!preg_match('/^\<.+@.+\>$/', $message)) { - throw new SocketException(__('Invalid format to Message-ID. The text should be something like ""')); + throw new SocketException(__d('cake', 'Invalid format to Message-ID. The text should be something like ""')); } $this->_messageId = $message; } @@ -700,7 +700,7 @@ class CakeEmail { foreach ((array)$attachments as $name => $file) { $path = realpath($file); if ($path === false) { - throw new SocketException(__('File not found: "%s"', $attach)); + throw new SocketException(__d('cake', 'File not found: "%s"', $attach)); } if (is_int($name)) { $name = basename($path); @@ -758,11 +758,11 @@ class CakeEmail { public function send($content = null) { if (is_string($this->_config)) { if (!config('email')) { - throw new SocketException(__('%s not found.', APP . DS . 'email.php')); + throw new SocketException(__d('cake', '%s not found.', APP . DS . 'email.php')); } $configs = new EMAIL_CONFIG(); if (!isset($configs->{$this->_config})) { - throw new SocketException(__('Unknown email configuration "%s".', $this->_config)); + throw new SocketException(__d('cake', 'Unknown email configuration "%s".', $this->_config)); } $config = $configs->{$this->_config}; } else { @@ -773,11 +773,11 @@ class CakeEmail { if (!empty($config['from'])) { $this->to($config['from']); } else { - throw new SocketException(__('From is not specified.')); + throw new SocketException(__d('cake', 'From is not specified.')); } } if (empty($this->_to) && empty($this->_cc) && empty($this->_bcc)) { - throw new SocketExpcetion(__('You need specify one destination on to, cc or bcc.')); + throw new SocketExpcetion(__d('cake', 'You need specify one destination on to, cc or bcc.')); } if (is_array($content)) { @@ -818,9 +818,9 @@ class CakeEmail { $transportClassname .= 'Transport'; App::uses($transportClassname, $plugin . 'Network/Email'); if (!class_exists($transportClassname)) { - throw new SocketException(__('Class "%s" not found.', $transportClassname)); + throw new SocketException(__d('cake', 'Class "%s" not found.', $transportClassname)); } elseif (!method_exists($transportClassname, 'send')) { - throw new SocketException(__('The "%s" do not have send method.', $transportClassname)); + throw new SocketException(__d('cake', 'The "%s" do not have send method.', $transportClassname)); } $transport = new $transportClassname($config); diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index 6e3a2e5ac..cec2cfb61 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -77,7 +77,7 @@ class SmtpTransport extends AbstractTransport { protected function _connect() { $this->_generateSocket(); if (!$this->_socket->connect()) { - throw new SocketException(__('Unable to connect in SMTP server.')); + throw new SocketException(__d('cake', 'Unable to connect in SMTP server.')); } $this->_smtpSend(null, '220'); @@ -95,7 +95,7 @@ class SmtpTransport extends AbstractTransport { try { $this->_smtpSend("HELO {$host}", '250'); } catch (SocketException $e2) { - throw new SocketException(__('SMTP server not accepted the connection.')); + throw new SocketException(__d('cake', 'SMTP server not accepted the connection.')); } } } @@ -111,13 +111,13 @@ class SmtpTransport extends AbstractTransport { $authRequired = $this->_smtpSend('AUTH LOGIN', '334|503'); if ($authRequired == '334') { if (!$this->_smtpSend(base64_encode($this->_config['username']), '334')) { - throw new SocketException(__('SMTP server not accepted the username.')); + throw new SocketException(__d('cake', 'SMTP server not accepted the username.')); } if (!$this->_smtpSend(base64_encode($this->_config['password']), '235')) { - throw new SocketException(__('SMTP server not accepted the password.')); + throw new SocketException(__d('cake', 'SMTP server not accepted the password.')); } } elseif ($authRequired != '503') { - throw new SocketException(__('SMTP do not require authentication.')); + throw new SocketException(__d('cake', 'SMTP do not require authentication.')); } } } @@ -196,7 +196,7 @@ class SmtpTransport extends AbstractTransport { $response .= $this->_socket->read(); } if (substr($response, -2) !== "\r\n") { - throw new SocketException(__('SMTP timeout.')); + throw new SocketException(__d('cake', 'SMTP timeout.')); } $response = end(explode("\r\n", rtrim($response, "\r\n"))); @@ -206,7 +206,7 @@ class SmtpTransport extends AbstractTransport { } return $code[1]; } - throw new SocketException(__('SMTP Error: %s', $response)); + throw new SocketException(__d('cake', 'SMTP Error: %s', $response)); } } From f4f3bfe2fc7c74cf97a362acb8901b6d77181379 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 12 Apr 2011 23:45:02 -0400 Subject: [PATCH 058/103] Return the object when is set method. --- lib/Cake/Network/CakeEmail.php | 77 ++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 60ba2b546..8de03b182 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -246,7 +246,7 @@ class CakeEmail { if ($email === null) { return $this->_from; } - $this->_setEmailSingle('_from', $email, $name, __d('cake', 'From requires only 1 email address.')); + return $this->_setEmailSingle('_from', $email, $name, __d('cake', 'From requires only 1 email address.')); } /** @@ -261,7 +261,7 @@ class CakeEmail { if ($email === null) { return $this->_replyTo; } - $this->_setEmailSingle('_replyTo', $email, $name, __d('cake', 'Reply-To requires only 1 email address.')); + return $this->_setEmailSingle('_replyTo', $email, $name, __d('cake', 'Reply-To requires only 1 email address.')); } /** @@ -276,7 +276,7 @@ class CakeEmail { if ($email === null) { return $this->_readReceipt; } - $this->_setEmailSingle('_readReceipt', $email, $name, __d('cake', 'Disposition-Notification-To requires only 1 email address.')); + return $this->_setEmailSingle('_readReceipt', $email, $name, __d('cake', 'Disposition-Notification-To requires only 1 email address.')); } /** @@ -291,7 +291,7 @@ class CakeEmail { if ($email === null) { return $this->_returnPath; } - $this->_setEmailSingle('_returnPath', $email, $name, __d('cake', 'Return-Path requires only 1 email address.')); + return $this->_setEmailSingle('_returnPath', $email, $name, __d('cake', 'Return-Path requires only 1 email address.')); } /** @@ -305,7 +305,7 @@ class CakeEmail { if ($email === null) { return $this->_to; } - $this->_setEmail('_to', $email, $name); + return $this->_setEmail('_to', $email, $name); } /** @@ -313,10 +313,10 @@ class CakeEmail { * * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) * @param string $name - * @return void + * @return object $this */ public function addTo($email, $name = null) { - $this->_addEmail('_to', $email, $name); + return $this->_addEmail('_to', $email, $name); } /** @@ -330,7 +330,7 @@ class CakeEmail { if ($email === null) { return $this->_cc; } - $this->_setEmail('_cc', $email, $name); + return $this->_setEmail('_cc', $email, $name); } /** @@ -338,10 +338,10 @@ class CakeEmail { * * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) * @param string $name - * @return void + * @return object $this */ public function addCc($email, $name = null) { - $this->_addEmail('_cc', $email, $name); + return $this->_addEmail('_cc', $email, $name); } /** @@ -349,13 +349,13 @@ class CakeEmail { * * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) * @param string $name - * @return void + * @return mixed */ public function bcc($email = null, $name = null) { if ($email === null) { return $this->_bcc; } - $this->_setEmail('_bcc', $email, $name); + return $this->_setEmail('_bcc', $email, $name); } /** @@ -363,10 +363,10 @@ class CakeEmail { * * @param mixed $email String with email, Array with email as key, name as value or email as value (without name) * @param string $name - * @return void + * @return object $this */ public function addBcc($email, $name = null) { - $this->_addEmail('_bcc', $email, $name); + return $this->_addEmail('_bcc', $email, $name); } /** @@ -375,7 +375,7 @@ class CakeEmail { * @param string $varName * @param mixed $email * @param mixed $name - * @return void + * @return object $this * @thrown SocketException */ protected function _setEmail($varName, $email, $name) { @@ -387,7 +387,7 @@ class CakeEmail { $name = $email; } $this->{$varName} = array($email => $name); - return; + return $this; } $list = array(); foreach ($email as $key => $value) { @@ -400,6 +400,7 @@ class CakeEmail { $list[$key] = $value; } $this->{$varName} = $list; + return $this; } /** @@ -409,7 +410,7 @@ class CakeEmail { * @param mixed $email * @param string $name * @param string $throwMessage - * @return void + * @return object $this * @thrown SocketExpceiton */ protected function _setEmailSingle($varName, $email, $name, $throwMessage) { @@ -419,6 +420,7 @@ class CakeEmail { $this->{$varName} = $current; throw new SocketException($throwMessage); } + return $this; } /** @@ -427,7 +429,7 @@ class CakeEmail { * @param string $varName * @param mixed $email * @param mixed $name - * @return void + * @return object $this */ protected function _addEmail($varName, $email, $name) { if (!is_array($email)) { @@ -438,7 +440,7 @@ class CakeEmail { $name = $email; } $this->{$varName}[$email] = $name; - return; + return $this; } $list = array(); foreach ($email as $key => $value) { @@ -451,6 +453,7 @@ class CakeEmail { $list[$key] = $value; } $this->{$varName} = array_merge($this->{$varName}, $list); + return $this; } /** @@ -464,13 +467,14 @@ class CakeEmail { return $this->_subject; } $this->_subject = (string)$subject; + return $this; } /** * Sets eaders for the message * * @param array Associative array containing headers to be set. - * @return void + * @return object $this * @thrown SocketException */ public function setHeaders($headers) { @@ -478,13 +482,14 @@ class CakeEmail { throw new SocketException(__d('cake', '$headers should be an array.')); } $this->_headers = $headers; + return $this; } /** * Add header for the message * * @param array $headers - * @return void + * @return mixed $this * @thrown SocketException */ public function addHeaders($headers) { @@ -492,6 +497,7 @@ class CakeEmail { throw new SocketException(__d('cake', '$headers should be an array.')); } $this->_headers = array_merge($this->_headers, $headers); + return $this; } /** @@ -619,6 +625,7 @@ class CakeEmail { if ($template !== null) { $this->_template = (string)$template; } + return $this; } /** @@ -632,6 +639,7 @@ class CakeEmail { return $this->_viewRender; } $this->_viewRender = $viewClass; + return $this; } /** @@ -649,6 +657,7 @@ class CakeEmail { throw new SocketException(__d('cake', 'Format not available.')); } $this->_emailFormat = $format; + return $this; } /** @@ -662,6 +671,7 @@ class CakeEmail { return $this->_transportName; } $this->_transportName = (string)$name; + return $this; } /** @@ -683,6 +693,7 @@ class CakeEmail { } $this->_messageId = $message; } + return $this; } /** @@ -708,19 +719,21 @@ class CakeEmail { $attach[$name] = $path; } $this->_attachments = $attach; + return $this; } /** * Add attachments * * @param mixed $attachments String with the filename or array with filenames - * @return void + * @return object $this * @thrown SocketException */ public function addAttachments($attachments) { $current = $this->_attachments; $this->attachments($attachments); $this->_attachments = array_merge($current, $this->_attachments); + return $this; } /** @@ -736,17 +749,18 @@ class CakeEmail { * Configuration to use when send email * * @param mixed $config String with configuration name (from email.php), array with config or null to return current config - * @return string + * @return mixed */ public function config($config = null) { - if (!empty($config)) { - if (is_array($config)) { - $this->_config = $config; - } else { - $this->_config = (string)$config; - } + if (empty($config)) { + return $this->_config; } - return $this->_config; + if (is_array($config)) { + $this->_config = $config; + } else { + $this->_config = (string)$config; + } + return $this; } /** @@ -830,7 +844,7 @@ class CakeEmail { /** * Reset all EmailComponent internal variables to be able to send out a new email. * - * @return void + * @return object $this */ public function reset() { $this->_to = array(); @@ -853,6 +867,7 @@ class CakeEmail { $this->_transportName = 'mail'; $this->_attachments = array(); $this->_config = 'default'; + return $this; } /** From 3200e380d3abc53059a1916647bb9f6bc7c06763 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Wed, 13 Apr 2011 00:04:37 -0400 Subject: [PATCH 059/103] Created a new method to return the transport class before send. In some cases you need to do extra calls/configurations before send. --- lib/Cake/Network/CakeEmail.php | 48 ++++++++++++++++---- lib/Cake/Network/Email/AbstractTransport.php | 22 +++++---- lib/Cake/Network/Email/SmtpTransport.php | 28 ++++++++---- 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 8de03b182..fd8161fd8 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -193,6 +193,13 @@ class CakeEmail { */ protected $_transportName = 'mail'; +/** + * Instance of tranport class + * + * @var object + */ + protected $_transportClass = null; + /** * charset the email is sent in * @@ -671,9 +678,32 @@ class CakeEmail { return $this->_transportName; } $this->_transportName = (string)$name; + $this->_transportClass = null; return $this; } +/** + * Return the transport class + * + * @return object + * @thrown SocketException + */ + public function transportClass() { + if ($this->_transportClass) { + return $this->_transportClass; + } + list($plugin, $transportClassname) = pluginSplit($this->_transportName, true); + $transportClassname .= 'Transport'; + App::uses($transportClassname, $plugin . 'Network/Email'); + if (!class_exists($transportClassname)) { + throw new SocketException(__d('cake', 'Class "%s" not found.', $transportClassname)); + } elseif (!method_exists($transportClassname, 'send')) { + throw new SocketException(__d('cake', 'The "%s" do not have send method.', $transportClassname)); + } + + return $this->_transportClass = new $transportClassname(); + } + /** * Message-ID * @@ -755,11 +785,17 @@ class CakeEmail { if (empty($config)) { return $this->_config; } + if (is_array($config)) { $this->_config = $config; } else { $this->_config = (string)$config; } + + if ($this->_transportClass) { + $this->_transportClass->config($this->_config); + } + return $this; } @@ -828,16 +864,9 @@ class CakeEmail { $this->_message[] = ''; } - list($plugin, $transportClassname) = pluginSplit($this->_transportName, true); - $transportClassname .= 'Transport'; - App::uses($transportClassname, $plugin . 'Network/Email'); - if (!class_exists($transportClassname)) { - throw new SocketException(__d('cake', 'Class "%s" not found.', $transportClassname)); - } elseif (!method_exists($transportClassname, 'send')) { - throw new SocketException(__d('cake', 'The "%s" do not have send method.', $transportClassname)); - } + $transport = $this->transportClass(); + $transport->config($config); - $transport = new $transportClassname($config); return $transport->send($this); } @@ -865,6 +894,7 @@ class CakeEmail { $this->_message = ''; $this->_emailFormat = 'text'; $this->_transportName = 'mail'; + $this->_transportClass = null; $this->_attachments = array(); $this->_config = 'default'; return $this; diff --git a/lib/Cake/Network/Email/AbstractTransport.php b/lib/Cake/Network/Email/AbstractTransport.php index 9e6a59139..a655eaded 100644 --- a/lib/Cake/Network/Email/AbstractTransport.php +++ b/lib/Cake/Network/Email/AbstractTransport.php @@ -31,16 +31,6 @@ abstract class AbstractTransport { */ protected $_config = array(); -/** - * Constructor - * - */ - public function __construct($config = array()) { - if (!empty($config)) { - $this->_config = $config; - } - } - /** * Send mail * @@ -49,6 +39,18 @@ abstract class AbstractTransport { */ abstract public function send(CakeEmail $email); +/** + * Set the config + * + * @param array $config + * @return object $this + */ + public function config($config = array()) { + if (!empty($config)) { + $this->_config = $config; + } + } + /** * Help to convert headers in string * diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index cec2cfb61..aba0bd9f2 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -47,16 +47,6 @@ class SmtpTransport extends AbstractTransport { * @thrown SocketException */ public function send(CakeEmail $email) { - $config = array( - 'host' => 'localhost', - 'port' => 25, - 'timeout' => 30, - 'username' => null, - 'password' => null, - 'client' => null - ); - $this->_config += $config; - $this->_cakeEmail = $email; $this->_connect(); @@ -68,6 +58,24 @@ class SmtpTransport extends AbstractTransport { 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; + } + /** * Connect to SMTP Server * From 9ac5f9c349edf80f021c870f65f22f1af99fbec5 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Wed, 13 Apr 2011 00:20:35 -0400 Subject: [PATCH 060/103] Fixed the tests. --- lib/Cake/Network/CakeEmail.php | 4 +++- lib/Cake/tests/Case/Network/CakeEmailTest.php | 4 +++- lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index fd8161fd8..69c2f78c3 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -567,6 +567,7 @@ class CakeEmail { } if ($this->_messageId !== false) { if ($this->_messageId === true) { + App::uses('String', 'Utility'); $headers['Message-ID'] = '<' . String::UUID() . '@' . env('HTTP_HOST') . '>'; } else { $headers['Message-ID'] = $this->_messageId; @@ -808,7 +809,7 @@ class CakeEmail { public function send($content = null) { if (is_string($this->_config)) { if (!config('email')) { - throw new SocketException(__d('cake', '%s not found.', APP . DS . 'email.php')); + throw new SocketException(__d('cake', '%s not found.', APP . 'config' . DS . 'email.php')); } $configs = new EMAIL_CONFIG(); if (!isset($configs->{$this->_config})) { @@ -1077,6 +1078,7 @@ class CakeEmail { protected function _render($content) { $viewClass = $this->_viewRender; + App::uses('View', 'View'); if ($viewClass !== 'View') { list($plugin, $viewClass) = pluginSplit($viewClass, true); $viewClass .= 'View'; diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index c20c7b989..368c1e7ff 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -110,7 +110,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail = new TestCakeEmail(); App::build(array( - 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS) + 'views' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'View'. DS) )); } @@ -421,6 +421,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->from('cake@cakephp.org'); $this->CakeEmail->to(array('you@cakephp.org' => 'You')); $this->CakeEmail->subject('My title'); + $this->CakeEmail->config(array('empty')); $result = $this->CakeEmail->send("Here is my body, with multi lines.\nThis is the second line.\r\n\r\nAnd the last."); $this->assertTrue($result); @@ -450,6 +451,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->from('cake@cakephp.org'); $this->CakeEmail->to(array('you@cakephp.org' => 'You')); $this->CakeEmail->subject('My title'); + $this->CakeEmail->config(array('empty')); $this->CakeEmail->layout('default', 'default'); $result = $this->CakeEmail->send(); diff --git a/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php index a65e3b3cb..332e7b15f 100644 --- a/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php +++ b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php @@ -17,6 +17,7 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ App::uses('CakeEmail', 'Network'); +App::uses('AbstractTransport', 'Network/Email'); App::uses('SmtpTransport', 'Network/Email'); /** From 3a5c04273ee2f852682e08d8a6ea9211216f1cf8 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 15 Apr 2011 22:02:07 -0400 Subject: [PATCH 061/103] With class loading these code can be global. --- lib/Cake/Network/CakeEmail.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 69c2f78c3..e87739c28 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -19,6 +19,8 @@ App::uses('Validation', 'Utility'); App::uses('Multibyte', 'I18n'); App::uses('AbstractTransport', 'Network/Email'); +App::uses('String', 'Utility'); +App::uses('View', 'View'); /** * Cake e-mail class. @@ -567,7 +569,6 @@ class CakeEmail { } if ($this->_messageId !== false) { if ($this->_messageId === true) { - App::uses('String', 'Utility'); $headers['Message-ID'] = '<' . String::UUID() . '@' . env('HTTP_HOST') . '>'; } else { $headers['Message-ID'] = $this->_messageId; @@ -1078,7 +1079,6 @@ class CakeEmail { protected function _render($content) { $viewClass = $this->_viewRender; - App::uses('View', 'View'); if ($viewClass !== 'View') { list($plugin, $viewClass) = pluginSplit($viewClass, true); $viewClass .= 'View'; From 5b223e747b31dece5e477848589242ebb86284ab Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 15 Apr 2011 22:09:56 -0400 Subject: [PATCH 062/103] Adjusted the Smtp test to use the new config method. --- .../Case/Network/Email/SmtpTransportTest.php | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php index 332e7b15f..49477968b 100644 --- a/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php +++ b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php @@ -26,15 +26,6 @@ App::uses('SmtpTransport', 'Network/Email'); */ class SmtpTestTransport extends SmtpTransport { -/** - * Config the timeout - * - * @var array - */ - protected $_config = array( - 'timeout' => 30 - ); - /** * Helper to change the socket * @@ -45,16 +36,6 @@ class SmtpTestTransport extends SmtpTransport { $this->_socket = $socket; } -/** - * Helper to change the config attribute - * - * @param array $config - * @return void - */ - public function setConfig($config) { - $this->_config = array_merge($this->_config, $config); - } - /** * Helper to change the CakeEmail * @@ -107,6 +88,7 @@ class StmpProtocolTest extends CakeTestCase { $this->SmtpTransport = new SmtpTestTransport(); $this->SmtpTransport->setSocket($this->socket); + $this->SmtpTransport->config(); } /** @@ -176,7 +158,7 @@ class StmpProtocolTest extends CakeTestCase { $this->socket->expects($this->at(6))->method('write')->with("c3Rvcnk=\r\n"); $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("235 OK\r\n")); - $this->SmtpTransport->setConfig(array('username' => 'mark', 'password' => 'story')); + $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); $this->SmtpTransport->auth(); } @@ -187,7 +169,7 @@ class StmpProtocolTest extends CakeTestCase { */ public function testAuthNoAuth() { $this->socket->expects($this->never())->method('write')->with("AUTH LOGIN\r\n"); - $this->SmtpTransport->setConfig(array('username' => null, 'password' => null)); + $this->SmtpTransport->config(array('username' => null, 'password' => null)); $this->SmtpTransport->auth(); } From c5f289fccf9fcd366c00bb2f110872ef4215c8bf Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 15 Apr 2011 22:37:55 -0400 Subject: [PATCH 063/103] More tests to CakeEmail. --- lib/Cake/tests/Case/Network/CakeEmailTest.php | 60 +++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 368c1e7ff..f75b017bc 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -75,6 +75,23 @@ class DebugTransport extends AbstractTransport { */ public static $includeAddresses = false; +/** + * Config + * + * @var array + */ + public static $config = array(); + +/** + * Config + * + * @param mixed $config + * @return mixed + */ + public function config($config) { + self::$config = $config; + } + /** * Send * @@ -143,8 +160,9 @@ class CakeEmailTest extends CakeTestCase { $expected = array('cake@cakephp.org' => 'CakePHP'); $this->assertIdentical($this->CakeEmail->from(), $expected); - $this->CakeEmail->from(array('cake@cakephp.org' => 'CakePHP')); + $result = $this->CakeEmail->from(array('cake@cakephp.org' => 'CakePHP')); $this->assertIdentical($this->CakeEmail->from(), $expected); + $this->assertIdentical($this->CakeEmail, $result); } /** @@ -155,9 +173,10 @@ class CakeEmailTest extends CakeTestCase { public function testTo() { $this->assertIdentical($this->CakeEmail->to(), array()); - $this->CakeEmail->to('cake@cakephp.org'); + $result = $this->CakeEmail->to('cake@cakephp.org'); $expected = array('cake@cakephp.org' => 'cake@cakephp.org'); $this->assertIdentical($this->CakeEmail->to(), $expected); + $this->assertIdentical($this->CakeEmail, $result); $this->CakeEmail->to('cake@cakephp.org', 'CakePHP'); $expected = array('cake@cakephp.org' => 'CakePHP'); @@ -178,7 +197,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->addTo('jrbasso@cakephp.org'); $this->CakeEmail->addTo('mark_story@cakephp.org', 'Mark Story'); - $this->CakeEmail->addTo(array('phpnut@cakephp.org' => 'PhpNut', 'jose_zap@cakephp.org')); + $result = $this->CakeEmail->addTo(array('phpnut@cakephp.org' => 'PhpNut', 'jose_zap@cakephp.org')); $expected = array( 'cake@cakephp.org' => 'Cake PHP', 'cake-php@googlegroups.com' => 'Cake Groups', @@ -189,6 +208,7 @@ class CakeEmailTest extends CakeTestCase { 'jose_zap@cakephp.org' => 'jose_zap@cakephp.org' ); $this->assertIdentical($this->CakeEmail->to(), $expected); + $this->assertIdentical($this->CakeEmail, $result); } /** @@ -291,7 +311,8 @@ class CakeEmailTest extends CakeTestCase { $result = $this->CakeEmail->getHeaders(); $this->assertFalse(isset($result['Message-ID'])); - $this->CakeEmail->messageId(''); + $result = $this->CakeEmail->messageId(''); + $this->assertIdentical($this->CakeEmail, $result); $result = $this->CakeEmail->getHeaders(); $this->assertIdentical($result['Message-ID'], ''); } @@ -318,8 +339,9 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->subject(1); $this->assertIdentical($this->CakeEmail->subject(), '1'); - $this->CakeEmail->subject(array('something')); + $result = $this->CakeEmail->subject(array('something')); $this->assertIdentical($this->CakeEmail->subject(), 'Array'); + $this->assertIdentical($this->CakeEmail, $result); } /** @@ -408,6 +430,34 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->attachments(), $expected); } +/** + * testTransport method + * + * @return void + */ + public function testTransport() { + $result = $this->CakeEmail->transport('debug'); + $this->assertIdentical($this->CakeEmail, $result); + $this->assertIdentical($this->CakeEmail->transport(), 'debug'); + + $result = $this->CakeEmail->transportClass(); + $this->assertIsA($result, 'DebugTransport'); + } + +/** + * testConfig method + * + * @return void + */ + public function testConfig() { + $this->CakeEmail->transport('debug')->transportClass(); + DebugTransport::$config = array(); + + $config = array('test' => 'ok', 'test2' => true); + $this->CakeEmail->config($config); + $this->assertIdentical(DebugTransport::$config, $config); + } + /** * testSendWithContent method * From c48db361969f9aae771a32699aa39b0b287a37e4 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:53:12 -0400 Subject: [PATCH 064/103] Changed to be able to configure empty array in CakeEmail. --- lib/Cake/Network/CakeEmail.php | 2 +- lib/Cake/tests/Case/Network/CakeEmailTest.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index e87739c28..18662a7a8 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -784,7 +784,7 @@ class CakeEmail { * @return mixed */ public function config($config = null) { - if (empty($config)) { + if ($config === null) { return $this->_config; } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index f75b017bc..6b8097371 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -456,6 +456,10 @@ class CakeEmailTest extends CakeTestCase { $config = array('test' => 'ok', 'test2' => true); $this->CakeEmail->config($config); $this->assertIdentical(DebugTransport::$config, $config); + $this->assertIdentical($this->CakeEmail->config(), $config); + + $this->CakeEmail->config(array()); + $this->assertIdentical(DebugTransport::$config, array()); } /** From d5938dd3c46df9b7b07775d2542d3ec8dd92217e Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 14:00:19 -0400 Subject: [PATCH 065/103] Support to multibyte in subject. --- lib/Cake/Network/CakeEmail.php | 2 +- lib/Cake/tests/Case/Network/CakeEmailTest.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 18662a7a8..697914d6a 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -475,7 +475,7 @@ class CakeEmail { if ($subject === null) { return $this->_subject; } - $this->_subject = (string)$subject; + $this->_subject = $this->_encode((string)$subject); return $this; } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 6b8097371..97bda298e 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -342,6 +342,10 @@ class CakeEmailTest extends CakeTestCase { $result = $this->CakeEmail->subject(array('something')); $this->assertIdentical($this->CakeEmail->subject(), 'Array'); $this->assertIdentical($this->CakeEmail, $result); + + $this->CakeEmail->subject('هذه رسالة بعنوان طويل مرسل للمستلم'); + $expected = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?='; + $this->assertIdentical($this->CakeEmail->subject(), $expected); } /** From 33ca64f505d862764264a6f9dcd72bfc8d4f08cd Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 17:22:20 -0400 Subject: [PATCH 066/103] Added support to set variables to be used in the render. --- lib/Cake/Network/CakeEmail.php | 23 +++++++++++++++++++ lib/Cake/tests/Case/Network/CakeEmailTest.php | 21 +++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 697914d6a..a8f428619 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -153,6 +153,13 @@ class CakeEmail { */ protected $_viewRender = 'View'; +/** + * Vars to sent to render + * + * @var array + */ + protected $_viewVars = array(); + /** * Text message * @@ -651,6 +658,20 @@ class CakeEmail { return $this; } +/** + * Variables to be set on render + * + * @param array + * @return mixed + */ + public function viewVars($viewVars = null) { + if ($viewVars === null) { + return $this->_viewVars; + } + $this->_viewVars = $viewVars; + return $this; + } + /** * Email format * @@ -891,6 +912,7 @@ class CakeEmail { $this->_layout = 'default'; $this->_template = ''; $this->_viewRender = 'View'; + $this->_viewVars = array(); $this->_textMessage = ''; $this->_htmlMessage = ''; $this->_message = ''; @@ -1087,6 +1109,7 @@ class CakeEmail { $View = new $viewClass(null); $View->layout = $this->_layout; + $View->viewVars = $this->_viewVars; $msg = array(); $content = implode("\n", $content); diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 97bda298e..645ac8640 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -518,6 +518,27 @@ class CakeEmailTest extends CakeTestCase { $this->assertTrue((bool)strpos(DebugTransport::$lastHeader, 'To: ')); } +/** + * testSendRenderWithVars method + * + * @return void + */ + public function testSendRenderWithVars() { + $this->CakeEmail->reset(); + $this->CakeEmail->transport('debug'); + DebugTransport::$includeAddresses = true; + + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to(array('you@cakephp.org' => 'You')); + $this->CakeEmail->subject('My title'); + $this->CakeEmail->config(array('empty')); + $this->CakeEmail->layout('default', 'custom'); + $this->CakeEmail->viewVars(array('value' => 12345)); + $result = $this->CakeEmail->send(); + + $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, 'Here is your value: 12345')); + } + /** * testReset method * From ff5365d6abc82c4683c5554e2e777dd986df4a83 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 17:53:51 -0400 Subject: [PATCH 067/103] Added support to return the html and text message. --- lib/Cake/Network/CakeEmail.php | 25 ++++++++++++++-- lib/Cake/tests/Case/Network/CakeEmailTest.php | 29 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index a8f428619..c03b121be 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -52,6 +52,20 @@ class CakeEmail { */ const LINE_LENGTH_MUST = 998; +/** + * Type of message - HTML + * + * @constant MESSAGE_HTML + */ + const MESSAGE_HTML = 'html'; + +/** + * Type of message - TEXT + * + * @constant MESSAGE_TEXT + */ + const MESSAGE_TEXT = 'text'; + /** * Recipient of the email * @@ -792,9 +806,16 @@ class CakeEmail { /** * Get generated message (used by transport classes) * - * @return array + * @param mixed $type Use MESSAGE_* constants or null to return the full message as array + * @return mixed String if have type, array if type is null */ - public function message() { + public function message($type = null) { + switch ($type) { + case self::MESSAGE_HTML: + return $this->_htmlMessage; + case self::MESSAGE_TEXT: + return $this->_textMessage; + } return $this->_message; } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 645ac8640..7149c0c5b 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -539,6 +539,35 @@ class CakeEmailTest extends CakeTestCase { $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, 'Here is your value: 12345')); } +/** + * testMessage method + * + * @return void + */ + public function testMessage() { + $this->CakeEmail->reset(); + $this->CakeEmail->transport('debug'); + DebugTransport::$includeAddresses = true; + + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to(array('you@cakephp.org' => 'You')); + $this->CakeEmail->subject('My title'); + $this->CakeEmail->config(array('empty')); + $this->CakeEmail->layout('default', 'default'); + $this->CakeEmail->emailFormat('both'); + $result = $this->CakeEmail->send(); + + $expected = '

This email was sent using the CakePHP Framework

'; + $this->assertTrue((bool)strpos($this->CakeEmail->message(CakeEmail::MESSAGE_HTML), $expected)); + + $expected = 'This email was sent using the CakePHP Framework, http://cakephp.org.'; + $this->assertTrue((bool)strpos($this->CakeEmail->message(CakeEmail::MESSAGE_TEXT), $expected)); + + $message = $this->CakeEmail->message(); + $this->assertTrue(in_array('Content-Type: text/plain; charset=UTF-8', $message)); + $this->assertTrue(in_array('Content-Type: text/html; charset=UTF-8', $message)); + } + /** * testReset method * From 3b896a82efa5d44528a6c1a2cd3c464380eb28d0 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sat, 16 Apr 2011 21:51:51 -0400 Subject: [PATCH 068/103] Revert "Removing the methods from Email component. Tests commentds until adjust the code to BC." This reverts commit 00016c515d8fd09b8e97e56121491f881ae827c9. --- .../Controller/Component/EmailComponent.php | 217 ++++++++- .../Component/EmailComponentTest.php | 421 ++++++++++++++++-- 2 files changed, 587 insertions(+), 51 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 87a1962c8..103ccafed 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -28,8 +28,7 @@ App::uses('Multibyte', 'I18n'); * * @package cake.libs.controller.components * @link http://book.cakephp.org/view/1283/Email - * @deprecated - * @see CakeEmail Lib + * */ class EmailComponent extends Component { @@ -252,6 +251,15 @@ class EmailComponent extends Component { */ public $smtpOptions = array(); +/** + * Placeholder for any errors that might happen with the + * smtp mail methods + * + * @var string + * @access public + */ + public $smtpError = null; + /** * Contains the rendered plain text message if one was sent. * @@ -306,6 +314,14 @@ class EmailComponent extends Component { */ protected $_message = array(); +/** + * Variable that holds SMTP connection + * + * @var resource + * @access protected + */ + protected $_smtpConnection = null; + /** * Constructor * @@ -397,8 +413,7 @@ class EmailComponent extends Component { $_method = '_' . $this->delivery; - //$sent = $this->$_method(); - $sent = true; + $sent = $this->$_method(); $this->_header = array(); $this->_message = array(); @@ -422,6 +437,7 @@ class EmailComponent extends Component { $this->subject = null; $this->additionalParams = null; $this->date = null; + $this->smtpError = null; $this->attachments = array(); $this->htmlMessage = null; $this->textMessage = null; @@ -797,4 +813,197 @@ class EmailComponent extends Component { return $value; } +/** + * Wrapper for PHP mail function used for sending out emails + * + * @return bool Success + * @access private + */ + function _mail() { + $header = implode($this->lineFeed, $this->_header); + $message = implode($this->lineFeed, $this->_message); + if (is_array($this->to)) { + $to = implode(', ', array_map(array($this, '_formatAddress'), $this->to)); + } else { + $to = $this->to; + } + if (ini_get('safe_mode')) { + return @mail($to, $this->_encode($this->subject), $message, $header); + } + return @mail($to, $this->_encode($this->subject), $message, $header, $this->additionalParams); + } + + +/** + * Helper method to get socket, overridden in tests + * + * @param array $config Config data for the socket. + * @return void + * @access protected + */ + function _getSocket($config) { + $this->_smtpConnection = new CakeSocket($config); + } + +/** + * Sends out email via SMTP + * + * @return bool Success + * @access private + */ + function _smtp() { + App::uses('CakeSocket', 'Network'); + + $defaults = array( + 'host' => 'localhost', + 'port' => 25, + 'protocol' => 'smtp', + 'timeout' => 30 + ); + $this->smtpOptions = array_merge($defaults, $this->smtpOptions); + $this->_getSocket($this->smtpOptions); + + if (!$this->_smtpConnection->connect()) { + $this->smtpError = $this->_smtpConnection->lastError(); + return false; + } elseif (!$this->_smtpSend(null, '220')) { + return false; + } + + $httpHost = env('HTTP_HOST'); + + if (isset($this->smtpOptions['client'])) { + $host = $this->smtpOptions['client']; + } elseif (!empty($httpHost)) { + list($host) = explode(':', $httpHost); + } else { + $host = 'localhost'; + } + + if (!$this->_smtpSend("EHLO {$host}", '250') && !$this->_smtpSend("HELO {$host}", '250')) { + return false; + } + + if (isset($this->smtpOptions['username']) && isset($this->smtpOptions['password'])) { + $authRequired = $this->_smtpSend('AUTH LOGIN', '334|503'); + if ($authRequired == '334') { + if (!$this->_smtpSend(base64_encode($this->smtpOptions['username']), '334')) { + return false; + } + if (!$this->_smtpSend(base64_encode($this->smtpOptions['password']), '235')) { + return false; + } + } elseif ($authRequired != '503') { + return false; + } + } + + if (!$this->_smtpSend('MAIL FROM: ' . $this->_formatAddress($this->from, true))) { + return false; + } + + if (!is_array($this->to)) { + $tos = array_map('trim', explode(',', $this->to)); + } else { + $tos = $this->to; + } + foreach ($tos as $to) { + if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($to, true))) { + return false; + } + } + + foreach ($this->cc as $cc) { + if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($cc, true))) { + return false; + } + } + foreach ($this->bcc as $bcc) { + if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($bcc, true))) { + return false; + } + } + + if (!$this->_smtpSend('DATA', '354')) { + return false; + } + + $header = implode("\r\n", $this->_header); + $message = implode("\r\n", $this->_message); + if (!$this->_smtpSend($header . "\r\n\r\n" . $message . "\r\n\r\n\r\n.")) { + return false; + } + $this->_smtpSend('QUIT', false); + + $this->_smtpConnection->disconnect(); + return true; + } + +/** + * 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 bool Success + * @access protected + */ + function _smtpSend($data, $checkCode = '250') { + if (!is_null($data)) { + $this->_smtpConnection->write($data . "\r\n"); + } + while ($checkCode !== false) { + $response = ''; + $startTime = time(); + while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->smtpOptions['timeout'])) { + $response .= $this->_smtpConnection->read(); + } + if (substr($response, -2) !== "\r\n") { + $this->smtpError = 'timeout'; + return false; + } + $response = end(explode("\r\n", rtrim($response, "\r\n"))); + + if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) { + if ($code[2] === '-') { + continue; + } + return $code[1]; + } + $this->smtpError = $response; + return false; + } + return true; + } + +/** + * Set as controller flash message a debug message showing current settings in component + * + * @return boolean Success + * @access private + */ + function _debug() { + $nl = "\n"; + $header = implode($nl, $this->_header); + $message = implode($nl, $this->_message); + $fm = '
';
+
+		if (is_array($this->to)) {
+			$to = implode(', ', array_map(array($this, '_formatAddress'), $this->to));
+		} else {
+			$to = $this->to;
+		}
+		$fm .= sprintf('%s %s%s', 'To:', $to, $nl);
+		$fm .= sprintf('%s %s%s', 'From:', $this->from, $nl);
+		$fm .= sprintf('%s %s%s', 'Subject:', $this->_encode($this->subject), $nl);
+		$fm .= sprintf('%s%3$s%3$s%s', 'Header:', $header, $nl);
+		$fm .= sprintf('%s%3$s%3$s%s', 'Parameters:', $this->additionalParams, $nl);
+		$fm .= sprintf('%s%3$s%3$s%s', 'Message:', $message, $nl);
+		$fm .= '
'; + + if (isset($this->Controller->Session)) { + $this->Controller->Session->setFlash($fm, 'default', null, 'email'); + return true; + } + return $fm; + } } diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index 493ecc052..949daf8c2 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -29,6 +29,62 @@ App::uses('CakeSocket', 'Network'); */ class EmailTestComponent extends EmailComponent { + var $smtpSend = ''; +/** + * smtpSend method override for testing + * + * @access public + * @return mixed + */ + function smtpSend($data, $code = '250') { + return parent::_smtpSend($data, $code); + } + +/** + * undocumented function + * + * @return void + */ + function _smtpSend($data, $code = '250') { + if ($this->_debug) { + $this->smtpSend .= $data . "\n"; + return true; + } + return parent::_smtpSend($data, $code); + } + +/** + * Convenience setter method for testing. + * + * @access public + * @return void + */ + function setConnectionSocket($socket) { + $this->_smtpConnection = $socket; + } + +/** + * Allows mocks to be used with tests. + * + * @param array $config + * @return void + */ + function _getSocket($config) { + if (empty($this->_smtpConnection)) { + parent::_getSocket($config); + } + } + +/** + * Convenience getter method for testing. + * + * @access public + * @return mixed + */ + function getConnectionSocket() { + return $this->_smtpConnection; + } + /** * Convenience setter for testing. * @@ -212,7 +268,7 @@ class EmailComponentTest extends CakeTestCase { function tearDown() { Configure::write('App.encoding', $this->_appEncoding); App::build(); - //$this->Controller->Session->delete('Message'); + $this->Controller->Session->delete('Message'); ClassRegistry::flush(); } @@ -227,6 +283,252 @@ class EmailComponentTest extends CakeTestCase { return str_replace(array("\r\n", "\r"), "\n", $string); } +/** + * testSmtpConfig method + * + * @access public + * @return void + */ + function testSmtpConfig() { + if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { + return; + } + $this->Controller->EmailTest->delivery = 'smtp'; + $this->Controller->EmailTest->smtpOptions = array(); + $this->Controller->EmailTest->send('anything'); + $config = array( + 'host' => 'localhost', + 'port' => 25, + 'protocol' => 'smtp', + 'timeout' => 30 + ); + $this->assertEqual($config, $this->Controller->EmailTest->smtpOptions); + + $this->Controller->EmailTest->smtpOptions = array('port' => 80); + $this->Controller->EmailTest->send('anything'); + $config['port'] = 80; + $this->assertEqual($config, $this->Controller->EmailTest->smtpOptions); + } + +/** + * testBadSmtpSend method + * + * @access public + * @return void + */ + function testBadSmtpSend() { + if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { + return; + } + $this->Controller->EmailTest->smtpOptions['host'] = 'blah'; + $this->Controller->EmailTest->delivery = 'smtp'; + $this->assertFalse($this->Controller->EmailTest->send('Should not work')); + } + +/** + * testSmtpSend method + * + * @access public + * @return void + */ + function testSmtpSend() { + if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { + return; + } + + $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->from = 'noreply@example.com'; + $this->Controller->EmailTest->subject = 'Cake SMTP test'; + $this->Controller->EmailTest->replyTo = 'noreply@example.com'; + $this->Controller->EmailTest->template = null; + + $this->Controller->EmailTest->delivery = 'smtp'; + $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); + + $this->Controller->EmailTest->_debug = true; + $this->Controller->EmailTest->sendAs = 'text'; + $expect = <<Host: localhost +Port: 25 +Timeout: 30 +To: postmaster@localhost +From: noreply@example.com +Subject: Cake SMTP test +Header: + +To: postmaster@localhost +From: noreply@example.com +Reply-To: noreply@example.com +Subject: Cake SMTP test +X-Mailer: CakePHP Email Component +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bitParameters: + +Message: + +This is the body of the message + + +TEMPDOC; + $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + } + +/** + * testSmtpEhlo method + * + * @access public + * @return void + */ + function testSmtpEhlo() { + if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { + return; + } + + $connection = new CakeSocket(array('protocol'=>'smtp', 'host' => 'localhost', 'port' => 25)); + $this->Controller->EmailTest->setConnectionSocket($connection); + $this->Controller->EmailTest->smtpOptions['timeout'] = 10; + $this->assertTrue($connection->connect()); + $this->assertTrue($this->Controller->EmailTest->smtpSend(null, '220') !== false); + $this->skipIf($this->Controller->EmailTest->smtpSend('EHLO locahost', '250') === false, '%s do not support EHLO.'); + $connection->disconnect(); + + $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->from = 'noreply@example.com'; + $this->Controller->EmailTest->subject = 'Cake SMTP test'; + $this->Controller->EmailTest->replyTo = 'noreply@example.com'; + $this->Controller->EmailTest->template = null; + + $this->Controller->EmailTest->delivery = 'smtp'; + $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); + + $this->Controller->EmailTest->_debug = true; + $this->Controller->EmailTest->sendAs = 'text'; + $expect = <<Host: localhost +Port: 25 +Timeout: 30 +To: postmaster@localhost +From: noreply@example.com +Subject: Cake SMTP test +Header: + +To: postmaster@localhost +From: noreply@example.com +Reply-To: noreply@example.com +Subject: Cake SMTP test +X-Mailer: CakePHP Email Component +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bitParameters: + +Message: + +This is the body of the message + + +TEMPDOC; + $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + } + +/** + * testSmtpSendMultipleTo method + * + * @access public + * @return void + */ + function testSmtpSendMultipleTo() { + if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) { + return; + } + $this->Controller->EmailTest->reset(); + $this->Controller->EmailTest->to = array('postmaster@localhost', 'root@localhost'); + $this->Controller->EmailTest->from = 'noreply@example.com'; + $this->Controller->EmailTest->subject = 'Cake SMTP multiple To test'; + $this->Controller->EmailTest->replyTo = 'noreply@example.com'; + $this->Controller->EmailTest->template = null; + $this->Controller->EmailTest->_debug = true; + $this->Controller->EmailTest->sendAs = 'text'; + $this->Controller->EmailTest->delivery = 'smtp'; + + $socket = $this->getMock('CakeSocket'); + $socket->expects($this->any()) + ->method('connect') + ->will($this->returnValue(true)); + $this->Controller->EmailTest->setConnectionSocket($socket); + + $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); + + $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend); + $this->assertPattern('/MAIL FROM: \n/', $this->Controller->EmailTest->smtpSend); + $this->assertPattern('/RCPT TO: \n/', $this->Controller->EmailTest->smtpSend); + $this->assertPattern('/RCPT TO: \n/', $this->Controller->EmailTest->smtpSend); + $this->assertPattern( + '/To: postmaster@localhost, root@localhost[\n\r]/', + $this->Controller->EmailTest->smtpSend + ); + } + +/** + * test sending smtp from a host using a port. + * + * @return void + */ + function testSmtpSendHostWithPort() { + $bkp = env('HTTP_HOST'); + $_SERVER['HTTP_HOST'] = 'localhost:8080'; + + $this->Controller->EmailTest->reset(); + $this->Controller->EmailTest->to = array('root@localhost'); + $this->Controller->EmailTest->from = 'noreply@example.com'; + $this->Controller->EmailTest->subject = 'Cake SMTP host test'; + $this->Controller->EmailTest->replyTo = 'noreply@example.com'; + $this->Controller->EmailTest->template = null; + $this->Controller->EmailTest->delivery = 'smtp'; + $this->Controller->EmailTest->sendAs = 'text'; + $this->Controller->EmailTest->_debug = true; + + $socket = $this->getMock('CakeSocket'); + $socket->expects($this->any()) + ->method('connect') + ->will($this->returnValue(true)); + + $this->Controller->EmailTest->setConnectionSocket($socket); + $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); + + $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend); + + $_SERVER['HTTP_HOST'] = $bkp; + } + +/** + * testAuthenticatedSmtpSend method + * + * @access public + * @return void + */ + function testAuthenticatedSmtpSend() { + if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { + return; + } + + $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->from = 'noreply@example.com'; + $this->Controller->EmailTest->subject = 'Cake SMTP test'; + $this->Controller->EmailTest->replyTo = 'noreply@example.com'; + $this->Controller->EmailTest->template = null; + $this->Controller->EmailTest->smtpOptions['username'] = 'test'; + $this->Controller->EmailTest->smtpOptions['password'] = 'testing'; + + $this->Controller->EmailTest->delivery = 'smtp'; + $result = $this->Controller->EmailTest->send('This is the body of the message'); + $code = substr($this->Controller->EmailTest->smtpError, 0, 3); + $this->skipIf(!$code, '%s Authentication not enabled on server'); + + $this->assertFalse($result); + $this->assertEqual($code, '535'); + } + /** * testSendFormats method * @@ -265,19 +567,19 @@ MSGBLOC; $this->Controller->EmailTest->sendAs = 'text'; $expect = str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'html'; $expect = str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); // TODO: better test for format of message sent? $this->Controller->EmailTest->sendAs = 'both'; $expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); } /** @@ -344,12 +646,12 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'text'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $header) . $text . "\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'html'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . "\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'both'; $expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $header); @@ -358,7 +660,7 @@ HTMLBLOC; $expect = '
' . $expect . '--alt---' . "\n\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $html = << @@ -379,7 +681,7 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'html'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message', 'default', 'thin')); - //$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); $result = ClassRegistry::getObject('view'); $this->assertFalse($result); @@ -404,9 +706,34 @@ HTMLBLOC; $this->Controller->helpers = array('Html'); $this->Controller->EmailTest->send(); - //$result = $this->Controller->Session->read('Message.email.message'); - //$this->assertPattern('/Test/', $result); - //$this->assertPattern('/http\:\/\/example\.com/', $result); + $result = $this->Controller->Session->read('Message.email.message'); + $this->assertPattern('/Test/', $result); + $this->assertPattern('/http\:\/\/example\.com/', $result); + } + +/** + * testSmtpSendSocket method + * + * @access public + * @return void + */ + function testSmtpSendSocket() { + if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { + return; + } + + $socket = new CakeSocket(array_merge(array('protocol'=>'smtp'), $this->Controller->EmailTest->smtpOptions)); + $this->Controller->EmailTest->setConnectionSocket($socket); + + $this->assertSame($this->Controller->EmailTest->getConnectionSocket(), $socket); + + $response = $this->Controller->EmailTest->smtpSend('HELO', '250'); + $this->assertPattern('/501 Syntax: HELO hostname/', $this->Controller->EmailTest->smtpError); + + $this->Controller->EmailTest->reset(); + $response = $this->Controller->EmailTest->smtpSend('HELO somehostname', '250'); + + $this->assertNoPattern('/501 Syntax: HELO hostname/', (string)$this->Controller->EmailTest->smtpError); } /** @@ -426,7 +753,6 @@ HTMLBLOC; $this->Controller->EmailTest->delivery = 'debug'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); -/* $result = $this->Controller->Session->read('Message.email.message'); $this->assertPattern('/To: postmaster@localhost\n/', $result); @@ -440,7 +766,6 @@ HTMLBLOC; $this->assertPattern('/Content-Type: text\/plain; charset=UTF-8\n/', $result); $this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result); $this->assertPattern('/This is the body of the message/', $result); -*/ } /** @@ -456,7 +781,7 @@ HTMLBLOC; $this->Controller->EmailTest->subject = 'Cake Debug Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; -/* + $this->Controller->EmailTest->delivery = 'debug'; $result = $this->Controller->EmailTest->send('This is the body of the message'); @@ -470,7 +795,6 @@ HTMLBLOC; $this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result); $this->assertPattern('/This is the body of the message/', $result); $this->Controller->Session = $session; -*/ } /** @@ -587,7 +911,6 @@ HTMLBLOC; $content = array('First line', 'Second line', 'Third line'); $this->assertTrue($this->Controller->EmailTest->send($content)); -/* $result = $this->Controller->Session->read('Message.email.message'); $this->assertPattern('/To: postmaster@localhost\n/', $result); @@ -600,7 +923,6 @@ HTMLBLOC; $this->assertPattern('/First line\n/', $result); $this->assertPattern('/Second line\n/', $result); $this->assertPattern('/Third line\n/', $result); -*/ } /** @@ -617,8 +939,8 @@ HTMLBLOC; $this->Controller->EmailTest->delivery = 'debug'; $this->assertTrue($this->Controller->EmailTest->send('test message')); - //$result = $this->Controller->Session->read('Message.email.message'); - //$this->assertPattern('/Date: Today!\n/', $result); + $result = $this->Controller->Session->read('Message.email.message'); + $this->assertPattern('/Date: Today!\n/', $result); } /** @@ -673,8 +995,8 @@ HTMLBLOC; $subject = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?='; - //preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); - //$this->assertEqual(trim($matches[1]), $subject); + preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + $this->assertEqual(trim($matches[1]), $subject); $result = mb_internal_encoding(); $this->assertEqual($result, 'ISO-8859-1'); @@ -701,18 +1023,18 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'text'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); - //$this->assertEqual(trim($matches[1]), $subject); + preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + $this->assertEqual(trim($matches[1]), $subject); $this->Controller->EmailTest->sendAs = 'html'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); - //$this->assertEqual(trim($matches[1]), $subject); + preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + $this->assertEqual(trim($matches[1]), $subject); $this->Controller->EmailTest->sendAs = 'both'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); - //$this->assertEqual(trim($matches[1]), $subject); + preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + $this->assertEqual(trim($matches[1]), $subject); } /** @@ -735,9 +1057,9 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'text'; $this->assertTrue($this->Controller->EmailTest->send($body)); - //$msg = $this->Controller->Session->read('Message.email.message'); - //$this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="EmailComponentTest.php"') . '/', $msg); - //$this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="some-name.php"') . '/', $msg); + $msg = $this->Controller->Session->read('Message.email.message'); + $this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="EmailComponentTest.php"') . '/', $msg); + $this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="some-name.php"') . '/', $msg); } /** @@ -755,7 +1077,6 @@ HTMLBLOC; $this->Controller->EmailTest->attachments = array(__FILE__); $body = '

This is the body of the message

'; -/* $this->Controller->EmailTest->sendAs = 'html'; $this->assertTrue($this->Controller->EmailTest->send($body)); $msg = $this->Controller->Session->read('Message.email.message'); @@ -775,7 +1096,6 @@ HTMLBLOC; $this->assertNoPattern('/text\/plain/', $msg); $this->assertNoPattern('/text\/html/', $msg); $this->assertPattern('/multipart\/alternative/', $msg); -*/ } /** @@ -794,10 +1114,10 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'both'; $this->assertTrue($this->Controller->EmailTest->send($body)); - //$msg = $this->Controller->Session->read('Message.email.message'); + $msg = $this->Controller->Session->read('Message.email.message'); - //$this->assertNoPattern('/\n\nContent-Transfer-Encoding/', $msg); - //$this->assertPattern('/\nContent-Transfer-Encoding/', $msg); + $this->assertNoPattern('/\n\nContent-Transfer-Encoding/', $msg); + $this->assertPattern('/\nContent-Transfer-Encoding/', $msg); } /** @@ -817,18 +1137,21 @@ HTMLBLOC; $this->Controller->EmailTest->date = 'Today!'; $this->Controller->EmailTest->subject = 'Test subject'; $this->Controller->EmailTest->additionalParams = 'X-additional-header'; + $this->Controller->EmailTest->delivery = 'smtp'; + $this->Controller->EmailTest->smtpOptions['host'] = 'blah'; + $this->Controller->EmailTest->smtpOptions['timeout'] = 0.2; $this->Controller->EmailTest->attachments = array('attachment1', 'attachment2'); $this->Controller->EmailTest->textMessage = 'This is the body of the message'; $this->Controller->EmailTest->htmlMessage = 'This is the body of the message'; $this->Controller->EmailTest->messageId = false; -/* + try { $this->Controller->EmailTest->send('Should not work'); $this->fail('No exception'); } catch (SocketException $e) { $this->assertTrue(true, 'SocketException raised'); } -*/ + $this->Controller->EmailTest->reset(); $this->assertNull($this->Controller->EmailTest->template); @@ -844,6 +1167,7 @@ HTMLBLOC; $this->assertIdentical($this->Controller->EmailTest->getHeaders(), array()); $this->assertNull($this->Controller->EmailTest->getBoundary()); $this->assertIdentical($this->Controller->EmailTest->getMessage(), array()); + $this->assertNull($this->Controller->EmailTest->smtpError); $this->assertIdentical($this->Controller->EmailTest->attachments, array()); $this->assertNull($this->Controller->EmailTest->textMessage); $this->assertTrue($this->Controller->EmailTest->messageId); @@ -864,8 +1188,10 @@ HTMLBLOC; $body = 'Body of message'; $this->assertTrue($this->Controller->EmailTest->send($body)); - //$result = $this->Controller->Session->read('Message.email.message'); - //$this->assertPattern('/Body of message/', $result); + $result = $this->Controller->Session->read('Message.email.message'); + + $this->assertPattern('/Body of message/', $result); + } /** @@ -893,20 +1219,23 @@ HTMLBLOC; $this->Controller->EmailTest->delivery = 'debug'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$result = $this->Controller->Session->read('Message.email.message'); - //$this->assertPattern('/Message-ID: \<[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}@' . env('HTTP_HOST') . '\>\n/', $result); + $result = $this->Controller->Session->read('Message.email.message'); + + $this->assertPattern('/Message-ID: \<[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}@' . env('HTTP_HOST') . '\>\n/', $result); $this->Controller->EmailTest->messageId = '<22091985.998877@localhost>'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$result = $this->Controller->Session->read('Message.email.message'); - //$this->assertPattern('/Message-ID: <22091985.998877@localhost>\n/', $result); + $result = $this->Controller->Session->read('Message.email.message'); + + $this->assertPattern('/Message-ID: <22091985.998877@localhost>\n/', $result); $this->Controller->EmailTest->messageId = false; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - //$result = $this->Controller->Session->read('Message.email.message'); - //$this->assertNoPattern('/Message-ID:/', $result); + $result = $this->Controller->Session->read('Message.email.message'); + + $this->assertNoPattern('/Message-ID:/', $result); } /** @@ -916,7 +1245,6 @@ HTMLBLOC; * @return void */ function testSendMessage() { -/* $this->Controller->EmailTest->delivery = 'getMessage'; $this->Controller->EmailTest->lineLength = 70; @@ -940,7 +1268,6 @@ HTMLBLOC; '' ); $this->assertEqual($expected, $result); -*/ } /** From 5e56f7651000b636e9f60c5246abe087702ce80f Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:02:08 -0400 Subject: [PATCH 069/103] Rewrited the send method to use CakeEmail. --- .../Controller/Component/EmailComponent.php | 124 +++++++++--------- 1 file changed, 65 insertions(+), 59 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 103ccafed..cfdc79100 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -19,6 +19,7 @@ App::uses('Component', 'Controller'); App::uses('Multibyte', 'I18n'); +App::uses('CakeEmail', 'Network'); /** * EmailComponent @@ -361,59 +362,60 @@ class EmailComponent extends Component { * @return boolean Success */ public function send($content = null, $template = null, $layout = null) { - $this->_createHeader(); + $lib = new CakeEmail(); + $lib->charset = $this->charset; + + $lib->from($this->_formatAddresses((array)$this->from)); + if (!empty($this->to)) { + $lib->to($this->_formatAddresses((array)$this->to)); + } + if (!empty($this->cc)) { + $lib->cc($this->_formatAddresses((array)$this->cc)); + } + if (!empty($this->bcc)) { + $lib->bcc($this->_formatAddresses((array)$this->bcc)); + } + if (!empty($this->replyTo)) { + $lib->replyTo($this->_formatAddresses((array)$this->replyTo)); + } + if (!empty($this->return)) { + $lib->returnPath($this->_formatAddresses((array)$this->return)); + } + if (!empty($readReceipt)) { + $lib->readReceipt($this->_formatAddresses((array)$this->readReceipt)); + } + + $lib->subject($this->subject)->messageID($this->messageId); + + $headers = array(); + foreach ($this->headers as $key => $value) { + $headers['X-' . $key] = $value; + } + if ($this->date != false) { + $headers['Date'] = $this->date; + } + $lib->setHeaders($headers); if ($template) { $this->template = $template; } - if ($layout) { $this->layout = $layout; } - - if (is_array($content)) { - $content = implode("\n", $content) . "\n"; - } - - $this->htmlMessage = $this->textMessage = null; - if ($content) { - if ($this->sendAs === 'html') { - $this->htmlMessage = $content; - } elseif ($this->sendAs === 'text') { - $this->textMessage = $content; - } else { - $this->htmlMessage = $this->textMessage = $content; - } - } - - if ($this->sendAs === 'text') { - $message = $this->_wrap($content); - } else { - $message = $this->_wrap($content, 998); - } - - if ($this->template === null) { - $message = $this->_formatMessage($message); - } else { - $message = $this->_render($message); - } - - $message[] = ''; - $this->_message = $message; + $lib->layout($this->layout, $this->template)->emailFormat($this->sendAs); if (!empty($this->attachments)) { - $this->_attachFiles(); + $lib->attachment($this->_formatAttachFiles()); } - if (!is_null($this->_boundary)) { - $this->_message[] = ''; - $this->_message[] = '--' . $this->_boundary . '--'; - $this->_message[] = ''; + $transport = $lib->transport($this->delivery)->transportClass(); + if ($this->delivery === 'mail') { + $transport->config(array('eol' => $this->lineFeed)); + } elseif ($this->delivery === 'smtp') { + $transport->config($this->smtpOptions); } - - $_method = '_' . $this->delivery; - $sent = $this->$_method(); + $sent = $lib->send($content); $this->_header = array(); $this->_message = array(); @@ -657,12 +659,11 @@ class EmailComponent extends Component { } /** - * Attach files by adding file contents inside boundaries. + * Format the attach array * - * @access private - * @TODO: modify to use the core File class? + * @return array */ - function _attachFiles() { + protected function _formatAttachFiles() { $files = array(); foreach ($this->attachments as $filename => $attachment) { $file = $this->_findFiles($attachment); @@ -673,21 +674,7 @@ class EmailComponent extends Component { $files[$filename] = $file; } } - - foreach ($files as $filename => $file) { - $handle = fopen($file, 'rb'); - $data = fread($handle, filesize($file)); - $data = chunk_split(base64_encode($data)) ; - fclose($handle); - - $this->_message[] = '--' . $this->_boundary; - $this->_message[] = 'Content-Type: application/octet-stream'; - $this->_message[] = 'Content-Transfer-Encoding: base64'; - $this->_message[] = 'Content-Disposition: attachment; filename="' . basename($filename) . '"'; - $this->_message[] = ''; - $this->_message[] = $data; - $this->_message[] = ''; - } + return $files; } /** @@ -790,6 +777,25 @@ class EmailComponent extends Component { return $this->_strip($string); } +/** + * Format addresses to be an array with email as key and alias as value + * + * @param array $addresses + * @return array + */ + protected function _formatAddresses($addresses) { + $formatted = array(); + foreach ($addresses as $address) { + if (preg_match('/((.*))?\s?<(.+)>/', $address, $matches) && !empty($matches[2])) { + $formatted[$this->_strip($matches[3])] = $this->_encode($matches[2]); + } else { + $address = $this->_strip($address); + $formatted[$address] = $address; + } + } + return $formatted; + } + /** * Remove certain elements (such as bcc:, to:, %0a) from given value. * Helps prevent header injection / mainipulation on user content. From 46c79ec4a19457afd033e1727e4f9c5bcc0f736a Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:06:27 -0400 Subject: [PATCH 070/103] Removing headers methods. --- .../Controller/Component/EmailComponent.php | 88 ------------------- .../Component/EmailComponentTest.php | 24 ----- 2 files changed, 112 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index cfdc79100..35fb9200a 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -547,94 +547,6 @@ class EmailComponent extends Component { $this->_boundary = md5(uniqid(time())); } -/** - * Sets headers for the message - * - * @access public - * @param array Associative array containing headers to be set. - */ - function header($headers) { - foreach ($headers as $header => $value) { - $this->_header[] = sprintf('%s: %s', trim($header), trim($value)); - } - } -/** - * Create emails headers including (but not limited to) from email address, reply to, - * bcc and cc. - * - * @access private - */ - function _createHeader() { - $headers = array(); - - if ($this->delivery == 'smtp') { - $headers['To'] = implode(', ', array_map(array($this, '_formatAddress'), (array)$this->to)); - } - $headers['From'] = $this->_formatAddress($this->from); - - if (!empty($this->replyTo)) { - $headers['Reply-To'] = $this->_formatAddress($this->replyTo); - } - if (!empty($this->return)) { - $headers['Return-Path'] = $this->_formatAddress($this->return); - } - if (!empty($this->readReceipt)) { - $headers['Disposition-Notification-To'] = $this->_formatAddress($this->readReceipt); - } - - if (!empty($this->cc)) { - $headers['Cc'] = implode(', ', array_map(array($this, '_formatAddress'), (array)$this->cc)); - } - - if (!empty($this->bcc) && $this->delivery != 'smtp') { - $headers['Bcc'] = implode(', ', array_map(array($this, '_formatAddress'), (array)$this->bcc)); - } - if ($this->delivery == 'smtp') { - $headers['Subject'] = $this->_encode($this->subject); - } - - if ($this->messageId !== false) { - if ($this->messageId === true) { - $headers['Message-ID'] = '<' . String::UUID() . '@' . env('HTTP_HOST') . '>'; - } else { - $headers['Message-ID'] = $this->messageId; - } - } - - $date = $this->date; - if ($date == false) { - $date = date(DATE_RFC2822); - } - $headers['Date'] = $date; - - $headers['X-Mailer'] = $this->xMailer; - - if (!empty($this->headers)) { - foreach ($this->headers as $key => $val) { - $headers['X-' . $key] = $val; - } - } - - if (!empty($this->attachments)) { - $this->_createBoundary(); - $headers['MIME-Version'] = '1.0'; - $headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"'; - $headers[] = 'This part of the E-mail should never be seen. If'; - $headers[] = 'you are reading this, consider upgrading your e-mail'; - $headers[] = 'client to a MIME-compatible client.'; - } elseif ($this->sendAs === 'text') { - $headers['Content-Type'] = 'text/plain; charset=' . $this->charset; - } elseif ($this->sendAs === 'html') { - $headers['Content-Type'] = 'text/html; charset=' . $this->charset; - } elseif ($this->sendAs === 'both') { - $headers['Content-Type'] = 'multipart/alternative; boundary="alt-' . $this->_boundary . '"'; - } - - $headers['Content-Transfer-Encoding'] = '7bit'; - - $this->header($headers); - } - /** * Format the message by seeing if it has attachments. * diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index 949daf8c2..a4374ea34 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -85,29 +85,6 @@ class EmailTestComponent extends EmailComponent { return $this->_smtpConnection; } -/** - * Convenience setter for testing. - * - * @access public - * @return void - */ - function setHeaders($headers) { - $this->_header += $headers; - } - -/** - * Convenience getter for testing. - * - * @access public - * @return array - */ - function getHeaders() { - if (empty($this->_header)) { - return array(); - } - return $this->_header; - } - /** * Convenience setter for testing. * @@ -1164,7 +1141,6 @@ HTMLBLOC; $this->assertNull($this->Controller->EmailTest->date); $this->assertNull($this->Controller->EmailTest->subject); $this->assertNull($this->Controller->EmailTest->additionalParams); - $this->assertIdentical($this->Controller->EmailTest->getHeaders(), array()); $this->assertNull($this->Controller->EmailTest->getBoundary()); $this->assertIdentical($this->Controller->EmailTest->getMessage(), array()); $this->assertNull($this->Controller->EmailTest->smtpError); From 163c7f06bbb2d1becc97cba5bd1f0f3146104420 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:07:18 -0400 Subject: [PATCH 071/103] Removed boundary methods. --- .../Controller/Component/EmailComponent.php | 9 ------- .../Component/EmailComponentTest.php | 24 ------------------- 2 files changed, 33 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 35fb9200a..d9cdd950e 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -538,15 +538,6 @@ class EmailComponent extends Component { return $msg; } -/** - * Create unique boundary identifier - * - * @access private - */ - function _createboundary() { - $this->_boundary = md5(uniqid(time())); - } - /** * Format the message by seeing if it has attachments. * diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index a4374ea34..01733c6b6 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -85,29 +85,6 @@ class EmailTestComponent extends EmailComponent { return $this->_smtpConnection; } -/** - * Convenience setter for testing. - * - * @access public - * @return void - */ - function setBoundary() { - $this->_createBoundary(); - } - -/** - * Convenience getter for testing. - * - * @access public - * @return string - */ - function getBoundary() { - if (empty($this->_boundary)) { - return null; - } - return $this->_boundary; - } - /** * Convenience getter for testing. * @@ -1141,7 +1118,6 @@ HTMLBLOC; $this->assertNull($this->Controller->EmailTest->date); $this->assertNull($this->Controller->EmailTest->subject); $this->assertNull($this->Controller->EmailTest->additionalParams); - $this->assertNull($this->Controller->EmailTest->getBoundary()); $this->assertIdentical($this->Controller->EmailTest->getMessage(), array()); $this->assertNull($this->Controller->EmailTest->smtpError); $this->assertIdentical($this->Controller->EmailTest->attachments, array()); From 5815743e0a21e6c7864918bc443e5351dac4fce4 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:08:16 -0400 Subject: [PATCH 072/103] Removed formatMessage and render methods. --- .../Controller/Component/EmailComponent.php | 112 ------------------ 1 file changed, 112 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index d9cdd950e..4275506be 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -449,118 +449,6 @@ class EmailComponent extends Component { $this->_message = array(); } -/** - * Render the contents using the current layout and template. - * - * @param string $content Content to render - * @return array Email ready to be sent - * @access private - */ - function _render($content) { - $viewClass = $this->Controller->view; - - if ($viewClass != 'View') { - list($plugin, $viewClass) = pluginSplit($viewClass, true); - $viewClass = $viewClass . 'View'; - App::uses($viewClass, $plugin . 'View'); - } - - $View = new $viewClass($this->Controller); - $View->layout = $this->layout; - $msg = array(); - - $content = implode("\n", $content); - - if ($this->sendAs === 'both') { - $htmlContent = $content; - if (!empty($this->attachments)) { - $msg[] = '--' . $this->_boundary; - $msg[] = 'Content-Type: multipart/alternative; boundary="alt-' . $this->_boundary . '"'; - $msg[] = ''; - } - $msg[] = '--alt-' . $this->_boundary; - $msg[] = 'Content-Type: text/plain; charset=' . $this->charset; - $msg[] = 'Content-Transfer-Encoding: 7bit'; - $msg[] = ''; - - $content = $View->element('email' . DS . 'text' . DS . $this->template, array('content' => $content), true); - $View->layoutPath = 'email' . DS . 'text'; - $content = explode("\n", $this->textMessage = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($content))); - - $msg = array_merge($msg, $content); - - $msg[] = ''; - $msg[] = '--alt-' . $this->_boundary; - $msg[] = 'Content-Type: text/html; charset=' . $this->charset; - $msg[] = 'Content-Transfer-Encoding: 7bit'; - $msg[] = ''; - - $htmlContent = $View->element('email' . DS . 'html' . DS . $this->template, array('content' => $htmlContent), true); - $View->layoutPath = 'email' . DS . 'html'; - $htmlContent = explode("\n", $this->htmlMessage = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($htmlContent))); - $msg = array_merge($msg, $htmlContent); - $msg[] = ''; - $msg[] = '--alt-' . $this->_boundary . '--'; - $msg[] = ''; - - ClassRegistry::removeObject('view'); - return $msg; - } - - if (!empty($this->attachments)) { - if ($this->sendAs === 'html') { - $msg[] = ''; - $msg[] = '--' . $this->_boundary; - $msg[] = 'Content-Type: text/html; charset=' . $this->charset; - $msg[] = 'Content-Transfer-Encoding: 7bit'; - $msg[] = ''; - } else { - $msg[] = '--' . $this->_boundary; - $msg[] = 'Content-Type: text/plain; charset=' . $this->charset; - $msg[] = 'Content-Transfer-Encoding: 7bit'; - $msg[] = ''; - } - } - - $content = $View->element('email' . DS . $this->sendAs . DS . $this->template, array('content' => $content), true); - $View->layoutPath = 'email' . DS . $this->sendAs; - $content = explode("\n", $rendered = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($content))); - - if ($this->sendAs === 'html') { - $this->htmlMessage = $rendered; - } else { - $this->textMessage = $rendered; - } - - $msg = array_merge($msg, $content); - ClassRegistry::removeObject('view'); - - return $msg; - } - -/** - * Format the message by seeing if it has attachments. - * - * @param string $message Message to format - * @access private - */ - function _formatMessage($message) { - if (!empty($this->attachments)) { - $prefix = array('--' . $this->_boundary); - if ($this->sendAs === 'text') { - $prefix[] = 'Content-Type: text/plain; charset=' . $this->charset; - } elseif ($this->sendAs === 'html') { - $prefix[] = 'Content-Type: text/html; charset=' . $this->charset; - } elseif ($this->sendAs === 'both') { - $prefix[] = 'Content-Type: multipart/alternative; boundary="alt-' . $this->_boundary . '"'; - } - $prefix[] = 'Content-Transfer-Encoding: 7bit'; - $prefix[] = ''; - $message = array_merge($prefix, $message); - } - return $message; - } - /** * Format the attach array * From 8457c8f8402477cea8821d833b6f11aa111d356b Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:09:08 -0400 Subject: [PATCH 073/103] Removed wrap method. --- .../Controller/Component/EmailComponent.php | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 4275506be..5e292556a 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -488,39 +488,6 @@ class EmailComponent extends Component { return null; } -/** - * Wrap the message using EmailComponent::$lineLength - * - * @param string $message Message to wrap - * @param integer $lineLength Max length of line - * @return array Wrapped message - * @access protected - */ - function _wrap($message, $lineLength = null) { - $message = $this->_strip($message, true); - $message = str_replace(array("\r\n","\r"), "\n", $message); - $lines = explode("\n", $message); - $formatted = array(); - - if ($this->_lineLength !== null) { - trigger_error(__d('cake_dev', '_lineLength cannot be accessed please use lineLength'), E_USER_WARNING); - $this->lineLength = $this->_lineLength; - } - - if (!$lineLength) { - $lineLength = $this->lineLength; - } - - foreach ($lines as $line) { - if (substr($line, 0, 1) == '.') { - $line = '.' . $line; - } - $formatted = array_merge($formatted, explode("\n", wordwrap($line, $lineLength, "\n", true))); - } - $formatted[] = ''; - return $formatted; - } - /** * Encode the specified string using the current charset * From 8f2aeec2f3473db5057020124c394ed85625dd75 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:13:12 -0400 Subject: [PATCH 074/103] Removed the transport methods (mail, smtp, debug). --- .../Controller/Component/EmailComponent.php | 193 ----------- .../Component/EmailComponentTest.php | 327 ------------------ 2 files changed, 520 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 5e292556a..4fe0c9ddf 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -577,197 +577,4 @@ class EmailComponent extends Component { return $value; } -/** - * Wrapper for PHP mail function used for sending out emails - * - * @return bool Success - * @access private - */ - function _mail() { - $header = implode($this->lineFeed, $this->_header); - $message = implode($this->lineFeed, $this->_message); - if (is_array($this->to)) { - $to = implode(', ', array_map(array($this, '_formatAddress'), $this->to)); - } else { - $to = $this->to; - } - if (ini_get('safe_mode')) { - return @mail($to, $this->_encode($this->subject), $message, $header); - } - return @mail($to, $this->_encode($this->subject), $message, $header, $this->additionalParams); - } - - -/** - * Helper method to get socket, overridden in tests - * - * @param array $config Config data for the socket. - * @return void - * @access protected - */ - function _getSocket($config) { - $this->_smtpConnection = new CakeSocket($config); - } - -/** - * Sends out email via SMTP - * - * @return bool Success - * @access private - */ - function _smtp() { - App::uses('CakeSocket', 'Network'); - - $defaults = array( - 'host' => 'localhost', - 'port' => 25, - 'protocol' => 'smtp', - 'timeout' => 30 - ); - $this->smtpOptions = array_merge($defaults, $this->smtpOptions); - $this->_getSocket($this->smtpOptions); - - if (!$this->_smtpConnection->connect()) { - $this->smtpError = $this->_smtpConnection->lastError(); - return false; - } elseif (!$this->_smtpSend(null, '220')) { - return false; - } - - $httpHost = env('HTTP_HOST'); - - if (isset($this->smtpOptions['client'])) { - $host = $this->smtpOptions['client']; - } elseif (!empty($httpHost)) { - list($host) = explode(':', $httpHost); - } else { - $host = 'localhost'; - } - - if (!$this->_smtpSend("EHLO {$host}", '250') && !$this->_smtpSend("HELO {$host}", '250')) { - return false; - } - - if (isset($this->smtpOptions['username']) && isset($this->smtpOptions['password'])) { - $authRequired = $this->_smtpSend('AUTH LOGIN', '334|503'); - if ($authRequired == '334') { - if (!$this->_smtpSend(base64_encode($this->smtpOptions['username']), '334')) { - return false; - } - if (!$this->_smtpSend(base64_encode($this->smtpOptions['password']), '235')) { - return false; - } - } elseif ($authRequired != '503') { - return false; - } - } - - if (!$this->_smtpSend('MAIL FROM: ' . $this->_formatAddress($this->from, true))) { - return false; - } - - if (!is_array($this->to)) { - $tos = array_map('trim', explode(',', $this->to)); - } else { - $tos = $this->to; - } - foreach ($tos as $to) { - if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($to, true))) { - return false; - } - } - - foreach ($this->cc as $cc) { - if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($cc, true))) { - return false; - } - } - foreach ($this->bcc as $bcc) { - if (!$this->_smtpSend('RCPT TO: ' . $this->_formatAddress($bcc, true))) { - return false; - } - } - - if (!$this->_smtpSend('DATA', '354')) { - return false; - } - - $header = implode("\r\n", $this->_header); - $message = implode("\r\n", $this->_message); - if (!$this->_smtpSend($header . "\r\n\r\n" . $message . "\r\n\r\n\r\n.")) { - return false; - } - $this->_smtpSend('QUIT', false); - - $this->_smtpConnection->disconnect(); - return true; - } - -/** - * 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 bool Success - * @access protected - */ - function _smtpSend($data, $checkCode = '250') { - if (!is_null($data)) { - $this->_smtpConnection->write($data . "\r\n"); - } - while ($checkCode !== false) { - $response = ''; - $startTime = time(); - while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->smtpOptions['timeout'])) { - $response .= $this->_smtpConnection->read(); - } - if (substr($response, -2) !== "\r\n") { - $this->smtpError = 'timeout'; - return false; - } - $response = end(explode("\r\n", rtrim($response, "\r\n"))); - - if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) { - if ($code[2] === '-') { - continue; - } - return $code[1]; - } - $this->smtpError = $response; - return false; - } - return true; - } - -/** - * Set as controller flash message a debug message showing current settings in component - * - * @return boolean Success - * @access private - */ - function _debug() { - $nl = "\n"; - $header = implode($nl, $this->_header); - $message = implode($nl, $this->_message); - $fm = '
';
-
-		if (is_array($this->to)) {
-			$to = implode(', ', array_map(array($this, '_formatAddress'), $this->to));
-		} else {
-			$to = $this->to;
-		}
-		$fm .= sprintf('%s %s%s', 'To:', $to, $nl);
-		$fm .= sprintf('%s %s%s', 'From:', $this->from, $nl);
-		$fm .= sprintf('%s %s%s', 'Subject:', $this->_encode($this->subject), $nl);
-		$fm .= sprintf('%s%3$s%3$s%s', 'Header:', $header, $nl);
-		$fm .= sprintf('%s%3$s%3$s%s', 'Parameters:', $this->additionalParams, $nl);
-		$fm .= sprintf('%s%3$s%3$s%s', 'Message:', $message, $nl);
-		$fm .= '
'; - - if (isset($this->Controller->Session)) { - $this->Controller->Session->setFlash($fm, 'default', null, 'email'); - return true; - } - return $fm; - } } diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index 01733c6b6..48d558ac2 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -29,62 +29,6 @@ App::uses('CakeSocket', 'Network'); */ class EmailTestComponent extends EmailComponent { - var $smtpSend = ''; -/** - * smtpSend method override for testing - * - * @access public - * @return mixed - */ - function smtpSend($data, $code = '250') { - return parent::_smtpSend($data, $code); - } - -/** - * undocumented function - * - * @return void - */ - function _smtpSend($data, $code = '250') { - if ($this->_debug) { - $this->smtpSend .= $data . "\n"; - return true; - } - return parent::_smtpSend($data, $code); - } - -/** - * Convenience setter method for testing. - * - * @access public - * @return void - */ - function setConnectionSocket($socket) { - $this->_smtpConnection = $socket; - } - -/** - * Allows mocks to be used with tests. - * - * @param array $config - * @return void - */ - function _getSocket($config) { - if (empty($this->_smtpConnection)) { - parent::_getSocket($config); - } - } - -/** - * Convenience getter method for testing. - * - * @access public - * @return mixed - */ - function getConnectionSocket() { - return $this->_smtpConnection; - } - /** * Convenience getter for testing. * @@ -237,252 +181,6 @@ class EmailComponentTest extends CakeTestCase { return str_replace(array("\r\n", "\r"), "\n", $string); } -/** - * testSmtpConfig method - * - * @access public - * @return void - */ - function testSmtpConfig() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - $this->Controller->EmailTest->delivery = 'smtp'; - $this->Controller->EmailTest->smtpOptions = array(); - $this->Controller->EmailTest->send('anything'); - $config = array( - 'host' => 'localhost', - 'port' => 25, - 'protocol' => 'smtp', - 'timeout' => 30 - ); - $this->assertEqual($config, $this->Controller->EmailTest->smtpOptions); - - $this->Controller->EmailTest->smtpOptions = array('port' => 80); - $this->Controller->EmailTest->send('anything'); - $config['port'] = 80; - $this->assertEqual($config, $this->Controller->EmailTest->smtpOptions); - } - -/** - * testBadSmtpSend method - * - * @access public - * @return void - */ - function testBadSmtpSend() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - $this->Controller->EmailTest->smtpOptions['host'] = 'blah'; - $this->Controller->EmailTest->delivery = 'smtp'; - $this->assertFalse($this->Controller->EmailTest->send('Should not work')); - } - -/** - * testSmtpSend method - * - * @access public - * @return void - */ - function testSmtpSend() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - - $this->Controller->EmailTest->to = 'postmaster@localhost'; - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - - $this->Controller->EmailTest->delivery = 'smtp'; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - - $this->Controller->EmailTest->_debug = true; - $this->Controller->EmailTest->sendAs = 'text'; - $expect = <<Host: localhost -Port: 25 -Timeout: 30 -To: postmaster@localhost -From: noreply@example.com -Subject: Cake SMTP test -Header: - -To: postmaster@localhost -From: noreply@example.com -Reply-To: noreply@example.com -Subject: Cake SMTP test -X-Mailer: CakePHP Email Component -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 7bitParameters: - -Message: - -This is the body of the message - - -TEMPDOC; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); - } - -/** - * testSmtpEhlo method - * - * @access public - * @return void - */ - function testSmtpEhlo() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - - $connection = new CakeSocket(array('protocol'=>'smtp', 'host' => 'localhost', 'port' => 25)); - $this->Controller->EmailTest->setConnectionSocket($connection); - $this->Controller->EmailTest->smtpOptions['timeout'] = 10; - $this->assertTrue($connection->connect()); - $this->assertTrue($this->Controller->EmailTest->smtpSend(null, '220') !== false); - $this->skipIf($this->Controller->EmailTest->smtpSend('EHLO locahost', '250') === false, '%s do not support EHLO.'); - $connection->disconnect(); - - $this->Controller->EmailTest->to = 'postmaster@localhost'; - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - - $this->Controller->EmailTest->delivery = 'smtp'; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - - $this->Controller->EmailTest->_debug = true; - $this->Controller->EmailTest->sendAs = 'text'; - $expect = <<Host: localhost -Port: 25 -Timeout: 30 -To: postmaster@localhost -From: noreply@example.com -Subject: Cake SMTP test -Header: - -To: postmaster@localhost -From: noreply@example.com -Reply-To: noreply@example.com -Subject: Cake SMTP test -X-Mailer: CakePHP Email Component -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 7bitParameters: - -Message: - -This is the body of the message - - -TEMPDOC; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); - } - -/** - * testSmtpSendMultipleTo method - * - * @access public - * @return void - */ - function testSmtpSendMultipleTo() { - if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) { - return; - } - $this->Controller->EmailTest->reset(); - $this->Controller->EmailTest->to = array('postmaster@localhost', 'root@localhost'); - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP multiple To test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->_debug = true; - $this->Controller->EmailTest->sendAs = 'text'; - $this->Controller->EmailTest->delivery = 'smtp'; - - $socket = $this->getMock('CakeSocket'); - $socket->expects($this->any()) - ->method('connect') - ->will($this->returnValue(true)); - $this->Controller->EmailTest->setConnectionSocket($socket); - - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - - $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend); - $this->assertPattern('/MAIL FROM: \n/', $this->Controller->EmailTest->smtpSend); - $this->assertPattern('/RCPT TO: \n/', $this->Controller->EmailTest->smtpSend); - $this->assertPattern('/RCPT TO: \n/', $this->Controller->EmailTest->smtpSend); - $this->assertPattern( - '/To: postmaster@localhost, root@localhost[\n\r]/', - $this->Controller->EmailTest->smtpSend - ); - } - -/** - * test sending smtp from a host using a port. - * - * @return void - */ - function testSmtpSendHostWithPort() { - $bkp = env('HTTP_HOST'); - $_SERVER['HTTP_HOST'] = 'localhost:8080'; - - $this->Controller->EmailTest->reset(); - $this->Controller->EmailTest->to = array('root@localhost'); - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP host test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'smtp'; - $this->Controller->EmailTest->sendAs = 'text'; - $this->Controller->EmailTest->_debug = true; - - $socket = $this->getMock('CakeSocket'); - $socket->expects($this->any()) - ->method('connect') - ->will($this->returnValue(true)); - - $this->Controller->EmailTest->setConnectionSocket($socket); - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - - $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend); - - $_SERVER['HTTP_HOST'] = $bkp; - } - -/** - * testAuthenticatedSmtpSend method - * - * @access public - * @return void - */ - function testAuthenticatedSmtpSend() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - - $this->Controller->EmailTest->to = 'postmaster@localhost'; - $this->Controller->EmailTest->from = 'noreply@example.com'; - $this->Controller->EmailTest->subject = 'Cake SMTP test'; - $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->smtpOptions['username'] = 'test'; - $this->Controller->EmailTest->smtpOptions['password'] = 'testing'; - - $this->Controller->EmailTest->delivery = 'smtp'; - $result = $this->Controller->EmailTest->send('This is the body of the message'); - $code = substr($this->Controller->EmailTest->smtpError, 0, 3); - $this->skipIf(!$code, '%s Authentication not enabled on server'); - - $this->assertFalse($result); - $this->assertEqual($code, '535'); - } - /** * testSendFormats method * @@ -665,31 +363,6 @@ HTMLBLOC; $this->assertPattern('/http\:\/\/example\.com/', $result); } -/** - * testSmtpSendSocket method - * - * @access public - * @return void - */ - function testSmtpSendSocket() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } - - $socket = new CakeSocket(array_merge(array('protocol'=>'smtp'), $this->Controller->EmailTest->smtpOptions)); - $this->Controller->EmailTest->setConnectionSocket($socket); - - $this->assertSame($this->Controller->EmailTest->getConnectionSocket(), $socket); - - $response = $this->Controller->EmailTest->smtpSend('HELO', '250'); - $this->assertPattern('/501 Syntax: HELO hostname/', $this->Controller->EmailTest->smtpError); - - $this->Controller->EmailTest->reset(); - $response = $this->Controller->EmailTest->smtpSend('HELO somehostname', '250'); - - $this->assertNoPattern('/501 Syntax: HELO hostname/', (string)$this->Controller->EmailTest->smtpError); - } - /** * testSendDebug method * From 84e405db81e25a773fa371cc12f42d0ce28ae673 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:15:17 -0400 Subject: [PATCH 075/103] Removed the format address method. --- .../Controller/Component/EmailComponent.php | 21 ------- .../Component/EmailComponentTest.php | 55 ------------------- 2 files changed, 76 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 4fe0c9ddf..cc61b8cce 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -514,27 +514,6 @@ class EmailComponent extends Component { return $return; } -/** - * Format a string as an email address - * - * @param string $string String representing an email address - * @return string Email address suitable for email headers or smtp pipe - * @access private - */ - function _formatAddress($string, $smtp = false) { - $hasAlias = preg_match('/((.*))?\s?<(.+)>/', $string, $matches); - if ($smtp && $hasAlias) { - return $this->_strip('<' . $matches[3] . '>'); - } elseif ($smtp) { - return $this->_strip('<' . $string . '>'); - } - - if ($hasAlias && !empty($matches[2])) { - return $this->_encode($matches[2]) . $this->_strip(' <' . $matches[3] . '>'); - } - return $this->_strip($string); - } - /** * Format addresses to be an array with email as key and alias as value * diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index 48d558ac2..4acd85638 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -62,14 +62,6 @@ class EmailTestComponent extends EmailComponent { return parent::_strip($content, $message); } -/** - * Wrapper for testing. - * - * @return void - */ - function formatAddress($string, $smtp = false) { - return parent::_formatAddress($string, $smtp); - } } /** @@ -895,51 +887,4 @@ HTMLBLOC; $this->assertEqual($expected, $result); } -/** - * Test that _formatName doesn't jack up email addresses with alias parts. - * - * @return void - */ - function testFormatAddressAliases() { - $result = $this->Controller->EmailTest->formatAddress('email@example.com'); - $this->assertEqual($result, 'email@example.com'); - - $result = $this->Controller->EmailTest->formatAddress('alias '); - $this->assertEqual($result, 'alias '); - - $result = $this->Controller->EmailTest->formatAddress('alias'); - $this->assertEqual($result, 'alias '); - - $result = $this->Controller->EmailTest->formatAddress('email@example.com'); - $this->assertEqual($result, 'email@example.com'); - - $result = $this->Controller->EmailTest->formatAddress(''); - $this->assertEqual($result, ''); - - $result = $this->Controller->EmailTest->formatAddress('email@example.com', true); - $this->assertEqual($result, ''); - - $result = $this->Controller->EmailTest->formatAddress('', true); - $this->assertEqual($result, ''); - - $result = $this->Controller->EmailTest->formatAddress('alias name ', true); - $this->assertEqual($result, ''); - } - -/** - * test formatting addresses with multibyte chars - * - * @return void - */ - function testFormatAddressMultibyte() { - $this->Controller->EmailTest->charset = 'UTF-8'; - $result = $this->Controller->EmailTest->formatAddress('ÄÖÜTest '); - $this->assertEqual($result, '=?UTF-8?B?w4TDlsOcVGVzdCA=?= '); - - $result = $this->Controller->EmailTest->formatAddress('ÄÖÜTest'); - $this->assertEqual($result, '=?UTF-8?B?w4TDlsOcVGVzdA==?= '); - - $result = $this->Controller->EmailTest->formatAddress('ÄÖÜTest ', true); - $this->assertEqual($result, ''); - } } From a28e8ba4e78f645d7b44e7a91ddb96abf7448968 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:21:04 -0400 Subject: [PATCH 076/103] Removed unused code. --- .../Controller/Component/EmailComponent.php | 65 +------------------ .../Component/EmailComponentTest.php | 25 ------- 2 files changed, 1 insertion(+), 89 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index cc61b8cce..25f7c7435 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -150,14 +150,6 @@ class EmailComponent extends Component { */ public $template = null; -/** - * as per RFC2822 Section 2.1.1 - * - * @var integer - * @access public - */ - public $lineLength = 70; - /** * Line feed character(s) to be used when sending using mail() function * By default PHP_EOL is used. @@ -168,12 +160,7 @@ class EmailComponent extends Component { * @var string * @access public */ - var $lineFeed = PHP_EOL; - -/** - * @deprecated see lineLength - */ - protected $_lineLength = null; + public $lineFeed = PHP_EOL; /** * What format should the email be sent in @@ -291,49 +278,6 @@ class EmailComponent extends Component { */ public $messageId = true; -/** - * Temporary store of message header lines - * - * @var array - * @access protected - */ - protected $_header = array(); - -/** - * If set, boundary to use for multipart mime messages - * - * @var string - * @access protected - */ - protected $_boundary = null; - -/** - * Temporary store of message lines - * - * @var array - * @access protected - */ - protected $_message = array(); - -/** - * Variable that holds SMTP connection - * - * @var resource - * @access protected - */ - protected $_smtpConnection = null; - -/** - * Constructor - * - * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components - * @param array $settings Array of configuration settings. - */ - public function __construct(ComponentCollection $collection, $settings = array()) { - $this->Controller = $collection->getController(); - parent::__construct($collection, $settings); - } - /** * Initialize component * @@ -345,13 +289,6 @@ class EmailComponent extends Component { } } -/** - * Startup component - * - * @param object $controller Instantiating controller - */ - public function startup($controller) {} - /** * Send an email using the specified content, template and layout * diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index 4acd85638..dfd594b9c 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -20,7 +20,6 @@ */ App::uses('Controller', 'Controller'); App::uses('EmailComponent', 'Controller/Component'); -App::uses('CakeSocket', 'Network'); /** * EmailTestComponent class @@ -29,29 +28,6 @@ App::uses('CakeSocket', 'Network'); */ class EmailTestComponent extends EmailComponent { -/** - * Convenience getter for testing. - * - * @access public - * @return string - */ - function getMessage() { - if (empty($this->_message)) { - return array(); - } - return $this->_message; - } - -/** - * Convenience getter for testing. - * - * @access protected - * @return string - */ - function _getMessage() { - return $this->_message; - } - /** * Convenience method for testing. * @@ -783,7 +759,6 @@ HTMLBLOC; $this->assertNull($this->Controller->EmailTest->date); $this->assertNull($this->Controller->EmailTest->subject); $this->assertNull($this->Controller->EmailTest->additionalParams); - $this->assertIdentical($this->Controller->EmailTest->getMessage(), array()); $this->assertNull($this->Controller->EmailTest->smtpError); $this->assertIdentical($this->Controller->EmailTest->attachments, array()); $this->assertNull($this->Controller->EmailTest->textMessage); From 35c77b5a7a2cdab927c3dfe71da0fa72532a29f6 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:24:49 -0400 Subject: [PATCH 077/103] Setting the additional parameters to mail transport. --- lib/Cake/Controller/Component/EmailComponent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 25f7c7435..de3e808c1 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -347,7 +347,7 @@ class EmailComponent extends Component { $transport = $lib->transport($this->delivery)->transportClass(); if ($this->delivery === 'mail') { - $transport->config(array('eol' => $this->lineFeed)); + $transport->config(array('eol' => $this->lineFeed, 'additionalParameters' => $this->additionalParams)); } elseif ($this->delivery === 'smtp') { $transport->config($this->smtpOptions); } From 1ee8ad6d8e310f9a47cf48b68788490cc16d01ea Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 11:26:50 -0400 Subject: [PATCH 078/103] Removed more unused code. --- lib/Cake/Controller/Component/EmailComponent.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index de3e808c1..b7a6aa836 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -239,15 +239,6 @@ class EmailComponent extends Component { */ public $smtpOptions = array(); -/** - * Placeholder for any errors that might happen with the - * smtp mail methods - * - * @var string - * @access public - */ - public $smtpError = null; - /** * Contains the rendered plain text message if one was sent. * @@ -376,14 +367,10 @@ class EmailComponent extends Component { $this->subject = null; $this->additionalParams = null; $this->date = null; - $this->smtpError = null; $this->attachments = array(); $this->htmlMessage = null; $this->textMessage = null; $this->messageId = true; - $this->_header = array(); - $this->_boundary = null; - $this->_message = array(); } /** From 0bf8e3483bf8176f25ff0edbea2f9279e0f45e07 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 12:02:26 -0400 Subject: [PATCH 079/103] Fixed methods to integrate with CakeEmail. --- lib/Cake/Controller/Component/EmailComponent.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index b7a6aa836..5e2bb9d03 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -333,14 +333,16 @@ class EmailComponent extends Component { $lib->layout($this->layout, $this->template)->emailFormat($this->sendAs); if (!empty($this->attachments)) { - $lib->attachment($this->_formatAttachFiles()); + $lib->attachments($this->_formatAttachFiles()); } - $transport = $lib->transport($this->delivery)->transportClass(); + $lib->transport($this->delivery); if ($this->delivery === 'mail') { - $transport->config(array('eol' => $this->lineFeed, 'additionalParameters' => $this->additionalParams)); + $lib->config(array('eol' => $this->lineFeed, 'additionalParameters' => $this->additionalParams)); } elseif ($this->delivery === 'smtp') { - $transport->config($this->smtpOptions); + $lib->config($this->smtpOptions); + } else { + $lib->config(array()); } $sent = $lib->send($content); From b2f948dfeb3f3e9e2c9091dc5b9482a994d26e04 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 13:54:38 -0400 Subject: [PATCH 080/103] Adjust partial of test case for EmailComponent. --- .../Component/EmailComponentTest.php | 233 +++++++++--------- 1 file changed, 117 insertions(+), 116 deletions(-) diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index dfd594b9c..59f9dd5d6 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -20,6 +20,7 @@ */ App::uses('Controller', 'Controller'); App::uses('EmailComponent', 'Controller/Component'); +App::uses('AbstractTransport', 'Network/Email'); /** * EmailTestComponent class @@ -40,6 +41,49 @@ class EmailTestComponent extends EmailComponent { } +/** + * DebugCompTransport class + * + * @package cake.tests.cases.libs.controller.components + */ +class DebugCompTransport extends AbstractTransport { + +/** + * Last email + * + * @var string + */ + public static $lastEmail = null; + +/** + * Send mail + * + * @params object $email CakeEmail + * @return boolean + */ + public function send(CakeEmail $email) { + $headers = $email->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), true)); + $to = $headers['To']; + $subject = $headers['Subject']; + unset($headers['To'], $headers['Subject']); + + $message = implode("\n", $email->message()); + + $last = '
';
+		$last .= sprintf("%s %s\n", 'To:', $to);
+		$last .= sprintf("%s %s\n", 'From:', $headers['From']);
+		$last .= sprintf("%s %s\n", 'Subject:', $subject);
+		$last .= sprintf("%s\n\n%s", 'Header:', $this->_headersToString($headers, "\n"));
+		$last .= sprintf("%s\n\n%s", 'Message:', $message);
+		$last .= '
'; + + self::$lastEmail = $last; + + return true; + } + +} + /** * EmailTestController class * @@ -71,13 +115,6 @@ class EmailTestController extends Controller { */ public $components = array('Session', 'EmailTest'); -/** - * pageTitle property - * - * @var string - * @access public - */ - public $pageTitle = 'EmailTest'; } /** @@ -134,7 +171,6 @@ class EmailComponentTest extends CakeTestCase { function tearDown() { Configure::write('App.encoding', $this->_appEncoding); App::build(); - $this->Controller->Session->delete('Message'); ClassRegistry::flush(); } @@ -156,50 +192,48 @@ class EmailComponentTest extends CakeTestCase { * @return void */ function testSendFormats() { - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake SMTP test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->Controller->EmailTest->messageId = false; $date = date(DATE_RFC2822); $message = <<To: postmaster@localhost +
To: postmaster@example.com
 From: noreply@example.com
 Subject: Cake SMTP test
 Header:
 
 From: noreply@example.com
 Reply-To: noreply@example.com
-Date: $date
 X-Mailer: CakePHP Email Component
+Date: $date
 Content-Type: {CONTENTTYPE}
-Content-Transfer-Encoding: 7bitParameters:
-
-Message:
+Content-Transfer-Encoding: 7bitMessage:
 
 This is the body of the message
 
 
MSGBLOC; + $this->Controller->EmailTest->sendAs = 'text'; $expect = str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'html'; $expect = str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); // TODO: better test for format of message sent? $this->Controller->EmailTest->sendAs = 'both'; $expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $message); - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); } /** @@ -211,29 +245,27 @@ MSGBLOC; function testTemplates() { ClassRegistry::flush(); - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake SMTP test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->Controller->EmailTest->messageId = false; $date = date(DATE_RFC2822); $header = <<Controller->EmailTest->sendAs = 'text'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $header) . $text . "\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'html'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . "\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); $this->Controller->EmailTest->sendAs = 'both'; $expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $header); @@ -280,7 +312,7 @@ HTMLBLOC; $expect = '
' . $expect . '--alt---' . "\n\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); $html = << @@ -301,7 +333,7 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'html'; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message', 'default', 'thin')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); $result = ClassRegistry::getObject('view'); $this->assertFalse($result); @@ -313,12 +345,12 @@ HTMLBLOC; * @return void */ function testTemplateNestedElements() { - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake SMTP test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->Controller->EmailTest->messageId = false; $this->Controller->EmailTest->layout = 'default'; $this->Controller->EmailTest->template = 'nested_element'; @@ -326,7 +358,7 @@ HTMLBLOC; $this->Controller->helpers = array('Html'); $this->Controller->EmailTest->send(); - $result = $this->Controller->Session->read('Message.email.message'); + $result = DebugCompTransport::$lastEmail; $this->assertPattern('/Test/', $result); $this->assertPattern('/http\:\/\/example\.com/', $result); } @@ -338,7 +370,7 @@ HTMLBLOC; * @return void */ function testSendDebug() { - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->cc = 'cc@example.com'; $this->Controller->EmailTest->bcc = 'bcc@example.com'; @@ -346,11 +378,11 @@ HTMLBLOC; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $result = $this->Controller->Session->read('Message.email.message'); + $result = DebugCompTransport::$lastEmail; - $this->assertPattern('/To: postmaster@localhost\n/', $result); + $this->assertPattern('/To: postmaster@example.com\n/', $result); $this->assertPattern('/Subject: Cake Debug Test\n/', $result); $this->assertPattern('/Reply-To: noreply@example.com\n/', $result); $this->assertPattern('/From: noreply@example.com\n/', $result); @@ -359,7 +391,7 @@ HTMLBLOC; $this->assertPattern('/Date: ' . preg_quote(date(DATE_RFC2822)) . '\n/', $result); $this->assertPattern('/X-Mailer: CakePHP Email Component\n/', $result); $this->assertPattern('/Content-Type: text\/plain; charset=UTF-8\n/', $result); - $this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result); + $this->assertPattern('/Content-Transfer-Encoding: 7bitMessage:\n/', $result); $this->assertPattern('/This is the body of the message/', $result); } @@ -371,23 +403,24 @@ HTMLBLOC; function testSendDebugWithNoSessions() { $session = $this->Controller->Session; unset($this->Controller->Session); - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake Debug Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; - $result = $this->Controller->EmailTest->send('This is the body of the message'); + $this->Controller->EmailTest->delivery = 'DebugComp'; + $this->Controller->EmailTest->send('This is the body of the message'); + $result = DebugCompTransport::$lastEmail; - $this->assertPattern('/To: postmaster@localhost\n/', $result); + $this->assertPattern('/To: postmaster@example.com\n/', $result); $this->assertPattern('/Subject: Cake Debug Test\n/', $result); $this->assertPattern('/Reply-To: noreply@example.com\n/', $result); $this->assertPattern('/From: noreply@example.com\n/', $result); $this->assertPattern('/Date: ' . preg_quote(date(DATE_RFC2822)) . '\n/', $result); $this->assertPattern('/X-Mailer: CakePHP Email Component\n/', $result); $this->assertPattern('/Content-Type: text\/plain; charset=UTF-8\n/', $result); - $this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result); + $this->assertPattern('/Content-Transfer-Encoding: 7bitMessage:\n/', $result); $this->assertPattern('/This is the body of the message/', $result); $this->Controller->Session = $session; } @@ -403,14 +436,14 @@ HTMLBLOC; 'View' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'View'. DS) )); - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake Debug Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->layout = 'default'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $text = $html = 'This is the body of the message'; @@ -444,14 +477,14 @@ HTMLBLOC; $this->Controller->set('value', 22091985); $this->Controller->set('title_for_layout', 'EmailTest'); - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake Debug Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->layout = 'default'; $this->Controller->EmailTest->template = 'custom'; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $text = <<Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake Debug Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $content = array('First line', 'Second line', 'Third line'); $this->assertTrue($this->Controller->EmailTest->send($content)); - $result = $this->Controller->Session->read('Message.email.message'); + $result = DebugCompTransport::$lastEmail; - $this->assertPattern('/To: postmaster@localhost\n/', $result); + $this->assertPattern('/To: postmaster@example.com\n/', $result); $this->assertPattern('/Subject: Cake Debug Test\n/', $result); $this->assertPattern('/Reply-To: noreply@example.com\n/', $result); $this->assertPattern('/From: noreply@example.com\n/', $result); $this->assertPattern('/X-Mailer: CakePHP Email Component\n/', $result); $this->assertPattern('/Content-Type: text\/plain; charset=UTF-8\n/', $result); - $this->assertPattern('/Content-Transfer-Encoding: 7bitParameters:\n/', $result); + $this->assertPattern('/Content-Transfer-Encoding: 7bitMessage:\n/', $result); $this->assertPattern('/First line\n/', $result); $this->assertPattern('/Second line\n/', $result); $this->assertPattern('/Third line\n/', $result); @@ -526,15 +559,15 @@ HTMLBLOC; * @return void */ function testDateProperty() { - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake Debug Test'; $this->Controller->EmailTest->date = 'Today!'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->assertTrue($this->Controller->EmailTest->send('test message')); - $result = $this->Controller->Session->read('Message.email.message'); + $result = DebugCompTransport::$lastEmail; $this->assertPattern('/Date: Today!\n/', $result); } @@ -578,19 +611,19 @@ HTMLBLOC; mb_internal_encoding('ISO-8859-1'); $this->Controller->charset = 'UTF-8'; - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'هذه رسالة بعنوان طويل مرسل للمستلم'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->Controller->EmailTest->sendAs = 'text'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); $subject = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?='; - preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + preg_match('/Subject: (.*)Header:/s', DebugCompTransport::$lastEmail, $matches); $this->assertEqual(trim($matches[1]), $subject); $result = mb_internal_encoding(); @@ -607,28 +640,28 @@ HTMLBLOC; */ function testMultibyte() { $this->Controller->charset = 'UTF-8'; - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'هذه رسالة بعنوان طويل مرسل للمستلم'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $subject = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?='; $this->Controller->EmailTest->sendAs = 'text'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + preg_match('/Subject: (.*)Header:/s', DebugCompTransport::$lastEmail, $matches); $this->assertEqual(trim($matches[1]), $subject); $this->Controller->EmailTest->sendAs = 'html'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + preg_match('/Subject: (.*)Header:/s', DebugCompTransport::$lastEmail, $matches); $this->assertEqual(trim($matches[1]), $subject); $this->Controller->EmailTest->sendAs = 'both'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - preg_match('/Subject: (.*)Header:/s', $this->Controller->Session->read('Message.email.message'), $matches); + preg_match('/Subject: (.*)Header:/s', DebugCompTransport::$lastEmail, $matches); $this->assertEqual(trim($matches[1]), $subject); } @@ -638,12 +671,12 @@ HTMLBLOC; * @return void */ public function testSendWithAttachments() { - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Attachment Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->Controller->EmailTest->attachments = array( __FILE__, 'some-name.php' => __FILE__ @@ -652,7 +685,7 @@ HTMLBLOC; $this->Controller->EmailTest->sendAs = 'text'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $msg = $this->Controller->Session->read('Message.email.message'); + $msg = DebugCompTransport::$lastEmail; $this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="EmailComponentTest.php"') . '/', $msg); $this->assertPattern('/' . preg_quote('Content-Disposition: attachment; filename="some-name.php"') . '/', $msg); } @@ -663,30 +696,30 @@ HTMLBLOC; * @return void */ public function testSendAsIsNotIgnoredIfAttachmentsPresent() { - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Attachment Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->Controller->EmailTest->attachments = array(__FILE__); $body = '

This is the body of the message

'; $this->Controller->EmailTest->sendAs = 'html'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $msg = $this->Controller->Session->read('Message.email.message'); + $msg = DebugCompTransport::$lastEmail; $this->assertNoPattern('/text\/plain/', $msg); $this->assertPattern('/text\/html/', $msg); $this->Controller->EmailTest->sendAs = 'text'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $msg = $this->Controller->Session->read('Message.email.message'); + $msg = DebugCompTransport::$lastEmail; $this->assertPattern('/text\/plain/', $msg); $this->assertNoPattern('/text\/html/', $msg); $this->Controller->EmailTest->sendAs = 'both'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $msg = $this->Controller->Session->read('Message.email.message'); + $msg = DebugCompTransport::$lastEmail; $this->assertNoPattern('/text\/plain/', $msg); $this->assertNoPattern('/text\/html/', $msg); @@ -699,17 +732,17 @@ HTMLBLOC; * @return void */ public function testNoDoubleNewlinesInHeaders() { - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Attachment Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $body = '

This is the body of the message

'; $this->Controller->EmailTest->sendAs = 'both'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $msg = $this->Controller->Session->read('Message.email.message'); + $msg = DebugCompTransport::$lastEmail; $this->assertNoPattern('/\n\nContent-Transfer-Encoding/', $msg); $this->assertPattern('/\nContent-Transfer-Encoding/', $msg); @@ -773,14 +806,14 @@ HTMLBLOC; $this->Controller->view = 'TestPlugin.Email'; - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'CustomViewClass test'; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $body = 'Body of message'; $this->assertTrue($this->Controller->EmailTest->send($body)); - $result = $this->Controller->Session->read('Message.email.message'); + $result = DebugCompTransport::$lastEmail; $this->assertPattern('/Body of message/', $result); @@ -803,63 +836,31 @@ HTMLBLOC; * @return void */ function testMessageId() { - $this->Controller->EmailTest->to = 'postmaster@localhost'; + $this->Controller->EmailTest->to = 'postmaster@example.com'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake Debug Test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - $this->Controller->EmailTest->delivery = 'debug'; + $this->Controller->EmailTest->delivery = 'DebugComp'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $result = $this->Controller->Session->read('Message.email.message'); + $result = DebugCompTransport::$lastEmail; $this->assertPattern('/Message-ID: \<[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}@' . env('HTTP_HOST') . '\>\n/', $result); - $this->Controller->EmailTest->messageId = '<22091985.998877@localhost>'; + $this->Controller->EmailTest->messageId = '<22091985.998877@example.com>'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $result = $this->Controller->Session->read('Message.email.message'); + $result = DebugCompTransport::$lastEmail; - $this->assertPattern('/Message-ID: <22091985.998877@localhost>\n/', $result); + $this->assertPattern('/Message-ID: <22091985.998877@example.com>\n/', $result); $this->Controller->EmailTest->messageId = false; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $result = $this->Controller->Session->read('Message.email.message'); + $result = DebugCompTransport::$lastEmail; $this->assertNoPattern('/Message-ID:/', $result); } -/** - * testSendMessage method - * - * @access public - * @return void - */ - function testSendMessage() { - $this->Controller->EmailTest->delivery = 'getMessage'; - $this->Controller->EmailTest->lineLength = 70; - - $text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'; - $this->Controller->EmailTest->sendAs = 'text'; - $result = $this->Controller->EmailTest->send($text); - $expected = array( - 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do', - 'eiusmod tempor incididunt ut labore et dolore magna aliqua.', - '', - '' - ); - $this->assertEqual($expected, $result); - - $text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'; - $this->Controller->EmailTest->sendAs = 'html'; - $result = $this->Controller->EmailTest->send($text); - $expected = array( - $text, - '', - '' - ); - $this->assertEqual($expected, $result); - } - } From 88f2c19336d2794f0e8f13c98598b0111b969c60 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 17:30:21 -0400 Subject: [PATCH 081/103] Added the support to set variables in component. --- .../Controller/Component/EmailComponent.php | 20 ++++++++++++++++++- .../Component/EmailComponentTest.php | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 5e2bb9d03..30b1d7f6c 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -269,6 +269,24 @@ class EmailComponent extends Component { */ public $messageId = true; +/** + * Controller reference + * + * @var object Controller + */ + protected $_controller = null; + +/** + * Constructor + * + * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components + * @param array $settings Array of configuration settings. + */ + public function __construct(ComponentCollection $collection, $settings = array()) { + $this->_controller = $collection->getController(); + parent::__construct($collection, $settings); + } + /** * Initialize component * @@ -330,7 +348,7 @@ class EmailComponent extends Component { if ($layout) { $this->layout = $layout; } - $lib->layout($this->layout, $this->template)->emailFormat($this->sendAs); + $lib->layout($this->layout, $this->template)->viewVars($this->_controller->viewVars)->emailFormat($this->sendAs); if (!empty($this->attachments)) { $lib->attachments($this->_formatAttachFiles()); diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index 59f9dd5d6..fb0b8cb3e 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -272,6 +272,7 @@ HEADBLOC; $this->Controller->EmailTest->layout = 'default'; $this->Controller->EmailTest->template = 'default'; + $this->Controller->set('title_for_layout', 'Email Test'); $text = << Date: Sun, 17 Apr 2011 17:31:39 -0400 Subject: [PATCH 082/103] Removed from the tests the view from class registry. --- .../tests/Case/Controller/Component/EmailComponentTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index fb0b8cb3e..f1a023bef 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -155,7 +155,6 @@ class EmailComponentTest extends CakeTestCase { $this->Controller->Components->init($this->Controller); $this->Controller->EmailTest->initialize($this->Controller, array()); - ClassRegistry::addObject('view', new View($this->Controller)); App::build(array( 'View' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'View'. DS) @@ -335,9 +334,6 @@ HTMLBLOC; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message', 'default', 'thin')); $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); - - $result = ClassRegistry::getObject('view'); - $this->assertFalse($result); } /** From 96686e79bbf04d5cfc35d3cfbe4f0f19a6fc5416 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 17:58:33 -0400 Subject: [PATCH 083/103] Added the html and text message in component. --- lib/Cake/Controller/Component/EmailComponent.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 30b1d7f6c..da197e5a2 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -365,6 +365,15 @@ class EmailComponent extends Component { $sent = $lib->send($content); + $this->htmlMessage = $lib->message(CakeEmail::MESSAGE_HTML); + if (empty($this->htmlMessage)) { + $this->htmlMessage = null; + } + $this->textMessage = $lib->message(CakeEmail::MESSAGE_TEXT); + if (empty($this->textMessage)) { + $this->textMessage = null; + } + $this->_header = array(); $this->_message = array(); From 42ee001d716b78d8d1dfbb77ca0d5c6f030a141c Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 18:11:46 -0400 Subject: [PATCH 084/103] Changed the classname of email config. --- app/config/email.php.default | 4 ++-- lib/Cake/Network/CakeEmail.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/config/email.php.default b/app/config/email.php.default index 7861f3be1..3f36fe54c 100644 --- a/app/config/email.php.default +++ b/app/config/email.php.default @@ -28,7 +28,7 @@ * You can specify multiple configurations for production, development and testing. * * transport => The name of a supported transport; valid options are as follows: - * mail - MySQL 4 & 5, + * mail - Send using PHP mail function * smtp - Send using SMTP * * You can add custom database transports (or override existing transports) by adding the @@ -39,7 +39,7 @@ * The origin email. See CakeEmail::to() about the valid values * */ -class EMAIL_CONFIG { +class EmailConfig { public $default = array( 'driver' => 'mail', diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index c03b121be..b3d3e7af5 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -854,7 +854,7 @@ class CakeEmail { if (!config('email')) { throw new SocketException(__d('cake', '%s not found.', APP . 'config' . DS . 'email.php')); } - $configs = new EMAIL_CONFIG(); + $configs = new EmailConfig(); if (!isset($configs->{$this->_config})) { throw new SocketException(__d('cake', 'Unknown email configuration "%s".', $this->_config)); } From 38f5d9da1faf1c9da00d27967f2e1c9caf4143b2 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 18:23:09 -0400 Subject: [PATCH 085/103] Fixed issues related with email config. --- app/config/email.php.default | 14 +++++++------- lib/Cake/Network/CakeEmail.php | 7 +++++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/config/email.php.default b/app/config/email.php.default index 3f36fe54c..8cddda194 100644 --- a/app/config/email.php.default +++ b/app/config/email.php.default @@ -19,7 +19,7 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ /** - * In this file you set up your database connection details. + * In this file you set up your send email details. * * @package cake.config */ @@ -31,23 +31,23 @@ * mail - Send using PHP mail function * smtp - Send using SMTP * - * You can add custom database transports (or override existing transports) by adding the - * appropriate file to app/libs/emails. Transports should be named 'x_transport.php', - * where 'x' is the name of the transport. + * You can add custom transports (or override existing transports) by adding the + * appropriate file to app/Network/Email. Transports should be named 'YourTransport.php', + * where 'Your' is the name of the transport. * * from => - * The origin email. See CakeEmail::to() about the valid values + * The origin email. See CakeEmail::from() about the valid values * */ class EmailConfig { public $default = array( - 'driver' => 'mail', + 'transport' => 'mail', 'from' => 'you@localhost' ); public $smtp = array( - 'driver' => 'smtp', + 'transport' => 'smtp', 'from' => array('My Site', 'site@localhost'), 'host' => 'localhost', 'port' => 25, diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index b3d3e7af5..69049f868 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -852,20 +852,23 @@ class CakeEmail { public function send($content = null) { if (is_string($this->_config)) { if (!config('email')) { - throw new SocketException(__d('cake', '%s not found.', APP . 'config' . DS . 'email.php')); + throw new SocketException(__d('cake', '%s not found.', CONFIGS . 'email.php')); } $configs = new EmailConfig(); if (!isset($configs->{$this->_config})) { throw new SocketException(__d('cake', 'Unknown email configuration "%s".', $this->_config)); } $config = $configs->{$this->_config}; + if (isset($config['transport'])) { + $this->transport($config['transport']); + } } else { $config = $this->_config; } if (empty($this->_from)) { if (!empty($config['from'])) { - $this->to($config['from']); + $this->from($config['from']); } else { throw new SocketException(__d('cake', 'From is not specified.')); } From 7acdf1e436f8d18af0afb11e649791af47277ff6 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 19:40:18 -0400 Subject: [PATCH 086/103] Changed the method layout to template. Template is required to render, but layout is not. --- lib/Cake/Network/CakeEmail.php | 20 ++++++------ lib/Cake/tests/Case/Network/CakeEmailTest.php | 31 ++++++++++++++++--- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 69049f868..ae62d4a40 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -638,22 +638,22 @@ class CakeEmail { } /** - * Layout and template + * Template and layout * - * @param string $layout - * @param string $template + * @param mixed $template Template name or null to not use + * @param mixed $layout Layout name or null to not use * @return mixed */ - public function layout($layout = null, $template = null) { - if ($layout === null) { + public function template($template = false, $layout = false) { + if ($template === false) { return array( - 'layout' => $this->_layout, - 'template' => $this->_template + 'template' => $this->_template, + 'layout' => $this->_layout ); } - $this->_layout = (string)$layout; - if ($template !== null) { - $this->_template = (string)$template; + $this->_template = $template; + if ($layout !== false) { + $this->_layout = $layout; } return $this; } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 7149c0c5b..d96503a0e 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -409,7 +409,30 @@ class CakeEmailTest extends CakeTestCase { } /** - * testAttachments + * testTemplate method + * + * @return void + */ + public function testTemplate() { + $this->CakeEmail->template('template', 'layout'); + $expected = array('template' => 'template', 'layout' => 'layout'); + $this->assertIdentical($this->CakeEmail->template(), $expected); + + $this->CakeEmail->template('new_template'); + $expected = array('template' => 'new_template', 'layout' => 'layout'); + $this->assertIdentical($this->CakeEmail->template(), $expected); + + $this->CakeEmail->template('template', null); + $expected = array('template' => 'template', 'layout' => null); + $this->assertIdentical($this->CakeEmail->template(), $expected); + + $this->CakeEmail->template(null, null); + $expected = array('template' => null, 'layout' => null); + $this->assertIdentical($this->CakeEmail->template(), $expected); + } + +/** + * testAttachments method * * @return void */ @@ -510,7 +533,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->to(array('you@cakephp.org' => 'You')); $this->CakeEmail->subject('My title'); $this->CakeEmail->config(array('empty')); - $this->CakeEmail->layout('default', 'default'); + $this->CakeEmail->template('default', 'default'); $result = $this->CakeEmail->send(); $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, 'This email was sent using the CakePHP Framework')); @@ -532,7 +555,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->to(array('you@cakephp.org' => 'You')); $this->CakeEmail->subject('My title'); $this->CakeEmail->config(array('empty')); - $this->CakeEmail->layout('default', 'custom'); + $this->CakeEmail->template('custom', 'default'); $this->CakeEmail->viewVars(array('value' => 12345)); $result = $this->CakeEmail->send(); @@ -553,7 +576,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->to(array('you@cakephp.org' => 'You')); $this->CakeEmail->subject('My title'); $this->CakeEmail->config(array('empty')); - $this->CakeEmail->layout('default', 'default'); + $this->CakeEmail->template('default', 'default'); $this->CakeEmail->emailFormat('both'); $result = $this->CakeEmail->send(); From 5ea3b75b2fc0dfce45dd169ca1d877554c2f40a3 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 20:57:57 -0400 Subject: [PATCH 087/103] CakeEmail::viewVars() now merge the param with previous config. --- lib/Cake/Network/CakeEmail.php | 4 ++-- lib/Cake/tests/Case/Network/CakeEmailTest.php | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index ae62d4a40..c2f60c4cc 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -675,14 +675,14 @@ class CakeEmail { /** * Variables to be set on render * - * @param array + * @param array $viewVars * @return mixed */ public function viewVars($viewVars = null) { if ($viewVars === null) { return $this->_viewVars; } - $this->_viewVars = $viewVars; + $this->_viewVars = array_merge($this->_viewVars, (array)$viewVars); return $this; } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index d96503a0e..0186d9a69 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -431,6 +431,24 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail->template(), $expected); } +/** + * testViewVars method + * + * @return void + */ + public function testViewVars() { + $this->assertIdentical($this->CakeEmail->viewVars(), array()); + + $this->CakeEmail->viewVars(array('value' => 12345)); + $this->assertIdentical($this->CakeEmail->viewVars(), array('value' => 12345)); + + $this->CakeEmail->viewVars(array('name' => 'CakePHP')); + $this->assertIdentical($this->CakeEmail->viewVars(), array('value' => 12345, 'name' => 'CakePHP')); + + $this->CakeEmail->viewVars(array('value' => 4567)); + $this->assertIdentical($this->CakeEmail->viewVars(), array('value' => 4567, 'name' => 'CakePHP')); + } + /** * testAttachments method * From 11331066ab60283c2743f1f19a0a68f29cf2b726 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 21:21:09 -0400 Subject: [PATCH 088/103] Setted EmailComponent as deprecated. --- lib/Cake/Controller/Component/EmailComponent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index da197e5a2..eba5637b8 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -29,7 +29,7 @@ App::uses('CakeEmail', 'Network'); * * @package cake.libs.controller.components * @link http://book.cakephp.org/view/1283/Email - * + * @deprecated Use Network/CakeEmail */ class EmailComponent extends Component { From a1bcaa9d2931b896043d2e65e631d80eea6f3444 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 21:23:48 -0400 Subject: [PATCH 089/103] Created a static method to send fast emails. --- app/config/email.php.default | 27 ++++++ lib/Cake/Network/CakeEmail.php | 83 ++++++++++++++++++- lib/Cake/tests/Case/Network/CakeEmailTest.php | 30 +++++++ 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/app/config/email.php.default b/app/config/email.php.default index 8cddda194..81d6ea9f5 100644 --- a/app/config/email.php.default +++ b/app/config/email.php.default @@ -57,4 +57,31 @@ class EmailConfig { 'client' => null ); + public $fast = array( + 'from' => 'you@localhost', + 'to' => null, + 'cc' => null, + 'bcc' => null, + 'replyTo' => null, + 'readReceipt' => null, + 'returnPath' => null, + 'messageId' => true, + 'subject' => null, + 'message' => null, + 'headers' => null, + 'viewRender' => null, + 'template' => false, + 'layout' => false, + 'viewVars' => null, + 'attachments' => null, + 'emailFormat' => null, + 'transport' => 'smtp', + 'host' => 'localhost', + 'port' => 25, + 'timeout' => 30, + 'username' => 'user', + 'password' => 'secret', + 'client' => null + ); + } diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index c2f60c4cc..d1c78c2cb 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -748,7 +748,7 @@ class CakeEmail { * @return mixed * @thrown SocketException */ - public function messageID($message = null) { + public function messageId($message = null) { if ($message === null) { return $this->_messageId; } @@ -917,6 +917,87 @@ class CakeEmail { return $transport->send($this); } +/** + * Static method to fast create an instance of CakeEmail + * + * @param mixed $to Address to send (see CakeEmail::to()). If null, will try to use 'to' from transport config + * @param mixed $subject String of subject or null to use 'subject' from transport config + * @param mixed $message String with message or array with variables to be used in render + * @param mixed $transportConfig String to use config from EmailConfig or array with configs + * @param boolean $send Send the email or just return the instance pre-configured + * @return object Instance of CakeEmail + */ + public static function fastSend($to = null, $subject = null, $message = null, $transportConfig = 'fast', $send = true) { + $class = __CLASS__; + $instance = new $class(); + + if (is_string($transportConfig)) { + if (!config('email')) { + throw new SocketException(__d('cake', '%s not found.', CONFIGS . 'email.php')); + } + $configs = new EmailConfig(); + if (!isset($configs->{$transportConfig})) { + throw new SocketException(__d('cake', 'Unknown email configuration "%s".', $transportConfig)); + } + $transportConfig = $configs->{$transportConfig}; + } + self::_applyConfig($instance, $transportConfig); + + if ($to !== null) { + $instance->to($to); + } + if ($subject !== null) { + $instance->subject($subject); + } + if (is_array($message)) { + $instance->viewVars($message); + $message = null; + } elseif ($message === null && isset($config['message'])) { + $message = $config['message']; + } + + if ($send === true) { + $instance->send($message); + } + + return $instance; + } + +/** + * Apply the config to an instance + * + * @param object $obj CakeEmail + * @param array $config + * @return void + */ + protected static function _applyConfig(CakeEmail $obj, $config) { + $simpleMethods = array( + 'from', 'to', 'replyTo', 'readReceipt', 'returnPath', 'cc', 'bcc', + 'messageId', 'subject', 'viewRender', 'viewVars', 'attachments', + 'transport', 'emailFormat' + ); + foreach ($simpleMethods as $method) { + if (isset($config[$method])) { + $obj->$method($config[$method]); + unset($config[$method]); + } + } + if (isset($config['headers'])) { + $obj->setHeaders($config['headers']); + unset($config['headers']); + } + if (array_key_exists('template', $config)) { + $layout = false; + if (array_key_exists('layout', $config)) { + $layout = $config['layout']; + unset($config['layout']); + } + $obj->template($config['template'], $layout); + unset($config['template']); + } + $obj->config($config); + } + /** * Reset all EmailComponent internal variables to be able to send out a new email. * diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 0186d9a69..bdef865bc 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -580,6 +580,36 @@ class CakeEmailTest extends CakeTestCase { $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, 'Here is your value: 12345')); } +/** + * testFastSend method + * + * @return void + */ + public function testFastSend() { + $instance = CakeEmail::fastSend('all@cakephp.org', 'About', 'Everything ok', array('from' => 'root@cakephp.org'), false); + $this->assertIsA($instance, 'CakeEmail'); + $this->assertIdentical($instance->to(), array('all@cakephp.org' => 'all@cakephp.org')); + $this->assertIdentical($instance->subject(), 'About'); + $this->assertIdentical($instance->from(), array('root@cakephp.org' => 'root@cakephp.org')); + + $config = array( + 'from' => 'cake@cakephp.org', + 'to' => 'debug@cakephp.org', + 'subject' => 'Update ok', + 'template' => 'custom', + 'layout' => 'custom_layout', + 'viewVars' => array('value' => 123), + 'cc' => array('cake@cakephp.org' => 'Myself') + ); + $instance = CakeEmail::fastSend(null, null, array('name' => 'CakePHP'), $config, false); + $this->assertIdentical($instance->from(), array('cake@cakephp.org' => 'cake@cakephp.org')); + $this->assertIdentical($instance->to(), array('debug@cakephp.org' => 'debug@cakephp.org')); + $this->assertIdentical($instance->subject(), 'Update ok'); + $this->assertIdentical($instance->template(), array('template' => 'custom', 'layout' => 'custom_layout')); + $this->assertIdentical($instance->viewVars(), array('value' => 123, 'name' => 'CakePHP')); + $this->assertIdentical($instance->cc(), array('cake@cakephp.org' => 'Myself')); + } + /** * testMessage method * From 25705af8ed6a4587a13fddcbbbcfc276f2082493 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 17 Apr 2011 21:53:30 -0400 Subject: [PATCH 090/103] Added the same email config sample of app/config to console skeleton. --- .../templates/skel/config/email.php.default | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 lib/Cake/Console/templates/skel/config/email.php.default diff --git a/lib/Cake/Console/templates/skel/config/email.php.default b/lib/Cake/Console/templates/skel/config/email.php.default new file mode 100644 index 000000000..81d6ea9f5 --- /dev/null +++ b/lib/Cake/Console/templates/skel/config/email.php.default @@ -0,0 +1,87 @@ + The name of a supported transport; valid options are as follows: + * mail - Send using PHP mail function + * smtp - Send using SMTP + * + * You can add custom transports (or override existing transports) by adding the + * appropriate file to app/Network/Email. Transports should be named 'YourTransport.php', + * where 'Your' is the name of the transport. + * + * from => + * The origin email. See CakeEmail::from() about the valid values + * + */ +class EmailConfig { + + public $default = array( + 'transport' => 'mail', + 'from' => 'you@localhost' + ); + + public $smtp = array( + 'transport' => 'smtp', + 'from' => array('My Site', 'site@localhost'), + 'host' => 'localhost', + 'port' => 25, + 'timeout' => 30, + 'username' => 'user', + 'password' => 'secret', + 'client' => null + ); + + public $fast = array( + 'from' => 'you@localhost', + 'to' => null, + 'cc' => null, + 'bcc' => null, + 'replyTo' => null, + 'readReceipt' => null, + 'returnPath' => null, + 'messageId' => true, + 'subject' => null, + 'message' => null, + 'headers' => null, + 'viewRender' => null, + 'template' => false, + 'layout' => false, + 'viewVars' => null, + 'attachments' => null, + 'emailFormat' => null, + 'transport' => 'smtp', + 'host' => 'localhost', + 'port' => 25, + 'timeout' => 30, + 'username' => 'user', + 'password' => 'secret', + 'client' => null + ); + +} From 1004b1a16815426a9f3f99f8b4a085b283aaa1d0 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 19 Apr 2011 09:22:42 -0400 Subject: [PATCH 091/103] Fixed the set of boundary. --- lib/Cake/Network/CakeEmail.php | 11 +++-- lib/Cake/Network/Email/SmtpTransport.php | 1 + lib/Cake/tests/Case/Network/CakeEmailTest.php | 48 +++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index d1c78c2cb..9f5a73a3d 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -601,7 +601,6 @@ class CakeEmail { } if (!empty($this->_attachments)) { - $this->_createBoundary(); $headers['MIME-Version'] = '1.0'; $headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"'; $headers[] = 'This part of the E-mail should never be seen. If'; @@ -892,6 +891,8 @@ class CakeEmail { } } + $this->_createBoundary(); + $message = $this->_wrap($content); if (empty($this->_template)) { $message = $this->_formatMessage($message); @@ -905,7 +906,7 @@ class CakeEmail { $this->_attachFiles(); } - if (!is_null($this->_boundary)) { + if (!empty($this->_attachments)) { $this->_message[] = ''; $this->_message[] = '--' . $this->_boundary . '--'; $this->_message[] = ''; @@ -1147,8 +1148,10 @@ class CakeEmail { * * @return void */ - protected function _createboundary() { - $this->_boundary = md5(uniqid(time())); + protected function _createBoundary() { + if (!empty($this->_attachments) || $this->_emailFormat === 'both') { + $this->_boundary = md5(uniqid(time())); + } } /** diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index aba0bd9f2..6713d68bb 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -161,6 +161,7 @@ class SmtpTransport extends AbstractTransport { $headers = $this->_cakeEmail->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), true)); $headers = $this->_headersToString($headers); $message = implode("\r\n", $this->_cakeEmail->message()); + pr($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); $this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); } diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index bdef865bc..382b377e9 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -46,6 +46,15 @@ class TestCakeEmail extends CakeEmail { return parent::_wrap($text); } +/** + * Get the boundary attribute + * + * @return string + */ + public function getBoundary() { + return $this->_boundary; + } + } /** @@ -580,6 +589,45 @@ class CakeEmailTest extends CakeTestCase { $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, 'Here is your value: 12345')); } +/** + * testSendMultipleMIME method + * + * @return void + */ + public function testSendMultipleMIME() { + $this->CakeEmail->reset(); + $this->CakeEmail->transport('debug'); + DebugTransport::$includeAddresses = true; + + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to(array('you@cakephp.org' => 'You')); + $this->CakeEmail->subject('My title'); + $this->CakeEmail->template('custom', 'default'); + $this->CakeEmail->config(array()); + $this->CakeEmail->viewVars(array('value' => 12345)); + $this->CakeEmail->emailFormat('both'); + $result = $this->CakeEmail->send(); + + $message = $this->CakeEmail->message(); + $boundary = $this->CakeEmail->getBoundary(); + $this->assertFalse(empty($boundary)); + $this->assertFalse(in_array('--' . $boundary, $message)); + $this->assertFalse(in_array('--' . $boundary . '--', $message)); + $this->assertTrue(in_array('--alt-' . $boundary, $message)); + $this->assertTrue(in_array('--alt-' . $boundary . '--', $message)); + + $this->CakeEmail->attachments(array('fake.php' => __FILE__)); + $this->CakeEmail->send(); + + $message = $this->CakeEmail->message(); + $boundary = $this->CakeEmail->getBoundary(); + $this->assertFalse(empty($boundary)); + $this->assertTrue(in_array('--' . $boundary, $message)); + $this->assertTrue(in_array('--' . $boundary . '--', $message)); + $this->assertTrue(in_array('--alt-' . $boundary, $message)); + $this->assertTrue(in_array('--alt-' . $boundary . '--', $message)); + } + /** * testFastSend method * From 8443b669862416adcc59412b1b2413c1731d2830 Mon Sep 17 00:00:00 2001 From: evilbloodydemon Date: Tue, 19 Apr 2011 22:02:35 +0400 Subject: [PATCH 092/103] PhpDoc and naming fixes --- lib/Cake/Network/CakeEmail.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 9f5a73a3d..ef95e879d 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -217,7 +217,7 @@ class CakeEmail { protected $_transportName = 'mail'; /** - * Instance of tranport class + * Instance of transport class * * @var object */ @@ -501,7 +501,7 @@ class CakeEmail { } /** - * Sets eaders for the message + * Sets headers for the message * * @param array Associative array containing headers to be set. * @return object $this @@ -846,7 +846,7 @@ class CakeEmail { * Send an email using the specified content, template and layout * * @return boolean Success - * @thrown SocketExpcetion + * @thrown SocketException */ public function send($content = null) { if (is_string($this->_config)) { @@ -873,7 +873,7 @@ class CakeEmail { } } if (empty($this->_to) && empty($this->_cc) && empty($this->_bcc)) { - throw new SocketExpcetion(__d('cake', 'You need specify one destination on to, cc or bcc.')); + throw new SocketException(__d('cake', 'You need specify one destination on to, cc or bcc.')); } if (is_array($content)) { From 98afe4e09b1234c127f11e485c3e085b5ce08af5 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 19 Apr 2011 17:07:38 -0400 Subject: [PATCH 093/103] Renamed the method fastSend to deliver. --- lib/Cake/Network/CakeEmail.php | 2 +- lib/Cake/tests/Case/Network/CakeEmailTest.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index ef95e879d..d808887f8 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -928,7 +928,7 @@ class CakeEmail { * @param boolean $send Send the email or just return the instance pre-configured * @return object Instance of CakeEmail */ - public static function fastSend($to = null, $subject = null, $message = null, $transportConfig = 'fast', $send = true) { + public static function deliver($to = null, $subject = null, $message = null, $transportConfig = 'fast', $send = true) { $class = __CLASS__; $instance = new $class(); diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 382b377e9..835beffc9 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -629,12 +629,12 @@ class CakeEmailTest extends CakeTestCase { } /** - * testFastSend method + * testDeliver method * * @return void */ - public function testFastSend() { - $instance = CakeEmail::fastSend('all@cakephp.org', 'About', 'Everything ok', array('from' => 'root@cakephp.org'), false); + public function testDeliver() { + $instance = CakeEmail::deliver('all@cakephp.org', 'About', 'Everything ok', array('from' => 'root@cakephp.org'), false); $this->assertIsA($instance, 'CakeEmail'); $this->assertIdentical($instance->to(), array('all@cakephp.org' => 'all@cakephp.org')); $this->assertIdentical($instance->subject(), 'About'); @@ -649,7 +649,7 @@ class CakeEmailTest extends CakeTestCase { 'viewVars' => array('value' => 123), 'cc' => array('cake@cakephp.org' => 'Myself') ); - $instance = CakeEmail::fastSend(null, null, array('name' => 'CakePHP'), $config, false); + $instance = CakeEmail::deliver(null, null, array('name' => 'CakePHP'), $config, false); $this->assertIdentical($instance->from(), array('cake@cakephp.org' => 'cake@cakephp.org')); $this->assertIdentical($instance->to(), array('debug@cakephp.org' => 'debug@cakephp.org')); $this->assertIdentical($instance->subject(), 'Update ok'); From baba9fd270ec85ad7b16d5da5b7ef69e3be28dc5 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 19 Apr 2011 19:48:52 -0400 Subject: [PATCH 094/103] Fixed phpdoc. --- lib/Cake/Network/CakeEmail.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index d808887f8..441101329 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -69,28 +69,28 @@ class CakeEmail { /** * Recipient of the email * - * @var string + * @var array */ protected $_to = array(); /** * The mail which the email is sent from * - * @var string + * @var array */ protected $_from = array(); /** * The email the recipient will reply to * - * @var string + * @var array */ protected $_replyTo = array(); /** * The read receipt email * - * @var string + * @var array */ protected $_readReceipt = array(); @@ -100,7 +100,7 @@ class CakeEmail { * - Remote user has exceeded his quota * - Unknown user * - * @var string + * @var array */ protected $_returnPath = array(); From e0b462306544146844909d4bcbde20381f6df7b9 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 19 Apr 2011 20:18:02 -0400 Subject: [PATCH 095/103] Added support to sender email. Fixes #13. --- app/config/email.php.default | 1 + .../templates/skel/config/email.php.default | 1 + lib/Cake/Network/CakeEmail.php | 33 ++++++++++++++++++- lib/Cake/Network/Email/MailTransport.php | 2 +- lib/Cake/Network/Email/SmtpTransport.php | 2 +- lib/Cake/tests/Case/Network/CakeEmailTest.php | 23 +++++++++++++ 6 files changed, 59 insertions(+), 3 deletions(-) diff --git a/app/config/email.php.default b/app/config/email.php.default index 81d6ea9f5..66c378f35 100644 --- a/app/config/email.php.default +++ b/app/config/email.php.default @@ -59,6 +59,7 @@ class EmailConfig { public $fast = array( 'from' => 'you@localhost', + 'sender' => null, 'to' => null, 'cc' => null, 'bcc' => null, diff --git a/lib/Cake/Console/templates/skel/config/email.php.default b/lib/Cake/Console/templates/skel/config/email.php.default index 81d6ea9f5..66c378f35 100644 --- a/lib/Cake/Console/templates/skel/config/email.php.default +++ b/lib/Cake/Console/templates/skel/config/email.php.default @@ -59,6 +59,7 @@ class EmailConfig { public $fast = array( 'from' => 'you@localhost', + 'sender' => null, 'to' => null, 'cc' => null, 'bcc' => null, diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 441101329..53b841e08 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -80,6 +80,13 @@ class CakeEmail { */ protected $_from = array(); +/** + * The sender email + * + * @var array(); + */ + protected $_sender = array(); + /** * The email the recipient will reply to * @@ -279,6 +286,21 @@ class CakeEmail { return $this->_setEmailSingle('_from', $email, $name, __d('cake', 'From requires only 1 email address.')); } +/** + * Sender + * + * @param mixed $email + * @param string $name + * @return mixed + * @thrown SocketException + */ + public function sender($email = null, $name = null) { + if ($email === null) { + return $this->_sender; + } + return $this->_setEmailSingle('_sender', $email, $name, __d('cake', 'Sender requires only 1 email address.')); + } + /** * Reply-To * @@ -550,6 +572,7 @@ class CakeEmail { public function getHeaders($include = array()) { $defaults = array( 'from' => false, + 'sender' => false, 'replyTo' => false, 'readReceipt' => false, 'returnPath' => false, @@ -573,6 +596,13 @@ class CakeEmail { $headers[$header] = current($this->_formatAddress($this->{$var})); } } + if ($include['sender']) { + if (key($this->_sender) === key($this->_from)) { + $headers['Sender'] = ''; + } else { + $headers['Sender'] = current($this->_formatAddress($this->_sender)); + } + } foreach (array('to', 'cc', 'bcc') as $var) { if ($include[$var]) { @@ -973,7 +1003,7 @@ class CakeEmail { */ protected static function _applyConfig(CakeEmail $obj, $config) { $simpleMethods = array( - 'from', 'to', 'replyTo', 'readReceipt', 'returnPath', 'cc', 'bcc', + 'from', 'sender', 'to', 'replyTo', 'readReceipt', 'returnPath', 'cc', 'bcc', 'messageId', 'subject', 'viewRender', 'viewVars', 'attachments', 'transport', 'emailFormat' ); @@ -1007,6 +1037,7 @@ class CakeEmail { public function reset() { $this->_to = array(); $this->_from = array(); + $this->_sender = array(); $this->_replyTo = array(); $this->_readReceipt = array(); $this->_returnPath = array(); diff --git a/lib/Cake/Network/Email/MailTransport.php b/lib/Cake/Network/Email/MailTransport.php index 229451a08..0b6d3cda4 100644 --- a/lib/Cake/Network/Email/MailTransport.php +++ b/lib/Cake/Network/Email/MailTransport.php @@ -35,7 +35,7 @@ class MailTransport extends AbstractTransport { if (isset($this->_config['eol'])) { $eol = $this->_config['eol']; } - $headers = $email->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true)); + $headers = $email->getHeaders(array_fill_keys(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true)); $to = $headers['To']; unset($headers['To']); $header = $this->_headersToString($headers, $eol); diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index 6713d68bb..55245a6ff 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -158,7 +158,7 @@ class SmtpTransport extends AbstractTransport { protected function _sendData() { $this->_smtpSend('DATA', '354'); - $headers = $this->_cakeEmail->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), true)); + $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()); pr($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 835beffc9..2750dc0de 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -174,6 +174,29 @@ class CakeEmailTest extends CakeTestCase { $this->assertIdentical($this->CakeEmail, $result); } +/** + * testSender method + * + * @return void + */ + public function testSender() { + $this->CakeEmail->reset(); + $this->assertIdentical($this->CakeEmail->sender(), array()); + + $this->CakeEmail->sender('cake@cakephp.org', 'Name'); + $expected = array('cake@cakephp.org' => 'Name'); + $this->assertIdentical($this->CakeEmail->sender(), $expected); + + $headers = $this->CakeEmail->getHeaders(array('from' => true, 'sender' => true)); + $this->assertIdentical($headers['From'], false); + $this->assertIdentical($headers['Sender'], 'Name '); + + $this->CakeEmail->from('cake@cakephp.org', 'CakePHP'); + $headers = $this->CakeEmail->getHeaders(array('from' => true, 'sender' => true)); + $this->assertIdentical($headers['From'], 'CakePHP '); + $this->assertIdentical($headers['Sender'], ''); + } + /** * testTo method * From 1fee54906327f154f1e8d2a23efdbf1856031163 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 19 Apr 2011 20:25:09 -0400 Subject: [PATCH 096/103] Ooops, removed debug call. --- lib/Cake/Network/Email/SmtpTransport.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index 55245a6ff..5cf6674b9 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -161,7 +161,6 @@ class SmtpTransport extends AbstractTransport { $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()); - pr($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); $this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); } From be4b9fcd02e8677e63af75c3adf32cfc2b0def0b Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 19 Apr 2011 21:47:48 -0400 Subject: [PATCH 097/103] The MIME version can be used in all types of e-mail. Fixes #14. --- lib/Cake/Network/CakeEmail.php | 2 +- lib/Cake/tests/Case/Network/CakeEmailTest.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 53b841e08..cb4345599 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -630,8 +630,8 @@ class CakeEmail { $headers['Subject'] = $this->_subject; } + $headers['MIME-Version'] = '1.0'; if (!empty($this->_attachments)) { - $headers['MIME-Version'] = '1.0'; $headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"'; $headers[] = 'This part of the E-mail should never be seen. If'; $headers[] = 'you are reading this, consider upgrading your e-mail'; diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 2750dc0de..cf79792ba 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -392,6 +392,7 @@ class CakeEmailTest extends CakeTestCase { 'X-Something' => 'nice', 'X-Mailer' => 'CakePHP Email Component', 'Date' => date(DATE_RFC2822), + 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8', 'Content-Transfer-Encoding' => '7bit' ); @@ -403,6 +404,7 @@ class CakeEmailTest extends CakeTestCase { 'X-Other' => 'cool', 'X-Mailer' => 'CakePHP Email Component', 'Date' => date(DATE_RFC2822), + 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8', 'Content-Transfer-Encoding' => '7bit' ); @@ -417,6 +419,7 @@ class CakeEmailTest extends CakeTestCase { 'X-Other' => 'cool', 'X-Mailer' => 'CakePHP Email Component', 'Date' => date(DATE_RFC2822), + 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8', 'Content-Transfer-Encoding' => '7bit' ); @@ -434,6 +437,7 @@ class CakeEmailTest extends CakeTestCase { 'X-Other' => 'cool', 'X-Mailer' => 'CakePHP Email Component', 'Date' => date(DATE_RFC2822), + 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8', 'Content-Transfer-Encoding' => '7bit' ); From 599d631f2f6516bf2a6bc59e28d2b31ae16d0ccb Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Wed, 20 Apr 2011 21:51:30 -0400 Subject: [PATCH 098/103] Adapted to support mimetype and contentId in the attachments. Fixes #1201. --- lib/Cake/Network/CakeEmail.php | 36 +++++++++++----- lib/Cake/tests/Case/Network/CakeEmailTest.php | 43 ++++++++++++++++--- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index cb4345599..251b179ed 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -804,15 +804,24 @@ class CakeEmail { return $this->_attachments; } $attach = array(); - foreach ((array)$attachments as $name => $file) { - $path = realpath($file); - if ($path === false) { - throw new SocketException(__d('cake', 'File not found: "%s"', $attach)); + foreach ((array)$attachments as $name => $fileInfo) { + if (!is_array($fileInfo)) { + $fileInfo = array('file' => $fileInfo); + } + if (!isset($fileInfo['file'])) { + throw new SocketException(__d('cake', 'File not specified.')); + } + $fileInfo['file'] = realpath($fileInfo['file']); + if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) { + throw new SocketException(__d('cake', 'File not found: "%s"', $fileInfo['file'])); } if (is_int($name)) { - $name = basename($path); + $name = basename($fileInfo['file']); } - $attach[$name] = $path; + if (!isset($fileInfo['mimetype'])) { + $fileInfo['mimetype'] = 'application/octet-stream'; + } + $attach[$name] = $fileInfo; } $this->_attachments = $attach; return $this; @@ -1191,16 +1200,21 @@ class CakeEmail { * @return void */ protected function _attachFiles() { - foreach ($this->_attachments as $filename => $file) { - $handle = fopen($file, 'rb'); - $data = fread($handle, filesize($file)); + foreach ($this->_attachments as $filename => $fileInfo) { + $handle = fopen($fileInfo['file'], 'rb'); + $data = fread($handle, filesize($fileInfo['file'])); $data = chunk_split(base64_encode($data)) ; fclose($handle); $this->_message[] = '--' . $this->_boundary; - $this->_message[] = 'Content-Type: application/octet-stream'; + $this->_message[] = 'Content-Type: ' . $fileInfo['mimetype']; $this->_message[] = 'Content-Transfer-Encoding: base64'; - $this->_message[] = 'Content-Disposition: attachment; filename="' . $filename . '"'; + if (empty($fileInfo['contentId'])) { + $this->_message[] = 'Content-Disposition: attachment; filename="' . $filename . '"'; + } else { + $this->_message[] = 'Content-ID: <' . $fileInfo['contentId'] . '>'; + $this->_message[] = 'Content-Disposition: inline; filename="' . $filename . '"'; + } $this->_message[] = ''; $this->_message[] = $data; $this->_message[] = ''; diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index cf79792ba..922761310 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -492,21 +492,21 @@ class CakeEmailTest extends CakeTestCase { */ public function testAttachments() { $this->CakeEmail->attachments(WWW_ROOT . 'index.php'); - $expected = array('index.php' => WWW_ROOT . 'index.php'); + $expected = array('index.php' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'application/octet-stream')); $this->assertIdentical($this->CakeEmail->attachments(), $expected); $this->CakeEmail->attachments(array()); $this->assertIdentical($this->CakeEmail->attachments(), array()); - $this->CakeEmail->attachments(WWW_ROOT . 'index.php'); + $this->CakeEmail->attachments(array(array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain'))); $this->CakeEmail->addAttachments(WWW_ROOT . 'test.php'); $this->CakeEmail->addAttachments(array(WWW_ROOT . 'test.php')); $this->CakeEmail->addAttachments(array('other.txt' => WWW_ROOT . 'test.php', 'ht' => WWW_ROOT . '.htaccess')); $expected = array( - 'index.php' => WWW_ROOT . 'index.php', - 'test.php' => WWW_ROOT . 'test.php', - 'other.txt' => WWW_ROOT . 'test.php', - 'ht' => WWW_ROOT . '.htaccess' + 'index.php' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain'), + 'test.php' => array('file' => WWW_ROOT . 'test.php', 'mimetype' => 'application/octet-stream'), + 'other.txt' => array('file' => WWW_ROOT . 'test.php', 'mimetype' => 'application/octet-stream'), + 'ht' => array('file' => WWW_ROOT . '.htaccess', 'mimetype' => 'application/octet-stream') ); $this->assertIdentical($this->CakeEmail->attachments(), $expected); } @@ -655,6 +655,37 @@ class CakeEmailTest extends CakeTestCase { $this->assertTrue(in_array('--alt-' . $boundary . '--', $message)); } +/** + * testSendAttachment method + * + * @return void + */ + public function testSendAttachment() { + $this->CakeEmail->reset(); + $this->CakeEmail->transport('debug'); + DebugTransport::$includeAddresses = false; + + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to(array('you@cakephp.org' => 'You')); + $this->CakeEmail->subject('My title'); + $this->CakeEmail->config(array()); + $this->CakeEmail->attachments(array(WWW_ROOT . 'index.php')); + $this->CakeEmail->send('body'); + $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"index.php\"")); + + $this->CakeEmail->attachments(array('my.file.txt' => WWW_ROOT . 'index.php')); + $this->CakeEmail->send('body'); + $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"my.file.txt\"")); + + $this->CakeEmail->attachments(array('file.txt' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain'))); + $this->CakeEmail->send('body'); + $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"file.txt\"")); + + $this->CakeEmail->attachments(array('file.txt' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain', 'contentId' => 'a1b1c1'))); + $this->CakeEmail->send('body'); + $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-ID: \r\nContent-Disposition: inline; filename=\"file.txt\"")); + } + /** * testDeliver method * From fac5ae50d0491f8941b9f8d43faf272406adaf00 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Wed, 20 Apr 2011 23:47:21 -0400 Subject: [PATCH 099/103] Moved the emails templates from elements to views. Renamed the path in layouts to keep the same name. Fixes #1415. --- .../{elements/email => emails}/html/empty | 0 .../{elements/email => emails}/text/empty | 0 app/View/layouts/{email => emails}/html/empty | 0 app/View/layouts/{email => emails}/text/empty | 0 .../email => emails}/html/default.ctp | 0 .../email => emails}/text/default.ctp | 0 .../{email => emails}/html/default.ctp | 0 .../{email => emails}/text/default.ctp | 0 lib/Cake/Network/CakeEmail.php | 29 ++++++++++--------- .../email => emails}/html/default.ctp | 0 .../email => emails}/text/default.ctp | 0 .../{email => emails}/html/default.ctp | 0 .../{email => emails}/text/default.ctp | 0 .../email => emails}/html/custom.ctp | 0 .../email => emails}/html/default.ctp | 0 .../email => emails}/html/nested_element.ctp | 0 .../email => emails}/text/custom.ctp | 0 .../email => emails}/text/default.ctp | 0 .../{elements/email => emails}/text/wide.ctp | 0 .../{email => emails}/html/default.ctp | 0 .../layouts/{email => emails}/html/thin.ctp | 0 .../{email => emails}/text/default.ctp | 0 22 files changed, 16 insertions(+), 13 deletions(-) rename app/View/{elements/email => emails}/html/empty (100%) rename app/View/{elements/email => emails}/text/empty (100%) rename app/View/layouts/{email => emails}/html/empty (100%) rename app/View/layouts/{email => emails}/text/empty (100%) rename lib/Cake/Console/templates/skel/View/{elements/email => emails}/html/default.ctp (100%) rename lib/Cake/Console/templates/skel/View/{elements/email => emails}/text/default.ctp (100%) rename lib/Cake/Console/templates/skel/View/layouts/{email => emails}/html/default.ctp (100%) rename lib/Cake/Console/templates/skel/View/layouts/{email => emails}/text/default.ctp (100%) rename lib/Cake/View/{elements/email => emails}/html/default.ctp (100%) rename lib/Cake/View/{elements/email => emails}/text/default.ctp (100%) rename lib/Cake/View/layouts/{email => emails}/html/default.ctp (100%) rename lib/Cake/View/layouts/{email => emails}/text/default.ctp (100%) rename lib/Cake/tests/test_app/View/{elements/email => emails}/html/custom.ctp (100%) rename lib/Cake/tests/test_app/View/{elements/email => emails}/html/default.ctp (100%) rename lib/Cake/tests/test_app/View/{elements/email => emails}/html/nested_element.ctp (100%) rename lib/Cake/tests/test_app/View/{elements/email => emails}/text/custom.ctp (100%) rename lib/Cake/tests/test_app/View/{elements/email => emails}/text/default.ctp (100%) rename lib/Cake/tests/test_app/View/{elements/email => emails}/text/wide.ctp (100%) rename lib/Cake/tests/test_app/View/layouts/{email => emails}/html/default.ctp (100%) rename lib/Cake/tests/test_app/View/layouts/{email => emails}/html/thin.ctp (100%) rename lib/Cake/tests/test_app/View/layouts/{email => emails}/text/default.ctp (100%) diff --git a/app/View/elements/email/html/empty b/app/View/emails/html/empty similarity index 100% rename from app/View/elements/email/html/empty rename to app/View/emails/html/empty diff --git a/app/View/elements/email/text/empty b/app/View/emails/text/empty similarity index 100% rename from app/View/elements/email/text/empty rename to app/View/emails/text/empty diff --git a/app/View/layouts/email/html/empty b/app/View/layouts/emails/html/empty similarity index 100% rename from app/View/layouts/email/html/empty rename to app/View/layouts/emails/html/empty diff --git a/app/View/layouts/email/text/empty b/app/View/layouts/emails/text/empty similarity index 100% rename from app/View/layouts/email/text/empty rename to app/View/layouts/emails/text/empty diff --git a/lib/Cake/Console/templates/skel/View/elements/email/html/default.ctp b/lib/Cake/Console/templates/skel/View/emails/html/default.ctp similarity index 100% rename from lib/Cake/Console/templates/skel/View/elements/email/html/default.ctp rename to lib/Cake/Console/templates/skel/View/emails/html/default.ctp diff --git a/lib/Cake/Console/templates/skel/View/elements/email/text/default.ctp b/lib/Cake/Console/templates/skel/View/emails/text/default.ctp similarity index 100% rename from lib/Cake/Console/templates/skel/View/elements/email/text/default.ctp rename to lib/Cake/Console/templates/skel/View/emails/text/default.ctp diff --git a/lib/Cake/Console/templates/skel/View/layouts/email/html/default.ctp b/lib/Cake/Console/templates/skel/View/layouts/emails/html/default.ctp similarity index 100% rename from lib/Cake/Console/templates/skel/View/layouts/email/html/default.ctp rename to lib/Cake/Console/templates/skel/View/layouts/emails/html/default.ctp diff --git a/lib/Cake/Console/templates/skel/View/layouts/email/text/default.ctp b/lib/Cake/Console/templates/skel/View/layouts/emails/text/default.ctp similarity index 100% rename from lib/Cake/Console/templates/skel/View/layouts/email/text/default.ctp rename to lib/Cake/Console/templates/skel/View/layouts/emails/text/default.ctp diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 251b179ed..7b49eeeb6 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -1261,14 +1261,13 @@ class CakeEmail { } $View = new $viewClass(null); - $View->layout = $this->_layout; $View->viewVars = $this->_viewVars; $msg = array(); $content = implode("\n", $content); if ($this->_emailFormat === 'both') { - $htmlContent = $content; + $originalContent = $content; if (!empty($this->_attachments)) { $msg[] = '--' . $this->_boundary; $msg[] = 'Content-Type: multipart/alternative; boundary="alt-' . $this->_boundary . '"'; @@ -1279,10 +1278,10 @@ class CakeEmail { $msg[] = 'Content-Transfer-Encoding: 7bit'; $msg[] = ''; - $content = $View->element('email' . DS . 'text' . DS . $this->_template, array('content' => $content), true); - $View->layoutPath = 'email' . DS . 'text'; - $content = explode("\n", $this->_textMessage = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($content))); - + $View->viewPath = $View->layoutPath = 'emails' . DS . 'text'; + $View->viewVars['content'] = $originalContent; + $this->_textMessage = str_replace(array("\r\n", "\r"), "\n", $View->render($this->_template, $this->_layout)); + $content = explode("\n", $this->_textMessage); $msg = array_merge($msg, $content); $msg[] = ''; @@ -1291,10 +1290,13 @@ class CakeEmail { $msg[] = 'Content-Transfer-Encoding: 7bit'; $msg[] = ''; - $htmlContent = $View->element('email' . DS . 'html' . DS . $this->_template, array('content' => $htmlContent), true); - $View->layoutPath = 'email' . DS . 'html'; - $htmlContent = explode("\n", $this->_htmlMessage = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($htmlContent))); - $msg = array_merge($msg, $htmlContent); + $View->viewPath = $View->layoutPath = 'emails' . DS . 'html'; + $View->viewVars['content'] = $originalContent; + $View->hasRendered = false; + $this->_htmlMessage = str_replace(array("\r\n", "\r"), "\n", $View->render($this->_template, $this->_layout)); + $content = explode("\n", $this->_htmlMessage); + $msg = array_merge($msg, $content); + $msg[] = ''; $msg[] = '--alt-' . $this->_boundary . '--'; $msg[] = ''; @@ -1317,9 +1319,10 @@ class CakeEmail { } } - $content = $View->element('email' . DS . $this->_emailFormat . DS . $this->_template, array('content' => $content), true); - $View->layoutPath = 'email' . DS . $this->_emailFormat; - $content = explode("\n", $rendered = str_replace(array("\r\n", "\r"), "\n", $View->renderLayout($content))); + $View->viewPath = $View->layoutPath = 'emails' . DS . $this->_emailFormat; + $View->viewVars['content'] = $content; + $rendered = $View->render($this->_template, $this->_layout); + $content = explode("\n", $rendered); if ($this->_emailFormat === 'html') { $this->_htmlMessage = $rendered; diff --git a/lib/Cake/View/elements/email/html/default.ctp b/lib/Cake/View/emails/html/default.ctp similarity index 100% rename from lib/Cake/View/elements/email/html/default.ctp rename to lib/Cake/View/emails/html/default.ctp diff --git a/lib/Cake/View/elements/email/text/default.ctp b/lib/Cake/View/emails/text/default.ctp similarity index 100% rename from lib/Cake/View/elements/email/text/default.ctp rename to lib/Cake/View/emails/text/default.ctp diff --git a/lib/Cake/View/layouts/email/html/default.ctp b/lib/Cake/View/layouts/emails/html/default.ctp similarity index 100% rename from lib/Cake/View/layouts/email/html/default.ctp rename to lib/Cake/View/layouts/emails/html/default.ctp diff --git a/lib/Cake/View/layouts/email/text/default.ctp b/lib/Cake/View/layouts/emails/text/default.ctp similarity index 100% rename from lib/Cake/View/layouts/email/text/default.ctp rename to lib/Cake/View/layouts/emails/text/default.ctp diff --git a/lib/Cake/tests/test_app/View/elements/email/html/custom.ctp b/lib/Cake/tests/test_app/View/emails/html/custom.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/elements/email/html/custom.ctp rename to lib/Cake/tests/test_app/View/emails/html/custom.ctp diff --git a/lib/Cake/tests/test_app/View/elements/email/html/default.ctp b/lib/Cake/tests/test_app/View/emails/html/default.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/elements/email/html/default.ctp rename to lib/Cake/tests/test_app/View/emails/html/default.ctp diff --git a/lib/Cake/tests/test_app/View/elements/email/html/nested_element.ctp b/lib/Cake/tests/test_app/View/emails/html/nested_element.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/elements/email/html/nested_element.ctp rename to lib/Cake/tests/test_app/View/emails/html/nested_element.ctp diff --git a/lib/Cake/tests/test_app/View/elements/email/text/custom.ctp b/lib/Cake/tests/test_app/View/emails/text/custom.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/elements/email/text/custom.ctp rename to lib/Cake/tests/test_app/View/emails/text/custom.ctp diff --git a/lib/Cake/tests/test_app/View/elements/email/text/default.ctp b/lib/Cake/tests/test_app/View/emails/text/default.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/elements/email/text/default.ctp rename to lib/Cake/tests/test_app/View/emails/text/default.ctp diff --git a/lib/Cake/tests/test_app/View/elements/email/text/wide.ctp b/lib/Cake/tests/test_app/View/emails/text/wide.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/elements/email/text/wide.ctp rename to lib/Cake/tests/test_app/View/emails/text/wide.ctp diff --git a/lib/Cake/tests/test_app/View/layouts/email/html/default.ctp b/lib/Cake/tests/test_app/View/layouts/emails/html/default.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/layouts/email/html/default.ctp rename to lib/Cake/tests/test_app/View/layouts/emails/html/default.ctp diff --git a/lib/Cake/tests/test_app/View/layouts/email/html/thin.ctp b/lib/Cake/tests/test_app/View/layouts/emails/html/thin.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/layouts/email/html/thin.ctp rename to lib/Cake/tests/test_app/View/layouts/emails/html/thin.ctp diff --git a/lib/Cake/tests/test_app/View/layouts/email/text/default.ctp b/lib/Cake/tests/test_app/View/layouts/emails/text/default.ctp similarity index 100% rename from lib/Cake/tests/test_app/View/layouts/email/text/default.ctp rename to lib/Cake/tests/test_app/View/layouts/emails/text/default.ctp From ddb54b67dfd52d80114bac66f9578595e0042223 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Thu, 21 Apr 2011 00:00:58 -0400 Subject: [PATCH 100/103] Updated the method name in email component. --- lib/Cake/Controller/Component/EmailComponent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index eba5637b8..9c6caa808 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -348,7 +348,7 @@ class EmailComponent extends Component { if ($layout) { $this->layout = $layout; } - $lib->layout($this->layout, $this->template)->viewVars($this->_controller->viewVars)->emailFormat($this->sendAs); + $lib->template($this->template, $this->layout)->viewVars($this->_controller->viewVars)->emailFormat($this->sendAs); if (!empty($this->attachments)) { $lib->attachments($this->_formatAttachFiles()); From 636b48024dbfe32a5af781045683db95c7ff9f31 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Thu, 21 Apr 2011 00:09:33 -0400 Subject: [PATCH 101/103] Updated the EmailComponent test to be compatible with CakeEmail changes. --- .../Case/Controller/Component/EmailComponentTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php index f1a023bef..b70c46511 100644 --- a/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php +++ b/lib/Cake/tests/Case/Controller/Component/EmailComponentTest.php @@ -210,6 +210,7 @@ From: noreply@example.com Reply-To: noreply@example.com X-Mailer: CakePHP Email Component Date: $date +MIME-Version: 1.0 Content-Type: {CONTENTTYPE} Content-Transfer-Encoding: 7bitMessage: @@ -232,7 +233,7 @@ MSGBLOC; $this->Controller->EmailTest->sendAs = 'both'; $expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $message); $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); + $this->assertEqual(preg_replace('/alt-[a-z0-9]{32}/i', 'alt-', DebugCompTransport::$lastEmail), $this->__osFix($expect)); } /** @@ -263,6 +264,7 @@ From: noreply@example.com Reply-To: noreply@example.com X-Mailer: CakePHP Email Component Date: $date +MIME-Version: 1.0 Content-Type: {CONTENTTYPE} Content-Transfer-Encoding: 7bitMessage: @@ -312,7 +314,7 @@ HTMLBLOC; $expect = '
' . $expect . '--alt---' . "\n\n" . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual(DebugCompTransport::$lastEmail, $this->__osFix($expect)); + $this->assertEqual(preg_replace('/alt-[a-z0-9]{32}/i', 'alt-', DebugCompTransport::$lastEmail), $this->__osFix($expect)); $html = << @@ -752,7 +754,7 @@ HTMLBLOC; * @return void */ function testReset() { - $this->Controller->EmailTest->template = 'test_template'; + $this->Controller->EmailTest->template = 'default'; $this->Controller->EmailTest->to = 'test.recipient@example.com'; $this->Controller->EmailTest->from = 'test.sender@example.com'; $this->Controller->EmailTest->replyTo = 'test.replyto@example.com'; From 6a7b42f1ebd55f1b2abef191001a9153064597db Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Fri, 22 Apr 2011 22:41:52 -0400 Subject: [PATCH 102/103] Renamed the default X-Mailer value. --- lib/Cake/Controller/Component/EmailComponent.php | 2 +- lib/Cake/Network/CakeEmail.php | 6 ++---- lib/Cake/tests/Case/Network/CakeEmailTest.php | 8 ++++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php index 9c6caa808..2311f0d55 100644 --- a/lib/Cake/Controller/Component/EmailComponent.php +++ b/lib/Cake/Controller/Component/EmailComponent.php @@ -333,7 +333,7 @@ class EmailComponent extends Component { $lib->subject($this->subject)->messageID($this->messageId); - $headers = array(); + $headers = array('X-Mailer' => $this->xMailer); foreach ($this->headers as $key => $value) { $headers['X-' . $key] = $value; } diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/CakeEmail.php index 7b49eeeb6..21c1540a9 100644 --- a/lib/Cake/Network/CakeEmail.php +++ b/lib/Cake/Network/CakeEmail.php @@ -32,11 +32,11 @@ App::uses('View', 'View'); */ class CakeEmail { /** - * What mailer should EmailComponent identify itself as + * Default X-Mailer * * @constant EMAIL_CLIENT */ - const EMAIL_CLIENT = 'CakePHP Email Component'; + const EMAIL_CLIENT = 'CakePHP Email'; /** * Line length - no should more - RFC 2822 - 2.1.1 @@ -943,9 +943,7 @@ class CakeEmail { if (!empty($this->_attachments)) { $this->_attachFiles(); - } - if (!empty($this->_attachments)) { $this->_message[] = ''; $this->_message[] = '--' . $this->_boundary . '--'; $this->_message[] = ''; diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 922761310..89d7f1838 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -390,7 +390,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->setHeaders(array('X-Something' => 'nice')); $expected = array( 'X-Something' => 'nice', - 'X-Mailer' => 'CakePHP Email Component', + 'X-Mailer' => 'CakePHP Email', 'Date' => date(DATE_RFC2822), 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8', @@ -402,7 +402,7 @@ class CakeEmailTest extends CakeTestCase { $expected = array( 'X-Something' => 'very nice', 'X-Other' => 'cool', - 'X-Mailer' => 'CakePHP Email Component', + 'X-Mailer' => 'CakePHP Email', 'Date' => date(DATE_RFC2822), 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8', @@ -417,7 +417,7 @@ class CakeEmailTest extends CakeTestCase { 'From' => 'cake@cakephp.org', 'X-Something' => 'very nice', 'X-Other' => 'cool', - 'X-Mailer' => 'CakePHP Email Component', + 'X-Mailer' => 'CakePHP Email', 'Date' => date(DATE_RFC2822), 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8', @@ -435,7 +435,7 @@ class CakeEmailTest extends CakeTestCase { 'To' => 'cake@cakephp.org, CakePHP ', 'X-Something' => 'very nice', 'X-Other' => 'cool', - 'X-Mailer' => 'CakePHP Email Component', + 'X-Mailer' => 'CakePHP Email', 'Date' => date(DATE_RFC2822), 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8', From dc7808e63a2ae14f0a4acbe9fea27b268368e977 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sat, 23 Apr 2011 22:29:05 -0400 Subject: [PATCH 103/103] Changed to use only the CAKE constant. --- lib/Cake/tests/Case/Network/CakeEmailTest.php | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/CakeEmailTest.php index 89d7f1838..d44a602b9 100644 --- a/lib/Cake/tests/Case/Network/CakeEmailTest.php +++ b/lib/Cake/tests/Case/Network/CakeEmailTest.php @@ -136,7 +136,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail = new TestCakeEmail(); App::build(array( - 'views' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'View'. DS) + 'views' => array(CAKE . 'tests' . DS . 'test_app' . DS . 'View'. DS) )); } @@ -491,22 +491,22 @@ class CakeEmailTest extends CakeTestCase { * @return void */ public function testAttachments() { - $this->CakeEmail->attachments(WWW_ROOT . 'index.php'); - $expected = array('index.php' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'application/octet-stream')); + $this->CakeEmail->attachments(CAKE . 'basics.php'); + $expected = array('basics.php' => array('file' => CAKE . 'basics.php', 'mimetype' => 'application/octet-stream')); $this->assertIdentical($this->CakeEmail->attachments(), $expected); $this->CakeEmail->attachments(array()); $this->assertIdentical($this->CakeEmail->attachments(), array()); - $this->CakeEmail->attachments(array(array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain'))); - $this->CakeEmail->addAttachments(WWW_ROOT . 'test.php'); - $this->CakeEmail->addAttachments(array(WWW_ROOT . 'test.php')); - $this->CakeEmail->addAttachments(array('other.txt' => WWW_ROOT . 'test.php', 'ht' => WWW_ROOT . '.htaccess')); + $this->CakeEmail->attachments(array(array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain'))); + $this->CakeEmail->addAttachments(CAKE . 'bootstrap.php'); + $this->CakeEmail->addAttachments(array(CAKE . 'bootstrap.php')); + $this->CakeEmail->addAttachments(array('other.txt' => CAKE . 'bootstrap.php', 'license' => CAKE . 'LICENSE.txt')); $expected = array( - 'index.php' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain'), - 'test.php' => array('file' => WWW_ROOT . 'test.php', 'mimetype' => 'application/octet-stream'), - 'other.txt' => array('file' => WWW_ROOT . 'test.php', 'mimetype' => 'application/octet-stream'), - 'ht' => array('file' => WWW_ROOT . '.htaccess', 'mimetype' => 'application/octet-stream') + 'basics.php' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain'), + 'bootstrap.php' => array('file' => CAKE . 'bootstrap.php', 'mimetype' => 'application/octet-stream'), + 'other.txt' => array('file' => CAKE . 'bootstrap.php', 'mimetype' => 'application/octet-stream'), + 'license' => array('file' => CAKE . 'LICENSE.txt', 'mimetype' => 'application/octet-stream') ); $this->assertIdentical($this->CakeEmail->attachments(), $expected); } @@ -669,19 +669,19 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->to(array('you@cakephp.org' => 'You')); $this->CakeEmail->subject('My title'); $this->CakeEmail->config(array()); - $this->CakeEmail->attachments(array(WWW_ROOT . 'index.php')); + $this->CakeEmail->attachments(array(CAKE . 'basics.php')); $this->CakeEmail->send('body'); - $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"index.php\"")); + $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"basics.php\"")); - $this->CakeEmail->attachments(array('my.file.txt' => WWW_ROOT . 'index.php')); + $this->CakeEmail->attachments(array('my.file.txt' => CAKE . 'basics.php')); $this->CakeEmail->send('body'); $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"my.file.txt\"")); - $this->CakeEmail->attachments(array('file.txt' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain'))); + $this->CakeEmail->attachments(array('file.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain'))); $this->CakeEmail->send('body'); $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"file.txt\"")); - $this->CakeEmail->attachments(array('file.txt' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain', 'contentId' => 'a1b1c1'))); + $this->CakeEmail->attachments(array('file.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain', 'contentId' => 'a1b1c1'))); $this->CakeEmail->send('body'); $this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-ID: \r\nContent-Disposition: inline; filename=\"file.txt\"")); }