mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 18:47:33 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			231 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 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://www.yiiframework.com/extension/yiisoft/yii2-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 the `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 the above example the 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 to 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 our 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') // a view rendering result becomes the message body 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 can 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']);
 | |
| ```
 | |
| 
 | |
| 
 | |
| Embedding 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 the view file you can use the following code:
 | |
| 
 | |
| ```php
 | |
| <img src="<?= $message->embed($imageFileName); ?>">
 | |
| ```
 | |
| 
 | |
| 
 | |
| Testing and debugging
 | |
| ---------------------
 | |
| 
 | |
| A developer often has to check, what actual emails are sent by the 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 the messages to the files or send them to the actual recipients, but can not do both simultaneously.
 | |
| 
 | |
| A mail message file can be opened by a regular text file editor, so you can browse the actual message headers, content and so on.
 | |
| This mechanism may prove itself, while debugging application or running unit test.
 | |
| 
 | |
| > Note: the mail message file content is composed via `\yii\mail\MessageInterface::toString()`, so it depends on the 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 the base classes for your solution. These classes
 | |
| already contain the 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 the abstract methods to build your solution.
 | 
