├── CHANGELOG.md ├── config ├── params.php └── di.php ├── rector.php ├── LICENSE.md ├── src ├── MessageBodyTemplate.php ├── ViewMailer.php └── MessageBodyRenderer.php ├── composer.json └── README.md /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Yii Mailer View Change Log 2 | 3 | ## 1.0.0 under development 4 | 5 | - Initial release. 6 | -------------------------------------------------------------------------------- /config/params.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'viewPath' => '@resources/mail', 8 | 'htmlLayout' => null, 9 | 'textLayout' => null, 10 | ], 11 | ]; 12 | -------------------------------------------------------------------------------- /config/di.php: -------------------------------------------------------------------------------- 1 | [ 16 | '__construct()' => [ 17 | 'template' => DynamicReference::to( 18 | static fn(?Aliases $aliases = null) => new MessageBodyTemplate( 19 | $aliases === null 20 | ? $params['yiisoft/mailer-view']['viewPath'] 21 | : $aliases->get($params['yiisoft/mailer-view']['viewPath']), 22 | $params['yiisoft/mailer-view']['htmlLayout'], 23 | $params['yiisoft/mailer-view']['textLayout'], 24 | ), 25 | ), 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | paths([ 14 | __DIR__ . '/src', 15 | __DIR__ . '/tests', 16 | ]); 17 | 18 | // register a single rule 19 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); 20 | 21 | // define sets of rules 22 | $rectorConfig->sets([ 23 | LevelSetList::UP_TO_PHP_81, 24 | ]); 25 | 26 | $rectorConfig->skip([ 27 | ClosureToArrowFunctionRector::class, 28 | ReadOnlyPropertyRector::class, 29 | NullToStrictStringFuncCallArgRector::class, 30 | ]); 31 | }; 32 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2008 by Yii Software () 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Yii Software nor the names of its 15 | contributors may be used to endorse or promote products derived 16 | from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /src/MessageBodyTemplate.php: -------------------------------------------------------------------------------- 1 | messageBodyRenderer = $new->messageBodyRenderer->withTemplate($template); 41 | return $new; 42 | } 43 | 44 | /** 45 | * Returns a new instance with specified locale code. 46 | * 47 | * @param string $locale The locale code. 48 | * 49 | * @return self 50 | */ 51 | public function withLocale(string $locale): self 52 | { 53 | $new = clone $this; 54 | $new->messageBodyRenderer = $new->messageBodyRenderer->withLocale($locale); 55 | return $new; 56 | } 57 | 58 | /** 59 | * Creates a new message instance and optionally composes its body content via view rendering. 60 | * 61 | * @param string|null $htmlView The view name to be used for rendering the message HTML body. 62 | * @param array $viewParameters The parameters (name-value pairs) that will be extracted and available in 63 | * the view file. 64 | * @param array $layoutParameters The parameters (name-value pairs) that will be extracted and available in 65 | * the layout file. 66 | * @param string|null $textView The view name to be used for rendering the message text body. If `null`, the text 67 | * body will be generated by strip tags in HTML body. 68 | * 69 | * @throws ViewNotFoundException If the view file does not exist. 70 | * @return MessageInterface The message instance. 71 | */ 72 | public function compose( 73 | ?string $htmlView = null, 74 | array $viewParameters = [], 75 | array $layoutParameters = [], 76 | ?string $textView = null, 77 | ): MessageInterface { 78 | $message = new Message(); 79 | 80 | if ($htmlView === null) { 81 | return $message; 82 | } 83 | 84 | return $this->messageBodyRenderer->addBodyToMessage( 85 | $message, 86 | $htmlView, 87 | $viewParameters, 88 | $layoutParameters, 89 | $textView, 90 | ); 91 | } 92 | 93 | public function send(MessageInterface $message): void 94 | { 95 | $this->mailer->send($message); 96 | } 97 | 98 | public function sendMultiple(array $messages): SendResults 99 | { 100 | return $this->mailer->sendMultiple($messages); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Yii 4 | 5 |

Yii Mailer View

6 |
7 |

