【EC-CUBE 4】自動送信されるメールテンプレートを変更する方法

商品の注文時や会員登録時に自動送信されるメール。本文の文言だけなら管理画面から編集できますが、あらかじめ用意した別のテンプレートへ丸ごと差し替えるには、サーバー上のファイルを触る必要があります。この記事では、注文時に送られるメールを新しいテンプレートに切り替える手順を紹介します。

自動送信されるメールを、別のテンプレートに変えるには?

やることは2つです。①設定ファイルに「テンプレート名とテンプレートID」の対応を書き足す②メール送信処理が参照するテンプレートIDを、その名前に差し替える

②はコアのファイルを直接編集する方法と、app/Customize に置いてオーバーライドする方法があります。EC-CUBEのバージョンアップでコアは上書きされるため、後者をおすすめします

作業後はキャッシュの削除が必須です。削除しないと、ファイルを正しく直しても古い設定のまま送信され続けます。

【動作環境】EC-CUBEのバージョン:4.3.0 / サーバー:Xserver

開発前にデバッグモードの設定をおすすめします。エラーが起きたときに詳細情報が表示されるようになり、原因の箇所を探しやすくなります。カスタマイズ後は解除を忘れずに。

設定と解除の手順は、こちらの記事にまとめています。

デバッグモードの設定/解除方法

目次

管理画面でできること、できないこと

先に切り分けておくと迷いません。メールまわりの設定は、管理画面で完結するものファイルを触らないと変えられないものに分かれます。

やりたいこと 管理画面 必要な作業
メール本文の文言を直す できる 「設定」→「メール設定」から編集
テンプレートを新しく増やす できる 管理画面から追加(別記事で解説)
どのテンプレートを送るか変える できない 設定ファイルとメール送信処理の修正(本記事)

つまり本記事は、3行目だけを扱います。テンプレートそのものの増やし方は別記事にまとめてあるので、まだ用意していない方はそちらを先にどうぞ。

メールテンプレートを増やす方法

実装後の状態

あらかじめ『注文受付メール2』というテンプレートを1つ追加しておきます。冒頭に「※これは新しく用意したテンプレートです。」という一文を入れて、切り替わったことが分かるようにしておきました。

EC-CUBE管理画面のメール設定に『注文受付メール2』を追加し、本文冒頭に確認用の一文を入れた状態

新規追加したメールテンプレート

この状態で商品を注文すると、デフォルトの『注文受付メール』ではなく、追加した『注文受付メール2』が送信されるようにします。

注文後に自動送信されたメールの受信画面。冒頭に「※これは新しく用意したテンプレートです。」の一文が表示されている

自動送信された新規テンプレートのメール

追加した一文が表示されており、送信されるメールが差し替わったことが確認できます。

同じやり方で『出荷通知メール』や『問合受付メール』を注文時に送ることもできます。ただし注文時に送る内容ではないので、実用的ではありません。

