├── rector.php ├── config ├── params.php └── di.php ├── LICENSE.md ├── CHANGELOG.md ├── composer.json ├── src ├── Mailer.php └── EmailFactory.php └── README.md /rector.php: -------------------------------------------------------------------------------- 1 | withPaths([ 13 | __DIR__ . '/src', 14 | __DIR__ . '/tests', 15 | ]) 16 | ->withPhpSets(php81: true) 17 | ->withRules([ 18 | InlineConstructorDefaultToPropertyRector::class, 19 | ]) 20 | ->withSkip([ 21 | ClosureToArrowFunctionRector::class, 22 | ReadOnlyPropertyRector::class, 23 | NullToStrictStringFuncCallArgRector::class, 24 | ]); 25 | -------------------------------------------------------------------------------- /config/params.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'useSendmail' => false, 8 | 'esmtpTransport' => [ 9 | 'scheme' => 'smtps', // "smtps": using TLS, "smtp": without using TLS. 10 | 'host' => 'smtp.example.com', 11 | 'port' => 465, 12 | 'username' => 'admin@example.com', 13 | 'password' => '', 14 | 'options' => [], // See: https://symfony.com/doc/current/mailer.html#tls-peer-verification 15 | ], 16 | 'messageSettings' => [ 17 | 'charset' => null, 18 | 'from' => null, 19 | 'addFrom' => null, 20 | 'to' => null, 21 | 'addTo' => null, 22 | 'replyTo' => null, 23 | 'addReplyTo' => null, 24 | 'cc' => null, 25 | 'addCc' => null, 26 | 'bcc' => null, 27 | 'addBcc' => null, 28 | 'subject' => null, 29 | 'date' => null, 30 | 'priority' => null, 31 | 'returnPath' => null, 32 | 'sender' => null, 33 | 'textBody' => null, 34 | 'htmlBody' => null, 35 | 'attachments' => null, 36 | 'addAttachments' => null, 37 | 'embeddings' => null, 38 | 'addEmbeddings' => null, 39 | 'headers' => null, 40 | 'overwriteHeaders' => null, 41 | 'convertHtmlToText' => true, 42 | ], 43 | ], 44 | ]; 45 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2008 by Yii Software (https://www.yiiframework.com/) 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 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Yii Mailer - Symfony Mailer Extension Change Log 2 | 3 | ## 4.0.1 under development 4 | 5 | - Chg #69: Change PHP constraint in `composer.json` to `8.1 - 8.4` (@vjik) 6 | 7 | ## 4.0.0 October 18, 2024 8 | 9 | - Chg #48: Change package configuration params prefix to `yiisoft/mailer-symfony` (@vjik) 10 | - Chg #49, #58, #62, #63, #66: Adapt to Yii Mailer 6: remove `Message` class, add `$messageSettings` parameter 11 | to `Mailer` constructor, remove `MessageBodyRenderer` usage (@vjik) 12 | - Chg #50: Raise minimal PHP version to `^8.1` (@vjik) 13 | - Chg #59: Change order of constructor parameters in `Mailer` (@vjik) 14 | - Chg #64: Remove `FileMailer` configuration and `writeToFiles` parameter from package configuration (@vjik) 15 | - Enh #59: Make `psr/event-dispatcher` dependency optional (@vjik) 16 | - Bug #56: Use file ID for attachments and embedded files (@vjik) 17 | 18 | ## 3.0.1 May 24, 2024 19 | 20 | - Enh #39: Add support for `symfony/mime` of version ^7.0 (@vjik) 21 | - Enh #41: Add support for `symfony/mailer` of version ^7.0 (@vjik) 22 | 23 | ## 3.0.0 February 16, 2023 24 | 25 | - Chg #27: Adapt configuration group names to Yii conventions (@vjik) 26 | 27 | ## 2.1.0 January 02, 2023 28 | 29 | - Chg #24: Raise minimal PHP version to `^8.0` (@vjik) 30 | - Chg #25: Raise `yiisoft/mailer` version to `^5.0`, `MessageInterface` adapt to it (@vjik) 31 | - Enh #18: Explicitly add transitive dependencies `psr/event-dispatcher` and `symfony/mime` (@vjik) 32 | 33 | ## 2.0.0 July 25, 2022 34 | 35 | - Chg #13: Update the `yiisoft/mailer` dependency, up to `^4.0` (@thenotsoft) 36 | - Enh #7: Add support for version `^6.0` for `symfony/mailer` package (@devanych) 37 | 38 | ## 1.0.1 November 22, 2021 39 | 40 | - Enh #6: Improve the configuration for passing additional options to `EsmtpTransport` instance (@devanych) 41 | 42 | ## 1.0.0 October 17, 2021 43 | 44 | - Initial release. 45 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yiisoft/mailer-symfony", 3 | "type": "library", 4 | "description": "Adapter for `yiisoft/mailer` relying on `symfony/mailer`", 5 | "keywords": [ 6 | "yii", 7 | "mail", 8 | "email", 9 | "mailer" 10 | ], 11 | "homepage": "https://www.yiiframework.com/", 12 | "license": "BSD-3-Clause", 13 | "support": { 14 | "issues": "https://github.com/yiisoft/mailer-symfony/issues?state=open", 15 | "source": "https://github.com/yiisoft/mailer-symfony", 16 | "forum": "https://www.yiiframework.com/forum/", 17 | "wiki": "https://www.yiiframework.com/wiki/", 18 | "irc": "ircs://irc.libera.chat:6697/yii", 19 | "chat": "https://t.me/yii3en" 20 | }, 21 | "funding": [ 22 | { 23 | "type": "opencollective", 24 | "url": "https://opencollective.com/yiisoft" 25 | }, 26 | { 27 | "type": "github", 28 | "url": "https://github.com/sponsors/yiisoft" 29 | } 30 | ], 31 | "require": { 32 | "php": "8.1 - 8.4", 33 | "symfony/mailer": "^5.3 || ^6.0 || ^7.0", 34 | "symfony/mime": "^5.4 || ^6.2 || ^7.0", 35 | "yiisoft/mailer": "^6.0.1" 36 | }, 37 | "require-dev": { 38 | "ext-openssl": "*", 39 | "maglnet/composer-require-checker": "^4.7.1", 40 | "phpunit/phpunit": "^10.5.45", 41 | "psr/event-dispatcher": "^1.0", 42 | "rector/rector": "^2.0.10", 43 | "roave/infection-static-analysis-plugin": "^1.35", 44 | "spatie/phpunit-watcher": "^1.24", 45 | "vimeo/psalm": "^5.26.1 || ^6.9.4", 46 | "yiisoft/aliases": "^3.0", 47 | "yiisoft/di": "^1.3", 48 | "yiisoft/files": "^2.0", 49 | "yiisoft/psr-dummy-provider": "^1.0.2", 50 | "yiisoft/test-support": "^3.0.2" 51 | }, 52 | "suggest": { 53 | "psr/event-dispatcher": "Use PSR Event Dispatcher implementation for process before/after send events" 54 | }, 55 | "autoload": { 56 | "psr-4": { 57 | "Yiisoft\\Mailer\\Symfony\\": "src" 58 | } 59 | }, 60 | "autoload-dev": { 61 | "psr-4": { 62 | "Yiisoft\\Mailer\\Symfony\\Tests\\": "tests" 63 | } 64 | }, 65 | "extra": { 66 | "config-plugin-options": { 67 | "source-directory": "config" 68 | }, 69 | "config-plugin": { 70 | "params": "params.php", 71 | "di": "di.php" 72 | } 73 | }, 74 | "config": { 75 | "sort-packages": true, 76 | "allow-plugins": { 77 | "infection/extension-installer": true, 78 | "composer/package-versions-deprecated": true 79 | } 80 | }, 81 | "scripts": { 82 | "test": "phpunit --testdox --no-interaction", 83 | "test-watch": "phpunit-watcher watch" 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /config/di.php: -------------------------------------------------------------------------------- 1 | $params['yiisoft/mailer-symfony']['useSendmail'] 18 | ? SendmailTransport::class 19 | : static fn(EsmtpTransportFactory $factory): TransportInterface => $factory->create( 20 | new Dsn( 21 | $params['yiisoft/mailer-symfony']['esmtpTransport']['scheme'], 22 | $params['yiisoft/mailer-symfony']['esmtpTransport']['host'], 23 | $params['yiisoft/mailer-symfony']['esmtpTransport']['username'], 24 | $params['yiisoft/mailer-symfony']['esmtpTransport']['password'], 25 | $params['yiisoft/mailer-symfony']['esmtpTransport']['port'], 26 | $params['yiisoft/mailer-symfony']['esmtpTransport']['options'], 27 | ) 28 | ), 29 | 30 | MailerInterface::class => Mailer::class, 31 | 32 | Mailer::class => [ 33 | '__construct()' => [ 34 | 'messageSettings' => new MessageSettings( 35 | $params['yiisoft/mailer-symfony']['messageSettings']['charset'], 36 | $params['yiisoft/mailer-symfony']['messageSettings']['from'], 37 | $params['yiisoft/mailer-symfony']['messageSettings']['addFrom'], 38 | $params['yiisoft/mailer-symfony']['messageSettings']['to'], 39 | $params['yiisoft/mailer-symfony']['messageSettings']['addTo'], 40 | $params['yiisoft/mailer-symfony']['messageSettings']['replyTo'], 41 | $params['yiisoft/mailer-symfony']['messageSettings']['addReplyTo'], 42 | $params['yiisoft/mailer-symfony']['messageSettings']['cc'], 43 | $params['yiisoft/mailer-symfony']['messageSettings']['addCc'], 44 | $params['yiisoft/mailer-symfony']['messageSettings']['bcc'], 45 | $params['yiisoft/mailer-symfony']['messageSettings']['addBcc'], 46 | $params['yiisoft/mailer-symfony']['messageSettings']['subject'], 47 | $params['yiisoft/mailer-symfony']['messageSettings']['date'], 48 | $params['yiisoft/mailer-symfony']['messageSettings']['priority'], 49 | $params['yiisoft/mailer-symfony']['messageSettings']['returnPath'], 50 | $params['yiisoft/mailer-symfony']['messageSettings']['sender'], 51 | $params['yiisoft/mailer-symfony']['messageSettings']['textBody'], 52 | $params['yiisoft/mailer-symfony']['messageSettings']['htmlBody'], 53 | $params['yiisoft/mailer-symfony']['messageSettings']['attachments'], 54 | $params['yiisoft/mailer-symfony']['messageSettings']['addAttachments'], 55 | $params['yiisoft/mailer-symfony']['messageSettings']['embeddings'], 56 | $params['yiisoft/mailer-symfony']['messageSettings']['addEmbeddings'], 57 | $params['yiisoft/mailer-symfony']['messageSettings']['headers'], 58 | $params['yiisoft/mailer-symfony']['messageSettings']['overwriteHeaders'], 59 | $params['yiisoft/mailer-symfony']['messageSettings']['convertHtmlToText'] 60 | ? new HtmlToTextBodyConverter() 61 | : null, 62 | ), 63 | ], 64 | ], 65 | ]; 66 | -------------------------------------------------------------------------------- /src/Mailer.php: -------------------------------------------------------------------------------- 1 | symfonyMailer = new SymfonyMailer($transport); 45 | $this->emailFactory = new EmailFactory(); 46 | } 47 | 48 | /** 49 | * Returns a new instance with the specified encryptor. 50 | * 51 | * @param SMimeEncrypter $encryptor The encryptor instance. 52 | * 53 | * @see https://symfony.com/doc/current/mailer.html#encrypting-messages 54 | */ 55 | public function withEncryptor(SMimeEncrypter $encryptor): self 56 | { 57 | $new = clone $this; 58 | $new->encryptor = $encryptor; 59 | return $new; 60 | } 61 | 62 | /** 63 | * Returns a new instance with the specified signer. 64 | * 65 | * @param DkimSigner|object|SMimeSigner $signer The signer instance. 66 | * @param array $options The options for DKIM signer {@see DkimSigner}. 67 | * 68 | * @throws RuntimeException If the signer is not an instance of {@see DkimSigner} or {@see SMimeSigner}. 69 | * 70 | * @see https://symfony.com/doc/current/mailer.html#signing-messages 71 | */ 72 | public function withSigner(object $signer, array $options = []): self 73 | { 74 | $new = clone $this; 75 | 76 | if ($signer instanceof DkimSigner) { 77 | $new->signer = $signer; 78 | $new->dkimSignerOptions = $options; 79 | return $new; 80 | } 81 | 82 | if ($signer instanceof SMimeSigner) { 83 | $new->signer = $signer; 84 | return $new; 85 | } 86 | 87 | throw new RuntimeException(sprintf( 88 | 'The signer must be an instance of "%s" or "%s". The "%s" instance is received.', 89 | DkimSigner::class, 90 | SMimeSigner::class, 91 | $signer::class, 92 | )); 93 | } 94 | 95 | /** 96 | * {@inheritDoc} 97 | * 98 | * @throws TransportExceptionInterface If sending failed. 99 | */ 100 | protected function sendMessage(MessageInterface $message): void 101 | { 102 | $email = $this->emailFactory->create($message); 103 | 104 | if ($this->encryptor !== null) { 105 | $email = $this->encryptor->encrypt($email); 106 | } 107 | 108 | if ($this->signer !== null) { 109 | $email = $this->signer instanceof DkimSigner 110 | ? $this->signer->sign($email, $this->dkimSignerOptions) 111 | : $this->signer->sign($email) 112 | ; 113 | } 114 | 115 | $this->symfonyMailer->send($email); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |