CakePHP3でモデルのないフォームからメール送信したい

CakePHP3でメール送信したい時ってあると思います。

通常はコントローラにメール送信処理を書きます。

ですが前回の続きの内容となるので、モデルのないフォームにメール送信処理を書いて送る方法を今回は見ていきます。

お問い合わせフォームでサンクスメールを相手に送ったり、お問い合わせ内容の載ったメールを自分に送りたかったりしますよね。

そこで今回はメール送信の方法を見ていきます。

【自分の環境】
macOS Catalina
PHP7.4.2
CakePHP3.8
MAMP5.7
Apache2.2
MySQL5.7

大前提

メール送信のプログラムを書く前に、設定が必要です。

自分の場合はMAMP環境でGmailから送る方法を調べました。

以下の記事が神のようにわかりやすいです。

【2021年版】PostfixからGmail経由でメールを送信する方法

結構な設定なので時間がかかりますが、MAMPの方は必須です。

他のレンタルサーバーの場合などは自分は分かりかねますので、各自で設定をお願い致します。

それではコードを見ていきましょう。

app.phpの設定を見る

app.phpにあるEmailTransportは以下のようになっていると思います。

'EmailTransport' => [
        'default' => [
            'className' => MailTransport::class,
            /*
             * The keys host, port, timeout, username, password, client and tls
             * are used in SMTP transports
             */
            'host' => 'localhost',
            'port' => 25,
            'timeout' => 30,
            /*
             * It is recommended to set these options through your environment or app_local.php
             */
            //'username' => null,
            //'password' => null,
            'client' => null,
            'tls' => false,
            'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
        ],
    ],

恐らくデフォルトでこうなっています。

もしも「className」が「smtp」になっていると別途設定が必要なので、気をつけてください。

以下は「className」が「Mail」や「MailTransport::class」となっている体で話します。

それでは見ていきましょう。

モデルのないフォームの_executeファンクションにメール送信処理を記述

モデルのないフォームは以下のようになります。

(中略)
use Cake\Mailer\Email;
(中略)
protected function _execute(array $data)
    {
        // メールを送信する
        $info_email = new Email('default');
        $info_email
            ->setFrom(['example@gmail.com'=>'事務局'])
            ->setTo('example@gmail.com')
            ->setSubject('ご意見・ご要望がありました。')
            ->send('お客様のお名前:'.$data['name'].' 様'."\n\n".'メールアドレス:'."\n".$data['email']."\n\n".'内容:'."\n".$data['body']);


        $thank_email = new Email('default');
        $thank_email
            ->setFrom(['example@gmail.com'=>'事務局'])
            ->setTo($data['email'])
            ->setSubject('ご意見・ご要望をありがとうございます!')
            ->send($data['name'].' 様'."\n\n".
                    '貴重なご意見・ご要望をいただきまして、誠にありがとうございます!'."\n".
                    'サービス改善のヒントとして役立てるほか、必要があればお客様に折り返しメールを差し上げることもございます。'."\n\n".
                    'お客様のお名前:'.$data['name']."\n\n".'メールアドレス:'."\n".$data['email']."\n\n".'内容:'."\n".$data['body']);

        return true;
    }

このようになっています。

まずinfo_emailというのは自分から自分宛てのメールです。

自分の場合はユーザーからのお問い合わせの内容を書いています。

そしてthank_emailは自分からお問い合わせユーザーに向けたメールです。

本文には「ご意見いただき、ありがとうございます」みたいなことが書いてあります。

構造ですが、一番上で「use Cake\Mailer\Email;」しています。

これでEmailクラスが使えるようになります。

そして_executeファンクションでは、そのEmailクラスを使って「new Email('default');」という記述があります。

まず「$info_email = new Email('default');」みたいなかんじで$info_emailに代入すると、メールのインスタンスができます。

そこからはメソッドチェーンで送信元(setFrom)、宛先(setTo)、題名(setSubject)など設定していきます。

重要なのがメールの本文(sendの引数)です。

あらかじめ$dataの中にname(お問い合わせユーザーの名前)、email(ユーザーのメールアドレス)、body(お問い合わせ内容)が入っています。

なのでこれを使ってメールの本文を作っています。

上記のものは実際のコードなので参考にしてみてください。

これでバリデーションに通れば送信できます。

終わりに

以上となります。

なかなかモデルのないフォームの記事でメール送信の方法が書いていなかったので苦労しました。

記事として残したいと強く思っていた部分です。

この記事は以下のページも参考にしながら書きました。

CakePHP3のメール送信の処理・テンプレート使用・添付ファイル送信も解説 | エス技研

このページには通常のコントローラでメール送信処理する方法が書いてあります。

ありがとうございました。