From 492f35621c213535c38156cfd74952cc58c51791 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Tue, 22 Oct 2013 17:22:08 +0300 Subject: [PATCH 01/31] Email components hierarchy created. SwiftMailer applied as email solution. --- .travis.yml | 2 +- framework/yii/email/BaseMailer.php | 125 ++++++++++++++++ framework/yii/email/BaseMessage.php | 125 ++++++++++++++++ framework/yii/email/Message.php | 34 +++++ framework/yii/email/swift/Mailer.php | 180 +++++++++++++++++++++++ framework/yii/email/swift/Message.php | 116 +++++++++++++++ framework/yii/email/swift/autoload.php | 9 ++ tests/unit/framework/email/BaseMailerTest.php | 97 ++++++++++++ tests/unit/framework/email/swift/MailerTest.php | 90 ++++++++++++ tests/unit/framework/email/swift/MessageTest.php | 40 +++++ 10 files changed, 817 insertions(+), 1 deletion(-) create mode 100644 framework/yii/email/BaseMailer.php create mode 100644 framework/yii/email/BaseMessage.php create mode 100644 framework/yii/email/Message.php create mode 100644 framework/yii/email/swift/Mailer.php create mode 100644 framework/yii/email/swift/Message.php create mode 100644 framework/yii/email/swift/autoload.php create mode 100644 tests/unit/framework/email/BaseMailerTest.php create mode 100644 tests/unit/framework/email/swift/MailerTest.php create mode 100644 tests/unit/framework/email/swift/MessageTest.php diff --git a/.travis.yml b/.travis.yml index a905b36..0218654 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_script: - tests/unit/data/travis/cubrid-setup.sh script: - - phpunit --coverage-clover tests/unit/runtime/coveralls/clover.xml --verbose --exclude-group mssql,oci,wincache,xcache,zenddata + - phpunit --coverage-clover tests/unit/runtime/coveralls/clover.xml --verbose --exclude-group mssql,oci,wincache,xcache,zenddata,swiftmailer after_script: - php vendor/bin/coveralls diff --git a/framework/yii/email/BaseMailer.php b/framework/yii/email/BaseMailer.php new file mode 100644 index 0000000..92fa3df --- /dev/null +++ b/framework/yii/email/BaseMailer.php @@ -0,0 +1,125 @@ + + * @since 2.0 + */ +abstract class BaseMailer extends Component +{ + /** + * @var \yii\base\View|array view instance or its array configuration. + */ + private $_view = []; + /** + * @var array configuration, which should be applied by default to any new created + * email message instance. + * For example: + * ~~~ + * array( + * 'encoding' => 'UTF-8', + * 'from' => 'noreply@mydomain.com', + * 'bcc' => 'email.test@mydomain.com', + * ) + * ~~~ + */ + private $_defaultMessageConfig = []; + + /** + * @param array|\yii\base\View $view view instance or its array configuration. + * @throws \yii\base\InvalidConfigException on invalid argument. + */ + public function setView($view) + { + if (!is_array($view) && !is_object($view)) { + throw new InvalidConfigException('"' . get_class($this) . '::view" should be either object or array, "' . gettype($view) . '" given.'); + } + $this->_view = $view; + } + + /** + * @return \yii\base\View view instance. + */ + public function getView() + { + if (!is_object($this->_view)) { + $this->_view = $this->createView($this->_view); + } + return $this->_view; + } + + /** + * @param array $defaultMessageConfig default message config + */ + public function setDefaultMessageConfig(array $defaultMessageConfig) + { + $this->_defaultMessageConfig = $defaultMessageConfig; + } + + /** + * @return array default message config + */ + public function getDefaultMessageConfig() + { + return $this->_defaultMessageConfig; + } + + /** + * Creates view instance from given configuration. + * @param array $config view configuration. + * @return \yii\base\View view instance. + */ + protected function createView(array $config) + { + if (!array_key_exists('class', $config)) { + $config['class'] = '\yii\base\View'; + } + $config['context'] = $this; + return Yii::createObject($config); + } + + /** + * Sends the given email message. + * @param object $message email message instance + * @return boolean whether the message has been sent. + */ + abstract public function send($message); + + /** + * Sends a couple of messages at once. + * Note: some particular mailers may benefit from sending messages as batch, + * saving resources, for example on open/close connection operations, + * they may override this method to create their specific implementation. + * @param array $messages list of email messages, which should be sent. + * @return integer number of successfull sends + */ + public function sendMultiple(array $messages) { + $successCount = 0; + foreach ($messages as $message) { + if ($this->send($message)) { + $successCount++; + } + } + return $successCount; + } +} \ No newline at end of file diff --git a/framework/yii/email/BaseMessage.php b/framework/yii/email/BaseMessage.php new file mode 100644 index 0000000..8127c9c --- /dev/null +++ b/framework/yii/email/BaseMessage.php @@ -0,0 +1,125 @@ + + * @since 2.0 + */ +abstract class BaseMessage extends Object +{ + /** + * @return \yii\email\BaseMailer + */ + public function getMailer() + { + return Yii::$app->getComponent('email'); + } + + /** + * Initializes the object. + * This method is invoked at the end of the constructor after the object is initialized with the + * given configuration. + */ + public function init() + { + Yii::configure($this, $this->getMailer()->getDefaultMessageConfig()); + } + + /** + * Sends this email message. + * @return boolean success. + */ + public function send() + { + return $this->getMailer()->send($this); + } + + /** + * Sets message sender. + * @param string|array $from sender email address, if array is given, + * its first element should be sender email address, second - sender name. + */ + abstract public function setFrom($from); + + /** + * Sets message receiver. + * @param string|array $to receiver email address, if array is given, + * its first element should be receiver email address, second - receiver name. + */ + abstract public function setTo($to); + + /** + * Sets message subject. + * @param string $subject message subject + */ + abstract public function setSubject($subject); + + /** + * Sets message plain text content. + * @param string $text message plain text content. + */ + abstract public function setText($text); + + /** + * Sets message HTML content. + * @param string $html message HTML content. + */ + abstract public function setHtml($html); + + /** + * Create file attachment for the email message. + * @param string $content attachment file content. + * @param string $fileName attachment file name. + * @param string $contentType MIME type of the attachment file, by default 'application/octet-stream' will be used. + */ + abstract public function createAttachment($content, $fileName, $contentType = 'application/octet-stream'); + + /** + * Attaches existing file to the email message. + * @param string $fileName full file name + * @param string $contentType MIME type of the attachment file, if empty it will be suggested automatically. + * @param string $attachFileName name, which should be used for attachment, if empty file base name will be used. + * @throws \yii\base\InvalidParamException if given file does not exist. + */ + public function attachFile($fileName, $contentType = null, $attachFileName = null) + { + if (!file_exists($fileName)) { + throw new InvalidParamException('Unable to attach file "' . $fileName . '": file does not exists!'); + } + if (empty($contentType)) { + $contentType = FileHelper::getMimeType($fileName); + } + if (empty($attachFileName)) { + $attachFileName = basename($fileName); + } + $content = file_get_contents($fileName); + $this->createAttachment($content, $attachFileName, $contentType); + } +} \ No newline at end of file diff --git a/framework/yii/email/Message.php b/framework/yii/email/Message.php new file mode 100644 index 0000000..c7ec534 --- /dev/null +++ b/framework/yii/email/Message.php @@ -0,0 +1,34 @@ +from = 'sender@domain.com'; + * $email->to = 'receiver@domain.com'; + * $email->subject = 'Message Subject'; + * $email->text = 'Message Content'; + * $email->send(); + * ~~~ + * + * This particular class uses 'SwiftMailer' library to perform the message sending. + * Note: you can replace usage of this class by your own one, using [[Yii::$classMap]]: + * ~~~ + * Yii::$classMap['yii\email\Message'] = '/path/to/my/email/Message.php' + * ~~~ + * + * @author Paul Klimov + * @since 2.0 + */ +class Message extends SwiftMessage {} \ No newline at end of file diff --git a/framework/yii/email/swift/Mailer.php b/framework/yii/email/swift/Mailer.php new file mode 100644 index 0000000..1f589a2 --- /dev/null +++ b/framework/yii/email/swift/Mailer.php @@ -0,0 +1,180 @@ + array( + * ... + * 'email' => array( + * 'class' => 'yii\email\swift\Mailer', + * 'transport' => [ + * 'class' => 'Swift_SmtpTransport', + * 'host' => 'localhost', + * 'username' => 'username', + * 'password' => 'password', + * 'port' => '587', + * 'encryption' => 'tls', + * ], + * ), + * ... + * ), + * ~~~ + * + * @see http://swiftmailer.org + * + * @author Paul Klimov + * @since 2.0 + */ +class Mailer extends BaseMailer +{ + /** + * @var string|callback SwiftMailer autoloader callback or path to autoloader file. + * If the SwiftMailer classes autoloading is already managed in some other place, + * for example via Composer, you should leave this field blank. + */ + public $autoload; + /** + * @var \Swift_Mailer Swift mailer instance. + */ + private $_swiftMailer; + /** + * @var \Swift_Transport|array Swift transport instance or its array configuration. + */ + private $_transport = []; + + /** + * @return array|\Swift_Mailer Swift mailer instance or array configuration. + */ + public function getSwiftMailer() + { + if (!is_object($this->_swiftMailer)) { + $this->_swiftMailer = $this->createSwiftMailer(); + } + return $this->_swiftMailer; + } + + /** + * @param array|\Swift_Transport $transport + * @throws \yii\base\InvalidConfigException on invalid argument. + */ + public function setTransport($transport) + { + if (!is_array($transport) && !is_object($transport)) { + throw new InvalidConfigException('"' . get_class($this) . '::transport" should be either object or array, "' . gettype($transport) . '" given.'); + } + $this->_transport = $transport; + } + + /** + * @return array|\Swift_Transport + */ + public function getTransport() + { + if (!is_object($this->_transport)) { + $this->_transport = $this->createTransport($this->_transport); + } + return $this->_transport; + } + + /** + * @inheritdoc + */ + public function init() + { + $this->setupSwiftMailerAutoload(); + } + + /** + * Sets up the SwiftMailer autoloader, if it is specified. + */ + protected function setupSwiftMailerAutoload() + { + if (!class_exists('Swift', false)) { + if (empty($this->autoload)) { + $this->autoload = __DIR__ . '/autoload.php'; + } + if (is_string($this->autoload)) { + if (file_exists($this->autoload)) { + require_once($this->autoload); + } elseif (function_exists($this->autoload)) { + spl_autoload_register($this->autoload); + } else { + throw new InvalidConfigException('"' . get_class($this) . '::autoload" value "' . $this->autoload . '" is invalid: no such function or file exists.'); + } + } else { + spl_autoload_register($this->autoload); + } + } + } + + /** + * @inheritdoc + */ + public function send($message) + { + return ($this->getSwiftMailer()->send($message->getSwiftMessage()) > 0); + } + + /** + * Creates Swift mailer instance. + * @return \Swift_Mailer mailer instance. + */ + protected function createSwiftMailer() + { + return \Swift_Mailer::newInstance($this->getTransport()); + } + + /** + * Creates email transport instance by its array configuration. + * @param array $config transport configuration. + * @throws \yii\base\InvalidConfigException on invalid transport configuration. + * @return \Swift_Transport transport instance. + */ + protected function createTransport(array $config) + { + if (array_key_exists('class', $config)) { + $className = $config['class']; + unset($config['class']); + } else { + $className = 'Swift_MailTransport'; + } + $transport = call_user_func([$className, 'newInstance']); + if (!empty($config)) { + foreach ($config as $name => $value) { + if (property_exists($transport, $name)) { + $transport->$name = $value; + } else { + $setter = 'set' . $name; + if (method_exists($transport, $setter)) { + $transport->$setter($value); + } else { + throw new InvalidConfigException('Setting unknown property: ' . get_class($transport) . '::' . $name); + } + } + } + } + return $transport; + } + + /** + * Creates the Swift email message instance. + * @return \Swift_Message email message instance. + */ + public function createSwiftMessage() + { + return new \Swift_Message(); + } +} \ No newline at end of file diff --git a/framework/yii/email/swift/Message.php b/framework/yii/email/swift/Message.php new file mode 100644 index 0000000..49a4b75 --- /dev/null +++ b/framework/yii/email/swift/Message.php @@ -0,0 +1,116 @@ + + * @since 2.0 + */ +class Message extends BaseMessage +{ + /** + * @var \Swift_Message Swift message instance. + */ + private $_swiftMessage; + + /** + * @return \Swift_Message Swift message instance. + */ + public function getSwiftMessage() + { + if (!is_object($this->_swiftMessage)) { + $this->_swiftMessage = $this->getMailer()->createSwiftMessage(); + } + return $this->_swiftMessage; + } + + /** + * Sets message sender. + * @param string|array $from sender email address, if array is given, + * its first element should be sender email address, second - sender name. + */ + public function setFrom($from) + { + if (is_array($from)) { + list ($address, $name) = $from; + } else { + $address = $from; + $name = null; + } + $this->getSwiftMessage()->setFrom($address, $name); + $this->getSwiftMessage()->setReplyTo($address, $name); + } + + /** + * Sets message receiver. + * @param string|array $to receiver email address, if array is given, + * its first element should be receiver email address, second - receiver name. + */ + public function setTo($to) + { + if (is_array($to)) { + list ($address, $name) = $to; + } else { + $address = $to; + $name = null; + } + $this->getSwiftMessage()->setTo($address, $name); + } + + /** + * Sets message subject. + * @param string $subject message subject + */ + public function setSubject($subject) + { + $this->getSwiftMessage()->setSubject($subject); + } + + /** + * Sets message plain text content. + * @param string $text message plain text content. + */ + public function setText($text) + { + $this->getSwiftMessage()->setBody($text, 'text/plain'); + } + + /** + * Sets message HTML content. + * @param string $html message HTML content. + */ + public function setHtml($html) + { + $this->getSwiftMessage()->setBody($html, 'text/html'); + } + + /** + * Create file attachment for the email message. + * @param string $content - attachment file content. + * @param string $fileName - attachment file name. + * @param string $contentType - MIME type of the attachment file, by default 'application/octet-stream' will be used. + */ + public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') + { + if (empty($contentType)) { + $contentType = 'application/octet-stream'; + } + $attachment = \Swift_Attachment::newInstance($content, $fileName, $contentType); + $this->getSwiftMessage()->attach($attachment); + } +} \ No newline at end of file diff --git a/framework/yii/email/swift/autoload.php b/framework/yii/email/swift/autoload.php new file mode 100644 index 0000000..494150f --- /dev/null +++ b/framework/yii/email/swift/autoload.php @@ -0,0 +1,9 @@ +mockApplication(); + Yii::$app->setComponent('email', $this->createTestEmailComponent()); + } + + /** + * @return Mailer test email component instance. + */ + protected function createTestEmailComponent() + { + $component = new Mailer(); + return $component; + } + + // Tests : + + public function testSetupView() + { + $mailer = new Mailer(); + + $view = new View(); + $mailer->setView($view); + $this->assertEquals($view, $mailer->getView(), 'Unable to setup view!'); + } + + public function testGetDefaultView() + { + $mailer = new Mailer(); + $view = $mailer->getView(); + $this->assertTrue(is_object($view), 'Unable to get default view!'); + } + + public function testDefaultMessageConfig() + { + $defaultMessageConfig = array( + 'id' => 'test-id', + 'encoding' => 'test-encoding', + ); + Yii::$app->getComponent('email')->setDefaultMessageConfig($defaultMessageConfig); + + $message = new Message(); + + foreach ($defaultMessageConfig as $name => $value) { + $this->assertEquals($value, $message->$name); + } + } +} + +/** + * Test Mailer class + */ +class Mailer extends BaseMailer +{ + public $sentMessages = array(); + + public function send($message) + { + $this->sentMessages[] = $message; + } +} + +/** + * Test Message class + */ +class Message extends BaseMessage +{ + public $id; + public $encoding; + + public function setFrom($from) {} + + public function setTo($to) {} + + public function setSubject($subject) {} + + public function setText($text) {} + + public function setHtml($html) {} + + public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') {} +} \ No newline at end of file diff --git a/tests/unit/framework/email/swift/MailerTest.php b/tests/unit/framework/email/swift/MailerTest.php new file mode 100644 index 0000000..f984139 --- /dev/null +++ b/tests/unit/framework/email/swift/MailerTest.php @@ -0,0 +1,90 @@ +mockApplication(array( + 'vendorPath' => Yii::getAlias('@yiiunit/vendor') + )); + Yii::$app->setComponent('email', $this->createTestEmailComponent()); + } + + /** + * @return Mailer test email component instance. + */ + protected function createTestEmailComponent() + { + $component = new Mailer(); + return $component; + } + + // Tests : + + public function testSetupTransport() + { + $mailer = new Mailer(); + + $transport = \Swift_MailTransport::newInstance(); + $mailer->setTransport($transport); + $this->assertEquals($transport, $mailer->getTransport(), 'Unable to setup transport!'); + } + + /** + * @depends testSetupTransport + */ + public function testConfigureTransport() + { + $mailer = new Mailer(); + + $transportConfig = [ + 'class' => 'Swift_SmtpTransport', + 'host' => 'localhost', + ]; + $mailer->setTransport($transportConfig); + $transport = $mailer->getTransport(); + $this->assertTrue(is_object($transport), 'Unable to setup transport via config!'); + $this->assertEquals($transportConfig['class'], get_class($transport), 'Invalid transport class!'); + $this->assertEquals($transportConfig['host'], $transport->getHost(), 'Invalid transport host!'); + } + + public function testGetSwiftMailer() + { + $mailer = new Mailer(); + $this->assertTrue(is_object($mailer->getSwiftMailer()), 'Unable to get Swift mailer instance!'); + } + + public function testCreateSwiftMessage() + { + $mailer = new Mailer(); + $message = $mailer->createSwiftMessage(); + $this->assertTrue(is_object($message), 'Unable to create Swift message instance!'); + } + + /** + * @depends testGetSwiftMailer + * @depends testCreateSwiftMessage + */ + public function testSend() + { + $emailAddress = 'someuser@somedomain.com'; + $message = new Message(); + $message->setTo($emailAddress); + $message->setFrom($emailAddress); + $message->setSubject('Yii Swift Test'); + $message->setText('Yii Swift Test body'); + $message->send(); + $this->assertTrue(true); + } +} \ No newline at end of file diff --git a/tests/unit/framework/email/swift/MessageTest.php b/tests/unit/framework/email/swift/MessageTest.php new file mode 100644 index 0000000..50742c9 --- /dev/null +++ b/tests/unit/framework/email/swift/MessageTest.php @@ -0,0 +1,40 @@ +mockApplication(array( + 'vendorPath' => Yii::getAlias('@yiiunit/vendor') + )); + Yii::$app->setComponent('email', $this->createTestEmailComponent()); + } + + /** + * @return Mailer test email component instance. + */ + protected function createTestEmailComponent() + { + $component = new Mailer(); + return $component; + } + + // Tests : + + public function testGetSwiftMessage() + { + $message = new Message(); + $this->assertTrue(is_object($message->getSwiftMessage()), 'Unable to get Swift message!'); + } +} \ No newline at end of file From 88126bc4d3147a4bef44c17b55935616b57af041 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Wed, 23 Oct 2013 12:19:01 +0300 Subject: [PATCH 02/31] Unit tests for \yii\email\swift have been improved. Methods 'addText' and 'addHtml' added to \yii\email\BaseMessage. --- framework/yii/email/BaseMessage.php | 12 +++++ framework/yii/email/swift/Message.php | 18 +++++++ tests/unit/framework/email/BaseMailerTest.php | 4 ++ tests/unit/framework/email/swift/MailerTest.php | 16 ------- tests/unit/framework/email/swift/MessageTest.php | 60 ++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 16 deletions(-) diff --git a/framework/yii/email/BaseMessage.php b/framework/yii/email/BaseMessage.php index 8127c9c..506563b 100644 --- a/framework/yii/email/BaseMessage.php +++ b/framework/yii/email/BaseMessage.php @@ -94,6 +94,18 @@ abstract class BaseMessage extends Object abstract public function setHtml($html); /** + * Add message plain text content part. + * @param string $text message plain text content. + */ + abstract public function addText($text); + + /** + * Add message HTML content part. + * @param string $html message HTML content. + */ + abstract public function addHtml($html); + + /** * Create file attachment for the email message. * @param string $content attachment file content. * @param string $fileName attachment file name. diff --git a/framework/yii/email/swift/Message.php b/framework/yii/email/swift/Message.php index 49a4b75..5b8c575 100644 --- a/framework/yii/email/swift/Message.php +++ b/framework/yii/email/swift/Message.php @@ -100,6 +100,24 @@ class Message extends BaseMessage } /** + * Add message plain text content part. + * @param string $text message plain text content. + */ + public function addText($text) + { + $this->getSwiftMessage()->addPart($text, 'text/plain'); + } + + /** + * Add message HTML content part. + * @param string $html message HTML content. + */ + public function addHtml($html) + { + $this->getSwiftMessage()->addPart($html, 'text/html'); + } + + /** * Create file attachment for the email message. * @param string $content - attachment file content. * @param string $fileName - attachment file name. diff --git a/tests/unit/framework/email/BaseMailerTest.php b/tests/unit/framework/email/BaseMailerTest.php index 8418d2b..178028b 100644 --- a/tests/unit/framework/email/BaseMailerTest.php +++ b/tests/unit/framework/email/BaseMailerTest.php @@ -93,5 +93,9 @@ class Message extends BaseMessage public function setHtml($html) {} + public function addText($text) {} + + public function addHtml($html) {} + public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') {} } \ No newline at end of file diff --git a/tests/unit/framework/email/swift/MailerTest.php b/tests/unit/framework/email/swift/MailerTest.php index f984139..f9cee72 100644 --- a/tests/unit/framework/email/swift/MailerTest.php +++ b/tests/unit/framework/email/swift/MailerTest.php @@ -71,20 +71,4 @@ class MailerTest extends TestCase $message = $mailer->createSwiftMessage(); $this->assertTrue(is_object($message), 'Unable to create Swift message instance!'); } - - /** - * @depends testGetSwiftMailer - * @depends testCreateSwiftMessage - */ - public function testSend() - { - $emailAddress = 'someuser@somedomain.com'; - $message = new Message(); - $message->setTo($emailAddress); - $message->setFrom($emailAddress); - $message->setSubject('Yii Swift Test'); - $message->setText('Yii Swift Test body'); - $message->send(); - $this->assertTrue(true); - } } \ No newline at end of file diff --git a/tests/unit/framework/email/swift/MessageTest.php b/tests/unit/framework/email/swift/MessageTest.php index 50742c9..112f4fc 100644 --- a/tests/unit/framework/email/swift/MessageTest.php +++ b/tests/unit/framework/email/swift/MessageTest.php @@ -13,6 +13,11 @@ use yiiunit\TestCase; */ class MessageTest extends TestCase { + /** + * @var string test email address, which will be used as receiver for the messages. + */ + protected $testEmailReceiver = 'someuser@somedomain.com'; + public function setUp() { $this->mockApplication(array( @@ -37,4 +42,59 @@ class MessageTest extends TestCase $message = new Message(); $this->assertTrue(is_object($message->getSwiftMessage()), 'Unable to get Swift message!'); } + + /** + * @depends testGetSwiftMessage + */ + public function testSend() + { + $message = new Message(); + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Test'); + $message->setText('Yii Swift Test body'); + $this->assertTrue($message->send()); + } + + /** + * @depends testSend + */ + public function testAttachFile() + { + $message = new Message(); + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Attach File Test'); + $message->setText('Yii Swift Attach File Test body'); + $message->attachFile(__FILE__); + $this->assertTrue($message->send()); + } + + /** + * @depends testSend + */ + public function testCreateAttachment() + { + $message = new Message(); + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Create Attachment Test'); + $message->setText('Yii Swift Create Attachment Test body'); + $message->createAttachment('Test attachment content', 'test.txt'); + $this->assertTrue($message->send()); + } + + /** + * @depends testSend + */ + public function testSendAlternativeBody() + { + $message = new Message(); + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Alternative Body Test'); + $message->addHtml('Yii Swift test HTML body'); + $message->addText('Yii Swift test plain text body'); + $this->assertTrue($message->send()); + } } \ No newline at end of file From e5e0de8c8f25ef4f5cfb515ed8fbc64743ba8569 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Wed, 23 Oct 2013 16:33:25 +0300 Subject: [PATCH 03/31] '\yii\email\ViewResolver' added. Email message render functionality added. --- framework/yii/email/BaseMailer.php | 55 +++++++++++++++- framework/yii/email/BaseMessage.php | 14 ++++ framework/yii/email/ViewResolver.php | 57 ++++++++++++++++ tests/unit/framework/email/BaseMailerTest.php | 86 +++++++++++++++++++++++++ tests/unit/framework/email/ViewResolverTest.php | 57 ++++++++++++++++ 5 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 framework/yii/email/ViewResolver.php create mode 100644 tests/unit/framework/email/ViewResolverTest.php diff --git a/framework/yii/email/BaseMailer.php b/framework/yii/email/BaseMailer.php index 92fa3df..b3b40b3 100644 --- a/framework/yii/email/BaseMailer.php +++ b/framework/yii/email/BaseMailer.php @@ -18,7 +18,8 @@ use Yii; * * @see BaseMessage * - * @property array $view view instance or its array configuration. + * @property \yii\base\View|array $view view instance or its array configuration. + * @property \yii\email\ViewResolver|array $viewResolver view resolver instance or its array configuration. * @property array $defaultMessageConfig configuration, which should be applied by default to any * new created email message instance. * @@ -32,6 +33,10 @@ abstract class BaseMailer extends Component */ private $_view = []; /** + * @var \yii\email\ViewResolver|array view resolver instance or its array configuration. + */ + private $_viewResolver = []; + /** * @var array configuration, which should be applied by default to any new created * email message instance. * For example: @@ -69,6 +74,29 @@ abstract class BaseMailer extends Component } /** + * @param array|\yii\email\ViewResolver $viewResolver view resolver instance or its array configuration. + * @throws \yii\base\InvalidConfigException on invalid argument. + */ + public function setViewResolver($viewResolver) + { + if (!is_array($viewResolver) && !is_object($viewResolver)) { + throw new InvalidConfigException('"' . get_class($this) . '::viewResolver" should be either object or array, "' . gettype($viewResolver) . '" given.'); + } + $this->_viewResolver = $viewResolver; + } + + /** + * @return \yii\email\ViewResolver view resolver. + */ + public function getViewResolver() + { + if (!is_object($this->_viewResolver)) { + $this->_viewResolver = $this->createViewResolver($this->_viewResolver); + } + return $this->_viewResolver; + } + + /** * @param array $defaultMessageConfig default message config */ public function setDefaultMessageConfig(array $defaultMessageConfig) @@ -94,7 +122,19 @@ abstract class BaseMailer extends Component if (!array_key_exists('class', $config)) { $config['class'] = '\yii\base\View'; } - $config['context'] = $this; + return Yii::createObject($config); + } + + /** + * Creates view resolver instance from given configuration. + * @param array $config view resolver configuration. + * @return \yii\email\ViewResolver view resolver instance. + */ + protected function createViewResolver(array $config) + { + if (!array_key_exists('class', $config)) { + $config['class'] = '\yii\email\ViewResolver'; + } return Yii::createObject($config); } @@ -122,4 +162,15 @@ abstract class BaseMailer extends Component } return $successCount; } + + /** + * Renders a view. + * @param string $view the view name or the path alias of the view file. + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return string string the rendering result + */ + public function render($view, $params = []) + { + return $this->getView()->renderFile($this->getViewResolver()->findViewFile($view), $params, $this); + } } \ No newline at end of file diff --git a/framework/yii/email/BaseMessage.php b/framework/yii/email/BaseMessage.php index 506563b..00d27e0 100644 --- a/framework/yii/email/BaseMessage.php +++ b/framework/yii/email/BaseMessage.php @@ -134,4 +134,18 @@ abstract class BaseMessage extends Object $content = file_get_contents($fileName); $this->createAttachment($content, $attachFileName, $contentType); } + + /** + * Renders a view. + * The view to be rendered can be specified in one of the following formats: + * - path alias (e.g. "@app/emails/contact/body"); + * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. + * @param string $view the view name or the path alias of the view file. + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return string string the rendering result + */ + public function render($view, $params = []) + { + return $this->getMailer()->render($view, $params); + } } \ No newline at end of file diff --git a/framework/yii/email/ViewResolver.php b/framework/yii/email/ViewResolver.php new file mode 100644 index 0000000..4f522be --- /dev/null +++ b/framework/yii/email/ViewResolver.php @@ -0,0 +1,57 @@ + + * @since 2.0 + */ +class ViewResolver extends Component +{ + /** + * @var string directory containing view files for this email messages. + */ + public $viewPath = '@app/emails'; + + /** + * Finds the view file based on the given view name. + * The view to be rendered can be specified in one of the following formats: + * - path alias (e.g. "@app/emails/contact/body"); + * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. + * @param string $view the view name or the path alias of the view file. + * @return string the view file path. Note that the file may not exist. + */ + public function findViewFile($view) + { + if (strncmp($view, '@', 1) === 0) { + // e.g. "@app/views/main" + $file = Yii::getAlias($view); + } else { + $file = $this->resolveView($view); + } + return pathinfo($file, PATHINFO_EXTENSION) === '' ? $file . '.php' : $file; + } + + /** + * Composes file name for the view name, appending view name to [[viewPath]]. + * Child classes may override this method to provide more sophisticated + * search of the view files or even composition of the view files "on the fly". + * @param string $view the view name. + * @return string the view file path. + */ + protected function resolveView($view) + { + return Yii::getAlias($this->viewPath) . DIRECTORY_SEPARATOR . $view; + } +} \ No newline at end of file diff --git a/tests/unit/framework/email/BaseMailerTest.php b/tests/unit/framework/email/BaseMailerTest.php index 178028b..bd97aeb 100644 --- a/tests/unit/framework/email/BaseMailerTest.php +++ b/tests/unit/framework/email/BaseMailerTest.php @@ -6,6 +6,8 @@ use Yii; use yii\base\View; use yii\email\BaseMailer; use yii\email\BaseMessage; +use yii\email\ViewResolver; +use yii\helpers\FileHelper; use yiiunit\TestCase; /** @@ -17,6 +19,26 @@ class BaseMailerTest extends TestCase { $this->mockApplication(); Yii::$app->setComponent('email', $this->createTestEmailComponent()); + $filePath = $this->getTestFilePath(); + if (!file_exists($filePath)) { + FileHelper::createDirectory($filePath); + } + } + + public function tearDown() + { + $filePath = $this->getTestFilePath(); + if (file_exists($filePath)) { + FileHelper::removeDirectory($filePath); + } + } + + /** + * @return string test file path. + */ + protected function getTestFilePath() + { + return Yii::getAlias('@yiiunit/runtime') . DIRECTORY_SEPARATOR . basename(get_class($this)) . '_' . getmypid(); } /** @@ -37,8 +59,22 @@ class BaseMailerTest extends TestCase $view = new View(); $mailer->setView($view); $this->assertEquals($view, $mailer->getView(), 'Unable to setup view!'); + + $viewConfig = [ + 'params' => [ + 'param1' => 'value1', + 'param2' => 'value2', + ] + ]; + $mailer->setView($viewConfig); + $view = $mailer->getView(); + $this->assertTrue(is_object($view), 'Unable to setup view via config!'); + $this->assertEquals($viewConfig['params'], $view->params, 'Unable to configure view via config array!'); } + /** + * @depends testSetupView + */ public function testGetDefaultView() { $mailer = new Mailer(); @@ -46,6 +82,33 @@ class BaseMailerTest extends TestCase $this->assertTrue(is_object($view), 'Unable to get default view!'); } + public function testSetupViewResolver() + { + $mailer = new Mailer(); + + $viewResolver = new ViewResolver(); + $mailer->setViewResolver($viewResolver); + $this->assertEquals($viewResolver, $mailer->getViewResolver(), 'Unable to setup view resolver!'); + + $viewResolverConfig = [ + 'viewPath' => '/test/view/path', + ]; + $mailer->setViewResolver($viewResolverConfig); + $viewResolver = $mailer->getViewResolver(); + $this->assertTrue(is_object($viewResolver), 'Unable to setup view resolver via config!'); + $this->assertEquals($viewResolverConfig['viewPath'], $viewResolver->viewPath, 'Unable to configure view resolver via config array!'); + } + + /** + * @depends testSetupViewResolver + */ + public function testGetDefaultViewResolver() + { + $mailer = new Mailer(); + $viewResolver = $mailer->getViewResolver(); + $this->assertTrue(is_object($viewResolver), 'Unable to get default view resolver!'); + } + public function testDefaultMessageConfig() { $defaultMessageConfig = array( @@ -60,6 +123,29 @@ class BaseMailerTest extends TestCase $this->assertEquals($value, $message->$name); } } + + /** + * @depends testGetDefaultView + * @depends testGetDefaultViewResolver + */ + public function testRender() + { + $mailer = new Mailer(); + + $filePath = $this->getTestFilePath(); + $mailer->getViewResolver()->viewPath = $filePath; + + $viewName = 'test_view'; + $fileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; + $fileContent = ''; + file_put_contents($fileName, $fileContent); + + $params = [ + 'testParam' => 'test output' + ]; + $renderResult = $mailer->render($viewName, $params); + $this->assertEquals($params['testParam'], $renderResult); + } } /** diff --git a/tests/unit/framework/email/ViewResolverTest.php b/tests/unit/framework/email/ViewResolverTest.php new file mode 100644 index 0000000..9185f72 --- /dev/null +++ b/tests/unit/framework/email/ViewResolverTest.php @@ -0,0 +1,57 @@ +testViewPath); + return [ + [ + $alias . '/test', + $aliasPath . '/test.php', + ], + [ + $alias . '/test.tpl', + $aliasPath . '/test.tpl', + ], + [ + 'contact/html', + $viewPath . '/contact/html.php', + ], + [ + 'contact/html.tpl', + $viewPath . '/contact/html.tpl', + ], + ]; + } + + /** + * @dataProvider dataProviderFindViewFile + * + * @param string $view + * @param string $expectedFileName + */ + public function testFindViewFile($view, $expectedFileName) + { + $viewResolver = new ViewResolver(); + $viewResolver->viewPath = $this->testViewPath; + $fileName = $viewResolver->findViewFile($view); + $this->assertEquals($expectedFileName, $fileName); + } +} \ No newline at end of file From b611c4241f3a6a5318411c973ecf31d4204299c1 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Wed, 23 Oct 2013 17:12:33 +0300 Subject: [PATCH 04/31] Email message interface extracted. --- framework/yii/email/BaseMessage.php | 79 ++---------------- framework/yii/email/Message.php | 11 +++ framework/yii/email/MessageInterface.php | 116 ++++++++++++++++++++++++++ framework/yii/email/swift/Message.php | 62 ++++++-------- tests/unit/framework/email/BaseMailerTest.php | 4 + 5 files changed, 166 insertions(+), 106 deletions(-) create mode 100644 framework/yii/email/MessageInterface.php diff --git a/framework/yii/email/BaseMessage.php b/framework/yii/email/BaseMessage.php index 00d27e0..aca71ee 100644 --- a/framework/yii/email/BaseMessage.php +++ b/framework/yii/email/BaseMessage.php @@ -21,10 +21,10 @@ use Yii; * @see BaseMailer * * @property \yii\email\BaseMailer $mailer mailer component instance. This property is read-only. - * @property string|array $from sender email address, if array is given, its first element should - * be sender email address, second - sender name. - * @property string|array $to receiver email address, if array is given, its first element should - * be receiver email address, second - receiver name. + * @property string|array $from sender email address. + * @property string|array $to receiver email address. + * @property string|array $cc copy receiver email address. + * @property string|array $bcc hidden copy receiver email address. * @property string $subject message subject. * @property string $text message plain text content. * @property string $html message HTML content. @@ -32,7 +32,7 @@ use Yii; * @author Paul Klimov * @since 2.0 */ -abstract class BaseMessage extends Object +abstract class BaseMessage extends Object implements MessageInterface { /** * @return \yii\email\BaseMailer @@ -53,8 +53,7 @@ abstract class BaseMessage extends Object } /** - * Sends this email message. - * @return boolean success. + * @inheritdoc */ public function send() { @@ -62,63 +61,7 @@ abstract class BaseMessage extends Object } /** - * Sets message sender. - * @param string|array $from sender email address, if array is given, - * its first element should be sender email address, second - sender name. - */ - abstract public function setFrom($from); - - /** - * Sets message receiver. - * @param string|array $to receiver email address, if array is given, - * its first element should be receiver email address, second - receiver name. - */ - abstract public function setTo($to); - - /** - * Sets message subject. - * @param string $subject message subject - */ - abstract public function setSubject($subject); - - /** - * Sets message plain text content. - * @param string $text message plain text content. - */ - abstract public function setText($text); - - /** - * Sets message HTML content. - * @param string $html message HTML content. - */ - abstract public function setHtml($html); - - /** - * Add message plain text content part. - * @param string $text message plain text content. - */ - abstract public function addText($text); - - /** - * Add message HTML content part. - * @param string $html message HTML content. - */ - abstract public function addHtml($html); - - /** - * Create file attachment for the email message. - * @param string $content attachment file content. - * @param string $fileName attachment file name. - * @param string $contentType MIME type of the attachment file, by default 'application/octet-stream' will be used. - */ - abstract public function createAttachment($content, $fileName, $contentType = 'application/octet-stream'); - - /** - * Attaches existing file to the email message. - * @param string $fileName full file name - * @param string $contentType MIME type of the attachment file, if empty it will be suggested automatically. - * @param string $attachFileName name, which should be used for attachment, if empty file base name will be used. - * @throws \yii\base\InvalidParamException if given file does not exist. + * @inheritdoc */ public function attachFile($fileName, $contentType = null, $attachFileName = null) { @@ -136,13 +79,7 @@ abstract class BaseMessage extends Object } /** - * Renders a view. - * The view to be rendered can be specified in one of the following formats: - * - path alias (e.g. "@app/emails/contact/body"); - * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. - * @param string $view the view name or the path alias of the view file. - * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return string string the rendering result + * @inheritdoc */ public function render($view, $params = []) { diff --git a/framework/yii/email/Message.php b/framework/yii/email/Message.php index c7ec534..e8a14ab 100644 --- a/framework/yii/email/Message.php +++ b/framework/yii/email/Message.php @@ -22,6 +22,17 @@ use yii\email\swift\Message as SwiftMessage; * $email->send(); * ~~~ * + * You can use message object to render view, which can be used to compose the message content: + * ~~~ + * $email = new Message(); + * $email->from = $contactForm->email; + * $email->to = 'admin@domain.com'; + * $email->subject = $email->render('contact/subject', ['form' => $contactForm]); + * $email->addHtml($email->render('contact/html', ['form' => $contactForm])); + * $email->addText($email->render('contact/text', ['form' => $contactForm])); + * $email->send(); + * ~~~ + * * This particular class uses 'SwiftMailer' library to perform the message sending. * Note: you can replace usage of this class by your own one, using [[Yii::$classMap]]: * ~~~ diff --git a/framework/yii/email/MessageInterface.php b/framework/yii/email/MessageInterface.php new file mode 100644 index 0000000..c94d2ab --- /dev/null +++ b/framework/yii/email/MessageInterface.php @@ -0,0 +1,116 @@ + + * @since 2.0 + */ +interface MessageInterface +{ + /** + * Sets message sender. + * @param string|array $from sender email address. + * You may pass an array of addresses if this message is from multiple people. + * You may also specify sender name in addition to email address using format: + * [email => name]. + */ + public function setFrom($from); + + /** + * Sets message receiver. + * @param string|array $to receiver email address. + * You may pass an array of addresses if multiple recipients should receive this message. + * You may also specify receiver name in addition to email address using format: + * [email => name]. + */ + public function setTo($to); + + /** + * Set the Cc (additional copy receiver) addresses of this message. + * @param string|array $cc copy receiver email address. + * You may pass an array of addresses if multiple recipients should receive this message. + * You may also specify receiver name in addition to email address using format: + * [email => name]. + */ + public function setCc($cc); + + /** + * Set the Bcc (hidden copy receiver) addresses of this message. + * @param string|array $bcc hidden copy receiver email address. + * You may pass an array of addresses if multiple recipients should receive this message. + * You may also specify receiver name in addition to email address using format: + * [email => name]. + */ + public function setBcc($bcc); + + /** + * Sets message subject. + * @param string $subject message subject + */ + public function setSubject($subject); + + /** + * Sets message plain text content. + * @param string $text message plain text content. + */ + public function setText($text); + + /** + * Sets message HTML content. + * @param string $html message HTML content. + */ + public function setHtml($html); + + /** + * Add message plain text content part. + * @param string $text message plain text content. + */ + public function addText($text); + + /** + * Add message HTML content part. + * @param string $html message HTML content. + */ + public function addHtml($html); + + /** + * Create file attachment for the email message. + * @param string $content attachment file content. + * @param string $fileName attachment file name. + * @param string $contentType MIME type of the attachment file, by default 'application/octet-stream' will be used. + */ + public function createAttachment($content, $fileName, $contentType = 'application/octet-stream'); + + /** + * Attaches existing file to the email message. + * @param string $fileName full file name + * @param string $contentType MIME type of the attachment file, if empty it will be suggested automatically. + * @param string $attachFileName name, which should be used for attachment, if empty file base name will be used. + */ + public function attachFile($fileName, $contentType = null, $attachFileName = null); + + /** + * Sends this email message. + * @return boolean success. + */ + public function send(); + + /** + * Renders a view. + * The view to be rendered can be specified in one of the following formats: + * - path alias (e.g. "@app/emails/contact/body"); + * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. + * @param string $view the view name or the path alias of the view file. + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return string string the rendering result + */ + public function render($view, $params = []); +} \ No newline at end of file diff --git a/framework/yii/email/swift/Message.php b/framework/yii/email/swift/Message.php index 5b8c575..04ef7b5 100644 --- a/framework/yii/email/swift/Message.php +++ b/framework/yii/email/swift/Message.php @@ -40,41 +40,40 @@ class Message extends BaseMessage } /** - * Sets message sender. - * @param string|array $from sender email address, if array is given, - * its first element should be sender email address, second - sender name. + * @inheritdoc */ public function setFrom($from) { - if (is_array($from)) { - list ($address, $name) = $from; - } else { - $address = $from; - $name = null; - } - $this->getSwiftMessage()->setFrom($address, $name); - $this->getSwiftMessage()->setReplyTo($address, $name); + $this->getSwiftMessage()->setFrom($from); + $this->getSwiftMessage()->setReplyTo($from); } /** - * Sets message receiver. - * @param string|array $to receiver email address, if array is given, - * its first element should be receiver email address, second - receiver name. + * @inheritdoc */ public function setTo($to) { - if (is_array($to)) { - list ($address, $name) = $to; - } else { - $address = $to; - $name = null; - } - $this->getSwiftMessage()->setTo($address, $name); + $this->getSwiftMessage()->setTo($to); + } + + /** + * @inheritdoc + */ + public function setCc($cc) + { + $this->getSwiftMessage()->setCc($cc); + } + + /** + * @inheritdoc + */ + public function setBcc($bcc) + { + $this->getSwiftMessage()->setBcc($bcc); } /** - * Sets message subject. - * @param string $subject message subject + * @inheritdoc */ public function setSubject($subject) { @@ -82,8 +81,7 @@ class Message extends BaseMessage } /** - * Sets message plain text content. - * @param string $text message plain text content. + * @inheritdoc */ public function setText($text) { @@ -91,8 +89,7 @@ class Message extends BaseMessage } /** - * Sets message HTML content. - * @param string $html message HTML content. + * @inheritdoc */ public function setHtml($html) { @@ -100,8 +97,7 @@ class Message extends BaseMessage } /** - * Add message plain text content part. - * @param string $text message plain text content. + * @inheritdoc */ public function addText($text) { @@ -109,8 +105,7 @@ class Message extends BaseMessage } /** - * Add message HTML content part. - * @param string $html message HTML content. + * @inheritdoc */ public function addHtml($html) { @@ -118,10 +113,7 @@ class Message extends BaseMessage } /** - * Create file attachment for the email message. - * @param string $content - attachment file content. - * @param string $fileName - attachment file name. - * @param string $contentType - MIME type of the attachment file, by default 'application/octet-stream' will be used. + * @inheritdoc */ public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') { diff --git a/tests/unit/framework/email/BaseMailerTest.php b/tests/unit/framework/email/BaseMailerTest.php index bd97aeb..b75d628 100644 --- a/tests/unit/framework/email/BaseMailerTest.php +++ b/tests/unit/framework/email/BaseMailerTest.php @@ -173,6 +173,10 @@ class Message extends BaseMessage public function setTo($to) {} + public function setCc($cc) {} + + public function setBcc($bcc) {} + public function setSubject($subject) {} public function setText($text) {} From 2a326c7d7b6ef44889613fbdc09cb1e5fe64f6d1 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Fri, 25 Oct 2013 13:15:36 +0300 Subject: [PATCH 05/31] 'email' renamed to 'mail'. 'SwiftMailer' recomposed into extension. --- extensions/swiftmailer/LICENSE.md | 32 ++++ extensions/swiftmailer/README.md | 58 +++++++ extensions/swiftmailer/composer.json | 28 +++ extensions/swiftmailer/yii/swiftmailer/Mailer.php | 143 +++++++++++++++ extensions/swiftmailer/yii/swiftmailer/Message.php | 126 ++++++++++++++ framework/yii/email/BaseMailer.php | 176 ------------------- framework/yii/email/BaseMessage.php | 88 ---------- framework/yii/email/Message.php | 45 ----- framework/yii/email/MessageInterface.php | 116 ------------- framework/yii/email/ViewResolver.php | 57 ------ framework/yii/email/swift/Mailer.php | 180 ------------------- framework/yii/email/swift/Message.php | 126 -------------- framework/yii/email/swift/autoload.php | 9 - framework/yii/mail/BaseMailer.php | 176 +++++++++++++++++++ framework/yii/mail/BaseMessage.php | 88 ++++++++++ framework/yii/mail/Message.php | 45 +++++ framework/yii/mail/MessageInterface.php | 116 +++++++++++++ framework/yii/mail/ViewResolver.php | 57 ++++++ tests/unit/extensions/swiftmailer/MailerTest.php | 74 ++++++++ tests/unit/extensions/swiftmailer/MessageTest.php | 100 +++++++++++ tests/unit/framework/email/BaseMailerTest.php | 191 --------------------- tests/unit/framework/email/ViewResolverTest.php | 57 ------ tests/unit/framework/email/swift/MailerTest.php | 74 -------- tests/unit/framework/email/swift/MessageTest.php | 100 ----------- tests/unit/framework/mail/BaseMailerTest.php | 191 +++++++++++++++++++++ tests/unit/framework/mail/ViewResolverTest.php | 61 +++++++ 26 files changed, 1295 insertions(+), 1219 deletions(-) create mode 100644 extensions/swiftmailer/LICENSE.md create mode 100644 extensions/swiftmailer/README.md create mode 100644 extensions/swiftmailer/composer.json create mode 100644 extensions/swiftmailer/yii/swiftmailer/Mailer.php create mode 100644 extensions/swiftmailer/yii/swiftmailer/Message.php delete mode 100644 framework/yii/email/BaseMailer.php delete mode 100644 framework/yii/email/BaseMessage.php delete mode 100644 framework/yii/email/Message.php delete mode 100644 framework/yii/email/MessageInterface.php delete mode 100644 framework/yii/email/ViewResolver.php delete mode 100644 framework/yii/email/swift/Mailer.php delete mode 100644 framework/yii/email/swift/Message.php delete mode 100644 framework/yii/email/swift/autoload.php create mode 100644 framework/yii/mail/BaseMailer.php create mode 100644 framework/yii/mail/BaseMessage.php create mode 100644 framework/yii/mail/Message.php create mode 100644 framework/yii/mail/MessageInterface.php create mode 100644 framework/yii/mail/ViewResolver.php create mode 100644 tests/unit/extensions/swiftmailer/MailerTest.php create mode 100644 tests/unit/extensions/swiftmailer/MessageTest.php delete mode 100644 tests/unit/framework/email/BaseMailerTest.php delete mode 100644 tests/unit/framework/email/ViewResolverTest.php delete mode 100644 tests/unit/framework/email/swift/MailerTest.php delete mode 100644 tests/unit/framework/email/swift/MessageTest.php create mode 100644 tests/unit/framework/mail/BaseMailerTest.php create mode 100644 tests/unit/framework/mail/ViewResolverTest.php diff --git a/extensions/swiftmailer/LICENSE.md b/extensions/swiftmailer/LICENSE.md new file mode 100644 index 0000000..0bb1a8d --- /dev/null +++ b/extensions/swiftmailer/LICENSE.md @@ -0,0 +1,32 @@ +The Yii framework is free software. It is released under the terms of +the following BSD License. + +Copyright © 2008-2013 by Yii Software LLC (http://www.yiisoft.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Yii Software LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/extensions/swiftmailer/README.md b/extensions/swiftmailer/README.md new file mode 100644 index 0000000..bb04a83 --- /dev/null +++ b/extensions/swiftmailer/README.md @@ -0,0 +1,58 @@ +Yii 2.0 Public Preview - SwiftMailer Mail Solution +================================================== + +Thank you for choosing Yii - a high-performance component-based PHP framework. + +If you are looking for a production-ready PHP framework, please use +[Yii v1.1](https://github.com/yiisoft/yii). + +Yii 2.0 is still under heavy development. We may make significant changes +without prior notices. **Yii 2.0 is not ready for production use yet.** + +[![Build Status](https://secure.travis-ci.org/yiisoft/yii2.png)](http://travis-ci.org/yiisoft/yii2) + +This is the yii2-swiftmailer extension. + + +Installation +------------ + +The preferred way to install this extension is through [composer](http://getcomposer.org/download/). + +Either run +``` +php composer.phar require yiisoft/yii2-swiftmailer "*" +``` + +or add +```json +"yiisoft/yii2-swiftmailer": "*" +``` +to the require section of your composer.json. + + +*Note: You might have to run `php composer.phar selfupdate`* + + +Usage & Documentation +--------------------- + +This extension has to be registered prior to usage. +To enable this view renderer add it to the $rendereres property of your view object. + +Example: + +```php + [ + 'mail' => [ + 'class' => 'yii\swiftmailer\Mailer', + ], + ], +]; +``` + +For further instructions refer to the related section in the yii guide. diff --git a/extensions/swiftmailer/composer.json b/extensions/swiftmailer/composer.json new file mode 100644 index 0000000..2aa47ae --- /dev/null +++ b/extensions/swiftmailer/composer.json @@ -0,0 +1,28 @@ +{ + "name": "yiisoft/yii2-swiftmailer", + "description": "The SwiftMailer integration for the Yii framework", + "keywords": ["yii", "swift", "swiftmailer", "mail", "email", "mailer"], + "type": "yii2-extension", + "license": "BSD-3-Clause", + "support": { + "issues": "https://github.com/yiisoft/yii2/issues?state=open", + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "authors": [ + { + "name": "Paul Klimov", + "email": "klimov.paul@gmail.com" + } + ], + "minimum-stability": "dev", + "require": { + "yiisoft/yii2": "*", + "swiftmailer/swiftmailer": ">=v5.0" + }, + "autoload": { + "psr-0": { "yii\\swiftmailer\\": "" } + } +} diff --git a/extensions/swiftmailer/yii/swiftmailer/Mailer.php b/extensions/swiftmailer/yii/swiftmailer/Mailer.php new file mode 100644 index 0000000..2f8bbe7 --- /dev/null +++ b/extensions/swiftmailer/yii/swiftmailer/Mailer.php @@ -0,0 +1,143 @@ + array( + * ... + * 'email' => array( + * 'class' => 'yii\email\swift\Mailer', + * 'transport' => [ + * 'class' => 'Swift_SmtpTransport', + * 'host' => 'localhost', + * 'username' => 'username', + * 'password' => 'password', + * 'port' => '587', + * 'encryption' => 'tls', + * ], + * ), + * ... + * ), + * ~~~ + * + * @see http://swiftmailer.org + * + * @author Paul Klimov + * @since 2.0 + */ +class Mailer extends BaseMailer +{ + /** + * @var \Swift_Mailer Swift mailer instance. + */ + private $_swiftMailer; + /** + * @var \Swift_Transport|array Swift transport instance or its array configuration. + */ + private $_transport = []; + + /** + * @return array|\Swift_Mailer Swift mailer instance or array configuration. + */ + public function getSwiftMailer() + { + if (!is_object($this->_swiftMailer)) { + $this->_swiftMailer = $this->createSwiftMailer(); + } + return $this->_swiftMailer; + } + + /** + * @param array|\Swift_Transport $transport + * @throws \yii\base\InvalidConfigException on invalid argument. + */ + public function setTransport($transport) + { + if (!is_array($transport) && !is_object($transport)) { + throw new InvalidConfigException('"' . get_class($this) . '::transport" should be either object or array, "' . gettype($transport) . '" given.'); + } + $this->_transport = $transport; + } + + /** + * @return array|\Swift_Transport + */ + public function getTransport() + { + if (!is_object($this->_transport)) { + $this->_transport = $this->createTransport($this->_transport); + } + return $this->_transport; + } + + /** + * @inheritdoc + */ + public function send($message) + { + return ($this->getSwiftMailer()->send($message->getSwiftMessage()) > 0); + } + + /** + * Creates Swift mailer instance. + * @return \Swift_Mailer mailer instance. + */ + protected function createSwiftMailer() + { + return \Swift_Mailer::newInstance($this->getTransport()); + } + + /** + * Creates email transport instance by its array configuration. + * @param array $config transport configuration. + * @throws \yii\base\InvalidConfigException on invalid transport configuration. + * @return \Swift_Transport transport instance. + */ + protected function createTransport(array $config) + { + if (array_key_exists('class', $config)) { + $className = $config['class']; + unset($config['class']); + } else { + $className = 'Swift_MailTransport'; + } + $transport = call_user_func([$className, 'newInstance']); + if (!empty($config)) { + foreach ($config as $name => $value) { + if (property_exists($transport, $name)) { + $transport->$name = $value; + } else { + $setter = 'set' . $name; + if (method_exists($transport, $setter)) { + $transport->$setter($value); + } else { + throw new InvalidConfigException('Setting unknown property: ' . get_class($transport) . '::' . $name); + } + } + } + } + return $transport; + } + + /** + * Creates the Swift email message instance. + * @return \Swift_Message email message instance. + */ + public function createSwiftMessage() + { + return new \Swift_Message(); + } +} \ No newline at end of file diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php new file mode 100644 index 0000000..e850208 --- /dev/null +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -0,0 +1,126 @@ + + * @since 2.0 + */ +class Message extends BaseMessage +{ + /** + * @var \Swift_Message Swift message instance. + */ + private $_swiftMessage; + + /** + * @return \Swift_Message Swift message instance. + */ + public function getSwiftMessage() + { + if (!is_object($this->_swiftMessage)) { + $this->_swiftMessage = $this->getMailer()->createSwiftMessage(); + } + return $this->_swiftMessage; + } + + /** + * @inheritdoc + */ + public function setFrom($from) + { + $this->getSwiftMessage()->setFrom($from); + $this->getSwiftMessage()->setReplyTo($from); + } + + /** + * @inheritdoc + */ + public function setTo($to) + { + $this->getSwiftMessage()->setTo($to); + } + + /** + * @inheritdoc + */ + public function setCc($cc) + { + $this->getSwiftMessage()->setCc($cc); + } + + /** + * @inheritdoc + */ + public function setBcc($bcc) + { + $this->getSwiftMessage()->setBcc($bcc); + } + + /** + * @inheritdoc + */ + public function setSubject($subject) + { + $this->getSwiftMessage()->setSubject($subject); + } + + /** + * @inheritdoc + */ + public function setText($text) + { + $this->getSwiftMessage()->setBody($text, 'text/plain'); + } + + /** + * @inheritdoc + */ + public function setHtml($html) + { + $this->getSwiftMessage()->setBody($html, 'text/html'); + } + + /** + * @inheritdoc + */ + public function addText($text) + { + $this->getSwiftMessage()->addPart($text, 'text/plain'); + } + + /** + * @inheritdoc + */ + public function addHtml($html) + { + $this->getSwiftMessage()->addPart($html, 'text/html'); + } + + /** + * @inheritdoc + */ + public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') + { + if (empty($contentType)) { + $contentType = 'application/octet-stream'; + } + $attachment = \Swift_Attachment::newInstance($content, $fileName, $contentType); + $this->getSwiftMessage()->attach($attachment); + } +} \ No newline at end of file diff --git a/framework/yii/email/BaseMailer.php b/framework/yii/email/BaseMailer.php deleted file mode 100644 index b3b40b3..0000000 --- a/framework/yii/email/BaseMailer.php +++ /dev/null @@ -1,176 +0,0 @@ - - * @since 2.0 - */ -abstract class BaseMailer extends Component -{ - /** - * @var \yii\base\View|array view instance or its array configuration. - */ - private $_view = []; - /** - * @var \yii\email\ViewResolver|array view resolver instance or its array configuration. - */ - private $_viewResolver = []; - /** - * @var array configuration, which should be applied by default to any new created - * email message instance. - * For example: - * ~~~ - * array( - * 'encoding' => 'UTF-8', - * 'from' => 'noreply@mydomain.com', - * 'bcc' => 'email.test@mydomain.com', - * ) - * ~~~ - */ - private $_defaultMessageConfig = []; - - /** - * @param array|\yii\base\View $view view instance or its array configuration. - * @throws \yii\base\InvalidConfigException on invalid argument. - */ - public function setView($view) - { - if (!is_array($view) && !is_object($view)) { - throw new InvalidConfigException('"' . get_class($this) . '::view" should be either object or array, "' . gettype($view) . '" given.'); - } - $this->_view = $view; - } - - /** - * @return \yii\base\View view instance. - */ - public function getView() - { - if (!is_object($this->_view)) { - $this->_view = $this->createView($this->_view); - } - return $this->_view; - } - - /** - * @param array|\yii\email\ViewResolver $viewResolver view resolver instance or its array configuration. - * @throws \yii\base\InvalidConfigException on invalid argument. - */ - public function setViewResolver($viewResolver) - { - if (!is_array($viewResolver) && !is_object($viewResolver)) { - throw new InvalidConfigException('"' . get_class($this) . '::viewResolver" should be either object or array, "' . gettype($viewResolver) . '" given.'); - } - $this->_viewResolver = $viewResolver; - } - - /** - * @return \yii\email\ViewResolver view resolver. - */ - public function getViewResolver() - { - if (!is_object($this->_viewResolver)) { - $this->_viewResolver = $this->createViewResolver($this->_viewResolver); - } - return $this->_viewResolver; - } - - /** - * @param array $defaultMessageConfig default message config - */ - public function setDefaultMessageConfig(array $defaultMessageConfig) - { - $this->_defaultMessageConfig = $defaultMessageConfig; - } - - /** - * @return array default message config - */ - public function getDefaultMessageConfig() - { - return $this->_defaultMessageConfig; - } - - /** - * Creates view instance from given configuration. - * @param array $config view configuration. - * @return \yii\base\View view instance. - */ - protected function createView(array $config) - { - if (!array_key_exists('class', $config)) { - $config['class'] = '\yii\base\View'; - } - return Yii::createObject($config); - } - - /** - * Creates view resolver instance from given configuration. - * @param array $config view resolver configuration. - * @return \yii\email\ViewResolver view resolver instance. - */ - protected function createViewResolver(array $config) - { - if (!array_key_exists('class', $config)) { - $config['class'] = '\yii\email\ViewResolver'; - } - return Yii::createObject($config); - } - - /** - * Sends the given email message. - * @param object $message email message instance - * @return boolean whether the message has been sent. - */ - abstract public function send($message); - - /** - * Sends a couple of messages at once. - * Note: some particular mailers may benefit from sending messages as batch, - * saving resources, for example on open/close connection operations, - * they may override this method to create their specific implementation. - * @param array $messages list of email messages, which should be sent. - * @return integer number of successfull sends - */ - public function sendMultiple(array $messages) { - $successCount = 0; - foreach ($messages as $message) { - if ($this->send($message)) { - $successCount++; - } - } - return $successCount; - } - - /** - * Renders a view. - * @param string $view the view name or the path alias of the view file. - * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return string string the rendering result - */ - public function render($view, $params = []) - { - return $this->getView()->renderFile($this->getViewResolver()->findViewFile($view), $params, $this); - } -} \ No newline at end of file diff --git a/framework/yii/email/BaseMessage.php b/framework/yii/email/BaseMessage.php deleted file mode 100644 index aca71ee..0000000 --- a/framework/yii/email/BaseMessage.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @since 2.0 - */ -abstract class BaseMessage extends Object implements MessageInterface -{ - /** - * @return \yii\email\BaseMailer - */ - public function getMailer() - { - return Yii::$app->getComponent('email'); - } - - /** - * Initializes the object. - * This method is invoked at the end of the constructor after the object is initialized with the - * given configuration. - */ - public function init() - { - Yii::configure($this, $this->getMailer()->getDefaultMessageConfig()); - } - - /** - * @inheritdoc - */ - public function send() - { - return $this->getMailer()->send($this); - } - - /** - * @inheritdoc - */ - public function attachFile($fileName, $contentType = null, $attachFileName = null) - { - if (!file_exists($fileName)) { - throw new InvalidParamException('Unable to attach file "' . $fileName . '": file does not exists!'); - } - if (empty($contentType)) { - $contentType = FileHelper::getMimeType($fileName); - } - if (empty($attachFileName)) { - $attachFileName = basename($fileName); - } - $content = file_get_contents($fileName); - $this->createAttachment($content, $attachFileName, $contentType); - } - - /** - * @inheritdoc - */ - public function render($view, $params = []) - { - return $this->getMailer()->render($view, $params); - } -} \ No newline at end of file diff --git a/framework/yii/email/Message.php b/framework/yii/email/Message.php deleted file mode 100644 index e8a14ab..0000000 --- a/framework/yii/email/Message.php +++ /dev/null @@ -1,45 +0,0 @@ -from = 'sender@domain.com'; - * $email->to = 'receiver@domain.com'; - * $email->subject = 'Message Subject'; - * $email->text = 'Message Content'; - * $email->send(); - * ~~~ - * - * You can use message object to render view, which can be used to compose the message content: - * ~~~ - * $email = new Message(); - * $email->from = $contactForm->email; - * $email->to = 'admin@domain.com'; - * $email->subject = $email->render('contact/subject', ['form' => $contactForm]); - * $email->addHtml($email->render('contact/html', ['form' => $contactForm])); - * $email->addText($email->render('contact/text', ['form' => $contactForm])); - * $email->send(); - * ~~~ - * - * This particular class uses 'SwiftMailer' library to perform the message sending. - * Note: you can replace usage of this class by your own one, using [[Yii::$classMap]]: - * ~~~ - * Yii::$classMap['yii\email\Message'] = '/path/to/my/email/Message.php' - * ~~~ - * - * @author Paul Klimov - * @since 2.0 - */ -class Message extends SwiftMessage {} \ No newline at end of file diff --git a/framework/yii/email/MessageInterface.php b/framework/yii/email/MessageInterface.php deleted file mode 100644 index c94d2ab..0000000 --- a/framework/yii/email/MessageInterface.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @since 2.0 - */ -interface MessageInterface -{ - /** - * Sets message sender. - * @param string|array $from sender email address. - * You may pass an array of addresses if this message is from multiple people. - * You may also specify sender name in addition to email address using format: - * [email => name]. - */ - public function setFrom($from); - - /** - * Sets message receiver. - * @param string|array $to receiver email address. - * You may pass an array of addresses if multiple recipients should receive this message. - * You may also specify receiver name in addition to email address using format: - * [email => name]. - */ - public function setTo($to); - - /** - * Set the Cc (additional copy receiver) addresses of this message. - * @param string|array $cc copy receiver email address. - * You may pass an array of addresses if multiple recipients should receive this message. - * You may also specify receiver name in addition to email address using format: - * [email => name]. - */ - public function setCc($cc); - - /** - * Set the Bcc (hidden copy receiver) addresses of this message. - * @param string|array $bcc hidden copy receiver email address. - * You may pass an array of addresses if multiple recipients should receive this message. - * You may also specify receiver name in addition to email address using format: - * [email => name]. - */ - public function setBcc($bcc); - - /** - * Sets message subject. - * @param string $subject message subject - */ - public function setSubject($subject); - - /** - * Sets message plain text content. - * @param string $text message plain text content. - */ - public function setText($text); - - /** - * Sets message HTML content. - * @param string $html message HTML content. - */ - public function setHtml($html); - - /** - * Add message plain text content part. - * @param string $text message plain text content. - */ - public function addText($text); - - /** - * Add message HTML content part. - * @param string $html message HTML content. - */ - public function addHtml($html); - - /** - * Create file attachment for the email message. - * @param string $content attachment file content. - * @param string $fileName attachment file name. - * @param string $contentType MIME type of the attachment file, by default 'application/octet-stream' will be used. - */ - public function createAttachment($content, $fileName, $contentType = 'application/octet-stream'); - - /** - * Attaches existing file to the email message. - * @param string $fileName full file name - * @param string $contentType MIME type of the attachment file, if empty it will be suggested automatically. - * @param string $attachFileName name, which should be used for attachment, if empty file base name will be used. - */ - public function attachFile($fileName, $contentType = null, $attachFileName = null); - - /** - * Sends this email message. - * @return boolean success. - */ - public function send(); - - /** - * Renders a view. - * The view to be rendered can be specified in one of the following formats: - * - path alias (e.g. "@app/emails/contact/body"); - * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. - * @param string $view the view name or the path alias of the view file. - * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return string string the rendering result - */ - public function render($view, $params = []); -} \ No newline at end of file diff --git a/framework/yii/email/ViewResolver.php b/framework/yii/email/ViewResolver.php deleted file mode 100644 index 4f522be..0000000 --- a/framework/yii/email/ViewResolver.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @since 2.0 - */ -class ViewResolver extends Component -{ - /** - * @var string directory containing view files for this email messages. - */ - public $viewPath = '@app/emails'; - - /** - * Finds the view file based on the given view name. - * The view to be rendered can be specified in one of the following formats: - * - path alias (e.g. "@app/emails/contact/body"); - * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. - * @param string $view the view name or the path alias of the view file. - * @return string the view file path. Note that the file may not exist. - */ - public function findViewFile($view) - { - if (strncmp($view, '@', 1) === 0) { - // e.g. "@app/views/main" - $file = Yii::getAlias($view); - } else { - $file = $this->resolveView($view); - } - return pathinfo($file, PATHINFO_EXTENSION) === '' ? $file . '.php' : $file; - } - - /** - * Composes file name for the view name, appending view name to [[viewPath]]. - * Child classes may override this method to provide more sophisticated - * search of the view files or even composition of the view files "on the fly". - * @param string $view the view name. - * @return string the view file path. - */ - protected function resolveView($view) - { - return Yii::getAlias($this->viewPath) . DIRECTORY_SEPARATOR . $view; - } -} \ No newline at end of file diff --git a/framework/yii/email/swift/Mailer.php b/framework/yii/email/swift/Mailer.php deleted file mode 100644 index 1f589a2..0000000 --- a/framework/yii/email/swift/Mailer.php +++ /dev/null @@ -1,180 +0,0 @@ - array( - * ... - * 'email' => array( - * 'class' => 'yii\email\swift\Mailer', - * 'transport' => [ - * 'class' => 'Swift_SmtpTransport', - * 'host' => 'localhost', - * 'username' => 'username', - * 'password' => 'password', - * 'port' => '587', - * 'encryption' => 'tls', - * ], - * ), - * ... - * ), - * ~~~ - * - * @see http://swiftmailer.org - * - * @author Paul Klimov - * @since 2.0 - */ -class Mailer extends BaseMailer -{ - /** - * @var string|callback SwiftMailer autoloader callback or path to autoloader file. - * If the SwiftMailer classes autoloading is already managed in some other place, - * for example via Composer, you should leave this field blank. - */ - public $autoload; - /** - * @var \Swift_Mailer Swift mailer instance. - */ - private $_swiftMailer; - /** - * @var \Swift_Transport|array Swift transport instance or its array configuration. - */ - private $_transport = []; - - /** - * @return array|\Swift_Mailer Swift mailer instance or array configuration. - */ - public function getSwiftMailer() - { - if (!is_object($this->_swiftMailer)) { - $this->_swiftMailer = $this->createSwiftMailer(); - } - return $this->_swiftMailer; - } - - /** - * @param array|\Swift_Transport $transport - * @throws \yii\base\InvalidConfigException on invalid argument. - */ - public function setTransport($transport) - { - if (!is_array($transport) && !is_object($transport)) { - throw new InvalidConfigException('"' . get_class($this) . '::transport" should be either object or array, "' . gettype($transport) . '" given.'); - } - $this->_transport = $transport; - } - - /** - * @return array|\Swift_Transport - */ - public function getTransport() - { - if (!is_object($this->_transport)) { - $this->_transport = $this->createTransport($this->_transport); - } - return $this->_transport; - } - - /** - * @inheritdoc - */ - public function init() - { - $this->setupSwiftMailerAutoload(); - } - - /** - * Sets up the SwiftMailer autoloader, if it is specified. - */ - protected function setupSwiftMailerAutoload() - { - if (!class_exists('Swift', false)) { - if (empty($this->autoload)) { - $this->autoload = __DIR__ . '/autoload.php'; - } - if (is_string($this->autoload)) { - if (file_exists($this->autoload)) { - require_once($this->autoload); - } elseif (function_exists($this->autoload)) { - spl_autoload_register($this->autoload); - } else { - throw new InvalidConfigException('"' . get_class($this) . '::autoload" value "' . $this->autoload . '" is invalid: no such function or file exists.'); - } - } else { - spl_autoload_register($this->autoload); - } - } - } - - /** - * @inheritdoc - */ - public function send($message) - { - return ($this->getSwiftMailer()->send($message->getSwiftMessage()) > 0); - } - - /** - * Creates Swift mailer instance. - * @return \Swift_Mailer mailer instance. - */ - protected function createSwiftMailer() - { - return \Swift_Mailer::newInstance($this->getTransport()); - } - - /** - * Creates email transport instance by its array configuration. - * @param array $config transport configuration. - * @throws \yii\base\InvalidConfigException on invalid transport configuration. - * @return \Swift_Transport transport instance. - */ - protected function createTransport(array $config) - { - if (array_key_exists('class', $config)) { - $className = $config['class']; - unset($config['class']); - } else { - $className = 'Swift_MailTransport'; - } - $transport = call_user_func([$className, 'newInstance']); - if (!empty($config)) { - foreach ($config as $name => $value) { - if (property_exists($transport, $name)) { - $transport->$name = $value; - } else { - $setter = 'set' . $name; - if (method_exists($transport, $setter)) { - $transport->$setter($value); - } else { - throw new InvalidConfigException('Setting unknown property: ' . get_class($transport) . '::' . $name); - } - } - } - } - return $transport; - } - - /** - * Creates the Swift email message instance. - * @return \Swift_Message email message instance. - */ - public function createSwiftMessage() - { - return new \Swift_Message(); - } -} \ No newline at end of file diff --git a/framework/yii/email/swift/Message.php b/framework/yii/email/swift/Message.php deleted file mode 100644 index 04ef7b5..0000000 --- a/framework/yii/email/swift/Message.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @since 2.0 - */ -class Message extends BaseMessage -{ - /** - * @var \Swift_Message Swift message instance. - */ - private $_swiftMessage; - - /** - * @return \Swift_Message Swift message instance. - */ - public function getSwiftMessage() - { - if (!is_object($this->_swiftMessage)) { - $this->_swiftMessage = $this->getMailer()->createSwiftMessage(); - } - return $this->_swiftMessage; - } - - /** - * @inheritdoc - */ - public function setFrom($from) - { - $this->getSwiftMessage()->setFrom($from); - $this->getSwiftMessage()->setReplyTo($from); - } - - /** - * @inheritdoc - */ - public function setTo($to) - { - $this->getSwiftMessage()->setTo($to); - } - - /** - * @inheritdoc - */ - public function setCc($cc) - { - $this->getSwiftMessage()->setCc($cc); - } - - /** - * @inheritdoc - */ - public function setBcc($bcc) - { - $this->getSwiftMessage()->setBcc($bcc); - } - - /** - * @inheritdoc - */ - public function setSubject($subject) - { - $this->getSwiftMessage()->setSubject($subject); - } - - /** - * @inheritdoc - */ - public function setText($text) - { - $this->getSwiftMessage()->setBody($text, 'text/plain'); - } - - /** - * @inheritdoc - */ - public function setHtml($html) - { - $this->getSwiftMessage()->setBody($html, 'text/html'); - } - - /** - * @inheritdoc - */ - public function addText($text) - { - $this->getSwiftMessage()->addPart($text, 'text/plain'); - } - - /** - * @inheritdoc - */ - public function addHtml($html) - { - $this->getSwiftMessage()->addPart($html, 'text/html'); - } - - /** - * @inheritdoc - */ - public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') - { - if (empty($contentType)) { - $contentType = 'application/octet-stream'; - } - $attachment = \Swift_Attachment::newInstance($content, $fileName, $contentType); - $this->getSwiftMessage()->attach($attachment); - } -} \ No newline at end of file diff --git a/framework/yii/email/swift/autoload.php b/framework/yii/email/swift/autoload.php deleted file mode 100644 index 494150f..0000000 --- a/framework/yii/email/swift/autoload.php +++ /dev/null @@ -1,9 +0,0 @@ - + * @since 2.0 + */ +abstract class BaseMailer extends Component +{ + /** + * @var \yii\base\View|array view instance or its array configuration. + */ + private $_view = []; + /** + * @var \yii\mail\ViewResolver|array view resolver instance or its array configuration. + */ + private $_viewResolver = []; + /** + * @var array configuration, which should be applied by default to any new created + * email message instance. + * For example: + * ~~~ + * array( + * 'encoding' => 'UTF-8', + * 'from' => 'noreply@mydomain.com', + * 'bcc' => 'email.test@mydomain.com', + * ) + * ~~~ + */ + private $_defaultMessageConfig = []; + + /** + * @param array|\yii\base\View $view view instance or its array configuration. + * @throws \yii\base\InvalidConfigException on invalid argument. + */ + public function setView($view) + { + if (!is_array($view) && !is_object($view)) { + throw new InvalidConfigException('"' . get_class($this) . '::view" should be either object or array, "' . gettype($view) . '" given.'); + } + $this->_view = $view; + } + + /** + * @return \yii\base\View view instance. + */ + public function getView() + { + if (!is_object($this->_view)) { + $this->_view = $this->createView($this->_view); + } + return $this->_view; + } + + /** + * @param array|\yii\mail\ViewResolver $viewResolver view resolver instance or its array configuration. + * @throws \yii\base\InvalidConfigException on invalid argument. + */ + public function setViewResolver($viewResolver) + { + if (!is_array($viewResolver) && !is_object($viewResolver)) { + throw new InvalidConfigException('"' . get_class($this) . '::viewResolver" should be either object or array, "' . gettype($viewResolver) . '" given.'); + } + $this->_viewResolver = $viewResolver; + } + + /** + * @return \yii\mail\ViewResolver view resolver. + */ + public function getViewResolver() + { + if (!is_object($this->_viewResolver)) { + $this->_viewResolver = $this->createViewResolver($this->_viewResolver); + } + return $this->_viewResolver; + } + + /** + * @param array $defaultMessageConfig default message config + */ + public function setDefaultMessageConfig(array $defaultMessageConfig) + { + $this->_defaultMessageConfig = $defaultMessageConfig; + } + + /** + * @return array default message config + */ + public function getDefaultMessageConfig() + { + return $this->_defaultMessageConfig; + } + + /** + * Creates view instance from given configuration. + * @param array $config view configuration. + * @return \yii\base\View view instance. + */ + protected function createView(array $config) + { + if (!array_key_exists('class', $config)) { + $config['class'] = '\yii\base\View'; + } + return Yii::createObject($config); + } + + /** + * Creates view resolver instance from given configuration. + * @param array $config view resolver configuration. + * @return \yii\mail\ViewResolver view resolver instance. + */ + protected function createViewResolver(array $config) + { + if (!array_key_exists('class', $config)) { + $config['class'] = '\yii\mail\ViewResolver'; + } + return Yii::createObject($config); + } + + /** + * Sends the given email message. + * @param object $message email message instance + * @return boolean whether the message has been sent. + */ + abstract public function send($message); + + /** + * Sends a couple of messages at once. + * Note: some particular mailers may benefit from sending messages as batch, + * saving resources, for example on open/close connection operations, + * they may override this method to create their specific implementation. + * @param array $messages list of email messages, which should be sent. + * @return integer number of successfull sends + */ + public function sendMultiple(array $messages) { + $successCount = 0; + foreach ($messages as $message) { + if ($this->send($message)) { + $successCount++; + } + } + return $successCount; + } + + /** + * Renders a view. + * @param string $view the view name or the path alias of the view file. + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return string string the rendering result + */ + public function render($view, $params = []) + { + return $this->getView()->renderFile($this->getViewResolver()->findViewFile($view), $params, $this); + } +} \ No newline at end of file diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php new file mode 100644 index 0000000..17658f4 --- /dev/null +++ b/framework/yii/mail/BaseMessage.php @@ -0,0 +1,88 @@ + + * @since 2.0 + */ +abstract class BaseMessage extends Object implements MessageInterface +{ + /** + * @return \yii\mail\BaseMailer + */ + public function getMailer() + { + return Yii::$app->getComponent('email'); + } + + /** + * Initializes the object. + * This method is invoked at the end of the constructor after the object is initialized with the + * given configuration. + */ + public function init() + { + Yii::configure($this, $this->getMailer()->getDefaultMessageConfig()); + } + + /** + * @inheritdoc + */ + public function send() + { + return $this->getMailer()->send($this); + } + + /** + * @inheritdoc + */ + public function attachFile($fileName, $contentType = null, $attachFileName = null) + { + if (!file_exists($fileName)) { + throw new InvalidParamException('Unable to attach file "' . $fileName . '": file does not exists!'); + } + if (empty($contentType)) { + $contentType = FileHelper::getMimeType($fileName); + } + if (empty($attachFileName)) { + $attachFileName = basename($fileName); + } + $content = file_get_contents($fileName); + $this->createAttachment($content, $attachFileName, $contentType); + } + + /** + * @inheritdoc + */ + public function render($view, $params = []) + { + return $this->getMailer()->render($view, $params); + } +} \ No newline at end of file diff --git a/framework/yii/mail/Message.php b/framework/yii/mail/Message.php new file mode 100644 index 0000000..fb34e24 --- /dev/null +++ b/framework/yii/mail/Message.php @@ -0,0 +1,45 @@ +from = 'sender@domain.com'; + * $email->to = 'receiver@domain.com'; + * $email->subject = 'Message Subject'; + * $email->text = 'Message Content'; + * $email->send(); + * ~~~ + * + * You can use message object to render view, which can be used to compose the message content: + * ~~~ + * $email = new Message(); + * $email->from = $contactForm->email; + * $email->to = 'admin@domain.com'; + * $email->subject = $email->render('contact/subject', ['form' => $contactForm]); + * $email->addHtml($email->render('contact/html', ['form' => $contactForm])); + * $email->addText($email->render('contact/text', ['form' => $contactForm])); + * $email->send(); + * ~~~ + * + * This particular class uses 'SwiftMailer' library to perform the message sending. + * Note: you can replace usage of this class by your own one, using [[Yii::$classMap]]: + * ~~~ + * Yii::$classMap['yii\mail\Message'] = '/path/to/my/email/Message.php' + * ~~~ + * + * @author Paul Klimov + * @since 2.0 + */ +class Message extends SwiftMessage {} \ No newline at end of file diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php new file mode 100644 index 0000000..c592edb --- /dev/null +++ b/framework/yii/mail/MessageInterface.php @@ -0,0 +1,116 @@ + + * @since 2.0 + */ +interface MessageInterface +{ + /** + * Sets message sender. + * @param string|array $from sender email address. + * You may pass an array of addresses if this message is from multiple people. + * You may also specify sender name in addition to email address using format: + * [email => name]. + */ + public function setFrom($from); + + /** + * Sets message receiver. + * @param string|array $to receiver email address. + * You may pass an array of addresses if multiple recipients should receive this message. + * You may also specify receiver name in addition to email address using format: + * [email => name]. + */ + public function setTo($to); + + /** + * Set the Cc (additional copy receiver) addresses of this message. + * @param string|array $cc copy receiver email address. + * You may pass an array of addresses if multiple recipients should receive this message. + * You may also specify receiver name in addition to email address using format: + * [email => name]. + */ + public function setCc($cc); + + /** + * Set the Bcc (hidden copy receiver) addresses of this message. + * @param string|array $bcc hidden copy receiver email address. + * You may pass an array of addresses if multiple recipients should receive this message. + * You may also specify receiver name in addition to email address using format: + * [email => name]. + */ + public function setBcc($bcc); + + /** + * Sets message subject. + * @param string $subject message subject + */ + public function setSubject($subject); + + /** + * Sets message plain text content. + * @param string $text message plain text content. + */ + public function setText($text); + + /** + * Sets message HTML content. + * @param string $html message HTML content. + */ + public function setHtml($html); + + /** + * Add message plain text content part. + * @param string $text message plain text content. + */ + public function addText($text); + + /** + * Add message HTML content part. + * @param string $html message HTML content. + */ + public function addHtml($html); + + /** + * Create file attachment for the email message. + * @param string $content attachment file content. + * @param string $fileName attachment file name. + * @param string $contentType MIME type of the attachment file, by default 'application/octet-stream' will be used. + */ + public function createAttachment($content, $fileName, $contentType = 'application/octet-stream'); + + /** + * Attaches existing file to the email message. + * @param string $fileName full file name + * @param string $contentType MIME type of the attachment file, if empty it will be suggested automatically. + * @param string $attachFileName name, which should be used for attachment, if empty file base name will be used. + */ + public function attachFile($fileName, $contentType = null, $attachFileName = null); + + /** + * Sends this email message. + * @return boolean success. + */ + public function send(); + + /** + * Renders a view. + * The view to be rendered can be specified in one of the following formats: + * - path alias (e.g. "@app/emails/contact/body"); + * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. + * @param string $view the view name or the path alias of the view file. + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return string string the rendering result + */ + public function render($view, $params = []); +} \ No newline at end of file diff --git a/framework/yii/mail/ViewResolver.php b/framework/yii/mail/ViewResolver.php new file mode 100644 index 0000000..31f57cb --- /dev/null +++ b/framework/yii/mail/ViewResolver.php @@ -0,0 +1,57 @@ + + * @since 2.0 + */ +class ViewResolver extends Component +{ + /** + * @var string directory containing view files for this email messages. + */ + public $viewPath = '@app/emails'; + + /** + * Finds the view file based on the given view name. + * The view to be rendered can be specified in one of the following formats: + * - path alias (e.g. "@app/emails/contact/body"); + * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. + * @param string $view the view name or the path alias of the view file. + * @return string the view file path. Note that the file may not exist. + */ + public function findViewFile($view) + { + if (strncmp($view, '@', 1) === 0) { + // e.g. "@app/views/main" + $file = Yii::getAlias($view); + } else { + $file = $this->resolveView($view); + } + return pathinfo($file, PATHINFO_EXTENSION) === '' ? $file . '.php' : $file; + } + + /** + * Composes file name for the view name, appending view name to [[viewPath]]. + * Child classes may override this method to provide more sophisticated + * search of the view files or even composition of the view files "on the fly". + * @param string $view the view name. + * @return string the view file path. + */ + protected function resolveView($view) + { + return Yii::getAlias($this->viewPath) . DIRECTORY_SEPARATOR . $view; + } +} \ No newline at end of file diff --git a/tests/unit/extensions/swiftmailer/MailerTest.php b/tests/unit/extensions/swiftmailer/MailerTest.php new file mode 100644 index 0000000..db5f298 --- /dev/null +++ b/tests/unit/extensions/swiftmailer/MailerTest.php @@ -0,0 +1,74 @@ +mockApplication(array( + 'vendorPath' => Yii::getAlias('@yiiunit/vendor') + )); + Yii::$app->setComponent('email', $this->createTestEmailComponent()); + } + + /** + * @return Mailer test email component instance. + */ + protected function createTestEmailComponent() + { + $component = new Mailer(); + return $component; + } + + // Tests : + + public function testSetupTransport() + { + $mailer = new Mailer(); + + $transport = \Swift_MailTransport::newInstance(); + $mailer->setTransport($transport); + $this->assertEquals($transport, $mailer->getTransport(), 'Unable to setup transport!'); + } + + /** + * @depends testSetupTransport + */ + public function testConfigureTransport() + { + $mailer = new Mailer(); + + $transportConfig = [ + 'class' => 'Swift_SmtpTransport', + 'host' => 'localhost', + ]; + $mailer->setTransport($transportConfig); + $transport = $mailer->getTransport(); + $this->assertTrue(is_object($transport), 'Unable to setup transport via config!'); + $this->assertEquals($transportConfig['class'], get_class($transport), 'Invalid transport class!'); + $this->assertEquals($transportConfig['host'], $transport->getHost(), 'Invalid transport host!'); + } + + public function testGetSwiftMailer() + { + $mailer = new Mailer(); + $this->assertTrue(is_object($mailer->getSwiftMailer()), 'Unable to get Swift mailer instance!'); + } + + public function testCreateSwiftMessage() + { + $mailer = new Mailer(); + $message = $mailer->createSwiftMessage(); + $this->assertTrue(is_object($message), 'Unable to create Swift message instance!'); + } +} \ No newline at end of file diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php new file mode 100644 index 0000000..cabf22a --- /dev/null +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -0,0 +1,100 @@ +mockApplication(array( + 'vendorPath' => Yii::getAlias('@yiiunit/vendor') + )); + Yii::$app->setComponent('email', $this->createTestEmailComponent()); + } + + /** + * @return Mailer test email component instance. + */ + protected function createTestEmailComponent() + { + $component = new Mailer(); + return $component; + } + + // Tests : + + public function testGetSwiftMessage() + { + $message = new Message(); + $this->assertTrue(is_object($message->getSwiftMessage()), 'Unable to get Swift message!'); + } + + /** + * @depends testGetSwiftMessage + */ + public function testSend() + { + $message = new Message(); + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Test'); + $message->setText('Yii Swift Test body'); + $this->assertTrue($message->send()); + } + + /** + * @depends testSend + */ + public function testAttachFile() + { + $message = new Message(); + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Attach File Test'); + $message->setText('Yii Swift Attach File Test body'); + $message->attachFile(__FILE__); + $this->assertTrue($message->send()); + } + + /** + * @depends testSend + */ + public function testCreateAttachment() + { + $message = new Message(); + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Create Attachment Test'); + $message->setText('Yii Swift Create Attachment Test body'); + $message->createAttachment('Test attachment content', 'test.txt'); + $this->assertTrue($message->send()); + } + + /** + * @depends testSend + */ + public function testSendAlternativeBody() + { + $message = new Message(); + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Alternative Body Test'); + $message->addHtml('Yii Swift test HTML body'); + $message->addText('Yii Swift test plain text body'); + $this->assertTrue($message->send()); + } +} \ No newline at end of file diff --git a/tests/unit/framework/email/BaseMailerTest.php b/tests/unit/framework/email/BaseMailerTest.php deleted file mode 100644 index b75d628..0000000 --- a/tests/unit/framework/email/BaseMailerTest.php +++ /dev/null @@ -1,191 +0,0 @@ -mockApplication(); - Yii::$app->setComponent('email', $this->createTestEmailComponent()); - $filePath = $this->getTestFilePath(); - if (!file_exists($filePath)) { - FileHelper::createDirectory($filePath); - } - } - - public function tearDown() - { - $filePath = $this->getTestFilePath(); - if (file_exists($filePath)) { - FileHelper::removeDirectory($filePath); - } - } - - /** - * @return string test file path. - */ - protected function getTestFilePath() - { - return Yii::getAlias('@yiiunit/runtime') . DIRECTORY_SEPARATOR . basename(get_class($this)) . '_' . getmypid(); - } - - /** - * @return Mailer test email component instance. - */ - protected function createTestEmailComponent() - { - $component = new Mailer(); - return $component; - } - - // Tests : - - public function testSetupView() - { - $mailer = new Mailer(); - - $view = new View(); - $mailer->setView($view); - $this->assertEquals($view, $mailer->getView(), 'Unable to setup view!'); - - $viewConfig = [ - 'params' => [ - 'param1' => 'value1', - 'param2' => 'value2', - ] - ]; - $mailer->setView($viewConfig); - $view = $mailer->getView(); - $this->assertTrue(is_object($view), 'Unable to setup view via config!'); - $this->assertEquals($viewConfig['params'], $view->params, 'Unable to configure view via config array!'); - } - - /** - * @depends testSetupView - */ - public function testGetDefaultView() - { - $mailer = new Mailer(); - $view = $mailer->getView(); - $this->assertTrue(is_object($view), 'Unable to get default view!'); - } - - public function testSetupViewResolver() - { - $mailer = new Mailer(); - - $viewResolver = new ViewResolver(); - $mailer->setViewResolver($viewResolver); - $this->assertEquals($viewResolver, $mailer->getViewResolver(), 'Unable to setup view resolver!'); - - $viewResolverConfig = [ - 'viewPath' => '/test/view/path', - ]; - $mailer->setViewResolver($viewResolverConfig); - $viewResolver = $mailer->getViewResolver(); - $this->assertTrue(is_object($viewResolver), 'Unable to setup view resolver via config!'); - $this->assertEquals($viewResolverConfig['viewPath'], $viewResolver->viewPath, 'Unable to configure view resolver via config array!'); - } - - /** - * @depends testSetupViewResolver - */ - public function testGetDefaultViewResolver() - { - $mailer = new Mailer(); - $viewResolver = $mailer->getViewResolver(); - $this->assertTrue(is_object($viewResolver), 'Unable to get default view resolver!'); - } - - public function testDefaultMessageConfig() - { - $defaultMessageConfig = array( - 'id' => 'test-id', - 'encoding' => 'test-encoding', - ); - Yii::$app->getComponent('email')->setDefaultMessageConfig($defaultMessageConfig); - - $message = new Message(); - - foreach ($defaultMessageConfig as $name => $value) { - $this->assertEquals($value, $message->$name); - } - } - - /** - * @depends testGetDefaultView - * @depends testGetDefaultViewResolver - */ - public function testRender() - { - $mailer = new Mailer(); - - $filePath = $this->getTestFilePath(); - $mailer->getViewResolver()->viewPath = $filePath; - - $viewName = 'test_view'; - $fileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; - $fileContent = ''; - file_put_contents($fileName, $fileContent); - - $params = [ - 'testParam' => 'test output' - ]; - $renderResult = $mailer->render($viewName, $params); - $this->assertEquals($params['testParam'], $renderResult); - } -} - -/** - * Test Mailer class - */ -class Mailer extends BaseMailer -{ - public $sentMessages = array(); - - public function send($message) - { - $this->sentMessages[] = $message; - } -} - -/** - * Test Message class - */ -class Message extends BaseMessage -{ - public $id; - public $encoding; - - public function setFrom($from) {} - - public function setTo($to) {} - - public function setCc($cc) {} - - public function setBcc($bcc) {} - - public function setSubject($subject) {} - - public function setText($text) {} - - public function setHtml($html) {} - - public function addText($text) {} - - public function addHtml($html) {} - - public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') {} -} \ No newline at end of file diff --git a/tests/unit/framework/email/ViewResolverTest.php b/tests/unit/framework/email/ViewResolverTest.php deleted file mode 100644 index 9185f72..0000000 --- a/tests/unit/framework/email/ViewResolverTest.php +++ /dev/null @@ -1,57 +0,0 @@ -testViewPath); - return [ - [ - $alias . '/test', - $aliasPath . '/test.php', - ], - [ - $alias . '/test.tpl', - $aliasPath . '/test.tpl', - ], - [ - 'contact/html', - $viewPath . '/contact/html.php', - ], - [ - 'contact/html.tpl', - $viewPath . '/contact/html.tpl', - ], - ]; - } - - /** - * @dataProvider dataProviderFindViewFile - * - * @param string $view - * @param string $expectedFileName - */ - public function testFindViewFile($view, $expectedFileName) - { - $viewResolver = new ViewResolver(); - $viewResolver->viewPath = $this->testViewPath; - $fileName = $viewResolver->findViewFile($view); - $this->assertEquals($expectedFileName, $fileName); - } -} \ No newline at end of file diff --git a/tests/unit/framework/email/swift/MailerTest.php b/tests/unit/framework/email/swift/MailerTest.php deleted file mode 100644 index f9cee72..0000000 --- a/tests/unit/framework/email/swift/MailerTest.php +++ /dev/null @@ -1,74 +0,0 @@ -mockApplication(array( - 'vendorPath' => Yii::getAlias('@yiiunit/vendor') - )); - Yii::$app->setComponent('email', $this->createTestEmailComponent()); - } - - /** - * @return Mailer test email component instance. - */ - protected function createTestEmailComponent() - { - $component = new Mailer(); - return $component; - } - - // Tests : - - public function testSetupTransport() - { - $mailer = new Mailer(); - - $transport = \Swift_MailTransport::newInstance(); - $mailer->setTransport($transport); - $this->assertEquals($transport, $mailer->getTransport(), 'Unable to setup transport!'); - } - - /** - * @depends testSetupTransport - */ - public function testConfigureTransport() - { - $mailer = new Mailer(); - - $transportConfig = [ - 'class' => 'Swift_SmtpTransport', - 'host' => 'localhost', - ]; - $mailer->setTransport($transportConfig); - $transport = $mailer->getTransport(); - $this->assertTrue(is_object($transport), 'Unable to setup transport via config!'); - $this->assertEquals($transportConfig['class'], get_class($transport), 'Invalid transport class!'); - $this->assertEquals($transportConfig['host'], $transport->getHost(), 'Invalid transport host!'); - } - - public function testGetSwiftMailer() - { - $mailer = new Mailer(); - $this->assertTrue(is_object($mailer->getSwiftMailer()), 'Unable to get Swift mailer instance!'); - } - - public function testCreateSwiftMessage() - { - $mailer = new Mailer(); - $message = $mailer->createSwiftMessage(); - $this->assertTrue(is_object($message), 'Unable to create Swift message instance!'); - } -} \ No newline at end of file diff --git a/tests/unit/framework/email/swift/MessageTest.php b/tests/unit/framework/email/swift/MessageTest.php deleted file mode 100644 index 112f4fc..0000000 --- a/tests/unit/framework/email/swift/MessageTest.php +++ /dev/null @@ -1,100 +0,0 @@ -mockApplication(array( - 'vendorPath' => Yii::getAlias('@yiiunit/vendor') - )); - Yii::$app->setComponent('email', $this->createTestEmailComponent()); - } - - /** - * @return Mailer test email component instance. - */ - protected function createTestEmailComponent() - { - $component = new Mailer(); - return $component; - } - - // Tests : - - public function testGetSwiftMessage() - { - $message = new Message(); - $this->assertTrue(is_object($message->getSwiftMessage()), 'Unable to get Swift message!'); - } - - /** - * @depends testGetSwiftMessage - */ - public function testSend() - { - $message = new Message(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Test'); - $message->setText('Yii Swift Test body'); - $this->assertTrue($message->send()); - } - - /** - * @depends testSend - */ - public function testAttachFile() - { - $message = new Message(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Attach File Test'); - $message->setText('Yii Swift Attach File Test body'); - $message->attachFile(__FILE__); - $this->assertTrue($message->send()); - } - - /** - * @depends testSend - */ - public function testCreateAttachment() - { - $message = new Message(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Create Attachment Test'); - $message->setText('Yii Swift Create Attachment Test body'); - $message->createAttachment('Test attachment content', 'test.txt'); - $this->assertTrue($message->send()); - } - - /** - * @depends testSend - */ - public function testSendAlternativeBody() - { - $message = new Message(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Alternative Body Test'); - $message->addHtml('Yii Swift test HTML body'); - $message->addText('Yii Swift test plain text body'); - $this->assertTrue($message->send()); - } -} \ No newline at end of file diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php new file mode 100644 index 0000000..88d6a4e --- /dev/null +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -0,0 +1,191 @@ +mockApplication(); + Yii::$app->setComponent('email', $this->createTestEmailComponent()); + $filePath = $this->getTestFilePath(); + if (!file_exists($filePath)) { + FileHelper::createDirectory($filePath); + } + } + + public function tearDown() + { + $filePath = $this->getTestFilePath(); + if (file_exists($filePath)) { + FileHelper::removeDirectory($filePath); + } + } + + /** + * @return string test file path. + */ + protected function getTestFilePath() + { + return Yii::getAlias('@yiiunit/runtime') . DIRECTORY_SEPARATOR . basename(get_class($this)) . '_' . getmypid(); + } + + /** + * @return Mailer test email component instance. + */ + protected function createTestEmailComponent() + { + $component = new Mailer(); + return $component; + } + + // Tests : + + public function testSetupView() + { + $mailer = new Mailer(); + + $view = new View(); + $mailer->setView($view); + $this->assertEquals($view, $mailer->getView(), 'Unable to setup view!'); + + $viewConfig = [ + 'params' => [ + 'param1' => 'value1', + 'param2' => 'value2', + ] + ]; + $mailer->setView($viewConfig); + $view = $mailer->getView(); + $this->assertTrue(is_object($view), 'Unable to setup view via config!'); + $this->assertEquals($viewConfig['params'], $view->params, 'Unable to configure view via config array!'); + } + + /** + * @depends testSetupView + */ + public function testGetDefaultView() + { + $mailer = new Mailer(); + $view = $mailer->getView(); + $this->assertTrue(is_object($view), 'Unable to get default view!'); + } + + public function testSetupViewResolver() + { + $mailer = new Mailer(); + + $viewResolver = new ViewResolver(); + $mailer->setViewResolver($viewResolver); + $this->assertEquals($viewResolver, $mailer->getViewResolver(), 'Unable to setup view resolver!'); + + $viewResolverConfig = [ + 'viewPath' => '/test/view/path', + ]; + $mailer->setViewResolver($viewResolverConfig); + $viewResolver = $mailer->getViewResolver(); + $this->assertTrue(is_object($viewResolver), 'Unable to setup view resolver via config!'); + $this->assertEquals($viewResolverConfig['viewPath'], $viewResolver->viewPath, 'Unable to configure view resolver via config array!'); + } + + /** + * @depends testSetupViewResolver + */ + public function testGetDefaultViewResolver() + { + $mailer = new Mailer(); + $viewResolver = $mailer->getViewResolver(); + $this->assertTrue(is_object($viewResolver), 'Unable to get default view resolver!'); + } + + public function testDefaultMessageConfig() + { + $defaultMessageConfig = array( + 'id' => 'test-id', + 'encoding' => 'test-encoding', + ); + Yii::$app->getComponent('email')->setDefaultMessageConfig($defaultMessageConfig); + + $message = new Message(); + + foreach ($defaultMessageConfig as $name => $value) { + $this->assertEquals($value, $message->$name); + } + } + + /** + * @depends testGetDefaultView + * @depends testGetDefaultViewResolver + */ + public function testRender() + { + $mailer = new Mailer(); + + $filePath = $this->getTestFilePath(); + $mailer->getViewResolver()->viewPath = $filePath; + + $viewName = 'test_view'; + $fileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; + $fileContent = ''; + file_put_contents($fileName, $fileContent); + + $params = [ + 'testParam' => 'test output' + ]; + $renderResult = $mailer->render($viewName, $params); + $this->assertEquals($params['testParam'], $renderResult); + } +} + +/** + * Test Mailer class + */ +class Mailer extends BaseMailer +{ + public $sentMessages = array(); + + public function send($message) + { + $this->sentMessages[] = $message; + } +} + +/** + * Test Message class + */ +class Message extends BaseMessage +{ + public $id; + public $encoding; + + public function setFrom($from) {} + + public function setTo($to) {} + + public function setCc($cc) {} + + public function setBcc($bcc) {} + + public function setSubject($subject) {} + + public function setText($text) {} + + public function setHtml($html) {} + + public function addText($text) {} + + public function addHtml($html) {} + + public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') {} +} \ No newline at end of file diff --git a/tests/unit/framework/mail/ViewResolverTest.php b/tests/unit/framework/mail/ViewResolverTest.php new file mode 100644 index 0000000..4ff4dbd --- /dev/null +++ b/tests/unit/framework/mail/ViewResolverTest.php @@ -0,0 +1,61 @@ +testViewPath); + return [ + [ + $alias . '/test', + $aliasPath . '/test.php', + ], + [ + $alias . '/test.tpl', + $aliasPath . '/test.tpl', + ], + [ + 'contact/html', + $viewPath . '/contact/html.php', + ], + [ + 'contact/html.tpl', + $viewPath . '/contact/html.tpl', + ], + ]; + } + + /** + * @dataProvider dataProviderFindViewFile + * + * @param string $view + * @param string $expectedFileName + */ + public function testFindViewFile($view, $expectedFileName) + { + $viewResolver = new ViewResolver(); + $viewResolver->viewPath = $this->testViewPath; + $fileName = $viewResolver->findViewFile($view); + $this->assertEquals($expectedFileName, $fileName); + } +} \ No newline at end of file From c7c32659b0d0dec85d63b75eedc6dfc303deae03 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Fri, 25 Oct 2013 14:49:43 +0300 Subject: [PATCH 06/31] Vendor testing support provided. 'swiftmailer' extension unit tests fixed. --- .travis.yml | 2 +- extensions/swiftmailer/yii/swiftmailer/Mailer.php | 2 +- extensions/swiftmailer/yii/swiftmailer/Message.php | 2 +- tests/unit/VendorTestCase.php | 30 ++++++++++++++++++++++ tests/unit/extensions/swiftmailer/MailerTest.php | 14 +++++----- tests/unit/extensions/swiftmailer/MessageTest.php | 14 +++++----- 6 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 tests/unit/VendorTestCase.php diff --git a/.travis.yml b/.travis.yml index 0218654..99ff95a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_script: - tests/unit/data/travis/cubrid-setup.sh script: - - phpunit --coverage-clover tests/unit/runtime/coveralls/clover.xml --verbose --exclude-group mssql,oci,wincache,xcache,zenddata,swiftmailer + - phpunit --coverage-clover tests/unit/runtime/coveralls/clover.xml --verbose --exclude-group mssql,oci,wincache,xcache,zenddata,vendor after_script: - php vendor/bin/coveralls diff --git a/extensions/swiftmailer/yii/swiftmailer/Mailer.php b/extensions/swiftmailer/yii/swiftmailer/Mailer.php index 2f8bbe7..1d5bc5c 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Mailer.php +++ b/extensions/swiftmailer/yii/swiftmailer/Mailer.php @@ -8,7 +8,7 @@ namespace yii\swiftmailer; use yii\base\InvalidConfigException; -use yii\email\BaseMailer; +use yii\mail\BaseMailer; /** * Mailer based on SwiftMailer library. diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index e850208..7cf3032 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -7,7 +7,7 @@ namespace yii\swiftmailer; -use yii\email\BaseMessage; +use yii\mail\BaseMessage; /** * Email message based on SwiftMailer library. diff --git a/tests/unit/VendorTestCase.php b/tests/unit/VendorTestCase.php new file mode 100644 index 0000000..d633d02 --- /dev/null +++ b/tests/unit/VendorTestCase.php @@ -0,0 +1,30 @@ +mockApplication(array( - 'vendorPath' => Yii::getAlias('@yiiunit/vendor') - )); - Yii::$app->setComponent('email', $this->createTestEmailComponent()); + $this->mockApplication([ + 'components' => [ + 'email' => $this->createTestEmailComponent() + ] + ]); } /** diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index cabf22a..530d725 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -5,13 +5,14 @@ namespace yiiunit\extensions\swiftmailer; use Yii; use yii\swiftmailer\Mailer; use yii\swiftmailer\Message; -use yiiunit\TestCase; +use yiiunit\VendorTestCase; /** + * @group vendor * @group email * @group swiftmailer */ -class MessageTest extends TestCase +class MessageTest extends VendorTestCase { /** * @var string test email address, which will be used as receiver for the messages. @@ -20,10 +21,11 @@ class MessageTest extends TestCase public function setUp() { - $this->mockApplication(array( - 'vendorPath' => Yii::getAlias('@yiiunit/vendor') - )); - Yii::$app->setComponent('email', $this->createTestEmailComponent()); + $this->mockApplication([ + 'components' => [ + 'email' => $this->createTestEmailComponent() + ] + ]); } /** From 4a9d546c7914db54df5a4f7a5046c814d9d898af Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Fri, 25 Oct 2013 16:08:14 +0300 Subject: [PATCH 07/31] 'MessageInterface::createAttachment()' renamed to 'MessageInterface::attachContentAsFile()' --- extensions/swiftmailer/yii/swiftmailer/Message.php | 2 +- framework/yii/mail/BaseMessage.php | 2 +- framework/yii/mail/MessageInterface.php | 4 ++-- tests/unit/extensions/swiftmailer/MessageTest.php | 2 +- tests/unit/framework/mail/BaseMailerTest.php | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index 7cf3032..8ae3ee4 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -115,7 +115,7 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') + public function attachContentAsFile($content, $fileName, $contentType = 'application/octet-stream') { if (empty($contentType)) { $contentType = 'application/octet-stream'; diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index 17658f4..5593cec 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -75,7 +75,7 @@ abstract class BaseMessage extends Object implements MessageInterface $attachFileName = basename($fileName); } $content = file_get_contents($fileName); - $this->createAttachment($content, $attachFileName, $contentType); + $this->attachContentAsFile($content, $attachFileName, $contentType); } /** diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index c592edb..28223a4 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -82,12 +82,12 @@ interface MessageInterface public function addHtml($html); /** - * Create file attachment for the email message. + * Attach specified content as file for the email message. * @param string $content attachment file content. * @param string $fileName attachment file name. * @param string $contentType MIME type of the attachment file, by default 'application/octet-stream' will be used. */ - public function createAttachment($content, $fileName, $contentType = 'application/octet-stream'); + public function attachContentAsFile($content, $fileName, $contentType = 'application/octet-stream'); /** * Attaches existing file to the email message. diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index 530d725..dabe831 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -82,7 +82,7 @@ class MessageTest extends VendorTestCase $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Create Attachment Test'); $message->setText('Yii Swift Create Attachment Test body'); - $message->createAttachment('Test attachment content', 'test.txt'); + $message->attachContentAsFile('Test attachment content', 'test.txt'); $this->assertTrue($message->send()); } diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 88d6a4e..95bd836 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -187,5 +187,5 @@ class Message extends BaseMessage public function addHtml($html) {} - public function createAttachment($content, $fileName, $contentType = 'application/octet-stream') {} + public function attachContentAsFile($content, $fileName, $contentType = 'application/octet-stream') {} } \ No newline at end of file From d33519e3e5afffddeed7dc5e6cbd359b7ad27fd4 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Fri, 25 Oct 2013 16:58:30 +0300 Subject: [PATCH 08/31] Method 'MessageInterface::__toString()' added --- extensions/swiftmailer/yii/swiftmailer/Message.php | 48 ++++++++++++++++++++++ framework/yii/mail/MessageInterface.php | 7 ++++ tests/unit/framework/mail/BaseMailerTest.php | 5 +++ 3 files changed, 60 insertions(+) diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index 8ae3ee4..bfefcde 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -49,6 +49,14 @@ class Message extends BaseMessage } /** + * @return string from address of this message. + */ + public function getFrom() + { + return $this->getSwiftMessage()->getFrom(); + } + + /** * @inheritdoc */ public function setTo($to) @@ -57,6 +65,14 @@ class Message extends BaseMessage } /** + * @return array To addresses of this message. + */ + public function getTo() + { + return $this->getSwiftMessage()->getTo(); + } + + /** * @inheritdoc */ public function setCc($cc) @@ -65,6 +81,14 @@ class Message extends BaseMessage } /** + * @return array Cc address of this message. + */ + public function getCc() + { + return $this->getSwiftMessage()->getCc(); + } + + /** * @inheritdoc */ public function setBcc($bcc) @@ -73,6 +97,14 @@ class Message extends BaseMessage } /** + * @return array Bcc addresses of this message. + */ + public function getBcc() + { + return $this->getSwiftMessage()->getBcc(); + } + + /** * @inheritdoc */ public function setSubject($subject) @@ -81,6 +113,14 @@ class Message extends BaseMessage } /** + * @return string the subject of this message. + */ + public function getSubject() + { + return $this->getSwiftMessage()->getSubject(); + } + + /** * @inheritdoc */ public function setText($text) @@ -123,4 +163,12 @@ class Message extends BaseMessage $attachment = \Swift_Attachment::newInstance($content, $fileName, $contentType); $this->getSwiftMessage()->attach($attachment); } + + /** + * @inheritdoc + */ + public function __toString() + { + return $this->getSwiftMessage()->toString(); + } } \ No newline at end of file diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 28223a4..48a4f10 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -113,4 +113,11 @@ interface MessageInterface * @return string string the rendering result */ public function render($view, $params = []); + + /** + * String output. + * This is PHP magic method that returns string representation of an object. + * @return string the string representation of the object + */ + public function __toString(); } \ No newline at end of file diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 95bd836..e80ca0c 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -188,4 +188,9 @@ class Message extends BaseMessage public function addHtml($html) {} public function attachContentAsFile($content, $fileName, $contentType = 'application/octet-stream') {} + + public function __toString() + { + return get_class($this); + } } \ No newline at end of file From 73a8e77c3d1dde759d01f95073c0124554fb1f58 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Fri, 25 Oct 2013 17:03:33 +0300 Subject: [PATCH 09/31] BaseMailer::defaultMessageConfig published as BaseMailer::messageConfig --- framework/yii/mail/BaseMailer.php | 18 +----------------- framework/yii/mail/BaseMessage.php | 2 +- tests/unit/framework/mail/BaseMailerTest.php | 6 +++--- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index 8e88749..a78b6fc 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -48,7 +48,7 @@ abstract class BaseMailer extends Component * ) * ~~~ */ - private $_defaultMessageConfig = []; + public $messageConfig = []; /** * @param array|\yii\base\View $view view instance or its array configuration. @@ -97,22 +97,6 @@ abstract class BaseMailer extends Component } /** - * @param array $defaultMessageConfig default message config - */ - public function setDefaultMessageConfig(array $defaultMessageConfig) - { - $this->_defaultMessageConfig = $defaultMessageConfig; - } - - /** - * @return array default message config - */ - public function getDefaultMessageConfig() - { - return $this->_defaultMessageConfig; - } - - /** * Creates view instance from given configuration. * @param array $config view configuration. * @return \yii\base\View view instance. diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index 5593cec..f48310c 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -49,7 +49,7 @@ abstract class BaseMessage extends Object implements MessageInterface */ public function init() { - Yii::configure($this, $this->getMailer()->getDefaultMessageConfig()); + Yii::configure($this, $this->getMailer()->messageConfig); } /** diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index e80ca0c..84bb293 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -111,15 +111,15 @@ class BaseMailerTest extends TestCase public function testDefaultMessageConfig() { - $defaultMessageConfig = array( + $messageConfig = array( 'id' => 'test-id', 'encoding' => 'test-encoding', ); - Yii::$app->getComponent('email')->setDefaultMessageConfig($defaultMessageConfig); + Yii::$app->getComponent('email')->messageConfig = $messageConfig; $message = new Message(); - foreach ($defaultMessageConfig as $name => $value) { + foreach ($messageConfig as $name => $value) { $this->assertEquals($value, $message->$name); } } From 5bc22a077fafa0e8f1100d274dcf407205bdc8c8 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Tue, 29 Oct 2013 12:13:26 +0200 Subject: [PATCH 10/31] Interface 'MailerInterface' extracted. Method 'MailerInterface::createMessage()' added. --- extensions/swiftmailer/yii/swiftmailer/Mailer.php | 17 ++++---- extensions/swiftmailer/yii/swiftmailer/Message.php | 11 +++++- framework/yii/mail/BaseMailer.php | 30 ++++++++++----- framework/yii/mail/BaseMessage.php | 12 +----- framework/yii/mail/MailerInterface.php | 40 +++++++++++++++++++ framework/yii/mail/Message.php | 45 ---------------------- framework/yii/mail/MessageInterface.php | 2 +- tests/unit/extensions/swiftmailer/MailerTest.php | 9 +---- tests/unit/extensions/swiftmailer/MessageTest.php | 20 +++++++--- tests/unit/framework/mail/BaseMailerTest.php | 37 +++++++++++++++--- tests/unit/framework/mail/ViewResolverTest.php | 2 +- 11 files changed, 128 insertions(+), 97 deletions(-) create mode 100644 framework/yii/mail/MailerInterface.php delete mode 100644 framework/yii/mail/Message.php diff --git a/extensions/swiftmailer/yii/swiftmailer/Mailer.php b/extensions/swiftmailer/yii/swiftmailer/Mailer.php index 1d5bc5c..f53001b 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Mailer.php +++ b/extensions/swiftmailer/yii/swiftmailer/Mailer.php @@ -19,7 +19,7 @@ use yii\mail\BaseMailer; * 'components' => array( * ... * 'email' => array( - * 'class' => 'yii\email\swift\Mailer', + * 'class' => 'yii\swiftmailer\Mailer', * 'transport' => [ * 'class' => 'Swift_SmtpTransport', * 'host' => 'localhost', @@ -35,12 +35,18 @@ use yii\mail\BaseMailer; * * @see http://swiftmailer.org * + * @method Message createMessage(array $config = []) creates new message instance from given configuration. + * * @author Paul Klimov * @since 2.0 */ class Mailer extends BaseMailer { /** + * @var string message default class name. + */ + public $messageClass = 'yii\swiftmailer\Message'; + /** * @var \Swift_Mailer Swift mailer instance. */ private $_swiftMailer; @@ -131,13 +137,4 @@ class Mailer extends BaseMailer } return $transport; } - - /** - * Creates the Swift email message instance. - * @return \Swift_Message email message instance. - */ - public function createSwiftMessage() - { - return new \Swift_Message(); - } } \ No newline at end of file diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index bfefcde..7fc908b 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -34,7 +34,7 @@ class Message extends BaseMessage public function getSwiftMessage() { if (!is_object($this->_swiftMessage)) { - $this->_swiftMessage = $this->getMailer()->createSwiftMessage(); + $this->_swiftMessage = $this->createSwiftMessage(); } return $this->_swiftMessage; } @@ -171,4 +171,13 @@ class Message extends BaseMessage { return $this->getSwiftMessage()->toString(); } + + /** + * Creates the Swift email message instance. + * @return \Swift_Message email message instance. + */ + protected function createSwiftMessage() + { + return new \Swift_Message(); + } } \ No newline at end of file diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index a78b6fc..ea7690b 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -20,13 +20,11 @@ use Yii; * * @property \yii\base\View|array $view view instance or its array configuration. * @property \yii\mail\ViewResolver|array $viewResolver view resolver instance or its array configuration. - * @property array $defaultMessageConfig configuration, which should be applied by default to any - * new created email message instance. * * @author Paul Klimov * @since 2.0 */ -abstract class BaseMailer extends Component +abstract class BaseMailer extends Component implements MailerInterface { /** * @var \yii\base\View|array view instance or its array configuration. @@ -49,6 +47,10 @@ abstract class BaseMailer extends Component * ~~~ */ public $messageConfig = []; + /** + * @var string message default class name. + */ + public $messageClass = 'yii\mail\BaseMessage'; /** * @param array|\yii\base\View $view view instance or its array configuration. @@ -123,11 +125,20 @@ abstract class BaseMailer extends Component } /** - * Sends the given email message. - * @param object $message email message instance - * @return boolean whether the message has been sent. + * Creates new message instance from given configuration. + * Message configuration will be merged with [[messageConfig]]. + * If 'class' parameter is omitted [[messageClass]], will be used. + * @param array $config message configuration. + * @return MessageInterface message instance. */ - abstract public function send($message); + public function createMessage(array $config = []) + { + $config = array_merge($this->messageConfig, $config); + if (!array_key_exists('class', $config)) { + $config['class'] = $this->messageClass; + } + return Yii::createObject($config); + } /** * Sends a couple of messages at once. @@ -135,9 +146,10 @@ abstract class BaseMailer extends Component * saving resources, for example on open/close connection operations, * they may override this method to create their specific implementation. * @param array $messages list of email messages, which should be sent. - * @return integer number of successfull sends + * @return integer number of successful sends. */ - public function sendMultiple(array $messages) { + public function sendMultiple(array $messages) + { $successCount = 0; foreach ($messages as $message) { if ($this->send($message)) { diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index f48310c..b573b16 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -39,17 +39,7 @@ abstract class BaseMessage extends Object implements MessageInterface */ public function getMailer() { - return Yii::$app->getComponent('email'); - } - - /** - * Initializes the object. - * This method is invoked at the end of the constructor after the object is initialized with the - * given configuration. - */ - public function init() - { - Yii::configure($this, $this->getMailer()->messageConfig); + return Yii::$app->getComponent('mail'); } /** diff --git a/framework/yii/mail/MailerInterface.php b/framework/yii/mail/MailerInterface.php new file mode 100644 index 0000000..60e231c --- /dev/null +++ b/framework/yii/mail/MailerInterface.php @@ -0,0 +1,40 @@ + + * @since 2.0 + */ +interface MailerInterface +{ + /** + * Creates new message instance from given configuration. + * @param array $config message configuration. + * @return MessageInterface message instance. + */ + public function createMessage(array $config = []); + + /** + * Sends the given email message. + * @param object $message email message instance + * @return boolean whether the message has been sent. + */ + public function send($message); + + /** + * Sends a couple of messages at once. + * Note: some particular mailers may benefit from sending messages as batch, + * saving resources, for example on open/close connection operations. + * @param array $messages list of email messages, which should be sent. + * @return integer number of successful sends. + */ + public function sendMultiple(array $messages); +} \ No newline at end of file diff --git a/framework/yii/mail/Message.php b/framework/yii/mail/Message.php deleted file mode 100644 index fb34e24..0000000 --- a/framework/yii/mail/Message.php +++ /dev/null @@ -1,45 +0,0 @@ -from = 'sender@domain.com'; - * $email->to = 'receiver@domain.com'; - * $email->subject = 'Message Subject'; - * $email->text = 'Message Content'; - * $email->send(); - * ~~~ - * - * You can use message object to render view, which can be used to compose the message content: - * ~~~ - * $email = new Message(); - * $email->from = $contactForm->email; - * $email->to = 'admin@domain.com'; - * $email->subject = $email->render('contact/subject', ['form' => $contactForm]); - * $email->addHtml($email->render('contact/html', ['form' => $contactForm])); - * $email->addText($email->render('contact/text', ['form' => $contactForm])); - * $email->send(); - * ~~~ - * - * This particular class uses 'SwiftMailer' library to perform the message sending. - * Note: you can replace usage of this class by your own one, using [[Yii::$classMap]]: - * ~~~ - * Yii::$classMap['yii\mail\Message'] = '/path/to/my/email/Message.php' - * ~~~ - * - * @author Paul Klimov - * @since 2.0 - */ -class Message extends SwiftMessage {} \ No newline at end of file diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 48a4f10..cdf2d3d 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -8,7 +8,7 @@ namespace yii\mail; /** - * Class MessageInterface + * MessageInterface is an interface, which email message should apply. * * @author Paul Klimov * @since 2.0 diff --git a/tests/unit/extensions/swiftmailer/MailerTest.php b/tests/unit/extensions/swiftmailer/MailerTest.php index 14c3719..306e128 100644 --- a/tests/unit/extensions/swiftmailer/MailerTest.php +++ b/tests/unit/extensions/swiftmailer/MailerTest.php @@ -9,7 +9,7 @@ use yiiunit\VendorTestCase; /** * @group vendor - * @group email + * @group mail * @group swiftmailer */ class MailerTest extends VendorTestCase @@ -66,11 +66,4 @@ class MailerTest extends VendorTestCase $mailer = new Mailer(); $this->assertTrue(is_object($mailer->getSwiftMailer()), 'Unable to get Swift mailer instance!'); } - - public function testCreateSwiftMessage() - { - $mailer = new Mailer(); - $message = $mailer->createSwiftMessage(); - $this->assertTrue(is_object($message), 'Unable to create Swift message instance!'); - } } \ No newline at end of file diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index dabe831..d55ac3a 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -9,7 +9,7 @@ use yiiunit\VendorTestCase; /** * @group vendor - * @group email + * @group mail * @group swiftmailer */ class MessageTest extends VendorTestCase @@ -23,7 +23,7 @@ class MessageTest extends VendorTestCase { $this->mockApplication([ 'components' => [ - 'email' => $this->createTestEmailComponent() + 'mail' => $this->createTestEmailComponent() ] ]); } @@ -37,6 +37,14 @@ class MessageTest extends VendorTestCase return $component; } + /** + * @return Message test message instance. + */ + protected function createTestMessage() + { + return Yii::$app->getComponent('mail')->createMessage(); + } + // Tests : public function testGetSwiftMessage() @@ -50,7 +58,7 @@ class MessageTest extends VendorTestCase */ public function testSend() { - $message = new Message(); + $message = $this->createTestMessage(); $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Test'); @@ -63,7 +71,7 @@ class MessageTest extends VendorTestCase */ public function testAttachFile() { - $message = new Message(); + $message = $this->createTestMessage(); $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Attach File Test'); @@ -77,7 +85,7 @@ class MessageTest extends VendorTestCase */ public function testCreateAttachment() { - $message = new Message(); + $message = $this->createTestMessage(); $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Create Attachment Test'); @@ -91,7 +99,7 @@ class MessageTest extends VendorTestCase */ public function testSendAlternativeBody() { - $message = new Message(); + $message = $this->createTestMessage(); $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Alternative Body Test'); diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 84bb293..ff37da2 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -11,14 +11,17 @@ use yii\helpers\FileHelper; use yiiunit\TestCase; /** - * @group email + * @group mail */ class BaseMailerTest extends TestCase { public function setUp() { - $this->mockApplication(); - Yii::$app->setComponent('email', $this->createTestEmailComponent()); + $this->mockApplication([ + 'components' => [ + 'mail' => $this->createTestEmailComponent() + ] + ]); $filePath = $this->getTestFilePath(); if (!file_exists($filePath)) { FileHelper::createDirectory($filePath); @@ -109,15 +112,38 @@ class BaseMailerTest extends TestCase $this->assertTrue(is_object($viewResolver), 'Unable to get default view resolver!'); } + public function testCreateMessage() + { + $mailer = new Mailer(); + $message = $mailer->createMessage(); + $this->assertTrue(is_object($message), 'Unable to create message instance!'); + $this->assertEquals($mailer->messageClass, get_class($message), 'Invalid message class!'); + + $messageConfig = array( + 'id' => 'test-id', + 'encoding' => 'test-encoding', + ); + $message = $mailer->createMessage($messageConfig); + + foreach ($messageConfig as $name => $value) { + $this->assertEquals($value, $message->$name, 'Unable to apply message config!'); + } + } + + /** + * @depends testCreateMessage + */ public function testDefaultMessageConfig() { + $mailer = new Mailer(); + $messageConfig = array( 'id' => 'test-id', 'encoding' => 'test-encoding', ); - Yii::$app->getComponent('email')->messageConfig = $messageConfig; + $mailer->messageConfig = $messageConfig; - $message = new Message(); + $message = $mailer->createMessage(); foreach ($messageConfig as $name => $value) { $this->assertEquals($value, $message->$name); @@ -153,6 +179,7 @@ class BaseMailerTest extends TestCase */ class Mailer extends BaseMailer { + public $messageClass = 'yiiunit\framework\mail\Message'; public $sentMessages = array(); public function send($message) diff --git a/tests/unit/framework/mail/ViewResolverTest.php b/tests/unit/framework/mail/ViewResolverTest.php index 4ff4dbd..5caa947 100644 --- a/tests/unit/framework/mail/ViewResolverTest.php +++ b/tests/unit/framework/mail/ViewResolverTest.php @@ -7,7 +7,7 @@ use Yii; use yiiunit\TestCase; /** - * @group email + * @group mail */ class ViewResolverTest extends TestCase { From 35429fbd440887bb0ddd6f05b65ba88e0f7d25f7 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Tue, 29 Oct 2013 12:34:08 +0200 Subject: [PATCH 11/31] 'yii\mail\ViewResolve' removed. Interface 'ViewContextInterface' applied to BaseMailer. --- framework/yii/mail/BaseMailer.php | 55 +++++++---------------- framework/yii/mail/ViewResolver.php | 57 ------------------------ tests/unit/framework/mail/BaseMailerTest.php | 30 +------------ tests/unit/framework/mail/ViewResolverTest.php | 61 -------------------------- 4 files changed, 16 insertions(+), 187 deletions(-) delete mode 100644 framework/yii/mail/ViewResolver.php delete mode 100644 tests/unit/framework/mail/ViewResolverTest.php diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index ea7690b..e5a1dde 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -10,6 +10,7 @@ namespace yii\mail; use yii\base\Component; use yii\base\InvalidConfigException; use Yii; +use yii\base\ViewContextInterface; /** * BaseMailer provides the basic interface for the email mailer application component. @@ -24,16 +25,16 @@ use Yii; * @author Paul Klimov * @since 2.0 */ -abstract class BaseMailer extends Component implements MailerInterface +abstract class BaseMailer extends Component implements MailerInterface, ViewContextInterface { /** * @var \yii\base\View|array view instance or its array configuration. */ private $_view = []; /** - * @var \yii\mail\ViewResolver|array view resolver instance or its array configuration. + * @var string directory containing view files for this email messages. */ - private $_viewResolver = []; + public $viewPath = '@app/mailviews'; /** * @var array configuration, which should be applied by default to any new created * email message instance. @@ -76,29 +77,6 @@ abstract class BaseMailer extends Component implements MailerInterface } /** - * @param array|\yii\mail\ViewResolver $viewResolver view resolver instance or its array configuration. - * @throws \yii\base\InvalidConfigException on invalid argument. - */ - public function setViewResolver($viewResolver) - { - if (!is_array($viewResolver) && !is_object($viewResolver)) { - throw new InvalidConfigException('"' . get_class($this) . '::viewResolver" should be either object or array, "' . gettype($viewResolver) . '" given.'); - } - $this->_viewResolver = $viewResolver; - } - - /** - * @return \yii\mail\ViewResolver view resolver. - */ - public function getViewResolver() - { - if (!is_object($this->_viewResolver)) { - $this->_viewResolver = $this->createViewResolver($this->_viewResolver); - } - return $this->_viewResolver; - } - - /** * Creates view instance from given configuration. * @param array $config view configuration. * @return \yii\base\View view instance. @@ -112,19 +90,6 @@ abstract class BaseMailer extends Component implements MailerInterface } /** - * Creates view resolver instance from given configuration. - * @param array $config view resolver configuration. - * @return \yii\mail\ViewResolver view resolver instance. - */ - protected function createViewResolver(array $config) - { - if (!array_key_exists('class', $config)) { - $config['class'] = '\yii\mail\ViewResolver'; - } - return Yii::createObject($config); - } - - /** * Creates new message instance from given configuration. * Message configuration will be merged with [[messageConfig]]. * If 'class' parameter is omitted [[messageClass]], will be used. @@ -167,6 +132,16 @@ abstract class BaseMailer extends Component implements MailerInterface */ public function render($view, $params = []) { - return $this->getView()->renderFile($this->getViewResolver()->findViewFile($view), $params, $this); + return $this->getView()->render($view, $params, $this); + } + + /** + * Finds the view file corresponding to the specified relative view name. + * @param string $view a relative view name. The name does NOT start with a slash. + * @return string the view file path. Note that the file may not exist. + */ + public function findViewFile($view) + { + return Yii::getAlias($this->viewPath) . DIRECTORY_SEPARATOR . $view; } } \ No newline at end of file diff --git a/framework/yii/mail/ViewResolver.php b/framework/yii/mail/ViewResolver.php deleted file mode 100644 index 31f57cb..0000000 --- a/framework/yii/mail/ViewResolver.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @since 2.0 - */ -class ViewResolver extends Component -{ - /** - * @var string directory containing view files for this email messages. - */ - public $viewPath = '@app/emails'; - - /** - * Finds the view file based on the given view name. - * The view to be rendered can be specified in one of the following formats: - * - path alias (e.g. "@app/emails/contact/body"); - * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. - * @param string $view the view name or the path alias of the view file. - * @return string the view file path. Note that the file may not exist. - */ - public function findViewFile($view) - { - if (strncmp($view, '@', 1) === 0) { - // e.g. "@app/views/main" - $file = Yii::getAlias($view); - } else { - $file = $this->resolveView($view); - } - return pathinfo($file, PATHINFO_EXTENSION) === '' ? $file . '.php' : $file; - } - - /** - * Composes file name for the view name, appending view name to [[viewPath]]. - * Child classes may override this method to provide more sophisticated - * search of the view files or even composition of the view files "on the fly". - * @param string $view the view name. - * @return string the view file path. - */ - protected function resolveView($view) - { - return Yii::getAlias($this->viewPath) . DIRECTORY_SEPARATOR . $view; - } -} \ No newline at end of file diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index ff37da2..cded1e4 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -85,33 +85,6 @@ class BaseMailerTest extends TestCase $this->assertTrue(is_object($view), 'Unable to get default view!'); } - public function testSetupViewResolver() - { - $mailer = new Mailer(); - - $viewResolver = new ViewResolver(); - $mailer->setViewResolver($viewResolver); - $this->assertEquals($viewResolver, $mailer->getViewResolver(), 'Unable to setup view resolver!'); - - $viewResolverConfig = [ - 'viewPath' => '/test/view/path', - ]; - $mailer->setViewResolver($viewResolverConfig); - $viewResolver = $mailer->getViewResolver(); - $this->assertTrue(is_object($viewResolver), 'Unable to setup view resolver via config!'); - $this->assertEquals($viewResolverConfig['viewPath'], $viewResolver->viewPath, 'Unable to configure view resolver via config array!'); - } - - /** - * @depends testSetupViewResolver - */ - public function testGetDefaultViewResolver() - { - $mailer = new Mailer(); - $viewResolver = $mailer->getViewResolver(); - $this->assertTrue(is_object($viewResolver), 'Unable to get default view resolver!'); - } - public function testCreateMessage() { $mailer = new Mailer(); @@ -152,14 +125,13 @@ class BaseMailerTest extends TestCase /** * @depends testGetDefaultView - * @depends testGetDefaultViewResolver */ public function testRender() { $mailer = new Mailer(); $filePath = $this->getTestFilePath(); - $mailer->getViewResolver()->viewPath = $filePath; + $mailer->viewPath = $filePath; $viewName = 'test_view'; $fileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; diff --git a/tests/unit/framework/mail/ViewResolverTest.php b/tests/unit/framework/mail/ViewResolverTest.php deleted file mode 100644 index 5caa947..0000000 --- a/tests/unit/framework/mail/ViewResolverTest.php +++ /dev/null @@ -1,61 +0,0 @@ -testViewPath); - return [ - [ - $alias . '/test', - $aliasPath . '/test.php', - ], - [ - $alias . '/test.tpl', - $aliasPath . '/test.tpl', - ], - [ - 'contact/html', - $viewPath . '/contact/html.php', - ], - [ - 'contact/html.tpl', - $viewPath . '/contact/html.tpl', - ], - ]; - } - - /** - * @dataProvider dataProviderFindViewFile - * - * @param string $view - * @param string $expectedFileName - */ - public function testFindViewFile($view, $expectedFileName) - { - $viewResolver = new ViewResolver(); - $viewResolver->viewPath = $this->testViewPath; - $fileName = $viewResolver->findViewFile($view); - $this->assertEquals($expectedFileName, $fileName); - } -} \ No newline at end of file From 774c4db860d6b2a4327dbc8502ff78892b248d19 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Tue, 29 Oct 2013 14:06:16 +0200 Subject: [PATCH 12/31] 'yii\mail\MessageInterface' file related methods interface adjusted to use options, embed file methods added. --- extensions/swiftmailer/yii/swiftmailer/Message.php | 56 +++++++++++++-- framework/yii/mail/BaseMessage.php | 18 ----- framework/yii/mail/MessageInterface.php | 36 ++++++++-- tests/unit/extensions/swiftmailer/MessageTest.php | 83 +++++++++++++++++++++- tests/unit/framework/mail/BaseMailerTest.php | 8 ++- 5 files changed, 170 insertions(+), 31 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index 7fc908b..808fbf8 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -155,18 +155,66 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function attachContentAsFile($content, $fileName, $contentType = 'application/octet-stream') + public function attachFile($fileName, array $options = []) { - if (empty($contentType)) { - $contentType = 'application/octet-stream'; + $attachment = \Swift_Attachment::fromPath($fileName); + if (!empty($options['fileName'])) { + $attachment->setFilename($options['fileName']); + } + if (!empty($options['contentType'])) { + $attachment->setContentType($options['contentType']); } - $attachment = \Swift_Attachment::newInstance($content, $fileName, $contentType); $this->getSwiftMessage()->attach($attachment); } /** * @inheritdoc */ + public function attachContent($content, array $options = []) + { + $attachment = \Swift_Attachment::newInstance($content); + if (!empty($options['fileName'])) { + $attachment->setFilename($options['fileName']); + } + if (!empty($options['contentType'])) { + $attachment->setContentType($options['contentType']); + } + $this->getSwiftMessage()->attach($attachment); + } + + /** + * @inheritdoc + */ + public function embedFile($fileName, array $options = []) + { + $embedFile = \Swift_EmbeddedFile::fromPath($fileName); + if (!empty($options['fileName'])) { + $embedFile->setFilename($options['fileName']); + } + if (!empty($options['contentType'])) { + $embedFile->setContentType($options['contentType']); + } + return $this->getSwiftMessage()->embed($embedFile); + } + + /** + * @inheritdoc + */ + public function embedContent($content, array $options = []) + { + $embedFile = \Swift_EmbeddedFile::newInstance($content); + if (!empty($options['fileName'])) { + $embedFile->setFilename($options['fileName']); + } + if (!empty($options['contentType'])) { + $embedFile->setContentType($options['contentType']); + } + return $this->getSwiftMessage()->embed($embedFile); + } + + /** + * @inheritdoc + */ public function __toString() { return $this->getSwiftMessage()->toString(); diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index b573b16..8c4daa8 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -53,24 +53,6 @@ abstract class BaseMessage extends Object implements MessageInterface /** * @inheritdoc */ - public function attachFile($fileName, $contentType = null, $attachFileName = null) - { - if (!file_exists($fileName)) { - throw new InvalidParamException('Unable to attach file "' . $fileName . '": file does not exists!'); - } - if (empty($contentType)) { - $contentType = FileHelper::getMimeType($fileName); - } - if (empty($attachFileName)) { - $attachFileName = basename($fileName); - } - $content = file_get_contents($fileName); - $this->attachContentAsFile($content, $attachFileName, $contentType); - } - - /** - * @inheritdoc - */ public function render($view, $params = []) { return $this->getMailer()->render($view, $params); diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index cdf2d3d..0f3e5a4 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -84,18 +84,42 @@ interface MessageInterface /** * Attach specified content as file for the email message. * @param string $content attachment file content. - * @param string $fileName attachment file name. - * @param string $contentType MIME type of the attachment file, by default 'application/octet-stream' will be used. + * @param array $options options for embed file. Valid options are: + * - fileName: name, which should be used to attach file. + * - contentType: attached file MIME type. */ - public function attachContentAsFile($content, $fileName, $contentType = 'application/octet-stream'); + public function attachContent($content, array $options = []); /** * Attaches existing file to the email message. * @param string $fileName full file name - * @param string $contentType MIME type of the attachment file, if empty it will be suggested automatically. - * @param string $attachFileName name, which should be used for attachment, if empty file base name will be used. + * @param array $options options for embed file. Valid options are: + * - fileName: name, which should be used to attach file. + * - contentType: attached file MIME type. */ - public function attachFile($fileName, $contentType = null, $attachFileName = null); + public function attachFile($fileName, array $options = []); + + /** + * Attach a file and return it's CID source. + * This method should be used when embedding images or other data in a message. + * @param string $fileName file name. + * @param array $options options for embed file. Valid options are: + * - fileName: name, which should be used to attach file. + * - contentType: attached file MIME type. + * @return string attachment CID. + */ + public function embedFile($fileName, array $options = []); + + /** + * Attach a content as file and return it's CID source. + * This method should be used when embedding images or other data in a message. + * @param string $content attachment file content. + * @param array $options options for embed file. Valid options are: + * - fileName: name, which should be used to attach file. + * - contentType: attached file MIME type. + * @return string attachment CID. + */ + public function embedContent($content, array $options = []); /** * Sends this email message. diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index d55ac3a..0a02b6d 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -3,6 +3,7 @@ namespace yiiunit\extensions\swiftmailer; use Yii; +use yii\helpers\FileHelper; use yii\swiftmailer\Mailer; use yii\swiftmailer\Message; use yiiunit\VendorTestCase; @@ -26,6 +27,26 @@ class MessageTest extends VendorTestCase 'mail' => $this->createTestEmailComponent() ] ]); + $filePath = $this->getTestFilePath(); + if (!file_exists($filePath)) { + FileHelper::createDirectory($filePath); + } + } + + public function tearDown() + { + $filePath = $this->getTestFilePath(); + if (file_exists($filePath)) { + FileHelper::removeDirectory($filePath); + } + } + + /** + * @return string test file path. + */ + protected function getTestFilePath() + { + return Yii::getAlias('@yiiunit/runtime') . DIRECTORY_SEPARATOR . basename(get_class($this)) . '_' . getmypid(); } /** @@ -45,6 +66,26 @@ class MessageTest extends VendorTestCase return Yii::$app->getComponent('mail')->createMessage(); } + /** + * Creates image file with given text. + * @param string $fileName file name. + * @param string $text text to be applied on image. + * @return string image file full name. + */ + protected function createImageFile($fileName = 'test.jpg', $text = 'Test Image') + { + if (!function_exists('imagecreatetruecolor')) { + $this->markTestSkipped('GD lib required.'); + } + $fileFullName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . $fileName; + $image = imagecreatetruecolor(120, 20); + $textColor = imagecolorallocate($image, 233, 14, 91); + imagestring($image, 1, 5, 5, $text, $textColor); + imagejpeg($image, $fileFullName); + imagedestroy($image); + return $fileFullName; + } + // Tests : public function testGetSwiftMessage() @@ -83,14 +124,52 @@ class MessageTest extends VendorTestCase /** * @depends testSend */ - public function testCreateAttachment() + public function testAttachContent() { $message = $this->createTestMessage(); $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Create Attachment Test'); $message->setText('Yii Swift Create Attachment Test body'); - $message->attachContentAsFile('Test attachment content', 'test.txt'); + $message->attachContent('Test attachment content', ['fileName' => 'test.txt']); + $this->assertTrue($message->send()); + } + + /** + * @depends testSend + */ + public function testEmbedFile() + { + $fileName = $this->createImageFile('embed_file.jpg', 'Embed Image File'); + + $message = $this->createTestMessage(); + + $cid = $message->embedFile($fileName); + + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Embed File Test'); + $message->setHtml('Embed image: pic'); + + $this->assertTrue($message->send()); + } + + /** + * @depends testSend + */ + public function testEmbedContent() + { + $fileName = $this->createImageFile('embed_file.jpg', 'Embed Image File'); + + $message = $this->createTestMessage(); + + $cid = $message->embedContent(file_get_contents($fileName), ['contentType' => 'image/jpeg']); + + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Embed File Test'); + $message->setHtml('Embed image: pic'); + $this->assertTrue($message->send()); } diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index cded1e4..f135f51 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -186,7 +186,13 @@ class Message extends BaseMessage public function addHtml($html) {} - public function attachContentAsFile($content, $fileName, $contentType = 'application/octet-stream') {} + public function attachContent($content, array $options = []) {} + + public function attachFile($fileName, array $options = []) {} + + public function embedFile($fileName, array $options = []) {} + + public function embedContent($content, array $options = []) {} public function __toString() { From 1d0891f0f6bea4e3f6fbc7d5e1878aefe1ac133e Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Tue, 29 Oct 2013 16:04:20 +0200 Subject: [PATCH 13/31] 'yii\mail\MessageInterface' methods 'addText()' and 'addHtml()' removed. --- extensions/swiftmailer/yii/swiftmailer/Message.php | 54 ++++++++++++++++------ framework/yii/mail/MessageInterface.php | 12 ----- tests/unit/extensions/swiftmailer/MessageTest.php | 4 +- tests/unit/framework/mail/BaseMailerTest.php | 4 -- 4 files changed, 43 insertions(+), 31 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index 808fbf8..42d25e7 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -125,7 +125,7 @@ class Message extends BaseMessage */ public function setText($text) { - $this->getSwiftMessage()->setBody($text, 'text/plain'); + $this->setBody($text, 'text/plain'); } /** @@ -133,23 +133,51 @@ class Message extends BaseMessage */ public function setHtml($html) { - $this->getSwiftMessage()->setBody($html, 'text/html'); + $this->setBody($html, 'text/html'); } /** - * @inheritdoc + * Sets the message body. + * If body is already set and its content type matches given one, it will + * be overridden, if content type miss match the multipart message will be composed. + * @param string $body body content. + * @param string $contentType body content type. */ - public function addText($text) + protected function setBody($body, $contentType) { - $this->getSwiftMessage()->addPart($text, 'text/plain'); - } - - /** - * @inheritdoc - */ - public function addHtml($html) - { - $this->getSwiftMessage()->addPart($html, 'text/html'); + $message = $this->getSwiftMessage(); + $oldBody = $message->getBody(); + if (empty($oldBody)) { + $parts = $message->getChildren(); + $partFound = false; + foreach ($parts as $key => $part) { + if (!($part instanceof \Swift_Mime_Attachment)) { + /* @var $part \Swift_Mime_MimePart */ + if ($part->getContentType() == $contentType) { + unset($parts[$key]); + $partFound = true; + break; + } + } + } + if ($partFound) { + reset($parts); + $message->setChildren($parts); + $message->addPart($body, $contentType); + } else { + $message->setBody($body, $contentType); + } + } else { + $oldContentType = $message->getContentType(); + if ($oldContentType == $contentType) { + $message->setBody($body, $contentType); + } else { + $message->setBody(null); + $message->setContentType(null); + $message->addPart($oldBody, $oldContentType); + $message->addPart($body, $contentType); + } + } } /** diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 0f3e5a4..e7de37b 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -70,18 +70,6 @@ interface MessageInterface public function setHtml($html); /** - * Add message plain text content part. - * @param string $text message plain text content. - */ - public function addText($text); - - /** - * Add message HTML content part. - * @param string $html message HTML content. - */ - public function addHtml($html); - - /** * Attach specified content as file for the email message. * @param string $content attachment file content. * @param array $options options for embed file. Valid options are: diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index 0a02b6d..2e45acb 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -182,8 +182,8 @@ class MessageTest extends VendorTestCase $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Alternative Body Test'); - $message->addHtml('Yii Swift test HTML body'); - $message->addText('Yii Swift test plain text body'); + $message->setHtml('Yii Swift test HTML body'); + $message->setText('Yii Swift test plain text body'); $this->assertTrue($message->send()); } } \ No newline at end of file diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index f135f51..ab70563 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -182,10 +182,6 @@ class Message extends BaseMessage public function setHtml($html) {} - public function addText($text) {} - - public function addHtml($html) {} - public function attachContent($content, array $options = []) {} public function attachFile($fileName, array $options = []) {} From 99d8216103a55064ddd73d5fd347ea2fadc94bd7 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Tue, 29 Oct 2013 16:11:57 +0200 Subject: [PATCH 14/31] Email message charset setup added. --- extensions/swiftmailer/yii/swiftmailer/Message.php | 20 ++++++++++++++++++-- framework/yii/mail/BaseMessage.php | 1 + framework/yii/mail/MessageInterface.php | 6 ++++++ tests/unit/framework/mail/BaseMailerTest.php | 2 ++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index 42d25e7..89a871d 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -42,6 +42,22 @@ class Message extends BaseMessage /** * @inheritdoc */ + public function setCharset($charset) + { + $this->getSwiftMessage()->setCharset($charset); + } + + /** + * @return string the character set of this message. + */ + public function getCharset() + { + return $this->getSwiftMessage()->getCharset(); + } + + /** + * @inheritdoc + */ public function setFrom($from) { $this->getSwiftMessage()->setFrom($from); @@ -232,8 +248,8 @@ class Message extends BaseMessage { $embedFile = \Swift_EmbeddedFile::newInstance($content); if (!empty($options['fileName'])) { - $embedFile->setFilename($options['fileName']); - } + $embedFile->setFilename($options['fileName']); + } if (!empty($options['contentType'])) { $embedFile->setContentType($options['contentType']); } diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index 8c4daa8..a641521 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -21,6 +21,7 @@ use Yii; * @see BaseMailer * * @property \yii\mail\BaseMailer $mailer mailer component instance. This property is read-only. + * @property string $charset the character set of this message. * @property string|array $from sender email address. * @property string|array $to receiver email address. * @property string|array $cc copy receiver email address. diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index e7de37b..171c4f3 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -16,6 +16,12 @@ namespace yii\mail; interface MessageInterface { /** + * Set the character set of this message. + * @param string $charset character set name. + */ + public function setCharset($charset); + + /** * Sets message sender. * @param string|array $from sender email address. * You may pass an array of addresses if this message is from multiple people. diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index ab70563..1781657 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -168,6 +168,8 @@ class Message extends BaseMessage public $id; public $encoding; + public function setCharset($charset) {} + public function setFrom($from) {} public function setTo($to) {} From 368c2447686cd26ad12cd54eff1ba0fa13881965 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Mon, 4 Nov 2013 11:52:33 +0200 Subject: [PATCH 15/31] MessageInterface::render() replaced by MessageInterface::renderHtml() and MessageInterface::renderText() --- framework/yii/mail/BaseMailer.php | 21 +++++++++++++++---- framework/yii/mail/BaseMessage.php | 16 ++++++++++++--- framework/yii/mail/MessageInterface.php | 21 ++++++++++++++----- tests/unit/framework/mail/BaseMailerTest.php | 30 +++++++++++++++++++++++++--- 4 files changed, 73 insertions(+), 15 deletions(-) diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index e5a1dde..4d61fd6 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -20,7 +20,6 @@ use yii\base\ViewContextInterface; * @see BaseMessage * * @property \yii\base\View|array $view view instance or its array configuration. - * @property \yii\mail\ViewResolver|array $viewResolver view resolver instance or its array configuration. * * @author Paul Klimov * @since 2.0 @@ -36,6 +35,14 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont */ public $viewPath = '@app/mailviews'; /** + * @var string HTML layout view name. + */ + public $htmlLayout = 'layouts/html'; + /** + * @var string text layout view name. + */ + public $textLayout = 'layouts/text'; + /** * @var array configuration, which should be applied by default to any new created * email message instance. * For example: @@ -128,11 +135,17 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont * Renders a view. * @param string $view the view name or the path alias of the view file. * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return string string the rendering result + * @param string|boolean $layout layout view name, if false given no layout will be applied. + * @return string the rendering result. */ - public function render($view, $params = []) + public function render($view, $params = [], $layout = false) { - return $this->getView()->render($view, $params, $this); + $output = $this->getView()->render($view, $params, $this); + if ($layout !== false) { + return $this->getView()->render($layout, ['content' => $output], $this); + } else { + return $output; + } } /** diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index a641521..4952721 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -36,7 +36,7 @@ use Yii; abstract class BaseMessage extends Object implements MessageInterface { /** - * @return \yii\mail\BaseMailer + * @return \yii\mail\BaseMailer mailer component instance. */ public function getMailer() { @@ -54,8 +54,18 @@ abstract class BaseMessage extends Object implements MessageInterface /** * @inheritdoc */ - public function render($view, $params = []) + public function renderHtml($view, $params = []) { - return $this->getMailer()->render($view, $params); + $this->setHtml($this->render($view, $params, $this->getMailer()->htmlLayout)); + return $this; + } + + /** + * @inheritdoc + */ + public function renderText($view, $params = []) + { + $this->setText($this->render($view, $params, $this->getMailer()->textLayout)); + return $this; } } \ No newline at end of file diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 171c4f3..301a8d1 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -122,15 +122,26 @@ interface MessageInterface public function send(); /** - * Renders a view. + * Fills up HTML body rendering a view. * The view to be rendered can be specified in one of the following formats: - * - path alias (e.g. "@app/emails/contact/body"); - * - relative path (e.g. "contact"): the actual view file will be resolved by [[resolveView]]. + * - path alias (e.g. "@app/mails/contact/body"); + * - relative path (e.g. "contact"): the actual view file will be resolved by [[\yii\base\ViewContextInterface]]. * @param string $view the view name or the path alias of the view file. * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return string string the rendering result + * @return static self reference. */ - public function render($view, $params = []); + public function renderHtml($view, $params = []); + + /** + * Fills up plain text body rendering a view. + * The view to be rendered can be specified in one of the following formats: + * - path alias (e.g. "@app/mails/contact/body"); + * - relative path (e.g. "contact"): the actual view file will be resolved by [[\yii\base\ViewContextInterface]]. + * @param string $view the view name or the path alias of the view file. + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return static self reference. + */ + public function renderText($view, $params = []); /** * String output. diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 1781657..f2d3762 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -134,9 +134,9 @@ class BaseMailerTest extends TestCase $mailer->viewPath = $filePath; $viewName = 'test_view'; - $fileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; - $fileContent = ''; - file_put_contents($fileName, $fileContent); + $viewFileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; + $viewFileContent = ''; + file_put_contents($viewFileName, $viewFileContent); $params = [ 'testParam' => 'test output' @@ -144,6 +144,30 @@ class BaseMailerTest extends TestCase $renderResult = $mailer->render($viewName, $params); $this->assertEquals($params['testParam'], $renderResult); } + + /** + * @depends testRender + */ + public function testRenderLayout() + { + $mailer = new Mailer(); + + $filePath = $this->getTestFilePath(); + $mailer->viewPath = $filePath; + + $viewName = 'test_view'; + $viewFileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; + $viewFileContent = 'view file content'; + file_put_contents($viewFileName, $viewFileContent); + + $layoutName = 'test_layout'; + $layoutFileName = $filePath . DIRECTORY_SEPARATOR . $layoutName . '.php'; + $layoutFileContent = 'Begin Layout End Layout'; + file_put_contents($layoutFileName, $layoutFileContent); + + $renderResult = $mailer->render($viewName, [], $layoutName); + $this->assertEquals('Begin Layout ' . $viewFileContent . ' End Layout', $renderResult); + } } /** From ef6fea961095a1e908ace3dd4df54ed67bbcf0a1 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Mon, 4 Nov 2013 13:24:22 +0200 Subject: [PATCH 16/31] Unit test 'BaseMessageTest' created --- framework/yii/mail/BaseMessage.php | 4 +- tests/unit/framework/mail/BaseMailerTest.php | 1 - tests/unit/framework/mail/BaseMessageTest.php | 127 ++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 tests/unit/framework/mail/BaseMessageTest.php diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index 4952721..20bc487 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -56,7 +56,7 @@ abstract class BaseMessage extends Object implements MessageInterface */ public function renderHtml($view, $params = []) { - $this->setHtml($this->render($view, $params, $this->getMailer()->htmlLayout)); + $this->setHtml($this->getMailer()->render($view, $params, $this->getMailer()->htmlLayout)); return $this; } @@ -65,7 +65,7 @@ abstract class BaseMessage extends Object implements MessageInterface */ public function renderText($view, $params = []) { - $this->setText($this->render($view, $params, $this->getMailer()->textLayout)); + $this->setText($this->getMailer()->render($view, $params, $this->getMailer()->textLayout)); return $this; } } \ No newline at end of file diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index f2d3762..08a099e 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -6,7 +6,6 @@ use Yii; use yii\base\View; use yii\mail\BaseMailer; use yii\mail\BaseMessage; -use yii\mail\ViewResolver; use yii\helpers\FileHelper; use yiiunit\TestCase; diff --git a/tests/unit/framework/mail/BaseMessageTest.php b/tests/unit/framework/mail/BaseMessageTest.php new file mode 100644 index 0000000..4b934da --- /dev/null +++ b/tests/unit/framework/mail/BaseMessageTest.php @@ -0,0 +1,127 @@ +mockApplication([ + 'components' => [ + 'mail' => $this->createTestEmailComponent() + ] + ]); + } + + /** + * @return Mailer test email component instance. + */ + protected function createTestEmailComponent() + { + $component = new TestMailer(); + return $component; + } + + /** + * @return TestMailer mailer instance. + */ + protected function getMailer() + { + return Yii::$app->getComponent('mail'); + } + + // Tests : + + public function testRender() + { + $mailer = $this->getMailer(); + $message = $mailer->createMessage(); + + $viewName = 'test/text/view'; + $message->renderText($viewName); + $expectedText = 'view=' . $viewName . ' layout=' . $mailer->textLayout; + $this->assertEquals($expectedText, $message->text, 'Unable to render text!'); + + $viewName = 'test/html/view'; + $message->renderHtml($viewName); + $expectedHtml = 'view=' . $viewName . ' layout=' . $mailer->htmlLayout; + $this->assertEquals($expectedHtml, $message->html, 'Unable to render text!'); + } + + public function testSend() + { + $mailer = $this->getMailer(); + $message = $mailer->createMessage(); + $message->send(); + $this->assertEquals($message, $mailer->sentMessages[0], 'Unable to send message!'); + } +} + +/** + * Test Mailer class + */ +class TestMailer extends BaseMailer +{ + public $messageClass = 'yiiunit\framework\mail\TestMessage'; + public $sentMessages = array(); + + public function render($view, $params = [], $layout = false) + { + return 'view=' . $view . ' layout=' . $layout; + } + + public function send($message) + { + $this->sentMessages[] = $message; + } +} + +/** + * Test Message class + */ +class TestMessage extends BaseMessage +{ + public $text; + public $html; + + public function setCharset($charset) {} + + public function setFrom($from) {} + + public function setTo($to) {} + + public function setCc($cc) {} + + public function setBcc($bcc) {} + + public function setSubject($subject) {} + + public function setText($text) { + $this->text = $text; + } + + public function setHtml($html) { + $this->html = $html; + } + + public function attachContent($content, array $options = []) {} + + public function attachFile($fileName, array $options = []) {} + + public function embedFile($fileName, array $options = []) {} + + public function embedContent($content, array $options = []) {} + + public function __toString() + { + return get_class($this); + } +} \ No newline at end of file From aab90c5164eb95fe156b651c9a69fad35377521d Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Mon, 4 Nov 2013 14:28:19 +0200 Subject: [PATCH 17/31] 'MessageInterface' updated to support 'method chain' call style. --- extensions/swiftmailer/yii/swiftmailer/Message.php | 10 ++++++++++ framework/yii/mail/MailerInterface.php | 2 ++ framework/yii/mail/MessageInterface.php | 23 ++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index 89a871d..cecb61f 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -45,6 +45,7 @@ class Message extends BaseMessage public function setCharset($charset) { $this->getSwiftMessage()->setCharset($charset); + return $this; } /** @@ -62,6 +63,7 @@ class Message extends BaseMessage { $this->getSwiftMessage()->setFrom($from); $this->getSwiftMessage()->setReplyTo($from); + return $this; } /** @@ -78,6 +80,7 @@ class Message extends BaseMessage public function setTo($to) { $this->getSwiftMessage()->setTo($to); + return $this; } /** @@ -94,6 +97,7 @@ class Message extends BaseMessage public function setCc($cc) { $this->getSwiftMessage()->setCc($cc); + return $this; } /** @@ -110,6 +114,7 @@ class Message extends BaseMessage public function setBcc($bcc) { $this->getSwiftMessage()->setBcc($bcc); + return $this; } /** @@ -126,6 +131,7 @@ class Message extends BaseMessage public function setSubject($subject) { $this->getSwiftMessage()->setSubject($subject); + return $this; } /** @@ -142,6 +148,7 @@ class Message extends BaseMessage public function setText($text) { $this->setBody($text, 'text/plain'); + return $this; } /** @@ -150,6 +157,7 @@ class Message extends BaseMessage public function setHtml($html) { $this->setBody($html, 'text/html'); + return $this; } /** @@ -209,6 +217,7 @@ class Message extends BaseMessage $attachment->setContentType($options['contentType']); } $this->getSwiftMessage()->attach($attachment); + return $this; } /** @@ -224,6 +233,7 @@ class Message extends BaseMessage $attachment->setContentType($options['contentType']); } $this->getSwiftMessage()->attach($attachment); + return $this; } /** diff --git a/framework/yii/mail/MailerInterface.php b/framework/yii/mail/MailerInterface.php index 60e231c..1ed9256 100644 --- a/framework/yii/mail/MailerInterface.php +++ b/framework/yii/mail/MailerInterface.php @@ -10,6 +10,8 @@ namespace yii\mail; /** * MailerInterface is an interface, which any mailer should apply. * + * @see MessageInterface + * * @author Paul Klimov * @since 2.0 */ diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 301a8d1..e2418d3 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -9,6 +9,19 @@ namespace yii\mail; /** * MessageInterface is an interface, which email message should apply. + * Together with application component, which matches the [[MailerInterface]], + * it introduces following mail sending syntax: + * ~~~php + * Yii::$app->mail->createMessage() + * ->setFrom('from@domain.com') + * ->setTo('to@domain.com') + * ->setSubject('Message Subject') + * ->renderText('text/view') + * ->renderHtml('html/view') + * ->send(); + * ~~~ + * + * @see MailerInterface * * @author Paul Klimov * @since 2.0 @@ -18,6 +31,7 @@ interface MessageInterface /** * Set the character set of this message. * @param string $charset character set name. + * @return static self reference. */ public function setCharset($charset); @@ -27,6 +41,7 @@ interface MessageInterface * You may pass an array of addresses if this message is from multiple people. * You may also specify sender name in addition to email address using format: * [email => name]. + * @return static self reference. */ public function setFrom($from); @@ -36,6 +51,7 @@ interface MessageInterface * You may pass an array of addresses if multiple recipients should receive this message. * You may also specify receiver name in addition to email address using format: * [email => name]. + * @return static self reference. */ public function setTo($to); @@ -45,6 +61,7 @@ interface MessageInterface * You may pass an array of addresses if multiple recipients should receive this message. * You may also specify receiver name in addition to email address using format: * [email => name]. + * @return static self reference. */ public function setCc($cc); @@ -54,24 +71,28 @@ interface MessageInterface * You may pass an array of addresses if multiple recipients should receive this message. * You may also specify receiver name in addition to email address using format: * [email => name]. + * @return static self reference. */ public function setBcc($bcc); /** * Sets message subject. * @param string $subject message subject + * @return static self reference. */ public function setSubject($subject); /** * Sets message plain text content. * @param string $text message plain text content. + * @return static self reference. */ public function setText($text); /** * Sets message HTML content. * @param string $html message HTML content. + * @return static self reference. */ public function setHtml($html); @@ -81,6 +102,7 @@ interface MessageInterface * @param array $options options for embed file. Valid options are: * - fileName: name, which should be used to attach file. * - contentType: attached file MIME type. + * @return static self reference. */ public function attachContent($content, array $options = []); @@ -90,6 +112,7 @@ interface MessageInterface * @param array $options options for embed file. Valid options are: * - fileName: name, which should be used to attach file. * - contentType: attached file MIME type. + * @return static self reference. */ public function attachFile($fileName, array $options = []); From 487ee6e098b89258ed596f6ac7397d572e3a93cb Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Mon, 4 Nov 2013 15:07:30 +0200 Subject: [PATCH 18/31] Unit test for 'yii\swiftmailer\Message' advanced. --- tests/unit/extensions/swiftmailer/MessageTest.php | 107 +++++++++++++++++++++- 1 file changed, 102 insertions(+), 5 deletions(-) diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index 2e45acb..c89bdd1 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -86,6 +86,24 @@ class MessageTest extends VendorTestCase return $fileFullName; } + /** + * Finds the attachment object in the message. + * @param Message $message message instance + * @return null|\Swift_Mime_Attachment attachment instance. + */ + protected function getAttachment(Message $message) + { + $messageParts = $message->getSwiftMessage()->getChildren(); + $attachment = null; + foreach ($messageParts as $part) { + if ($part instanceof \Swift_Mime_Attachment) { + $attachment = $part; + break; + } + } + return $attachment; + } + // Tests : public function testGetSwiftMessage() @@ -97,6 +115,39 @@ class MessageTest extends VendorTestCase /** * @depends testGetSwiftMessage */ + public function testSetupHeaders() + { + $charset = 'utf-16'; + $subject = 'Test Subject'; + $to = 'someuser@somedomain.com'; + + $messageString = $this->createTestMessage() + ->setCharset($charset) + ->setSubject($subject) + ->setTo($to) + ->__toString(); + + $this->assertContains('charset=' . $charset, $messageString, 'Incorrect charset!'); + $this->assertContains('Subject: ' . $subject, $messageString, 'Incorrect "Subject" header!'); + $this->assertContains('To: ' . $to, $messageString, 'Incorrect "To" header!'); + } + + /** + * @depends testGetSwiftMessage + */ + public function testSetupFrom() + { + $from = 'someuser@somedomain.com'; + $messageString = $this->createTestMessage() + ->setFrom($from) + ->__toString(); + $this->assertContains('From: ' . $from, $messageString, 'Incorrect "From" header!'); + $this->assertContains('Reply-To: ' . $from, $messageString, 'Incorrect "Reply-To" header!'); + } + + /** + * @depends testGetSwiftMessage + */ public function testSend() { $message = $this->createTestMessage(); @@ -113,12 +164,19 @@ class MessageTest extends VendorTestCase public function testAttachFile() { $message = $this->createTestMessage(); + $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Attach File Test'); $message->setText('Yii Swift Attach File Test body'); - $message->attachFile(__FILE__); + $fileName = __FILE__; + $message->attachFile($fileName); + $this->assertTrue($message->send()); + + $attachment = $this->getAttachment($message); + $this->assertTrue(is_object($attachment), 'No attachment found!'); + $this->assertContains($attachment->getFilename(), $fileName, 'Invalid file name!'); } /** @@ -127,12 +185,20 @@ class MessageTest extends VendorTestCase public function testAttachContent() { $message = $this->createTestMessage(); + $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Create Attachment Test'); $message->setText('Yii Swift Create Attachment Test body'); - $message->attachContent('Test attachment content', ['fileName' => 'test.txt']); + $fileName = 'test.txt'; + $fileContent = 'Test attachment content'; + $message->attachContent($fileContent, ['fileName' => $fileName]); + $this->assertTrue($message->send()); + + $attachment = $this->getAttachment($message); + $this->assertTrue(is_object($attachment), 'No attachment found!'); + $this->assertEquals($fileName, $attachment->getFilename(), 'Invalid file name!'); } /** @@ -152,6 +218,10 @@ class MessageTest extends VendorTestCase $message->setHtml('Embed image: pic'); $this->assertTrue($message->send()); + + $attachment = $this->getAttachment($message); + $this->assertTrue(is_object($attachment), 'No attachment found!'); + $this->assertContains($attachment->getFilename(), $fileName, 'Invalid file name!'); } /** @@ -159,11 +229,14 @@ class MessageTest extends VendorTestCase */ public function testEmbedContent() { - $fileName = $this->createImageFile('embed_file.jpg', 'Embed Image File'); - + $fileFullName = $this->createImageFile('embed_file.jpg', 'Embed Image File'); $message = $this->createTestMessage(); - $cid = $message->embedContent(file_get_contents($fileName), ['contentType' => 'image/jpeg']); + $fileName = basename($fileFullName); + $contentType = 'image/jpeg'; + $fileContent = file_get_contents($fileFullName); + + $cid = $message->embedContent($fileContent, ['fileName' => $fileName, 'contentType' => $contentType]); $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); @@ -171,6 +244,11 @@ class MessageTest extends VendorTestCase $message->setHtml('Embed image: pic'); $this->assertTrue($message->send()); + + $attachment = $this->getAttachment($message); + $this->assertTrue(is_object($attachment), 'No attachment found!'); + $this->assertEquals($fileName, $attachment->getFilename(), 'Invalid file name!'); + $this->assertEquals($contentType, $attachment->getContentType(), 'Invalid content type!'); } /** @@ -179,11 +257,30 @@ class MessageTest extends VendorTestCase public function testSendAlternativeBody() { $message = $this->createTestMessage(); + $message->setTo($this->testEmailReceiver); $message->setFrom('someuser@somedomain.com'); $message->setSubject('Yii Swift Alternative Body Test'); $message->setHtml('Yii Swift test HTML body'); $message->setText('Yii Swift test plain text body'); + $this->assertTrue($message->send()); + + $messageParts = $message->getSwiftMessage()->getChildren(); + $textPresent = false; + $htmlPresent = false; + foreach ($messageParts as $part) { + if (!($part instanceof \Swift_Mime_Attachment)) { + /* @var $part \Swift_Mime_MimePart */ + if ($part->getContentType() == 'text/plain') { + $textPresent = true; + } + if ($part->getContentType() == 'text/html') { + $htmlPresent = true; + } + } + } + $this->assertTrue($textPresent, 'No text!'); + $this->assertTrue($htmlPresent, 'No HTML!'); } } \ No newline at end of file From a7f21b2402a00a1fc683ec028a227f8fc07622b9 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Mon, 4 Nov 2013 15:21:49 +0200 Subject: [PATCH 19/31] 'Yii::trace()' added to 'yii\swiftmailer\Mailer::send()' --- extensions/swiftmailer/yii/swiftmailer/Mailer.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/swiftmailer/yii/swiftmailer/Mailer.php b/extensions/swiftmailer/yii/swiftmailer/Mailer.php index f53001b..60e9abb 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Mailer.php +++ b/extensions/swiftmailer/yii/swiftmailer/Mailer.php @@ -9,6 +9,7 @@ namespace yii\swiftmailer; use yii\base\InvalidConfigException; use yii\mail\BaseMailer; +use Yii; /** * Mailer based on SwiftMailer library. @@ -94,6 +95,7 @@ class Mailer extends BaseMailer */ public function send($message) { + Yii::trace('Sending email message', __METHOD__); return ($this->getSwiftMailer()->send($message->getSwiftMessage()) > 0); } From 20749d406900aef99ec1040f4f8a88df084788c3 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Mon, 4 Nov 2013 15:28:09 +0200 Subject: [PATCH 20/31] Swiftmailer composer version switched to @stable --- extensions/swiftmailer/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/swiftmailer/composer.json b/extensions/swiftmailer/composer.json index 2aa47ae..bbab7eb 100644 --- a/extensions/swiftmailer/composer.json +++ b/extensions/swiftmailer/composer.json @@ -20,7 +20,7 @@ "minimum-stability": "dev", "require": { "yiisoft/yii2": "*", - "swiftmailer/swiftmailer": ">=v5.0" + "swiftmailer/swiftmailer": "@stable" }, "autoload": { "psr-0": { "yii\\swiftmailer\\": "" } From c7e054789ee55c13e3d4df47293a25d913c33295 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Mon, 4 Nov 2013 15:45:01 +0200 Subject: [PATCH 21/31] Unit test for 'yii\swiftmailer\Message' serialization added. --- tests/unit/extensions/swiftmailer/MessageTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index c89bdd1..f0077ec 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -283,4 +283,23 @@ class MessageTest extends VendorTestCase $this->assertTrue($textPresent, 'No text!'); $this->assertTrue($htmlPresent, 'No HTML!'); } + + /** + * @depends testGetSwiftMessage + */ + public function testSerialize() + { + $message = $this->createTestMessage(); + + $message->setTo($this->testEmailReceiver); + $message->setFrom('someuser@somedomain.com'); + $message->setSubject('Yii Swift Alternative Body Test'); + $message->setText('Yii Swift test plain text body'); + + $serializedMessage = serialize($message); + $this->assertNotEmpty($serializedMessage, 'Unable to serialize message!'); + + $unserializedMessaage = unserialize($serializedMessage); + $this->assertEquals($message, $unserializedMessaage, 'Unable to unserialize message!'); + } } \ No newline at end of file From 87af95f7124b34e93291f78f048c12e242bc8dea Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Tue, 5 Nov 2013 14:57:13 +0200 Subject: [PATCH 22/31] 'yii\mail\MessageInterface' updated: - setter methods renamed to have pure name - method 'createMessage' renamed to 'compose' --- extensions/swiftmailer/yii/swiftmailer/Mailer.php | 2 +- extensions/swiftmailer/yii/swiftmailer/Message.php | 54 +++------------- framework/yii/mail/BaseMailer.php | 37 +++++++++-- framework/yii/mail/BaseMessage.php | 11 +--- framework/yii/mail/MailerInterface.php | 2 +- framework/yii/mail/MessageInterface.php | 22 +++---- tests/unit/extensions/swiftmailer/MessageTest.php | 72 ++++++++++++---------- tests/unit/framework/mail/BaseMailerTest.php | 71 ++++++++++++++++----- tests/unit/framework/mail/BaseMessageTest.php | 18 +++--- 9 files changed, 159 insertions(+), 130 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Mailer.php b/extensions/swiftmailer/yii/swiftmailer/Mailer.php index 60e9abb..9cde0e6 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Mailer.php +++ b/extensions/swiftmailer/yii/swiftmailer/Mailer.php @@ -36,7 +36,7 @@ use Yii; * * @see http://swiftmailer.org * - * @method Message createMessage(array $config = []) creates new message instance from given configuration. + * @method Message compose(array $config = []) creates new message instance from given configuration. * * @author Paul Klimov * @since 2.0 diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index cecb61f..6008dd9 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -59,7 +59,7 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function setFrom($from) + public function from($from) { $this->getSwiftMessage()->setFrom($from); $this->getSwiftMessage()->setReplyTo($from); @@ -67,85 +67,45 @@ class Message extends BaseMessage } /** - * @return string from address of this message. - */ - public function getFrom() - { - return $this->getSwiftMessage()->getFrom(); - } - - /** * @inheritdoc */ - public function setTo($to) + public function to($to) { $this->getSwiftMessage()->setTo($to); return $this; } /** - * @return array To addresses of this message. - */ - public function getTo() - { - return $this->getSwiftMessage()->getTo(); - } - - /** * @inheritdoc */ - public function setCc($cc) + public function cc($cc) { $this->getSwiftMessage()->setCc($cc); return $this; } /** - * @return array Cc address of this message. - */ - public function getCc() - { - return $this->getSwiftMessage()->getCc(); - } - - /** * @inheritdoc */ - public function setBcc($bcc) + public function bcc($bcc) { $this->getSwiftMessage()->setBcc($bcc); return $this; } /** - * @return array Bcc addresses of this message. - */ - public function getBcc() - { - return $this->getSwiftMessage()->getBcc(); - } - - /** * @inheritdoc */ - public function setSubject($subject) + public function subject($subject) { $this->getSwiftMessage()->setSubject($subject); return $this; } /** - * @return string the subject of this message. - */ - public function getSubject() - { - return $this->getSwiftMessage()->getSubject(); - } - - /** * @inheritdoc */ - public function setText($text) + public function text($text) { $this->setBody($text, 'text/plain'); return $this; @@ -154,7 +114,7 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function setHtml($html) + public function html($html) { $this->setBody($html, 'text/html'); return $this; diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index 4d61fd6..f131161 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -45,10 +45,18 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont /** * @var array configuration, which should be applied by default to any new created * email message instance. + * In addition to normal [[Yii::createObject()]] behavior extra config keys are available: + * - 'from' invokes [[MessageInterface::from()]] + * - 'to' invokes [[MessageInterface::to()]] + * - 'cc' invokes [[MessageInterface::cc()]] + * - 'bcc' invokes [[MessageInterface::bcc()]] + * - 'subject' invokes [[MessageInterface::subject()]] + * - 'text' invokes [[MessageInterface::text()]] + * - 'html' invokes [[MessageInterface::html()]] * For example: * ~~~ * array( - * 'encoding' => 'UTF-8', + * 'charset' => 'UTF-8', * 'from' => 'noreply@mydomain.com', * 'bcc' => 'email.test@mydomain.com', * ) @@ -100,16 +108,37 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont * Creates new message instance from given configuration. * Message configuration will be merged with [[messageConfig]]. * If 'class' parameter is omitted [[messageClass]], will be used. - * @param array $config message configuration. + * @param array $config message configuration. See [[messageConfig]] + * for the configuration format details. * @return MessageInterface message instance. */ - public function createMessage(array $config = []) + public function compose(array $config = []) { $config = array_merge($this->messageConfig, $config); if (!array_key_exists('class', $config)) { $config['class'] = $this->messageClass; } - return Yii::createObject($config); + $configMethodNames = [ + 'from', + 'to', + 'cc', + 'bcc', + 'subject', + 'text', + 'html', + ]; + $methodBasedConfig = []; + foreach ($config as $name => $value) { + if (in_array($name, $configMethodNames, true)) { + $methodBasedConfig[$name] = $value; + unset($config[$name]); + } + } + $message = Yii::createObject($config); + foreach ($methodBasedConfig as $name => $value) { + $message->$name($value); + } + return $message; } /** diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index 20bc487..b3dade7 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -22,13 +22,6 @@ use Yii; * * @property \yii\mail\BaseMailer $mailer mailer component instance. This property is read-only. * @property string $charset the character set of this message. - * @property string|array $from sender email address. - * @property string|array $to receiver email address. - * @property string|array $cc copy receiver email address. - * @property string|array $bcc hidden copy receiver email address. - * @property string $subject message subject. - * @property string $text message plain text content. - * @property string $html message HTML content. * * @author Paul Klimov * @since 2.0 @@ -56,7 +49,7 @@ abstract class BaseMessage extends Object implements MessageInterface */ public function renderHtml($view, $params = []) { - $this->setHtml($this->getMailer()->render($view, $params, $this->getMailer()->htmlLayout)); + $this->html($this->getMailer()->render($view, $params, $this->getMailer()->htmlLayout)); return $this; } @@ -65,7 +58,7 @@ abstract class BaseMessage extends Object implements MessageInterface */ public function renderText($view, $params = []) { - $this->setText($this->getMailer()->render($view, $params, $this->getMailer()->textLayout)); + $this->text($this->getMailer()->render($view, $params, $this->getMailer()->textLayout)); return $this; } } \ No newline at end of file diff --git a/framework/yii/mail/MailerInterface.php b/framework/yii/mail/MailerInterface.php index 1ed9256..2541d32 100644 --- a/framework/yii/mail/MailerInterface.php +++ b/framework/yii/mail/MailerInterface.php @@ -22,7 +22,7 @@ interface MailerInterface * @param array $config message configuration. * @return MessageInterface message instance. */ - public function createMessage(array $config = []); + public function compose(array $config = []); /** * Sends the given email message. diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index e2418d3..d0e4180 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -12,10 +12,10 @@ namespace yii\mail; * Together with application component, which matches the [[MailerInterface]], * it introduces following mail sending syntax: * ~~~php - * Yii::$app->mail->createMessage() - * ->setFrom('from@domain.com') - * ->setTo('to@domain.com') - * ->setSubject('Message Subject') + * Yii::$app->mail->compose() + * ->from('from@domain.com') + * ->to('to@domain.com') + * ->subject('Message Subject') * ->renderText('text/view') * ->renderHtml('html/view') * ->send(); @@ -43,7 +43,7 @@ interface MessageInterface * [email => name]. * @return static self reference. */ - public function setFrom($from); + public function from($from); /** * Sets message receiver. @@ -53,7 +53,7 @@ interface MessageInterface * [email => name]. * @return static self reference. */ - public function setTo($to); + public function to($to); /** * Set the Cc (additional copy receiver) addresses of this message. @@ -63,7 +63,7 @@ interface MessageInterface * [email => name]. * @return static self reference. */ - public function setCc($cc); + public function cc($cc); /** * Set the Bcc (hidden copy receiver) addresses of this message. @@ -73,28 +73,28 @@ interface MessageInterface * [email => name]. * @return static self reference. */ - public function setBcc($bcc); + public function bcc($bcc); /** * Sets message subject. * @param string $subject message subject * @return static self reference. */ - public function setSubject($subject); + public function subject($subject); /** * Sets message plain text content. * @param string $text message plain text content. * @return static self reference. */ - public function setText($text); + public function text($text); /** * Sets message HTML content. * @param string $html message HTML content. * @return static self reference. */ - public function setHtml($html); + public function html($html); /** * Attach specified content as file for the email message. diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index f0077ec..dbb7ce0 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -63,7 +63,7 @@ class MessageTest extends VendorTestCase */ protected function createTestMessage() { - return Yii::$app->getComponent('mail')->createMessage(); + return Yii::$app->getComponent('mail')->compose(); } /** @@ -120,16 +120,22 @@ class MessageTest extends VendorTestCase $charset = 'utf-16'; $subject = 'Test Subject'; $to = 'someuser@somedomain.com'; + $cc = 'ccuser@somedomain.com'; + $bcc = 'bccuser@somedomain.com'; $messageString = $this->createTestMessage() ->setCharset($charset) - ->setSubject($subject) - ->setTo($to) + ->subject($subject) + ->to($to) + ->cc($cc) + ->bcc($bcc) ->__toString(); $this->assertContains('charset=' . $charset, $messageString, 'Incorrect charset!'); $this->assertContains('Subject: ' . $subject, $messageString, 'Incorrect "Subject" header!'); $this->assertContains('To: ' . $to, $messageString, 'Incorrect "To" header!'); + $this->assertContains('Cc: ' . $cc, $messageString, 'Incorrect "Cc" header!'); + $this->assertContains('Bcc: ' . $bcc, $messageString, 'Incorrect "Bcc" header!'); } /** @@ -139,7 +145,7 @@ class MessageTest extends VendorTestCase { $from = 'someuser@somedomain.com'; $messageString = $this->createTestMessage() - ->setFrom($from) + ->from($from) ->__toString(); $this->assertContains('From: ' . $from, $messageString, 'Incorrect "From" header!'); $this->assertContains('Reply-To: ' . $from, $messageString, 'Incorrect "Reply-To" header!'); @@ -151,10 +157,10 @@ class MessageTest extends VendorTestCase public function testSend() { $message = $this->createTestMessage(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Test'); - $message->setText('Yii Swift Test body'); + $message->to($this->testEmailReceiver); + $message->from('someuser@somedomain.com'); + $message->subject('Yii Swift Test'); + $message->text('Yii Swift Test body'); $this->assertTrue($message->send()); } @@ -165,10 +171,10 @@ class MessageTest extends VendorTestCase { $message = $this->createTestMessage(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Attach File Test'); - $message->setText('Yii Swift Attach File Test body'); + $message->to($this->testEmailReceiver); + $message->from('someuser@somedomain.com'); + $message->subject('Yii Swift Attach File Test'); + $message->text('Yii Swift Attach File Test body'); $fileName = __FILE__; $message->attachFile($fileName); @@ -186,10 +192,10 @@ class MessageTest extends VendorTestCase { $message = $this->createTestMessage(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Create Attachment Test'); - $message->setText('Yii Swift Create Attachment Test body'); + $message->to($this->testEmailReceiver); + $message->from('someuser@somedomain.com'); + $message->subject('Yii Swift Create Attachment Test'); + $message->text('Yii Swift Create Attachment Test body'); $fileName = 'test.txt'; $fileContent = 'Test attachment content'; $message->attachContent($fileContent, ['fileName' => $fileName]); @@ -212,10 +218,10 @@ class MessageTest extends VendorTestCase $cid = $message->embedFile($fileName); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Embed File Test'); - $message->setHtml('Embed image: pic'); + $message->to($this->testEmailReceiver); + $message->from('someuser@somedomain.com'); + $message->subject('Yii Swift Embed File Test'); + $message->html('Embed image: pic'); $this->assertTrue($message->send()); @@ -238,10 +244,10 @@ class MessageTest extends VendorTestCase $cid = $message->embedContent($fileContent, ['fileName' => $fileName, 'contentType' => $contentType]); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Embed File Test'); - $message->setHtml('Embed image: pic'); + $message->to($this->testEmailReceiver); + $message->from('someuser@somedomain.com'); + $message->subject('Yii Swift Embed File Test'); + $message->html('Embed image: pic'); $this->assertTrue($message->send()); @@ -258,11 +264,11 @@ class MessageTest extends VendorTestCase { $message = $this->createTestMessage(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Alternative Body Test'); - $message->setHtml('Yii Swift test HTML body'); - $message->setText('Yii Swift test plain text body'); + $message->to($this->testEmailReceiver); + $message->from('someuser@somedomain.com'); + $message->subject('Yii Swift Alternative Body Test'); + $message->html('Yii Swift test HTML body'); + $message->text('Yii Swift test plain text body'); $this->assertTrue($message->send()); @@ -291,10 +297,10 @@ class MessageTest extends VendorTestCase { $message = $this->createTestMessage(); - $message->setTo($this->testEmailReceiver); - $message->setFrom('someuser@somedomain.com'); - $message->setSubject('Yii Swift Alternative Body Test'); - $message->setText('Yii Swift test plain text body'); + $message->to($this->testEmailReceiver); + $message->from('someuser@somedomain.com'); + $message->subject('Yii Swift Alternative Body Test'); + $message->text('Yii Swift test plain text body'); $serializedMessage = serialize($message); $this->assertNotEmpty($serializedMessage, 'Unable to serialize message!'); diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 08a099e..625aab9 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -84,10 +84,10 @@ class BaseMailerTest extends TestCase $this->assertTrue(is_object($view), 'Unable to get default view!'); } - public function testCreateMessage() + public function testComposeMessage() { $mailer = new Mailer(); - $message = $mailer->createMessage(); + $message = $mailer->compose(); $this->assertTrue(is_object($message), 'Unable to create message instance!'); $this->assertEquals($mailer->messageClass, get_class($message), 'Invalid message class!'); @@ -95,7 +95,7 @@ class BaseMailerTest extends TestCase 'id' => 'test-id', 'encoding' => 'test-encoding', ); - $message = $mailer->createMessage($messageConfig); + $message = $mailer->compose($messageConfig); foreach ($messageConfig as $name => $value) { $this->assertEquals($value, $message->$name, 'Unable to apply message config!'); @@ -103,21 +103,34 @@ class BaseMailerTest extends TestCase } /** - * @depends testCreateMessage + * @depends testComposeMessage */ public function testDefaultMessageConfig() { $mailer = new Mailer(); - $messageConfig = array( + $notPropertyConfig = [ + 'from' => 'from@domain.com', + 'to' => 'to@domain.com', + 'cc' => 'cc@domain.com', + 'bcc' => 'bcc@domain.com', + 'subject' => 'Test subject', + 'text' => 'Test text body', + 'html' => 'Test HTML body', + ]; + $propertyConfig = [ 'id' => 'test-id', 'encoding' => 'test-encoding', - ); + ]; + $messageConfig = array_merge($notPropertyConfig, $propertyConfig); $mailer->messageConfig = $messageConfig; - $message = $mailer->createMessage(); + $message = $mailer->compose(); - foreach ($messageConfig as $name => $value) { + foreach ($notPropertyConfig as $name => $value) { + $this->assertEquals($value, $message->{'_' . $name}); + } + foreach ($propertyConfig as $name => $value) { $this->assertEquals($value, $message->$name); } } @@ -190,22 +203,50 @@ class Message extends BaseMessage { public $id; public $encoding; + public $_from; + public $_to; + public $_cc; + public $_bcc; + public $_subject; + public $_text; + public $_html; public function setCharset($charset) {} - public function setFrom($from) {} + public function from($from) { + $this->_from = $from; + return $this; + } - public function setTo($to) {} + public function to($to) { + $this->_to = $to; + return $this; + } - public function setCc($cc) {} + public function cc($cc) { + $this->_cc = $cc; + return $this; + } - public function setBcc($bcc) {} + public function bcc($bcc) { + $this->_bcc = $bcc; + return $this; + } - public function setSubject($subject) {} + public function subject($subject) { + $this->_subject = $subject; + return $this; + } - public function setText($text) {} + public function text($text) { + $this->_text = $text; + return $this; + } - public function setHtml($html) {} + public function html($html) { + $this->_html = $html; + return $this; + } public function attachContent($content, array $options = []) {} diff --git a/tests/unit/framework/mail/BaseMessageTest.php b/tests/unit/framework/mail/BaseMessageTest.php index 4b934da..9409ed2 100644 --- a/tests/unit/framework/mail/BaseMessageTest.php +++ b/tests/unit/framework/mail/BaseMessageTest.php @@ -43,7 +43,7 @@ class BaseMessageTest extends TestCase public function testRender() { $mailer = $this->getMailer(); - $message = $mailer->createMessage(); + $message = $mailer->compose(); $viewName = 'test/text/view'; $message->renderText($viewName); @@ -59,7 +59,7 @@ class BaseMessageTest extends TestCase public function testSend() { $mailer = $this->getMailer(); - $message = $mailer->createMessage(); + $message = $mailer->compose(); $message->send(); $this->assertEquals($message, $mailer->sentMessages[0], 'Unable to send message!'); } @@ -94,21 +94,21 @@ class TestMessage extends BaseMessage public function setCharset($charset) {} - public function setFrom($from) {} + public function from($from) {} - public function setTo($to) {} + public function to($to) {} - public function setCc($cc) {} + public function cc($cc) {} - public function setBcc($bcc) {} + public function bcc($bcc) {} - public function setSubject($subject) {} + public function subject($subject) {} - public function setText($text) { + public function text($text) { $this->text = $text; } - public function setHtml($html) { + public function html($html) { $this->html = $html; } From 45d02d07a08247f25273267eb4fa34cd71b01a33 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Tue, 5 Nov 2013 15:45:27 +0200 Subject: [PATCH 23/31] Method 'yii\mail\MessageInterface::body()' added. --- framework/yii/mail/BaseMessage.php | 16 ++++++++++++++++ framework/yii/mail/MessageInterface.php | 11 +++++++++++ tests/unit/framework/mail/BaseMessageTest.php | 26 +++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index b3dade7..f81dfdc 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -61,4 +61,20 @@ abstract class BaseMessage extends Object implements MessageInterface $this->text($this->getMailer()->render($view, $params, $this->getMailer()->textLayout)); return $this; } + + /** + * @inheritdoc + */ + public function body($view, $params = []) + { + if (is_array($view)) { + $this->renderHtml($view['html'], $params); + $this->renderText($view['text'], $params); + } else { + $html = $this->getMailer()->render($view, $params, $this->getMailer()->htmlLayout); + $this->html($html); + $this->text(strip_tags($html)); + } + return $this; + } } \ No newline at end of file diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index d0e4180..8f7a3b2 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -167,6 +167,17 @@ interface MessageInterface public function renderText($view, $params = []); /** + * Composes the message HTML and plain text body. + * @param string|array $view varies method behavior depending on type: + * - string - the view name or the path alias of the HTML body view file, in this case + * text body will be composed from html one using [[strip_tags()]] function. + * - array - list of views for each body type in format: ['html' => 'htmlView', 'text' => 'textView'] + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. + * @return static self reference. + */ + public function body($view, $params = []); + + /** * String output. * This is PHP magic method that returns string representation of an object. * @return string the string representation of the object diff --git a/tests/unit/framework/mail/BaseMessageTest.php b/tests/unit/framework/mail/BaseMessageTest.php index 9409ed2..93d94f9 100644 --- a/tests/unit/framework/mail/BaseMessageTest.php +++ b/tests/unit/framework/mail/BaseMessageTest.php @@ -53,7 +53,31 @@ class BaseMessageTest extends TestCase $viewName = 'test/html/view'; $message->renderHtml($viewName); $expectedHtml = 'view=' . $viewName . ' layout=' . $mailer->htmlLayout; - $this->assertEquals($expectedHtml, $message->html, 'Unable to render text!'); + $this->assertEquals($expectedHtml, $message->html, 'Unable to render html!'); + } + + /** + * @depends testRender + */ + public function testComposeBody() + { + $mailer = $this->getMailer(); + $message = $mailer->compose(); + + $viewName = 'test/html/view'; + $message->body($viewName); + $expectedHtml = 'view=' . $viewName . ' layout=' . $mailer->htmlLayout; + $this->assertEquals($expectedHtml, $message->html, 'Unable to compose html!'); + $expectedText = strip_tags($expectedHtml); + $this->assertEquals($expectedText, $message->text, 'Unable to compose text from html!'); + + $textViewName = 'test/text/view'; + $htmlViewName = 'test/html/view'; + $message->body(['text' => $textViewName, 'html' => $htmlViewName]); + $expectedHtml = 'view=' . $htmlViewName . ' layout=' . $mailer->htmlLayout; + $this->assertEquals($expectedHtml, $message->html, 'Unable to compose html from separated view!'); + $expectedText = 'view=' . $textViewName . ' layout=' . $mailer->textLayout; + $this->assertEquals($expectedText, $message->text, 'Unable to compose text from separated view!'); } public function testSend() From 28b032737d8019aa29da2994b547d41971f56b18 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Tue, 5 Nov 2013 16:09:24 +0200 Subject: [PATCH 24/31] Method 'yii\mail\BaseMailer::compose()' updated, allowing composition of the complex methods like 'renderText' and 'body'. --- framework/yii/mail/BaseMailer.php | 41 +++++++++++++++++------- tests/unit/framework/mail/BaseMailerTest.php | 47 ++++++++++++++++++++++------ 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index f131161..ed236c8 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -46,19 +46,23 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont * @var array configuration, which should be applied by default to any new created * email message instance. * In addition to normal [[Yii::createObject()]] behavior extra config keys are available: - * - 'from' invokes [[MessageInterface::from()]] - * - 'to' invokes [[MessageInterface::to()]] - * - 'cc' invokes [[MessageInterface::cc()]] - * - 'bcc' invokes [[MessageInterface::bcc()]] - * - 'subject' invokes [[MessageInterface::subject()]] - * - 'text' invokes [[MessageInterface::text()]] - * - 'html' invokes [[MessageInterface::html()]] + * - 'from' argument for [[MessageInterface::from()]] + * - 'to' argument for [[MessageInterface::to()]] + * - 'cc' argument for [[MessageInterface::cc()]] + * - 'bcc' argument for [[MessageInterface::bcc()]] + * - 'subject' argument for [[MessageInterface::subject()]] + * - 'text' argument for [[MessageInterface::text()]] + * - 'html' argument for [[MessageInterface::html()]] + * - 'renderText' list of arguments for [[MessageInterface::renderText()]] + * - 'renderHtml' list of arguments for [[MessageInterface::renderHtml()]] + * - 'body' list of arguments for [[MessageInterface::body()]] * For example: * ~~~ * array( * 'charset' => 'UTF-8', * 'from' => 'noreply@mydomain.com', * 'bcc' => 'email.test@mydomain.com', + * 'renderText' => ['default/text', ['companyName' => 'YiiApp']], * ) * ~~~ */ @@ -118,7 +122,7 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont if (!array_key_exists('class', $config)) { $config['class'] = $this->messageClass; } - $configMethodNames = [ + $directSetterNames = [ 'from', 'to', 'cc', @@ -127,17 +131,30 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont 'text', 'html', ]; - $methodBasedConfig = []; + $setupMethodNames = [ + 'renderText', + 'renderHtml', + 'body', + ]; + $directSetterConfig = []; + $setupMethodConfig = []; foreach ($config as $name => $value) { - if (in_array($name, $configMethodNames, true)) { - $methodBasedConfig[$name] = $value; + if (in_array($name, $directSetterNames, true)) { + $directSetterConfig[$name] = $value; + unset($config[$name]); + } + if (in_array($name, $setupMethodNames, true)) { + $setupMethodConfig[$name] = $value; unset($config[$name]); } } $message = Yii::createObject($config); - foreach ($methodBasedConfig as $name => $value) { + foreach ($directSetterConfig as $name => $value) { $message->$name($value); } + foreach ($setupMethodConfig as $method => $arguments) { + call_user_func_array(array($message, $method), $arguments); + } return $message; } diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 625aab9..c769e61 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -18,7 +18,7 @@ class BaseMailerTest extends TestCase { $this->mockApplication([ 'components' => [ - 'mail' => $this->createTestEmailComponent() + 'mail' => $this->createTestMailComponent(), ] ]); $filePath = $this->getTestFilePath(); @@ -46,12 +46,21 @@ class BaseMailerTest extends TestCase /** * @return Mailer test email component instance. */ - protected function createTestEmailComponent() + protected function createTestMailComponent() { $component = new Mailer(); + $component->viewPath = $this->getTestFilePath(); return $component; } + /** + * @return Mailer mailer instance + */ + protected function getTestMailComponent() + { + return Yii::$app->getComponent('mail'); + } + // Tests : public function testSetupView() @@ -135,18 +144,17 @@ class BaseMailerTest extends TestCase } } + + /** * @depends testGetDefaultView */ public function testRender() { - $mailer = new Mailer(); - - $filePath = $this->getTestFilePath(); - $mailer->viewPath = $filePath; + $mailer = $this->getTestMailComponent(); $viewName = 'test_view'; - $viewFileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; + $viewFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . $viewName . '.php'; $viewFileContent = ''; file_put_contents($viewFileName, $viewFileContent); @@ -158,14 +166,35 @@ class BaseMailerTest extends TestCase } /** + * @depends testComposeMessage + * @depends testRender + */ + public function testComposeSetupMethods() + { + $mailer = $this->getTestMailComponent(); + $mailer->textLayout = false; + + $viewName = 'test_view'; + $viewFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . $viewName . '.php'; + $viewFileContent = 'view file content'; + file_put_contents($viewFileName, $viewFileContent); + + $messageConfig = array( + 'renderText' => [$viewName], + ); + $message = $mailer->compose($messageConfig); + + $this->assertEquals($viewFileContent, $message->_text); + } + + /** * @depends testRender */ public function testRenderLayout() { - $mailer = new Mailer(); + $mailer = $this->getTestMailComponent(); $filePath = $this->getTestFilePath(); - $mailer->viewPath = $filePath; $viewName = 'test_view'; $viewFileName = $filePath . DIRECTORY_SEPARATOR . $viewName . '.php'; From b0c5981d42c531324c12d25b63d3364a68186e8e Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Wed, 6 Nov 2013 12:28:39 +0200 Subject: [PATCH 25/31] Method names "yii\mail\MessageInterface" simplified. --- extensions/swiftmailer/yii/swiftmailer/Message.php | 16 +++------ framework/yii/mail/BaseMailer.php | 2 ++ framework/yii/mail/BaseMessage.php | 17 +++++++++- framework/yii/mail/MessageInterface.php | 23 ++++++------- tests/unit/extensions/swiftmailer/MessageTest.php | 10 +++--- tests/unit/framework/mail/BaseMailerTest.php | 39 ++++++++++++++-------- tests/unit/framework/mail/BaseMessageTest.php | 8 ++--- 7 files changed, 67 insertions(+), 48 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index 6008dd9..b8813f5 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -42,21 +42,13 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function setCharset($charset) + public function charset($charset) { $this->getSwiftMessage()->setCharset($charset); return $this; } /** - * @return string the character set of this message. - */ - public function getCharset() - { - return $this->getSwiftMessage()->getCharset(); - } - - /** * @inheritdoc */ public function from($from) @@ -167,7 +159,7 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function attachFile($fileName, array $options = []) + public function attach($fileName, array $options = []) { $attachment = \Swift_Attachment::fromPath($fileName); if (!empty($options['fileName'])) { @@ -199,7 +191,7 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function embedFile($fileName, array $options = []) + public function embed($fileName, array $options = []) { $embedFile = \Swift_EmbeddedFile::fromPath($fileName); if (!empty($options['fileName'])) { @@ -229,7 +221,7 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function __toString() + public function toString() { return $this->getSwiftMessage()->toString(); } diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index ed236c8..b129167 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -46,6 +46,7 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont * @var array configuration, which should be applied by default to any new created * email message instance. * In addition to normal [[Yii::createObject()]] behavior extra config keys are available: + * - 'charset' argument for [[MessageInterface::charset()]] * - 'from' argument for [[MessageInterface::from()]] * - 'to' argument for [[MessageInterface::to()]] * - 'cc' argument for [[MessageInterface::cc()]] @@ -123,6 +124,7 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont $config['class'] = $this->messageClass; } $directSetterNames = [ + 'charset', 'from', 'to', 'cc', diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index f81dfdc..e5406de 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -21,7 +21,6 @@ use Yii; * @see BaseMailer * * @property \yii\mail\BaseMailer $mailer mailer component instance. This property is read-only. - * @property string $charset the character set of this message. * * @author Paul Klimov * @since 2.0 @@ -77,4 +76,20 @@ abstract class BaseMessage extends Object implements MessageInterface } return $this; } + + /** + * PHP magic method that returns the string representation of this object. + * @return string the string representation of this object. + */ + public function __toString() + { + // __toString cannot throw exception + // use trigger_error to bypass this limitation + try { + return $this->toString(); + } catch (\Exception $e) { + trigger_error($e->getMessage()); + return ''; + } + } } \ No newline at end of file diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 8f7a3b2..df5097c 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -33,7 +33,7 @@ interface MessageInterface * @param string $charset character set name. * @return static self reference. */ - public function setCharset($charset); + public function charset($charset); /** * Sets message sender. @@ -97,24 +97,24 @@ interface MessageInterface public function html($html); /** - * Attach specified content as file for the email message. - * @param string $content attachment file content. + * Attaches existing file to the email message. + * @param string $fileName full file name * @param array $options options for embed file. Valid options are: * - fileName: name, which should be used to attach file. * - contentType: attached file MIME type. * @return static self reference. */ - public function attachContent($content, array $options = []); + public function attach($fileName, array $options = []); /** - * Attaches existing file to the email message. - * @param string $fileName full file name + * Attach specified content as file for the email message. + * @param string $content attachment file content. * @param array $options options for embed file. Valid options are: * - fileName: name, which should be used to attach file. * - contentType: attached file MIME type. * @return static self reference. */ - public function attachFile($fileName, array $options = []); + public function attachContent($content, array $options = []); /** * Attach a file and return it's CID source. @@ -125,7 +125,7 @@ interface MessageInterface * - contentType: attached file MIME type. * @return string attachment CID. */ - public function embedFile($fileName, array $options = []); + public function embed($fileName, array $options = []); /** * Attach a content as file and return it's CID source. @@ -178,9 +178,8 @@ interface MessageInterface public function body($view, $params = []); /** - * String output. - * This is PHP magic method that returns string representation of an object. - * @return string the string representation of the object + * Returns string representation of this message. + * @return string the string representation of this message. */ - public function __toString(); + public function toString(); } \ No newline at end of file diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index dbb7ce0..7a6fedf 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -124,12 +124,12 @@ class MessageTest extends VendorTestCase $bcc = 'bccuser@somedomain.com'; $messageString = $this->createTestMessage() - ->setCharset($charset) + ->charset($charset) ->subject($subject) ->to($to) ->cc($cc) ->bcc($bcc) - ->__toString(); + ->toString(); $this->assertContains('charset=' . $charset, $messageString, 'Incorrect charset!'); $this->assertContains('Subject: ' . $subject, $messageString, 'Incorrect "Subject" header!'); @@ -146,7 +146,7 @@ class MessageTest extends VendorTestCase $from = 'someuser@somedomain.com'; $messageString = $this->createTestMessage() ->from($from) - ->__toString(); + ->toString(); $this->assertContains('From: ' . $from, $messageString, 'Incorrect "From" header!'); $this->assertContains('Reply-To: ' . $from, $messageString, 'Incorrect "Reply-To" header!'); } @@ -176,7 +176,7 @@ class MessageTest extends VendorTestCase $message->subject('Yii Swift Attach File Test'); $message->text('Yii Swift Attach File Test body'); $fileName = __FILE__; - $message->attachFile($fileName); + $message->attach($fileName); $this->assertTrue($message->send()); @@ -216,7 +216,7 @@ class MessageTest extends VendorTestCase $message = $this->createTestMessage(); - $cid = $message->embedFile($fileName); + $cid = $message->embed($fileName); $message->to($this->testEmailReceiver); $message->from('someuser@somedomain.com'); diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index c769e61..135ba2d 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -119,6 +119,7 @@ class BaseMailerTest extends TestCase $mailer = new Mailer(); $notPropertyConfig = [ + 'charset' => 'utf-16', 'from' => 'from@domain.com', 'to' => 'to@domain.com', 'cc' => 'cc@domain.com', @@ -144,8 +145,6 @@ class BaseMailerTest extends TestCase } } - - /** * @depends testGetDefaultView */ @@ -217,7 +216,7 @@ class BaseMailerTest extends TestCase class Mailer extends BaseMailer { public $messageClass = 'yiiunit\framework\mail\Message'; - public $sentMessages = array(); + public $sentMessages = []; public function send($message) { @@ -232,6 +231,7 @@ class Message extends BaseMessage { public $id; public $encoding; + public $_charset; public $_from; public $_to; public $_cc; @@ -240,52 +240,63 @@ class Message extends BaseMessage public $_text; public $_html; - public function setCharset($charset) {} + public function charset($charset) + { + $this->_charset = $charset; + return $this; + } - public function from($from) { + public function from($from) + { $this->_from = $from; return $this; } - public function to($to) { + public function to($to) + { $this->_to = $to; return $this; } - public function cc($cc) { + public function cc($cc) + { $this->_cc = $cc; return $this; } - public function bcc($bcc) { + public function bcc($bcc) + { $this->_bcc = $bcc; return $this; } - public function subject($subject) { + public function subject($subject) + { $this->_subject = $subject; return $this; } - public function text($text) { + public function text($text) + { $this->_text = $text; return $this; } - public function html($html) { + public function html($html) + { $this->_html = $html; return $this; } public function attachContent($content, array $options = []) {} - public function attachFile($fileName, array $options = []) {} + public function attach($fileName, array $options = []) {} - public function embedFile($fileName, array $options = []) {} + public function embed($fileName, array $options = []) {} public function embedContent($content, array $options = []) {} - public function __toString() + public function toString() { return get_class($this); } diff --git a/tests/unit/framework/mail/BaseMessageTest.php b/tests/unit/framework/mail/BaseMessageTest.php index 93d94f9..80699ed 100644 --- a/tests/unit/framework/mail/BaseMessageTest.php +++ b/tests/unit/framework/mail/BaseMessageTest.php @@ -116,7 +116,7 @@ class TestMessage extends BaseMessage public $text; public $html; - public function setCharset($charset) {} + public function charset($charset) {} public function from($from) {} @@ -138,13 +138,13 @@ class TestMessage extends BaseMessage public function attachContent($content, array $options = []) {} - public function attachFile($fileName, array $options = []) {} + public function attach($fileName, array $options = []) {} - public function embedFile($fileName, array $options = []) {} + public function embed($fileName, array $options = []) {} public function embedContent($content, array $options = []) {} - public function __toString() + public function toString() { return get_class($this); } From 3d1a625cbb60f1513b8d592243a0b76055aac210 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Wed, 6 Nov 2013 12:48:44 +0200 Subject: [PATCH 26/31] 'yii\mail\MessageInterface' updated: - 'body()' renamed to 'renderBody()' - new 'body()' method introduced --- framework/yii/mail/BaseMailer.php | 6 ++++-- framework/yii/mail/BaseMessage.php | 20 +++++++++++++++++--- framework/yii/mail/MessageInterface.php | 12 +++++++++++- tests/unit/framework/mail/BaseMessageTest.php | 4 ++-- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index b129167..6e49afd 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -54,9 +54,10 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont * - 'subject' argument for [[MessageInterface::subject()]] * - 'text' argument for [[MessageInterface::text()]] * - 'html' argument for [[MessageInterface::html()]] + * - 'body' argument for [[MessageInterface::body()]] * - 'renderText' list of arguments for [[MessageInterface::renderText()]] * - 'renderHtml' list of arguments for [[MessageInterface::renderHtml()]] - * - 'body' list of arguments for [[MessageInterface::body()]] + * - 'renderBody' list of arguments for [[MessageInterface::renderBody()]] * For example: * ~~~ * array( @@ -132,11 +133,12 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont 'subject', 'text', 'html', + 'body', ]; $setupMethodNames = [ 'renderText', 'renderHtml', - 'body', + 'renderBody', ]; $directSetterConfig = []; $setupMethodConfig = []; diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index e5406de..ff6a724 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -46,6 +46,21 @@ abstract class BaseMessage extends Object implements MessageInterface /** * @inheritdoc */ + public function body($body) + { + if (is_array($body)) { + $this->html($body['html']); + $this->text($body['text']); + } else { + $this->html($body); + $this->text(strip_tags($body)); + } + return $this; + } + + /** + * @inheritdoc + */ public function renderHtml($view, $params = []) { $this->html($this->getMailer()->render($view, $params, $this->getMailer()->htmlLayout)); @@ -64,15 +79,14 @@ abstract class BaseMessage extends Object implements MessageInterface /** * @inheritdoc */ - public function body($view, $params = []) + public function renderBody($view, $params = []) { if (is_array($view)) { $this->renderHtml($view['html'], $params); $this->renderText($view['text'], $params); } else { $html = $this->getMailer()->render($view, $params, $this->getMailer()->htmlLayout); - $this->html($html); - $this->text(strip_tags($html)); + $this->body($html); } return $this; } diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index df5097c..6bfd421 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -97,6 +97,16 @@ interface MessageInterface public function html($html); /** + * Sets message HTML and plain text content. + * @param string|array $body varies method behavior depending on type: + * - string - the HTML body content, in this case text body will be composed from + * html one using [[strip_tags()]] function. + * - array - list of body contents for each body type in format: ['html' => 'htmlContent', 'text' => 'textContent'] + * @return static self reference. + */ + public function body($body); + + /** * Attaches existing file to the email message. * @param string $fileName full file name * @param array $options options for embed file. Valid options are: @@ -175,7 +185,7 @@ interface MessageInterface * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. * @return static self reference. */ - public function body($view, $params = []); + public function renderBody($view, $params = []); /** * Returns string representation of this message. diff --git a/tests/unit/framework/mail/BaseMessageTest.php b/tests/unit/framework/mail/BaseMessageTest.php index 80699ed..44a6388 100644 --- a/tests/unit/framework/mail/BaseMessageTest.php +++ b/tests/unit/framework/mail/BaseMessageTest.php @@ -65,7 +65,7 @@ class BaseMessageTest extends TestCase $message = $mailer->compose(); $viewName = 'test/html/view'; - $message->body($viewName); + $message->renderBody($viewName); $expectedHtml = 'view=' . $viewName . ' layout=' . $mailer->htmlLayout; $this->assertEquals($expectedHtml, $message->html, 'Unable to compose html!'); $expectedText = strip_tags($expectedHtml); @@ -73,7 +73,7 @@ class BaseMessageTest extends TestCase $textViewName = 'test/text/view'; $htmlViewName = 'test/html/view'; - $message->body(['text' => $textViewName, 'html' => $htmlViewName]); + $message->renderBody(['text' => $textViewName, 'html' => $htmlViewName]); $expectedHtml = 'view=' . $htmlViewName . ' layout=' . $mailer->htmlLayout; $this->assertEquals($expectedHtml, $message->html, 'Unable to compose html from separated view!'); $expectedText = 'view=' . $textViewName . ' layout=' . $mailer->textLayout; From ad7761f96a24f55a521cc29b85624ec411578178 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Wed, 6 Nov 2013 13:27:07 +0200 Subject: [PATCH 27/31] Method 'yii\mail\MessageInterface::compose()' renamed to 'yii\mail\MessageInterface::message()'. --- extensions/swiftmailer/yii/swiftmailer/Mailer.php | 2 +- framework/yii/mail/BaseMailer.php | 2 +- framework/yii/mail/MailerInterface.php | 2 +- tests/unit/extensions/swiftmailer/MessageTest.php | 2 +- tests/unit/framework/mail/BaseMailerTest.php | 8 ++++---- tests/unit/framework/mail/BaseMessageTest.php | 6 +++--- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Mailer.php b/extensions/swiftmailer/yii/swiftmailer/Mailer.php index 9cde0e6..eaca3bd 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Mailer.php +++ b/extensions/swiftmailer/yii/swiftmailer/Mailer.php @@ -36,7 +36,7 @@ use Yii; * * @see http://swiftmailer.org * - * @method Message compose(array $config = []) creates new message instance from given configuration. + * @method Message message(array $config = []) creates new message instance from given configuration. * * @author Paul Klimov * @since 2.0 diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index 6e49afd..a827f5a 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -118,7 +118,7 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont * for the configuration format details. * @return MessageInterface message instance. */ - public function compose(array $config = []) + public function message(array $config = []) { $config = array_merge($this->messageConfig, $config); if (!array_key_exists('class', $config)) { diff --git a/framework/yii/mail/MailerInterface.php b/framework/yii/mail/MailerInterface.php index 2541d32..a80f49b 100644 --- a/framework/yii/mail/MailerInterface.php +++ b/framework/yii/mail/MailerInterface.php @@ -22,7 +22,7 @@ interface MailerInterface * @param array $config message configuration. * @return MessageInterface message instance. */ - public function compose(array $config = []); + public function message(array $config = []); /** * Sends the given email message. diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index 7a6fedf..79d33f0 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -63,7 +63,7 @@ class MessageTest extends VendorTestCase */ protected function createTestMessage() { - return Yii::$app->getComponent('mail')->compose(); + return Yii::$app->getComponent('mail')->message(); } /** diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 135ba2d..0a145d8 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -96,7 +96,7 @@ class BaseMailerTest extends TestCase public function testComposeMessage() { $mailer = new Mailer(); - $message = $mailer->compose(); + $message = $mailer->message(); $this->assertTrue(is_object($message), 'Unable to create message instance!'); $this->assertEquals($mailer->messageClass, get_class($message), 'Invalid message class!'); @@ -104,7 +104,7 @@ class BaseMailerTest extends TestCase 'id' => 'test-id', 'encoding' => 'test-encoding', ); - $message = $mailer->compose($messageConfig); + $message = $mailer->message($messageConfig); foreach ($messageConfig as $name => $value) { $this->assertEquals($value, $message->$name, 'Unable to apply message config!'); @@ -135,7 +135,7 @@ class BaseMailerTest extends TestCase $messageConfig = array_merge($notPropertyConfig, $propertyConfig); $mailer->messageConfig = $messageConfig; - $message = $mailer->compose(); + $message = $mailer->message(); foreach ($notPropertyConfig as $name => $value) { $this->assertEquals($value, $message->{'_' . $name}); @@ -181,7 +181,7 @@ class BaseMailerTest extends TestCase $messageConfig = array( 'renderText' => [$viewName], ); - $message = $mailer->compose($messageConfig); + $message = $mailer->message($messageConfig); $this->assertEquals($viewFileContent, $message->_text); } diff --git a/tests/unit/framework/mail/BaseMessageTest.php b/tests/unit/framework/mail/BaseMessageTest.php index 44a6388..3eeb362 100644 --- a/tests/unit/framework/mail/BaseMessageTest.php +++ b/tests/unit/framework/mail/BaseMessageTest.php @@ -43,7 +43,7 @@ class BaseMessageTest extends TestCase public function testRender() { $mailer = $this->getMailer(); - $message = $mailer->compose(); + $message = $mailer->message(); $viewName = 'test/text/view'; $message->renderText($viewName); @@ -62,7 +62,7 @@ class BaseMessageTest extends TestCase public function testComposeBody() { $mailer = $this->getMailer(); - $message = $mailer->compose(); + $message = $mailer->message(); $viewName = 'test/html/view'; $message->renderBody($viewName); @@ -83,7 +83,7 @@ class BaseMessageTest extends TestCase public function testSend() { $mailer = $this->getMailer(); - $message = $mailer->compose(); + $message = $mailer->message(); $message->send(); $this->assertEquals($message, $mailer->sentMessages[0], 'Unable to send message!'); } From 1aafa73e1576bbb24827cf11266a717f14bb5c7d Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Thu, 7 Nov 2013 12:18:07 +0200 Subject: [PATCH 28/31] Render methods removed from 'yii\mail\MessageInterface'. Method 'yii\mail\MailerInterface::compose()' reworked allowing rendering message body. --- extensions/swiftmailer/yii/swiftmailer/Mailer.php | 2 +- framework/yii/mail/BaseMailer.php | 58 +++++++++--------- framework/yii/mail/BaseMessage.php | 48 --------------- framework/yii/mail/MailerInterface.php | 13 +++- framework/yii/mail/MessageInterface.php | 43 -------------- tests/unit/extensions/swiftmailer/MessageTest.php | 2 +- tests/unit/framework/mail/BaseMailerTest.php | 72 +++++++++++------------ tests/unit/framework/mail/BaseMessageTest.php | 51 ++++------------ 8 files changed, 88 insertions(+), 201 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Mailer.php b/extensions/swiftmailer/yii/swiftmailer/Mailer.php index eaca3bd..1d89290 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Mailer.php +++ b/extensions/swiftmailer/yii/swiftmailer/Mailer.php @@ -36,7 +36,7 @@ use Yii; * * @see http://swiftmailer.org * - * @method Message message(array $config = []) creates new message instance from given configuration. + * @method Message compose($view = null, array $params = []) creates new message optionally filling up its body via view rendering. * * @author Paul Klimov * @since 2.0 diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index a827f5a..6ee5899 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -33,7 +33,7 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont /** * @var string directory containing view files for this email messages. */ - public $viewPath = '@app/mailviews'; + public $viewPath = '@app/mails'; /** * @var string HTML layout view name. */ @@ -54,17 +54,12 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont * - 'subject' argument for [[MessageInterface::subject()]] * - 'text' argument for [[MessageInterface::text()]] * - 'html' argument for [[MessageInterface::html()]] - * - 'body' argument for [[MessageInterface::body()]] - * - 'renderText' list of arguments for [[MessageInterface::renderText()]] - * - 'renderHtml' list of arguments for [[MessageInterface::renderHtml()]] - * - 'renderBody' list of arguments for [[MessageInterface::renderBody()]] * For example: * ~~~ * array( * 'charset' => 'UTF-8', * 'from' => 'noreply@mydomain.com', - * 'bcc' => 'email.test@mydomain.com', - * 'renderText' => ['default/text', ['companyName' => 'YiiApp']], + * 'bcc' => 'developer@mydomain.com', * ) * ~~~ */ @@ -111,16 +106,37 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont } /** - * Creates new message instance from given configuration. - * Message configuration will be merged with [[messageConfig]]. - * If 'class' parameter is omitted [[messageClass]], will be used. - * @param array $config message configuration. See [[messageConfig]] - * for the configuration format details. + * @inheritdoc + */ + public function compose($view = null, array $params = []) + { + $message = $this->createMessage(); + if ($view !== null) { + $params['message'] = $message; + if (is_array($view)) { + if (array_key_exists('html', $view)) { + $message->html($this->render($view['html'], $params, $this->htmlLayout)); + } + if (array_key_exists('text', $view)) { + $message->text($this->render($view['text'], $params, $this->textLayout)); + } + } else { + $html = $this->render($view, $params, $this->htmlLayout); + $message->html($html); + $message->text(strip_tags($html)); + } + } + return $message; + } + + /** + * Creates mew message instance using configuration from [[messageConfig]]. + * If 'class' parameter is omitted, [[messageClass]] will be used. * @return MessageInterface message instance. */ - public function message(array $config = []) + protected function createMessage() { - $config = array_merge($this->messageConfig, $config); + $config = $this->messageConfig; if (!array_key_exists('class', $config)) { $config['class'] = $this->messageClass; } @@ -133,32 +149,18 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont 'subject', 'text', 'html', - 'body', - ]; - $setupMethodNames = [ - 'renderText', - 'renderHtml', - 'renderBody', ]; $directSetterConfig = []; - $setupMethodConfig = []; foreach ($config as $name => $value) { if (in_array($name, $directSetterNames, true)) { $directSetterConfig[$name] = $value; unset($config[$name]); } - if (in_array($name, $setupMethodNames, true)) { - $setupMethodConfig[$name] = $value; - unset($config[$name]); - } } $message = Yii::createObject($config); foreach ($directSetterConfig as $name => $value) { $message->$name($value); } - foreach ($setupMethodConfig as $method => $arguments) { - call_user_func_array(array($message, $method), $arguments); - } return $message; } diff --git a/framework/yii/mail/BaseMessage.php b/framework/yii/mail/BaseMessage.php index ff6a724..9a6fccf 100644 --- a/framework/yii/mail/BaseMessage.php +++ b/framework/yii/mail/BaseMessage.php @@ -44,54 +44,6 @@ abstract class BaseMessage extends Object implements MessageInterface } /** - * @inheritdoc - */ - public function body($body) - { - if (is_array($body)) { - $this->html($body['html']); - $this->text($body['text']); - } else { - $this->html($body); - $this->text(strip_tags($body)); - } - return $this; - } - - /** - * @inheritdoc - */ - public function renderHtml($view, $params = []) - { - $this->html($this->getMailer()->render($view, $params, $this->getMailer()->htmlLayout)); - return $this; - } - - /** - * @inheritdoc - */ - public function renderText($view, $params = []) - { - $this->text($this->getMailer()->render($view, $params, $this->getMailer()->textLayout)); - return $this; - } - - /** - * @inheritdoc - */ - public function renderBody($view, $params = []) - { - if (is_array($view)) { - $this->renderHtml($view['html'], $params); - $this->renderText($view['text'], $params); - } else { - $html = $this->getMailer()->render($view, $params, $this->getMailer()->htmlLayout); - $this->body($html); - } - return $this; - } - - /** * PHP magic method that returns the string representation of this object. * @return string the string representation of this object. */ diff --git a/framework/yii/mail/MailerInterface.php b/framework/yii/mail/MailerInterface.php index a80f49b..d17c65f 100644 --- a/framework/yii/mail/MailerInterface.php +++ b/framework/yii/mail/MailerInterface.php @@ -18,11 +18,18 @@ namespace yii\mail; interface MailerInterface { /** - * Creates new message instance from given configuration. - * @param array $config message configuration. + * Creates new message optionally filling up its body via view rendering. + * The view to be rendered can be specified in one of the following formats: + * - path alias (e.g. "@app/mails/contact/body"); + * - relative path (e.g. "contact"): the actual view file will be resolved by [[\yii\base\ViewContextInterface]]. + * @param string|array $view view, which should be used to render message body + * - if string - the view name or the path alias of the HTML body view file, in this case + * text body will be composed automatically from html one. + * - if array - list of views for each body type in format: ['html' => 'htmlView', 'text' => 'textView'] + * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. * @return MessageInterface message instance. */ - public function message(array $config = []); + public function compose($view = null, array $params = []); /** * Sends the given email message. diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 6bfd421..69344a4 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -97,16 +97,6 @@ interface MessageInterface public function html($html); /** - * Sets message HTML and plain text content. - * @param string|array $body varies method behavior depending on type: - * - string - the HTML body content, in this case text body will be composed from - * html one using [[strip_tags()]] function. - * - array - list of body contents for each body type in format: ['html' => 'htmlContent', 'text' => 'textContent'] - * @return static self reference. - */ - public function body($body); - - /** * Attaches existing file to the email message. * @param string $fileName full file name * @param array $options options for embed file. Valid options are: @@ -155,39 +145,6 @@ interface MessageInterface public function send(); /** - * Fills up HTML body rendering a view. - * The view to be rendered can be specified in one of the following formats: - * - path alias (e.g. "@app/mails/contact/body"); - * - relative path (e.g. "contact"): the actual view file will be resolved by [[\yii\base\ViewContextInterface]]. - * @param string $view the view name or the path alias of the view file. - * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return static self reference. - */ - public function renderHtml($view, $params = []); - - /** - * Fills up plain text body rendering a view. - * The view to be rendered can be specified in one of the following formats: - * - path alias (e.g. "@app/mails/contact/body"); - * - relative path (e.g. "contact"): the actual view file will be resolved by [[\yii\base\ViewContextInterface]]. - * @param string $view the view name or the path alias of the view file. - * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return static self reference. - */ - public function renderText($view, $params = []); - - /** - * Composes the message HTML and plain text body. - * @param string|array $view varies method behavior depending on type: - * - string - the view name or the path alias of the HTML body view file, in this case - * text body will be composed from html one using [[strip_tags()]] function. - * - array - list of views for each body type in format: ['html' => 'htmlView', 'text' => 'textView'] - * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file. - * @return static self reference. - */ - public function renderBody($view, $params = []); - - /** * Returns string representation of this message. * @return string the string representation of this message. */ diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index 79d33f0..7a6fedf 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -63,7 +63,7 @@ class MessageTest extends VendorTestCase */ protected function createTestMessage() { - return Yii::$app->getComponent('mail')->message(); + return Yii::$app->getComponent('mail')->compose(); } /** diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 0a145d8..505652c 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -93,26 +93,16 @@ class BaseMailerTest extends TestCase $this->assertTrue(is_object($view), 'Unable to get default view!'); } - public function testComposeMessage() + public function testCreateMessage() { $mailer = new Mailer(); - $message = $mailer->message(); + $message = $mailer->compose(); $this->assertTrue(is_object($message), 'Unable to create message instance!'); $this->assertEquals($mailer->messageClass, get_class($message), 'Invalid message class!'); - - $messageConfig = array( - 'id' => 'test-id', - 'encoding' => 'test-encoding', - ); - $message = $mailer->message($messageConfig); - - foreach ($messageConfig as $name => $value) { - $this->assertEquals($value, $message->$name, 'Unable to apply message config!'); - } } /** - * @depends testComposeMessage + * @depends testCreateMessage */ public function testDefaultMessageConfig() { @@ -135,7 +125,7 @@ class BaseMailerTest extends TestCase $messageConfig = array_merge($notPropertyConfig, $propertyConfig); $mailer->messageConfig = $messageConfig; - $message = $mailer->message(); + $message = $mailer->compose(); foreach ($notPropertyConfig as $name => $value) { $this->assertEquals($value, $message->{'_' . $name}); @@ -165,28 +155,6 @@ class BaseMailerTest extends TestCase } /** - * @depends testComposeMessage - * @depends testRender - */ - public function testComposeSetupMethods() - { - $mailer = $this->getTestMailComponent(); - $mailer->textLayout = false; - - $viewName = 'test_view'; - $viewFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . $viewName . '.php'; - $viewFileContent = 'view file content'; - file_put_contents($viewFileName, $viewFileContent); - - $messageConfig = array( - 'renderText' => [$viewName], - ); - $message = $mailer->message($messageConfig); - - $this->assertEquals($viewFileContent, $message->_text); - } - - /** * @depends testRender */ public function testRenderLayout() @@ -208,6 +176,38 @@ class BaseMailerTest extends TestCase $renderResult = $mailer->render($viewName, [], $layoutName); $this->assertEquals('Begin Layout ' . $viewFileContent . ' End Layout', $renderResult); } + + /** + * @depends testCreateMessage + * @depends testRender + */ + public function testCompose() + { + $mailer = $this->getTestMailComponent(); + $mailer->htmlLayout = false; + $mailer->textLayout = false; + + $htmlViewName = 'test_html_view'; + $htmlViewFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . $htmlViewName . '.php'; + $htmlViewFileContent = 'HTML view file content'; + file_put_contents($htmlViewFileName, $htmlViewFileContent); + + $textViewName = 'test_text_view'; + $textViewFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . $textViewName . '.php'; + $textViewFileContent = 'Plain text view file content'; + file_put_contents($textViewFileName, $textViewFileContent); + + $message = $mailer->compose([ + 'html' => $htmlViewName, + 'text' => $textViewName, + ]); + $this->assertEquals($htmlViewFileContent, $message->_html, 'Unable to render html!'); + $this->assertEquals($textViewFileContent, $message->_text, 'Unable to render text!'); + + $message = $mailer->compose($htmlViewName); + $this->assertEquals($htmlViewFileContent, $message->_html, 'Unable to render html by direct view!'); + $this->assertEquals(strip_tags($htmlViewFileContent), $message->_text, 'Unable to render text by direct view!'); + } } /** diff --git a/tests/unit/framework/mail/BaseMessageTest.php b/tests/unit/framework/mail/BaseMessageTest.php index 3eeb362..7b36a93 100644 --- a/tests/unit/framework/mail/BaseMessageTest.php +++ b/tests/unit/framework/mail/BaseMessageTest.php @@ -40,52 +40,26 @@ class BaseMessageTest extends TestCase // Tests : - public function testRender() + public function testGetMailer() { $mailer = $this->getMailer(); - $message = $mailer->message(); - - $viewName = 'test/text/view'; - $message->renderText($viewName); - $expectedText = 'view=' . $viewName . ' layout=' . $mailer->textLayout; - $this->assertEquals($expectedText, $message->text, 'Unable to render text!'); - - $viewName = 'test/html/view'; - $message->renderHtml($viewName); - $expectedHtml = 'view=' . $viewName . ' layout=' . $mailer->htmlLayout; - $this->assertEquals($expectedHtml, $message->html, 'Unable to render html!'); + $message = $mailer->compose(); + $this->assertEquals($mailer, $message->getMailer()); } - /** - * @depends testRender - */ - public function testComposeBody() + public function testSend() { $mailer = $this->getMailer(); - $message = $mailer->message(); - - $viewName = 'test/html/view'; - $message->renderBody($viewName); - $expectedHtml = 'view=' . $viewName . ' layout=' . $mailer->htmlLayout; - $this->assertEquals($expectedHtml, $message->html, 'Unable to compose html!'); - $expectedText = strip_tags($expectedHtml); - $this->assertEquals($expectedText, $message->text, 'Unable to compose text from html!'); - - $textViewName = 'test/text/view'; - $htmlViewName = 'test/html/view'; - $message->renderBody(['text' => $textViewName, 'html' => $htmlViewName]); - $expectedHtml = 'view=' . $htmlViewName . ' layout=' . $mailer->htmlLayout; - $this->assertEquals($expectedHtml, $message->html, 'Unable to compose html from separated view!'); - $expectedText = 'view=' . $textViewName . ' layout=' . $mailer->textLayout; - $this->assertEquals($expectedText, $message->text, 'Unable to compose text from separated view!'); + $message = $mailer->compose(); + $message->send(); + $this->assertEquals($message, $mailer->sentMessages[0], 'Unable to send message!'); } - public function testSend() + public function testToString() { $mailer = $this->getMailer(); - $message = $mailer->message(); - $message->send(); - $this->assertEquals($message, $mailer->sentMessages[0], 'Unable to send message!'); + $message = $mailer->compose(); + $this->assertEquals($message->toString(), '' . $message); } } @@ -97,11 +71,6 @@ class TestMailer extends BaseMailer public $messageClass = 'yiiunit\framework\mail\TestMessage'; public $sentMessages = array(); - public function render($view, $params = [], $layout = false) - { - return 'view=' . $view . ' layout=' . $layout; - } - public function send($message) { $this->sentMessages[] = $message; From 104cfd7cb2ba7cff97ab98ca0b90b8719f51ca56 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Thu, 7 Nov 2013 12:22:24 +0200 Subject: [PATCH 29/31] 'yii\mail\MessageInterface' methods renamed: 'text' to 'textBody', 'html' to 'htmlBody' --- extensions/swiftmailer/yii/swiftmailer/Message.php | 4 ++-- framework/yii/mail/BaseMailer.php | 16 +++++++-------- framework/yii/mail/MessageInterface.php | 4 ++-- tests/unit/extensions/swiftmailer/MessageTest.php | 16 +++++++-------- tests/unit/framework/mail/BaseMailerTest.php | 24 +++++++++++----------- tests/unit/framework/mail/BaseMessageTest.php | 4 ++-- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/extensions/swiftmailer/yii/swiftmailer/Message.php b/extensions/swiftmailer/yii/swiftmailer/Message.php index b8813f5..8997695 100644 --- a/extensions/swiftmailer/yii/swiftmailer/Message.php +++ b/extensions/swiftmailer/yii/swiftmailer/Message.php @@ -97,7 +97,7 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function text($text) + public function textBody($text) { $this->setBody($text, 'text/plain'); return $this; @@ -106,7 +106,7 @@ class Message extends BaseMessage /** * @inheritdoc */ - public function html($html) + public function htmlBody($html) { $this->setBody($html, 'text/html'); return $this; diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index 6ee5899..4e1982c 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -52,8 +52,8 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont * - 'cc' argument for [[MessageInterface::cc()]] * - 'bcc' argument for [[MessageInterface::bcc()]] * - 'subject' argument for [[MessageInterface::subject()]] - * - 'text' argument for [[MessageInterface::text()]] - * - 'html' argument for [[MessageInterface::html()]] + * - 'textBody' argument for [[MessageInterface::textBody()]] + * - 'htmlBody' argument for [[MessageInterface::htmlBody()]] * For example: * ~~~ * array( @@ -115,15 +115,15 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont $params['message'] = $message; if (is_array($view)) { if (array_key_exists('html', $view)) { - $message->html($this->render($view['html'], $params, $this->htmlLayout)); + $message->htmlBody($this->render($view['html'], $params, $this->htmlLayout)); } if (array_key_exists('text', $view)) { - $message->text($this->render($view['text'], $params, $this->textLayout)); + $message->textBody($this->render($view['text'], $params, $this->textLayout)); } } else { $html = $this->render($view, $params, $this->htmlLayout); - $message->html($html); - $message->text(strip_tags($html)); + $message->htmlBody($html); + $message->textBody(strip_tags($html)); } } return $message; @@ -147,8 +147,8 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont 'cc', 'bcc', 'subject', - 'text', - 'html', + 'textBody', + 'htmlBody', ]; $directSetterConfig = []; foreach ($config as $name => $value) { diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 69344a4..85f3f9e 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -87,14 +87,14 @@ interface MessageInterface * @param string $text message plain text content. * @return static self reference. */ - public function text($text); + public function textBody($text); /** * Sets message HTML content. * @param string $html message HTML content. * @return static self reference. */ - public function html($html); + public function htmlBody($html); /** * Attaches existing file to the email message. diff --git a/tests/unit/extensions/swiftmailer/MessageTest.php b/tests/unit/extensions/swiftmailer/MessageTest.php index 7a6fedf..33eff29 100644 --- a/tests/unit/extensions/swiftmailer/MessageTest.php +++ b/tests/unit/extensions/swiftmailer/MessageTest.php @@ -160,7 +160,7 @@ class MessageTest extends VendorTestCase $message->to($this->testEmailReceiver); $message->from('someuser@somedomain.com'); $message->subject('Yii Swift Test'); - $message->text('Yii Swift Test body'); + $message->textBody('Yii Swift Test body'); $this->assertTrue($message->send()); } @@ -174,7 +174,7 @@ class MessageTest extends VendorTestCase $message->to($this->testEmailReceiver); $message->from('someuser@somedomain.com'); $message->subject('Yii Swift Attach File Test'); - $message->text('Yii Swift Attach File Test body'); + $message->textBody('Yii Swift Attach File Test body'); $fileName = __FILE__; $message->attach($fileName); @@ -195,7 +195,7 @@ class MessageTest extends VendorTestCase $message->to($this->testEmailReceiver); $message->from('someuser@somedomain.com'); $message->subject('Yii Swift Create Attachment Test'); - $message->text('Yii Swift Create Attachment Test body'); + $message->textBody('Yii Swift Create Attachment Test body'); $fileName = 'test.txt'; $fileContent = 'Test attachment content'; $message->attachContent($fileContent, ['fileName' => $fileName]); @@ -221,7 +221,7 @@ class MessageTest extends VendorTestCase $message->to($this->testEmailReceiver); $message->from('someuser@somedomain.com'); $message->subject('Yii Swift Embed File Test'); - $message->html('Embed image: pic'); + $message->htmlBody('Embed image: pic'); $this->assertTrue($message->send()); @@ -247,7 +247,7 @@ class MessageTest extends VendorTestCase $message->to($this->testEmailReceiver); $message->from('someuser@somedomain.com'); $message->subject('Yii Swift Embed File Test'); - $message->html('Embed image: pic'); + $message->htmlBody('Embed image: pic'); $this->assertTrue($message->send()); @@ -267,8 +267,8 @@ class MessageTest extends VendorTestCase $message->to($this->testEmailReceiver); $message->from('someuser@somedomain.com'); $message->subject('Yii Swift Alternative Body Test'); - $message->html('Yii Swift test HTML body'); - $message->text('Yii Swift test plain text body'); + $message->htmlBody('Yii Swift test HTML body'); + $message->textBody('Yii Swift test plain text body'); $this->assertTrue($message->send()); @@ -300,7 +300,7 @@ class MessageTest extends VendorTestCase $message->to($this->testEmailReceiver); $message->from('someuser@somedomain.com'); $message->subject('Yii Swift Alternative Body Test'); - $message->text('Yii Swift test plain text body'); + $message->textBody('Yii Swift test plain text body'); $serializedMessage = serialize($message); $this->assertNotEmpty($serializedMessage, 'Unable to serialize message!'); diff --git a/tests/unit/framework/mail/BaseMailerTest.php b/tests/unit/framework/mail/BaseMailerTest.php index 505652c..4eab7e1 100644 --- a/tests/unit/framework/mail/BaseMailerTest.php +++ b/tests/unit/framework/mail/BaseMailerTest.php @@ -115,8 +115,8 @@ class BaseMailerTest extends TestCase 'cc' => 'cc@domain.com', 'bcc' => 'bcc@domain.com', 'subject' => 'Test subject', - 'text' => 'Test text body', - 'html' => 'Test HTML body', + 'textBody' => 'Test text body', + 'htmlBody' => 'Test HTML body', ]; $propertyConfig = [ 'id' => 'test-id', @@ -201,12 +201,12 @@ class BaseMailerTest extends TestCase 'html' => $htmlViewName, 'text' => $textViewName, ]); - $this->assertEquals($htmlViewFileContent, $message->_html, 'Unable to render html!'); - $this->assertEquals($textViewFileContent, $message->_text, 'Unable to render text!'); + $this->assertEquals($htmlViewFileContent, $message->_htmlBody, 'Unable to render html!'); + $this->assertEquals($textViewFileContent, $message->_textBody, 'Unable to render text!'); $message = $mailer->compose($htmlViewName); - $this->assertEquals($htmlViewFileContent, $message->_html, 'Unable to render html by direct view!'); - $this->assertEquals(strip_tags($htmlViewFileContent), $message->_text, 'Unable to render text by direct view!'); + $this->assertEquals($htmlViewFileContent, $message->_htmlBody, 'Unable to render html by direct view!'); + $this->assertEquals(strip_tags($htmlViewFileContent), $message->_textBody, 'Unable to render text by direct view!'); } } @@ -237,8 +237,8 @@ class Message extends BaseMessage public $_cc; public $_bcc; public $_subject; - public $_text; - public $_html; + public $_textBody; + public $_htmlBody; public function charset($charset) { @@ -276,15 +276,15 @@ class Message extends BaseMessage return $this; } - public function text($text) + public function textBody($text) { - $this->_text = $text; + $this->_textBody = $text; return $this; } - public function html($html) + public function htmlBody($html) { - $this->_html = $html; + $this->_htmlBody = $html; return $this; } diff --git a/tests/unit/framework/mail/BaseMessageTest.php b/tests/unit/framework/mail/BaseMessageTest.php index 7b36a93..1820764 100644 --- a/tests/unit/framework/mail/BaseMessageTest.php +++ b/tests/unit/framework/mail/BaseMessageTest.php @@ -97,11 +97,11 @@ class TestMessage extends BaseMessage public function subject($subject) {} - public function text($text) { + public function textBody($text) { $this->text = $text; } - public function html($html) { + public function htmlBody($html) { $this->html = $html; } From 85c26332c5c0267a3a945f711daef38c4d77b448 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Thu, 7 Nov 2013 17:16:25 +0200 Subject: [PATCH 30/31] Doc comments for "MessageInterface" and "MailerInterface" updated. --- framework/yii/mail/MailerInterface.php | 9 +++++++++ framework/yii/mail/MessageInterface.php | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/framework/yii/mail/MailerInterface.php b/framework/yii/mail/MailerInterface.php index d17c65f..bf2210c 100644 --- a/framework/yii/mail/MailerInterface.php +++ b/framework/yii/mail/MailerInterface.php @@ -9,6 +9,15 @@ namespace yii\mail; /** * MailerInterface is an interface, which any mailer should apply. + * Mailer creates and sends messages. Also it allows composition of the message + * body via view rendering: + * ~~~php + * Yii::$app->mail->compose('contact/html', ['contactForm' => $form]) + * ->from('from@domain.com') + * ->to($form->email) + * ->subject($form->subject) + * ->send(); + * ~~~ * * @see MessageInterface * diff --git a/framework/yii/mail/MessageInterface.php b/framework/yii/mail/MessageInterface.php index 85f3f9e..648e6ff 100644 --- a/framework/yii/mail/MessageInterface.php +++ b/framework/yii/mail/MessageInterface.php @@ -16,8 +16,8 @@ namespace yii\mail; * ->from('from@domain.com') * ->to('to@domain.com') * ->subject('Message Subject') - * ->renderText('text/view') - * ->renderHtml('html/view') + * ->textBody('Plain text content') + * ->htmlBody('HTML content') * ->send(); * ~~~ * From 9dbf4d7420b2946980c92d1adf53b9c377a02b6e Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Thu, 7 Nov 2013 17:18:48 +0200 Subject: [PATCH 31/31] Mailer default view class changed to "yii\web\View". --- framework/yii/mail/BaseMailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/yii/mail/BaseMailer.php b/framework/yii/mail/BaseMailer.php index 4e1982c..9636e63 100644 --- a/framework/yii/mail/BaseMailer.php +++ b/framework/yii/mail/BaseMailer.php @@ -100,7 +100,7 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont protected function createView(array $config) { if (!array_key_exists('class', $config)) { - $config['class'] = '\yii\base\View'; + $config['class'] = 'yii\web\View'; } return Yii::createObject($config); }