|
|
|
Mailing
|
|
|
|
=======
|
|
|
|
|
|
|
|
> Note: This section is under development.
|
|
|
|
|
|
|
|
Yii supports composition and sending of the email messages. However, the framework core provides
|
|
|
|
only the content composition functionality and basic interface. Actual mail sending mechanism should
|
|
|
|
be provided by the extension, because different projects may require its different implementation and
|
|
|
|
it usually depends on the external services and libraries.
|
|
|
|
|
|
|
|
For the most common cases you can use [yii2-swiftmailer](https://github.com/yiisoft/yii2/tree/master/extensions/swiftmailer) official extension.
|
|
|
|
|
|
|
|
|
|
|
|
Configuration
|
|
|
|
-------------
|
|
|
|
|
|
|
|
Mail component configuration depends on the extension you have chosen.
|
|
|
|
In general your application configuration should look like:
|
|
|
|
|
|
|
|
```php
|
|
|
|
return [
|
|
|
|
//....
|
|
|
|
'components' => [
|
|
|
|
'mailer' => [
|
|
|
|
'class' => 'yii\swiftmailer\Mailer',
|
|
|
|
],
|
|
|
|
],
|
|
|
|
];
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Basic usage
|
|
|
|
-----------
|
|
|
|
|
|
|
|
Once 'mailer' component is configured, you can use the following code to send an email message:
|
|
|
|
|
|
|
|
```php
|
|
|
|
Yii::$app->mailer->compose()
|
|
|
|
->setFrom('from@domain.com')
|
|
|
|
->setTo('to@domain.com')
|
|
|
|
->setSubject('Message subject')
|
|
|
|
->setTextBody('Plain text content')
|
|
|
|
->setHtmlBody('<b>HTML content</b>')
|
|
|
|
->send();
|
|
|
|
```
|
|
|
|
|
|
|
|
In above example method `compose()` creates an instance of the mail message, which then is populated and sent.
|
|
|
|
You may put more complex logic in this process if needed:
|
|
|
|
|
|
|
|
```php
|
|
|
|
$message = Yii::$app->mailer->compose();
|
|
|
|
if (Yii::$app->user->isGuest) {
|
|
|
|
$message->setFrom('from@domain.com')
|
|
|
|
} else {
|
|
|
|
$message->setFrom(Yii::$app->user->identity->email)
|
|
|
|
}
|
|
|
|
$message->setTo(Yii::$app->params['adminEmail'])
|
|
|
|
->setSubject('Message subject')
|
|
|
|
->setTextBody('Plain text content')
|
|
|
|
->send();
|
|
|
|
```
|
|
|
|
|
|
|
|
> Note: each 'mailer' extension comes in 2 major classes: 'Mailer' and 'Message'. 'Mailer' always knows
|
|
|
|
the class name and specific of the 'Message'. Do not attempt ot instantiate 'Message' object directly -
|
|
|
|
always use `compose()` method for it.
|
|
|
|
|
|
|
|
You may also send several messages at once:
|
|
|
|
|
|
|
|
```php
|
|
|
|
$messages = [];
|
|
|
|
foreach ($users as $user) {
|
|
|
|
$messages[] = Yii::$app->mailer->compose()
|
|
|
|
// ...
|
|
|
|
->setTo($user->email);
|
|
|
|
}
|
|
|
|
Yii::$app->mailer->sendMultiple($messages);
|
|
|
|
```
|
|
|
|
|
|
|
|
Some particular mail extensions may benefit from this approach, using single network message etc.
|
|
|
|
|
|
|
|
|
|
|
|
Composing mail content
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
Yii allows composition of the actual mail messages content via special view files.
|
|
|
|
By default these files should be located at '@app/mail' path.
|
|
|
|
|
|
|
|
Example mail view file content:
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
use yii\helpers\Html;
|
|
|
|
use yii\helpers\Url;
|
|
|
|
|
|
|
|
|
|
|
|
/* @var $this \yii\web\View view component instance */
|
|
|
|
/* @var $message \yii\mail\BaseMessage instance of newly created mail message */
|
|
|
|
|
|
|
|
?>
|
|
|
|
<h2>This message allows you to visit out site home page by one click</h2>
|
|
|
|
<?= Html::a('Go to home page', Url::home('http')) ?>
|
|
|
|
```
|
|
|
|
|
|
|
|
In order to compose message content via view file simply pass view name to the `compose()` method:
|
|
|
|
|
|
|
|
```php
|
|
|
|
Yii::$app->mailer->compose('home-link') // message body becomes a view rendering result here
|
|
|
|
->setFrom('from@domain.com')
|
|
|
|
->setTo('to@domain.com')
|
|
|
|
->setSubject('Message subject')
|
|
|
|
->send();
|
|
|
|
```
|
|
|
|
|
|
|
|
You may pass additional view parameters to `compose()` method, which will be available inside the view files:
|
|
|
|
|
|
|
|
```php
|
|
|
|
Yii::$app->mailer->compose('greetings', [
|
|
|
|
'user' => Yii::$app->user->identity,
|
|
|
|
'advertisement' => $adContent,
|
|
|
|
]);
|
|
|
|
```
|
|
|
|
|
|
|
|
You can specify different view files for HTML and plain text message contents:
|
|
|
|
|
|
|
|
```php
|
|
|
|
Yii::$app->mailer->compose([
|
|
|
|
'html' => 'contact-html',
|
|
|
|
'text' => 'contact-text',
|
|
|
|
]);
|
|
|
|
```
|
|
|
|
|
|
|
|
If you specify view name as a scalar string, its rendering result will be used as HTML body, while
|
|
|
|
plain text body will be composed by removing all HTML entities from HTML one.
|
|
|
|
|
|
|
|
View rendering result can be wrapped into the layout, which an be setup using [[yii\mail\BaseMailer::htmlLayout]]
|
|
|
|
and [[yii\mail\BaseMailer::textLayout]]. It will work the same way like layouts in regular web application.
|
|
|
|
Layout can be used to setup mail CSS styles or other shared content:
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
use yii\helpers\Html;
|
|
|
|
|
|
|
|
/* @var $this \yii\web\View view component instance */
|
|
|
|
/* @var $message \yii\mail\MessageInterface the message being composed */
|
|
|
|
/* @var $content string main view render result */
|
|
|
|
?>
|
|
|
|
<?php $this->beginPage() ?>
|
|
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
|
|
<head>
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=<?= Yii::$app->charset ?>" />
|
|
|
|
<style type="text/css">
|
|
|
|
.heading {...}
|
|
|
|
.list {...}
|
|
|
|
.footer {...}
|
|
|
|
</style>
|
|
|
|
<?php $this->head() ?>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<?php $this->beginBody() ?>
|
|
|
|
<?= $content ?>
|
|
|
|
<div class="footer">With kind regards, <?= Yii::$app->name ?> team</div>
|
|
|
|
<?php $this->endBody() ?>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
<?php $this->endPage() ?>
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
File attachment
|
|
|
|
---------------
|
|
|
|
|
|
|
|
You can add attachments to message using methods `attach()` and `attachContent()`:
|
|
|
|
|
|
|
|
```php
|
|
|
|
$message = Yii::$app->mailer->compose();
|
|
|
|
|
|
|
|
// Attach file from local file system:
|
|
|
|
$message->attach('/path/to/source/file.pdf');
|
|
|
|
|
|
|
|
// Create attachment on-the-fly
|
|
|
|
$message->attachContent('Attachment content', ['fileName' => 'attach.txt', 'contentType' => 'text/plain']);
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Embed images
|
|
|
|
------------
|
|
|
|
|
|
|
|
You can embed images into the message content using `embed()` method. This method returns the attachment id,
|
|
|
|
which should be then used at 'img' tag.
|
|
|
|
This method is easy to use when composing message content via view file:
|
|
|
|
|
|
|
|
```php
|
|
|
|
Yii::$app->mailer->compose('embed-email', ['imageFileName' => '/path/to/image.jpg'])
|
|
|
|
// ...
|
|
|
|
->send();
|
|
|
|
```
|
|
|
|
|
|
|
|
Then inside view file you can use following code:
|
|
|
|
|
|
|
|
```php
|
|
|
|
<img src="<?= $message->embed($imageFileName); ?>">
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Testing and debugging
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
Developer often a to check, what actual emails are sent by application, what was their content and so on.
|
|
|
|
Such ability is granted by Yii via `yii\mail\BaseMailer::useFileTransport`. If enabled, this option enforces
|
|
|
|
saving mail message data into the local files instead of regular sending. These files will be saved under
|
|
|
|
`yii\mail\BaseMailer::fileTransportPath`, which is '@runtime/mail' by default.
|
|
|
|
|
|
|
|
> Note: you can either save messages to the file or send them to actual recipients, but can not do both simultaneously.
|
|
|
|
|
|
|
|
Mail message file can be opened by regular text file editor, so you can browse actual message headers, content and so on.
|
|
|
|
This mechanism amy prove itself, while debugging application or running unit test.
|
|
|
|
|
|
|
|
> Note: mail message file content is composed via `\yii\mail\MessageInterface::toString()`, so it depends on actual
|
|
|
|
mail extension you are using in your application.
|
|
|
|
|
|
|
|
|
|
|
|
Creating your own mail solution
|
|
|
|
-------------------------------
|
|
|
|
|
|
|
|
In order to create your own custom mail solution, you need to create 2 classes: one for the 'Mailer' and
|
|
|
|
another one for the 'Message'.
|
|
|
|
You can use `yii\mail\BaseMailer` and `yii\mail\BaseMessage` as a base classes for your solution. These classes
|
|
|
|
already contains basic logic, which is described in this guide. However, their usage is not mandatory, it is enough
|
|
|
|
to implement `yii\mail\MailerInterface` and `yii\mail\MessageInterface` interfaces.
|
|
|
|
Then you need to implement all abstract methods to build you solution.
|