

**MailComponentなどでの呼び出しの流れを極力変えず利用Mailerを変えるには**

RFC違反のメールアドレスにもメールを送信できるよう、MailerをPHPMailerに変更してほしいという要望を受けました。  
PHPMailerをインストールして、直接ファイルを作り単体で動作させメールを送ることはできました。  
ただ、以下コードをあまり変えずに利用するメーラーをデフォルト出ないものに変えたいのですが、そういったことは可能なのでしょうか？

**現在の処理の流れ**  
現在はコントローラーからメールコンポーネントを呼び出します

[code]

    src/Controller/Component/MailComponent.php
    
        public function sendMailConfirm($club, $change) {
        if ($this->_isSend && !empty($change->mail)) $this->getMailer('Customer')->send('mail_confirm', [$club, $change]);
      }
    
[/code]

そのあと指定されたメーラーからテンプレートを呼び出し送信しています  
src/Mailer/CustomerMailer.php

[code]

      public function mail_confirm($club, $change) {
        $from = Configure::read('Mailer.From');
        $to = $change->mail;
        $this
          ->from($from)
          ->to($to)
          ->subject('PINコード送信')
          ->template('mail_confirm', 'default')
          ->set(['pin_code' => $change->pin_code]);
      }
    
[/code]

**調べてわからなかったこと**  
公式サイトには独自のトランスポートを作成し、他のメーラーを使うようにするとありました  
<https://book.cakephp.org/3/ja/core-libraries/email.html#id9>

ただ理解力が足りず、どのようにこれを使うのか全くイメージできていない状態です

追加した独自トランスポートを呼び出す方法もよくわかっていません。変更したいメーラーで呼び出して使えるのかと思い、つなぎ込めるか確認しようと簡易的に以下のようにしたのですがそもそも、transportClassメソッドがないとエラーが出ます  
src/Mailer/CustomerMailer.php

[code]

    <?php
    
    namespace App\Mailer;
    
    use Cake\Core\Configure;
    use Cake\Mailer\Mailer;
    use Cake\Mailer\Email;
    
    class CustomerMailer extends Mailer {
    ・・・・
    public function mail_confirm($club, $change) {
    　　$yourInstance = $this->getTransport()->transportClass();　
        $test = $yourInstance->myCustomMethod();
    $this->log('カスタマーメーラー'. var_export($test, true));
    
    
            $from = Configure::read('Mailer.From');
            $to = $change->mail;
            $this
              ->from($from)
              ->to($to)
              ->subject('PINコード送信')
              ->template('mail_confirm', 'default')
              ->set(['pin_code' => $change->pin_code]);
          }
    
[/code]

テストとして、追加して見た独自トランスポート  
src/Mailer/Transport/PhpmailerTransport.php

[code]

    <?php
    namespace App\Mailer\Transport;
    
    use Cake\Mailer\AbstractTransport;
    use Cake\Mailer\Email;
    
    class PhpmailerTransport extends AbstractTransport
    {
    
        public function test(){
            return 'from PhpmailerTransport message';
        }
    }
    
[/code]

この部分を変更するにあたり、組み込みかたが似ている  
もしくはCakephpでデフォルト以外のメーラーを利用しているサンプルをご存知のかたがいましたら教えていただけないでしょうか？

PHPMailerをダイレクトに利用する方法しかみつからず、効率的に切り替える方法が見えていない状況です

考え方そのもので間違っている部分があるなど、読んでいて何かおかしいと思われる部分あどありましたらご指摘いただければと思います

よろしくお願いいたします

**バージョン**  
cakephp3.5  
php7  
PHPMailer v6.1.5


CC BY-SA 4.0
2020-04-16T01:55:41.957
65661
2020-04-16T07:22:28.797
question
cakephp
cakephpでデフォルト以外のMailerを利用する場合、どのように利用メーラーを切り替えられるでしょうか？


許可するメールアドレスのパターンを変更したいのであれば、`Email::setEmailPattern` を使用します。

[Cake\Mailer\Email::emailPattern($pattern) | CakePHP
Cookbook](https://book.cakephp.org/3/ja/core-
libraries/email.html#Cake%5CMailer%5CEmail::emailPattern)

EmailクラスのメソッドはMailerクラスからも使用できますので、

[code]

    class CustomerMailer extends Mailer
    {
       // ...snip
       public function mail_confirm($club, $change)
       {
           $this->setEmailPattern('/^(?:[\p{L}0-9-._]+@[\p{L}0-9-._]+)$/ui');
           // ...snip
       }
    
[/code]

のように許可したいメールアドレスの正規表現を与えてください。

今回の目的には不要ですが、独自のメールトランスポートクラスを作成したいのであれば、`Cake\Mailer\AbstractTransport`
を継承したクラスを作成します。AbstractTransportは`send(Email
$mail)`メソッドを実装することを期待しているので、sendメソッドを作成し、与えられたEmailクラスを元に送信処理を作成します。

[独自のトランスポートの作成 | Email - 3.8](https://book.cakephp.org/3/ja/core-
libraries/email.html#id10)

[code]

    class PhpmailerTransport extends AbstractTransport
    {
    
        public function send(Email $email)
        {
            $phpmailer = new PHPMailer();
            // TODO: PHPMailer のセットアップ
            // TODO: $emailからヘッダーやメッセージボディを取得してPHPMailerにセットして送信
        }
    
    
[/code]

のようなクラスを実装してから `config/app.php` の `EmailTransport` に追加します。

[code]

        'EmailTransport' => [
            'default' => [ ... ],
            'phpmailer' => [
                'className' => 'Phpmailer',
                // ここでセットした値はトランスポートクラスのコンストラクタに渡され、
                // トランスポートクラスの`getConfig()`で取得できるようになります。
            ],
        ],
    
[/code]

最後にMailerクラスまたは、Emailクラスで `setTransport()` を使用してトランスポートクラスの切替えを行います。

[code]

    class CustomerMailer extends Mailer
    {
       // ...snip
       public function mail_confirm($club, $change)
       {
           $this->setTransport('phpmailer');
           // ...snip
       }
    
[/code]


CC BY-SA 4.0
2020-04-16T07:22:28.797
65672
2020-04-16T07:22:28.797
2668
65661
answer