8 | 9 | [![Latest Stable Version](https://poser.pugx.org/yiisoft/mailer-view/v)](https://packagist.org/packages/yiisoft/mailer-view) 10 | [![Total Downloads](https://poser.pugx.org/yiisoft/mailer-view/downloads)](https://packagist.org/packages/yiisoft/mailer-view) 11 | [![Build status](https://github.com/yiisoft/mailer-view/actions/workflows/build.yml/badge.svg)](https://github.com/yiisoft/mailer-view/actions/workflows/build.yml) 12 | [![Code Coverage](https://codecov.io/gh/yiisoft/mailer-view/branch/master/graph/badge.svg)](https://codecov.io/gh/yiisoft/mailer-view) 13 | [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fyiisoft%2Fmailer-view%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/mailer-view/master) 14 | [![static analysis](https://github.com/yiisoft/mailer-view/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/mailer-view/actions?query=workflow%3A%22static+analysis%22) 15 | [![type-coverage](https://shepherd.dev/github/yiisoft/mailer-view/coverage.svg)](https://shepherd.dev/github/yiisoft/mailer-view) 16 | [![psalm-level](https://shepherd.dev/github/yiisoft/mailer-view/level.svg)](https://shepherd.dev/github/yiisoft/mailer-view) 17 | 18 | This [Yii Mailer](https://github.com/yiisoft/mailer) extension provides classes for composing message body via view 19 | rendering: 20 | 21 | - `MessageBodyRenderer` - a view renderer used to compose message body. 22 | - `ViewMailer` - a mailer decorator with `compose()` method. 23 | 24 | ## Requirements 25 | 26 | - PHP 8.1 or higher. 27 | 28 | ## Installation 29 | 30 | The package could be installed with [Composer](https://getcomposer.org): 31 | 32 | ```shell 33 | composer require yiisoft/mailer-view 34 | ``` 35 | 36 | ## General usage 37 | 38 | ### Message body renderer 39 | 40 | ```php 41 | use Yiisoft\Mailer\View\MessageBodyRenderer; 42 | use Yiisoft\Mailer\View\MessageBodyTemplate; 43 | use Yiisoft\View\View; 44 | 45 | $renderer = new MessageBodyRenderer( 46 | new View(), 47 | new MessageBodyTemplate( 48 | __DIR__ . '/views', 49 | 'html-layout', 50 | ), 51 | ); 52 | 53 | // HTML body 54 | $htmlBody = $renderer->renderHtml( 55 | view: 'html-content', 56 | viewParameters: ['count' => 42], 57 | layoutParameters: ['header' => 'Hello!'], 58 | ); 59 | 60 | // Text body 61 | $textBody = $renderer->renderText( 62 | view: 'html-content', 63 | viewParameters: ['count' => 42], 64 | layoutParameters: ['header' => 'Hello!'], 65 | ); 66 | 67 | // Add body to message 68 | $message = $renderer->addBodyToMessage( 69 | message: new Message(), 70 | htmlView: 'html-content', 71 | viewParameters: ['count' => 42], 72 | layoutParameters: ['header' => 'Hello!'], 73 | ); 74 | ``` 75 | 76 | If needed, you can pass `textView` parameter with the name of the text view. 77 | 78 | ### Mailer decorator 79 | 80 | ```php 81 | /** 82 | * @var \Yiisoft\Mailer\MailerInterface $mailer 83 | * @var Yiisoft\Mailer\View\MessageBodyRenderer $messageBodyRenderer 84 | */ 85 | 86 | $viewMailer = new ViewMailer($mailer, $messageBodyRenderer); 87 | 88 | // Create message 89 | $message = $viewMailer->compose( 90 | htmlView: 'html-content', 91 | viewParameters: ['count' => 42], 92 | layoutParameters: ['header' => 'Hello!'], 93 | ); 94 | 95 | // Send message 96 | $viewMailer->send($message); 97 | ``` 98 | 99 | If needed, you can pass `textView` parameter with the name of the text view. 100 | 101 | ## Documentation 102 | 103 | - [Internals](docs/internals.md) 104 | 105 | If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place 106 | for that. You may also check out other [Yii Community Resources](https://www.yiiframework.com/community). 107 | 108 | ## License 109 | 110 | The Yii Mailer View is free software. It is released under the terms of the BSD License. 111 | Please see [`LICENSE`](./LICENSE.md) for more information. 112 | 113 | Maintained by [Yii Software](https://www.yiiframework.com/). 114 | 115 | ## Support the project 116 | 117 | [![Open Collective](https://img.shields.io/badge/Open%20Collective-sponsor-7eadf1?logo=open%20collective&logoColor=7eadf1&labelColor=555555)](https://opencollective.com/yiisoft) 118 | 119 | ## Follow updates 120 | 121 | [![Official website](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](https://www.yiiframework.com/) 122 | [![Twitter](https://img.shields.io/badge/twitter-follow-1DA1F2?logo=twitter&logoColor=1DA1F2&labelColor=555555?style=flat)](https://twitter.com/yiiframework) 123 | [![Telegram](https://img.shields.io/badge/telegram-join-1DA1F2?style=flat&logo=telegram)](https://t.me/yii3en) 124 | [![Facebook](https://img.shields.io/badge/facebook-join-1DA1F2?style=flat&logo=facebook&logoColor=ffffff)](https://www.facebook.com/groups/yiitalk) 125 | [![Slack](https://img.shields.io/badge/slack-join-1DA1F2?style=flat&logo=slack)](https://yiiframework.com/go/slack) 126 | -------------------------------------------------------------------------------- /src/MessageBodyRenderer.php: -------------------------------------------------------------------------------- 1 | view = $view; 39 | return $new; 40 | } 41 | 42 | /** 43 | * Returns a new instance with the specified message body template. 44 | * 45 | * @param MessageBodyTemplate $template The message body template. 46 | * 47 | * @return self The new instance. 48 | */ 49 | public function withTemplate(MessageBodyTemplate $template): self 50 | { 51 | $new = clone $this; 52 | $new->template = $template; 53 | return $new; 54 | } 55 | 56 | /** 57 | * Returns a new instance with specified locale code. 58 | * 59 | * @param string $locale The locale code. 60 | */ 61 | public function withLocale(string $locale): self 62 | { 63 | $new = clone $this; 64 | $new->view = $this->view->withLocale($locale); 65 | return $new; 66 | } 67 | 68 | /** 69 | * Adds the rendered body to the message and returns it. 70 | * 71 | * @param MessageInterface $message The message to which the body will be added. 72 | * @param string $htmlView The view name to be used for rendering the message HTML body. 73 | * @param array $viewParameters The parameters (name-value pairs) that will be extracted and available in 74 | * the view file. 75 | * @param array $layoutParameters The parameters (name-value pairs) that will be extracted and available in 76 | * the layout file. 77 | * @param string|null $textView The view name to be used for rendering the message text body. 78 | * 79 | * @throws ViewNotFoundException If the view file does not exist. 80 | * @return MessageInterface The message with the added body. 81 | */ 82 | public function addBodyToMessage( 83 | MessageInterface $message, 84 | string $htmlView, 85 | array $viewParameters = [], 86 | array $layoutParameters = [], 87 | ?string $textView = null, 88 | ): MessageInterface { 89 | $message = $message->withHtmlBody( 90 | $this->renderHtml($htmlView, $viewParameters, $layoutParameters) 91 | ); 92 | 93 | if ($textView !== null) { 94 | $message = $message->withTextBody( 95 | $this->renderText($textView, $viewParameters, $layoutParameters) 96 | ); 97 | } 98 | 99 | return $message; 100 | } 101 | 102 | /** 103 | * Renders the HTML view specified with optional parameters and layout. 104 | * 105 | * @param string $view The view name of the view file. 106 | * @param array $viewParameters The parameters (name-value pairs) that will be extracted and available in 107 | * the view file. 108 | * @param array $layoutParameters The parameters (name-value pairs) that will be extracted and available in 109 | * the layout file. 110 | * 111 | * @see View::render() 112 | * 113 | * @throws ViewNotFoundException If the view file does not exist. 114 | * @return string The rendering HTML result. 115 | */ 116 | public function renderHtml(string $view, array $viewParameters = [], array $layoutParameters = []): string 117 | { 118 | $content = $this->view 119 | ->withContextPath($this->template->viewPath) 120 | ->render($view, $viewParameters); 121 | 122 | if ($this->template->htmlLayout === null) { 123 | return $content; 124 | } 125 | 126 | $layoutParameters['content'] = $content; 127 | return $this->view 128 | ->withContextPath($this->template->viewPath) 129 | ->render($this->template->htmlLayout, $layoutParameters); 130 | } 131 | 132 | /** 133 | * Renders the text view specified with optional parameters and layout. 134 | * 135 | * @param string $view The view name of the view file. 136 | * @param array $viewParameters The parameters (name-value pairs) that will be extracted and available in 137 | * the view file. 138 | * @param array $layoutParameters The parameters (name-value pairs) that will be extracted and available in 139 | * the layout file. 140 | * 141 | * @see View::render() 142 | * 143 | * @throws ViewNotFoundException If the view file does not exist. 144 | * @return string The rendering text result. 145 | */ 146 | public function renderText(string $view, array $viewParameters = [], array $layoutParameters = []): string 147 | { 148 | $content = $this->view 149 | ->withContextPath($this->template->viewPath) 150 | ->render($view, $viewParameters); 151 | 152 | if ($this->template->textLayout === null) { 153 | return $content; 154 | } 155 | 156 | $layoutParameters['content'] = $content; 157 | return $this->view 158 | ->withContextPath($this->template->viewPath) 159 | ->render($this->template->textLayout, $layoutParameters); 160 | } 161 | } 162 | --------------------------------------------------------------------------------