商品の注文時や会員登録時に自動送信されるメール。本文の文言だけなら管理画面から編集できますが、あらかじめ用意した別のテンプレートへ丸ごと差し替えるには、サーバー上のファイルを触る必要があります。この記事では、注文時に送られるメールを新しいテンプレートに切り替える手順を紹介します。
やることは2つです。①設定ファイルに「テンプレート名とテンプレートID」の対応を書き足す、②メール送信処理が参照するテンプレートIDを、その名前に差し替える。
②はコアのファイルを直接編集する方法と、app/Customize に置いてオーバーライドする方法があります。EC-CUBEのバージョンアップでコアは上書きされるため、後者をおすすめします。
作業後はキャッシュの削除が必須です。削除しないと、ファイルを正しく直しても古い設定のまま送信され続けます。
【動作環境】EC-CUBEのバージョン:4.3.0 / サーバー:Xserver
開発前にデバッグモードの設定をおすすめします。エラーが起きたときに詳細情報が表示されるようになり、原因の箇所を探しやすくなります。カスタマイズ後は解除を忘れずに。
設定と解除の手順は、こちらの記事にまとめています。
管理画面でできること、できないこと
先に切り分けておくと迷いません。メールまわりの設定は、管理画面で完結するものとファイルを触らないと変えられないものに分かれます。
| やりたいこと | 管理画面 | 必要な作業 |
|---|---|---|
| メール本文の文言を直す | できる | 「設定」→「メール設定」から編集 |
| テンプレートを新しく増やす | できる | 管理画面から追加(別記事で解説) |
| どのテンプレートを送るか変える | できない | 設定ファイルとメール送信処理の修正(本記事) |
つまり本記事は、3行目だけを扱います。テンプレートそのものの増やし方は別記事にまとめてあるので、まだ用意していない方はそちらを先にどうぞ。
実装後の状態
あらかじめ『注文受付メール2』というテンプレートを1つ追加しておきます。冒頭に「※これは新しく用意したテンプレートです。」という一文を入れて、切り替わったことが分かるようにしておきました。
新規追加したメールテンプレート
この状態で商品を注文すると、デフォルトの『注文受付メール』ではなく、追加した『注文受付メール2』が送信されるようにします。
自動送信された新規テンプレートのメール
追加した一文が表示されており、送信されるメールが差し替わったことが確認できます。
同じやり方で『出荷通知メール』や『問合受付メール』を注文時に送ることもできます。ただし注文時に送る内容ではないので、実用的ではありません。
実装の手順
-
STEP1設定ファイルにテンプレートIDを追加する
まず、追加したテンプレートにプログラムから呼ぶための名前を与えます。編集するのは次のファイルです。
app/config/eccube/packages/eccube.yamlフォルダ名は
packages(複数形)です。packageというフォルダは存在しないので、見つからないときはここを疑ってください。
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』にあたります。
-
STEP2メール送信処理が見るテンプレートを差し替える
注文時のメール送信は
MailServiceのsendOrderMail()で行われています。このメソッドが読むテンプレートIDを、STEP1で決めた名前に差し替えます。やり方は2通りあります。結果は同じですが、保守性が大きく違います。
方法A:コアを直接編集 方法B:Customizeでオーバーライド 手間 1ファイルの1行だけ 2ファイルを新規作成・追記 バージョンアップ 上書きされて消える 影響を受けない おすすめ 動作確認・お試し向け こちら 方法A:コアの MailService.php を直接編集する
「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()をはじめとするリポジトリのメソッドについては、別記事にまとめてあります。方法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\MailServiceをEccube\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のものです。
これで、オリジナルのファイルに手を加えることなくカスタマイズできます。
-
STEP3キャッシュを削除する
最後に、管理画面の「コンテンツ管理」→「キャッシュ管理」からキャッシュを削除します。
ここを飛ばすと、ファイルを正しく直しても反映されません。設定ファイルの内容はキャッシュされているためです。「直したはずなのに前のメールが届く」ときは、まずキャッシュを疑ってください。
コマンドが使える環境なら、以下でも削除できます。
bin/console cache:clear --no-warmup削除できたら、実際に商品を注文して、変更したテンプレートのメールが届くか確認しておきましょう。
まとめ
- メール本文は管理画面で編集できるが、どのテンプレートを送るかはファイルの修正が必要
- 設定ファイルは
app/config/eccube/packages/eccube.yaml。フォルダ名は複数形、インデントは4スペース - 差し替えるのは
sendOrderMail()にあるfind()の引数1行だけ - バージョンアップで消えないのは方法B(
app/Customizeでオーバーライド) - メールの送信部品は4.2を境に SwiftMailer から Symfony Mailer へ変わっている。コードを写す前に自分の環境を確認する
- 作業後はキャッシュの削除が必須

あわせて読みたい
EC-CUBE 4 カスタマイズのまとめ
EC-CUBE 4について、筆者自身が学習・実践してきたカスタマイズ方法をまとめています。はじめて触る方向けに、手を動かす順番も並べました。
EC-CUBEのカスタマイズに関する記事
- カスタマイズのまとめ
- メールテンプレートを増やす方法
- 独自の定数(パラメータ)を設定・管理する方法
- リポジトリでよく使われるメソッド解説(find, findByなど)
- デバッグモードの設定/解除方法
- 遭遇したエラー&対処法まとめ


