EC-CUBE4.0.5　受注登録のメールテンプレートを追加・選択するカスタマイズ



受注管理 > 受注登録　> メールを作成で選択できるメールテンプレートを追加するカスタマイズと、
テンプレートを全て表示していると選択した時にエラーになるテンプレートがあるため、
一部テンプレートのみ選べるように修正したのでメモ書き。

追記:カスタマイズ側での実装方法に修正。4.0.5で動作確認・リリース済み

##1.DBにテンプレートを追加する
`dtb_mail_template`にテンプレート情報を追加する
必要な項目のみ記載。

| 項目    | 内容          |
|:--------------------|:------------------|
| name             　 | テンプレート名　　　　 |
| file_name        　 | 参照するtwigファイル|
| mail_subject     　 | メールの件名　 |
| discriminator_type  | mailtemplate |


設定例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211259/4cfb0011-90b0-4a4e-efce-aefdbf917727.png)


##2.Twigファイルをアップロード
先にかいたtwigファイルを
`app/template/default/Mail/`以下に作成する。


####（例1）新たにメールテンプレートを追加する時。

`app/template/default/Mail/＊＊＊＊.twig`

のように配置する。内容は
```src/Eccube/Resource/template/default/Mail/```
ディレクトリ内の各ファイルを参照すると作りやすい。

#### (例2)既存の注文受付を編集する場合
`src/Eccube/Resource/template/default/Mail/contact_mail.twig`
をコピーし、
`app/template/default/Mail/contact_mail.twig`のように配置する。

##3.任意のテンプレートだけ選べるようにする。

###3-1定数定義用ファイル追加
`template_file_name`というメールテンプレートを追加できるようにしたい場合、
`app/config/eccube/packages/customize.yaml`のような定数定義用のファイル（[^1]）を追加し、

[^1]: 名前は任意、アップデート時に破棄される可能性有。[[ECCUBE4] 本体カスタマイズ時の設定ファイル](https://ruco.la/memo/352)

1でDBに追加したメールテンプレートを以下のように定数定義する。

```app/config/eccube/packages/customize.yaml

    eccube_template_file_name_mail_template_id: 9

```

###3-2 カスタマイズ用Extensionを追加して調整。
元ファイルである`src/Eccube/Form/Type/Admin/OrderMailType.php`をコピーして
`app/Customize/Form/Extension/`以下に`OrderMailTypeExtension.php`を追加する。

もともと選択できる注文受付メールに加えて、他にも追加できるように、
```$templateIds```を定義し、先ほどの定数値を入れ、使えるようにした。

```src/Eccube/Form/Type/Admin/OrderMailType.php
 <?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\Form\Extension;

use Doctrine\ORM\EntityRepository;
use Eccube\Common\EccubeConfig;
use Eccube\Form\Type\Admin\OrderMailType;
use Eccube\Form\Type\Master\MailTemplateType;
use Eccube\Form\Validator\TwigLint;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints as Assert;

class OrderMailTypeExtension extends AbstractTypeExtension
{
    /**
     * @var EccubeConfig
     */
    protected $eccubeConfig;

    /**
     * MailType constructor.
     *
     * @param EccubeConfig $eccubeConfig
     */
    public function __construct(
        EccubeConfig $eccubeConfig
    ) {
        $this->eccubeConfig = $eccubeConfig;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // NOTE:表示させたいテンプレートのID郡を定義。
        $templateIds = [
            $this->eccubeConfig['eccube_order_mail_template_id'],
            $this->eccubeConfig['eccube_template_file_name_mail_template_id'],
        ];

        $builder
            ->add('template', MailTemplateType::class, [
                'required' => false,
                'mapped' => false,
                'query_builder' => function (EntityRepository $er) use ($templateIds) {
                    return $er->createQueryBuilder('mt')
                        ->andWhere('mt.id IN (:id)')
                        ->setParameter(':id', $templateIds, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
                        ->orderBy('mt.id', 'ASC');
                },
            ])
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function getExtendedType()
    {
        return OrderMailType::class;
    }

}
```

 * 最初、適当に```$templateIds```を使おうとしていたらエラーになったので、
よくよくみたら無名関数だったので```use ($templateIds) ```を追記した。

 * クエリビルダ部分について

`use Doctrine\ORM\EntityRepository`を追記して、
```addWhere```で```id```で```IN```することを指定し、
実際のパラメーターを```setParameter```で指定している。
この時第３引数の```\Doctrine\DBAL\Connection::PARAM_INT_ARRAY ```は必須。
[参考 【DBAL queryBuilder】コピペで使えるｶﾓ？チートシート IN句](https://qiita.com/fukumoto/items/caad9b1c0c17e796b4f4#in%E5%8F%A5)

```
return $er->createQueryBuilder('mt')
          ->andWhere('mt.id IN (:id)')
          ->setParameter(':id', $templateIds, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY 
```

#### (追記)formTypeのカスタマイズについて

 * 各所をカスタマイズ側に修正する。
   * `namespace Customize\Form\Extension;`
   * `class OrderMailTypeExtension extends AbstractTypeExtension`
   
 * 修正元のformtypeを`use`して、`getExtendedType()`関数を実装
    
    ```app/Customize/Form/Extension/OrderMailTypeExtension.php
     use Eccube\Form\Type\Admin\OrderMailType;

    // 中略
  /**
     * {@inheritdoc}
     */
    public function getExtendedType()
    {
        return OrderMailType::class;
    }
    ```

    * Doctrineが使えるように以下を追記する。
    
    ```
    use Doctrine\ORM\EntityRepository;
    ```


ここまで設定すれば追加したメールテンプレートをセレクトボックスから使用できます。
 
## 参考
[受注完了メールの種類について](https://xoops.ec-cube.net/modules/newbb/viewtopic.php?viewmode=flat&topic_id=21480&forum=2)
[[EC-CUBE4.0.3]メールテンプレートを追加する方法](https://sachips.byeto.jp/eccube/add-main-template.html)
[【DBAL queryBuilder】コピペで使えるｶﾓ？チートシート](https://qiita.com/fukumoto/items/caad9b1c0c17e796b4f4)

[EC-CUBE 4.0に触れてみて]
(https://lab-inc.jp/staffblog/cms/201912/11_739.html)
[[ECCUBE4] 本体カスタマイズ時の設定ファイル]
(https://ruco.la/memo/352)

----