From 7d6d01b4bc9d7a23a7f5ec2a145b60f4898c80d6 Mon Sep 17 00:00:00 2001 From: Dmitry Erofeev Date: Sat, 9 Nov 2013 21:45:46 +0400 Subject: [PATCH] added FileMailer implementation of mailer interface --- extensions/swiftmailer/FileMailer.php | 135 +++++++++++++++++++++ extensions/swiftmailer/README.md | 16 ++- extensions/swiftmailer/composer.json | 6 +- .../unit/extensions/swiftmailer/FileMailerTest.php | 62 ++++++++++ 4 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 extensions/swiftmailer/FileMailer.php create mode 100644 tests/unit/extensions/swiftmailer/FileMailerTest.php diff --git a/extensions/swiftmailer/FileMailer.php b/extensions/swiftmailer/FileMailer.php new file mode 100644 index 0000000..966c033 --- /dev/null +++ b/extensions/swiftmailer/FileMailer.php @@ -0,0 +1,135 @@ + array( + * ... + * 'email' => array( + * 'class' => 'yii\swiftmailer\FileMailer' + * ), + * ... + * ), + * ~~~ + * + * To send an email, you may use the following code: + * + * ~~~ + * Yii::$app->mail->compose('contact/html', ['contactForm' => $form]) + * ->setFrom('from@domain.com') + * ->setTo($form->email) + * ->setSubject($form->subject) + * ->send(); + * ~~~ + * + * @author Dmitry Erofeev + * @since 2.0 + */ +class FileMailer extends BaseMailer +{ + /** + * @var string message default class name. + */ + public $messageClass = 'yii\swiftmailer\Message'; + + /** + * @var string The path under which mail files will be written. Defaults to "@app/runtime/mail". + */ + protected $path; + + /** + * @var callable Callback that will be used to generate name of the message to save. + */ + protected $callback; + + /** + * Sets path under which mail files will be written. + * Any trailing '/' and '\' characters in the given path will be trimmed. + * + * @param $path + * @throws \InvalidArgumentException + */ + public function setPath($path) + { + $path = Yii::getAlias($path); + if (!is_dir($path) || !is_writable($path)) { + throw new \InvalidArgumentException('Filemailer::setPath expects a valid path in which to write mail files'); + } + + $this->path = rtrim($path, '\\/'); + } + + /** + * Gets path under which mail files will be written. + * + * @return string + */ + public function getPath() + { + if ($this->path == null) { + $path = Yii::getAlias('@app/runtime/mail'); + if (!is_dir($path)) { + FileHelper::createDirectory($path); + } + $this->setPath($path); + } + + return $this->path; + } + + /** + * Sets callback that will be used to generate name of the message to save. + * + * @param callable $callback + */ + public function setCallback(callable $callback) + { + $this->callback = $callback; + } + + /** + * Gets callback that will be used to generate name of the message to save. + * + * @return callable + */ + public function getCallback() + { + if ($this->callback == null) { + $this->setCallback(function () { + return uniqid('Message_') . '.txt'; + }); + } + + return $this->callback; + } + + /** + * @inheritdoc + */ + public function send($message) + { + $address = $message->getTo(); + if (is_array($address)) { + $address = implode(', ', array_keys($address)); + } + Yii::trace('Sending email "' . $message->getSubject() . '" to "' . $address . '"', __METHOD__); + + $filename = $this->getPath() . DIRECTORY_SEPARATOR . call_user_func($this->getCallback()); + + return file_put_contents($filename, $message->toString()) !== false; + } +} \ No newline at end of file diff --git a/extensions/swiftmailer/README.md b/extensions/swiftmailer/README.md index 3edd4a4..515dd49 100644 --- a/extensions/swiftmailer/README.md +++ b/extensions/swiftmailer/README.md @@ -3,7 +3,7 @@ SwiftMailer Extension for Yii 2 This extension provides a `SwiftMailer` mail solution for Yii 2. -To use this extension, simply add the following code in your application configuration: +To use this extension, simply add the following code in your application configuration: ```php return [ @@ -16,6 +16,20 @@ return [ ]; ``` +Extension also includes `FileMailer` that saves mails as files under runtime directory. +It can be useful during development. To use it add the following code in your application configuration: + +```php +return [ + //.... + 'components' => [ + 'mail' => [ + 'class' => 'yii\swiftmailer\FileMailer', + ], + ], +]; +``` + You can then send an email as follows: ```php diff --git a/extensions/swiftmailer/composer.json b/extensions/swiftmailer/composer.json index e995b2f..928230e 100644 --- a/extensions/swiftmailer/composer.json +++ b/extensions/swiftmailer/composer.json @@ -15,7 +15,11 @@ { "name": "Paul Klimov", "email": "klimov.paul@gmail.com" - } + }, + { + "name": "Dmitry Erofeev", + "email": "dmeroff@gmail.com" + } ], "minimum-stability": "dev", "require": { diff --git a/tests/unit/extensions/swiftmailer/FileMailerTest.php b/tests/unit/extensions/swiftmailer/FileMailerTest.php new file mode 100644 index 0000000..10b523d --- /dev/null +++ b/tests/unit/extensions/swiftmailer/FileMailerTest.php @@ -0,0 +1,62 @@ +mockApplication([ + 'components' => [ + 'mail' => $this->createTestEmailComponent() + ] + ]); + } + + /** + * @return FileMailer test email component instance. + */ + protected function createTestEmailComponent() + { + $component = new FileMailer([ + 'callback' => function () { + return 'Message_test.txt'; + } + ]); + + return $component; + } + + public function testConfigurePath() + { + $mailer = new FileMailer(); + $this->assertEquals(\Yii::getAlias('@app/runtime/mail'), $mailer->getPath()); + $mailer->setPath('@yiiunit/runtime/'); + $this->assertEquals(\Yii::getAlias('@yiiunit/runtime'), $mailer->getPath()); + } + + public function testSend() + { + $message = \Yii::$app->mail->compose() + ->setTo('tester@example.com') + ->setFrom('admin@example.com') + ->setSubject('Just a test') + ->setHtmlBody('This is html body'); + $message->send(); + $this->assertEquals( + $message->toString(), + file_get_contents(\Yii::$app->getRuntimePath() . '/mail/Message_test.txt') + ); + } +} + \ No newline at end of file