実装の手順

  1. STEP1
    設定ファイルにテンプレートIDを追加する

    まず、追加したテンプレートにプログラムから呼ぶための名前を与えます。編集するのは次のファイルです。

    app/config/eccube/packages/eccube.yaml

    フォルダ名は packages(複数形)です。package というフォルダは存在しないので、見つからないときはここを疑ってください。

    FTPクライアントでapp/config/eccube/packagesフォルダを開き、eccube.yamlを選択している画面

    app/config/eccube/packages/eccube.yaml

    121行目付近に、メールテンプレートの名前とテンプレートIDを結びつける記述があります。ここへ、追加したいテンプレートの名前(自由に決めてOK)とテンプレートIDを書き足します。

    parameters:
        eccube_order_mail_template_id: 1 #注文受付メール
        eccube_entry_confirm_mail_template_id: 2 #会員仮登録メール
        eccube_entry_complete_mail_template_id: 3 #会員本登録メール
        eccube_customer_withdraw_mail_template_id: 4 #会員退会メール
        eccube_contact_mail_template_id: 5 #問合受付メール
        eccube_forgot_mail_template_id: 6 #パスワードリセット
        eccube_reset_complete_mail_template_id: 7 #パスワードリマインダー
        eccube_shipping_notify_mail_template_id: 8 #出荷通知メール
    
        #追加したメールテンプレート
        my_order_mail_template_id: 9 #注文受付メール2

    インデント(行頭の空白4つ)を崩さないでください。これらは parameters: の下にぶら下がる項目です。行頭から書いてしまうとYAMLの構造が変わり、設定として読まれません。

    右側の数字は、管理画面のメール設定でテンプレートに割り振られているテンプレートIDです。9番が『注文受付メール2』にあたります。

    独自の定数(パラメータ)を設定・管理する方法

  2. STEP2
    メール送信処理が見るテンプレートを差し替える

    注文時のメール送信は MailServicesendOrderMail() で行われています。このメソッドが読むテンプレートIDを、STEP1で決めた名前に差し替えます。

    やり方は2通りあります。結果は同じですが、保守性が大きく違います。

    方法A:コアを直接編集 方法B:Customizeでオーバーライド
    手間 1ファイルの1行だけ 2ファイルを新規作成・追記
    バージョンアップ 上書きされて消える 影響を受けない
    おすすめ 動作確認・お試し向け こちら

    方法A:コアの MailService.php を直接編集する

    「src/Eccube/Service」下にある MailService.php に、メールの自動送信に関する処理が書かれています。

    FTPクライアントでsrc/Eccube/Serviceフォルダを開き、MailService.phpを選択している画面

    src/Eccube/Service/MailService.php

    sendOrderMail() の中にある変数 $MailTemplate に、送信したいテンプレートが代入されています。find() の引数がデフォルトでは eccubeConfig['eccube_order_mail_template_id'] になっているので、角括弧の中をSTEP1で決めた名前に書き換えます。

    public function sendOrderMail(Order $Order)
    {
        log_info('受注メール送信開始');
    
        // デフォルトのコード
        // $MailTemplate = $this->mailTemplateRepository->find($this->eccubeConfig['eccube_order_mail_template_id']);
    
        // 修正コード
        $MailTemplate = $this->mailTemplateRepository->find($this->eccubeConfig['my_order_mail_template_id']);
    
        $body = $this->twig->render($MailTemplate->getFileName(), [
            'Order' => $Order,
        ]);
    
        $message = (new Email())
            ->subject('['.$this->BaseInfo->getShopName().'] '.$MailTemplate->getMailSubject())
            ->from(new Address($this->BaseInfo->getEmail01(), $this->BaseInfo->getShopName()))
            ->to($this->convertRFCViolatingEmail($Order->getEmail()))
            ->bcc($this->BaseInfo->getEmail01())
            ->replyTo($this->BaseInfo->getEmail03())
            ->returnPath($this->BaseInfo->getEmail04());

    バージョンによってメールの送信部品が違います。EC-CUBE 4.2以降は Symfony Mailer(new Email())ですが、4.1以前は SwiftMailer(new \Swift_Message()でした。上のコードは4.3.0のものです。お使いの環境のファイルを開いて、どちらの書き方になっているか確かめてから直してください。

    差し替えるのは find() の引数だけなので、どちらのバージョンでも修正する箇所は同じ1行です。

    find() をはじめとするリポジトリのメソッドについては、別記事にまとめてあります。


    リポジトリでよく使われるメソッド解説記事のアイキャッチ

    あわせて読みたい
    リポジトリでよく使われるメソッド解説(find, findByなど)
    データベースから任意のデータを取り出すリポジトリのメソッドをまとめました。特に検索の自由度が高いものを中心に解説しています。

    方法B:app/Customize に置いてオーバーライドする(推奨)

    コアのファイルを触らずに、同じ結果を得る方法です。EC-CUBEをバージョンアップしても修正が消えません。修正するファイルは増えますが、長く運用するならこちらを選んでください。

    まず app/Customize/Service/MailService.php を新規作成し、以下のコードをアップロードします。コアの MailService を継承し、sendOrderMail() だけを上書きする形です。

    <?php
    
    /*
     * This file is part of EC-CUBE
     *
     * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
     *
     * http://www.ec-cube.co.jp/
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */
    
    namespace Customize\Service;
    
    use Doctrine\ORM\NonUniqueResultException;
    use Eccube\Common\EccubeConfig;
    use Eccube\Entity\BaseInfo;
    use Eccube\Entity\Customer;
    use Eccube\Entity\MailHistory;
    use Eccube\Entity\MailTemplate;
    use Eccube\Entity\Order;
    use Eccube\Entity\OrderItem;
    use Eccube\Entity\Shipping;
    use Eccube\Event\EccubeEvents;
    use Eccube\Event\EventArgs;
    use Eccube\Repository\BaseInfoRepository;
    use Eccube\Repository\MailHistoryRepository;
    use Eccube\Repository\MailTemplateRepository;
    use Symfony\Component\EventDispatcher\EventDispatcher;
    use Symfony\Component\EventDispatcher\EventDispatcherInterface;
    use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
    use Symfony\Component\Mailer\MailerInterface;
    use Symfony\Component\Mime\Address;
    use Symfony\Component\Mime\Email;
    use Twig\Error\LoaderError;
    use Twig\Error\RuntimeError;
    use Twig\Error\SyntaxError;
    use Eccube\Service\MailService as BaseMailService;
    
    class MailService extends BaseMailService
    {
        public function __construct(
            MailerInterface $mailer,
            MailTemplateRepository $mailTemplateRepository,
            MailHistoryRepository $mailHistoryRepository,
            BaseInfoRepository $baseInfoRepository,
            EventDispatcherInterface $eventDispatcher,
            \Twig\Environment $twig,
            EccubeConfig $eccubeConfig,
        ) {
            parent::__construct(
                $mailer,
                $mailTemplateRepository,
                $mailHistoryRepository,
                $baseInfoRepository,
                $eventDispatcher,
                $twig,
                $eccubeConfig
            );
        }
    
        /**
         * Send order mail.
         *
         * @param \Eccube\Entity\Order $Order 受注情報
         *
         * @return Email
         */
        public function sendOrderMail(Order $Order)
        {
            log_info('受注メール送信開始');
    
            // デフォルトのコード
            // $MailTemplate = $this->mailTemplateRepository->find($this->eccubeConfig['eccube_order_mail_template_id']);
    
            // 修正コード
            $MailTemplate = $this->mailTemplateRepository->find($this->eccubeConfig['my_order_mail_template_id']);
    
            $body = $this->twig->render($MailTemplate->getFileName(), [
                'Order' => $Order,
            ]);
    
            $message = (new Email())
                ->subject('['.$this->BaseInfo->getShopName().'] '.$MailTemplate->getMailSubject())
                ->from(new Address($this->BaseInfo->getEmail01(), $this->BaseInfo->getShopName()))
                ->to($this->convertRFCViolatingEmail($Order->getEmail()))
                ->bcc($this->BaseInfo->getEmail01())
                ->replyTo($this->BaseInfo->getEmail03())
                ->returnPath($this->BaseInfo->getEmail04());
    
            // HTMLテンプレートが存在する場合
            $htmlFileName = $this->getHtmlTemplate($MailTemplate->getFileName());
            if (!is_null($htmlFileName)) {
                $htmlBody = $this->twig->render($htmlFileName, [
                    'Order' => $Order,
                ]);
    
                $message
                    ->text($body)
                    ->html($htmlBody);
            } else {
                $message->text($body);
            }
    
            $event = new EventArgs(
                [
                    'message' => $message,
                    'Order' => $Order,
                    'MailTemplate' => $MailTemplate,
                    'BaseInfo' => $this->BaseInfo,
                ],
                null
            );
            $this->eventDispatcher->dispatch($event, EccubeEvents::MAIL_ORDER);
    
            try {
                $this->mailer->send($message);
            } catch (TransportExceptionInterface $e) {
                log_critical($e->getMessage());
            }
    
            $MailHistory = new MailHistory();
            $MailHistory->setMailSubject($message->getSubject())
                ->setMailBody($message->getTextBody())
                ->setOrder($Order)
                ->setSendDate(new \DateTime());
    
            // HTML用メールの設定
            $htmlBody = $message->getHtmlBody();
            if (!empty($htmlBody)) {
                $MailHistory->setMailHtmlBody($htmlBody);
            }
    
            $this->mailHistoryRepository->save($MailHistory);
    
            log_info('受注メール送信完了');
    
            return $message;
        }
    }

    次に、作成した Customize\Service\MailServiceEccube\Service\MailService の代わりに使わせます。app/config/eccube/services.yaml の最後に、以下を追記してください。

        Eccube\Service\MailService:
            class: Customize\Service\MailService
            arguments:
                - '@mailer.mailer'
                - '@Eccube\Repository\MailTemplateRepository'
                - '@Eccube\Repository\MailHistoryRepository'
                - '@Eccube\Repository\BaseInfoRepository'
                - '@event_dispatcher'
                - '@twig'
                - '@Eccube\Common\EccubeConfig'

    引数の並び順は、継承元のコンストラクタと同じにします。順番が違うと型が合わずエラーになります。上の並びはEC-CUBE 4.3.0のものです。

    これで、オリジナルのファイルに手を加えることなくカスタマイズできます。

  3. STEP3
    キャッシュを削除する

    最後に、管理画面の「コンテンツ管理」→「キャッシュ管理」からキャッシュを削除します。

    ここを飛ばすと、ファイルを正しく直しても反映されません。設定ファイルの内容はキャッシュされているためです。「直したはずなのに前のメールが届く」ときは、まずキャッシュを疑ってください。

    コマンドが使える環境なら、以下でも削除できます。

    bin/console cache:clear --no-warmup

    削除できたら、実際に商品を注文して、変更したテンプレートのメールが届くか確認しておきましょう。

まとめ

  • メール本文は管理画面で編集できるが、どのテンプレートを送るかはファイルの修正が必要
  • 設定ファイルは app/config/eccube/packages/eccube.yamlフォルダ名は複数形インデントは4スペース
  • 差し替えるのは sendOrderMail() にある find() の引数1行だけ
  • バージョンアップで消えないのは方法Bapp/Customize でオーバーライド)
  • メールの送信部品は4.2を境に SwiftMailer から Symfony Mailer へ変わっている。コードを写す前に自分の環境を確認する
  • 作業後はキャッシュの削除が必須


EC-CUBE 4カスタマイズのまとめ記事のアイキャッチ

あわせて読みたい
EC-CUBE 4 カスタマイズのまとめ
EC-CUBE 4について、筆者自身が学習・実践してきたカスタマイズ方法をまとめています。はじめて触る方向けに、手を動かす順番も並べました。

EC-CUBEのカスタマイズに関する記事

この記事に出てきた用語

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次