【EC-CUBE 4】マスターテーブルを新規に作成し、管理画面で操作する方法

この記事では、オリジナルのマスターテーブルをデータベースへ追加し、管理画面で登録できるようにする方法を紹介します。

データベース更新後のプルダウンリスト
独自マスターテーブル「mtb_maker_status」を追加、
マスタデータ管理で選択できるようにします。
データベース更新後のマスタデータ登録画面
「mtb_maker_status」を選択すると、IDとNameが登録できます。

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

開発前にデバッグモードの設定をお薦めします

デバッグモードを設定しておくと、エラーが起きたときに詳細情報が表示されるようになります。
エラー箇所を探しやすくなるので、開発前に設定しておくのをオススメします。
デバッグモードの設定方法については 以下記事 で解説しています。

カスタマイズ後は、デバッグモードの解除を忘れないように。

目次

マスターテーブルとは?

EC-CUBE では、システム上で使用される基本的な設定や情報を保持するマスターテーブルがあります。
以下のようなテーブルがデフォルトで用意されています。

  1. mtb_sale_type: 販売種別
  2. mtb_countory: 国名のリスト
  3. mtb_product_status: 商品ステータス(公開、非公開、廃止)
  4. mtb_order_status: 受注ステータス(新規受付、入金済、対応中、など)

管理画面の「設定」→「システム設定」→「マスタデータ管理」にて、マスターテーブルの一覧を確認・操作できます。
データベースでは、mtbから始まるテーブルがマスターテーブルにあたります。

マスターデータは、EC-CUBE の運用や設定を行う上で基盤となる情報です。
受注データや商品データと異なり、基本的に更新されることが少ないのが特徴です。

マスターテーブルを追加し、管理画面で操作できるようにする手順

  1. エンティティを作成し、「app/Customize/Entity/Master」にアップ
  2. リポジトリを作成し、「app/Customize/Repository/Master」にアップ
  3. サーバーにSSH接続し、コマンドでSQLを実行してマスターテーブルを作成
    • ここまででテーブルの追加は完了
  4. MasterdataTypeExtensionを作成し、「app/Customize/Form/Extension/Admin」にアップ
    • 追加したテーブルを、管理画面に表示して操作できるようにする

ステップ3までの流れは、通常のテーブル作成とほぼ同じです。(後述の通り、エンティティの中身が少し異なります。)
テーブル作成についてより詳しく知りたい方は、以下記事も合わせて参考にしてください。

以下、メーカーの取引状況を保存する「mtb_maker_status」というマスターテーブルを作成する手順です。

STEP

エンティティ(MakerStatus.php)の作成

以下コードを記したファイルを作成し、「app/Customize/Entity/Master」にアップします。

<?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\Entity\Master;

use Doctrine\ORM\Mapping as ORM;

/**
 * Option
 *
 * @ORM\Table(name="mtb_maker_status")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255)
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Entity(repositoryClass="Customize\Repository\Master\MakerStatusRepository")
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE")
 */
class MakerStatus extends \Eccube\Entity\Master\AbstractMasterEntity
{
}

通常のテーブルを作成する場合と異なり、MakerStatusクラスの中身が空になっています。

マスターテーブルのエンティティは、AbstractMasterEntityextendsで引き継ぐことにより、id / name / sort_idの3つのプロパティが自動でセットされます。従って、クラスの中でidなどを定義しなくてもOKです。

STEP

リポジトリ(MakerStatusRepository.php)の作成

続いて以下コードを記したRepositoryを作成し、「app/Customize/Repository/Master」にアップします。

なお、テーブルを作成するだけであれば本ステップ(Repository)は不要です。
が、将来的に特定のクエリや操作が必要になる可能性を考慮して、テーブル作成と合わせてRepositoryを作成しておきます。

<?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\Repository\Master;

use Doctrine\Persistence\ManagerRegistry as RegistryInterface;
use Customize\Entity\Master\MakerStatus;
use Eccube\Repository\AbstractRepository;

class MakerStatusRepository extends AbstractRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, MakerStatus::class);
    }
}
STEP

コマンドでSQLを実行し、テーブルを作成

サーバーにSSH接続し、以下コマンドを入力していきます。

bin/console cache:clear --no-warmup

※キャッシュをクリアするコマンドです。

実行すると、
[OK] Cache for the ・・・・・・・ was successfully cleared.
というような文言が表示される。

bin/console doctrine:schema:update --dump-sql --force

※データベースを更新するためのSQLコマンド

このコマンド実行後、問題がなければ以下のような新規テーブルが追加されています。

新しいマスターテーブル「mtb_maker_status」の構造
「dtb_maker_status」テーブルの構造

STEP 1で作成したエンティティのクラスは空でしたが、テーブルには id / name / sort_no のカラムが設定されていますね。

STEP

管理画面で操作できるよう、FormExtensionを作成

まだこの時点では、管理画面のマスタデータ管理で「mtb_maker_status」テーブルを選択・操作できません。

以下コードを記したFromExtensionを作成し、「app/Customize/Form/Extension/Admin」にアップします。

<?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\Admin;

use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\EntityManagerInterface;
use Eccube\Form\Type\Admin\MasterdataType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;

/**
 * Class MasterdataTypeExtension
 */
class MasterdataTypeExtension extends AbstractTypeExtension
{
    private $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $masterdata = [];

        /** @var MappingDriverChain $driverChain */
        $driverChain = $this->entityManager->getConfiguration()->getMetadataDriverImpl()->getDriver();
        /** @var MappingDriver[] $drivers */
        $drivers = $driverChain->getDrivers();
        
        foreach ($drivers as $namespace => $driver) {
            if ($namespace == 'Eccube\Entity' || $namespace == 'Customize\Entity') {
                $classNames = $driver->getAllClassNames();
                foreach ($classNames as $className) {
                    /** @var ClassMetadata $meta */
                    $meta = $this->entityManager->getMetadataFactory()->getMetadataFor($className);
                    if (strpos($meta->rootEntityName, 'Master') !== false
                        && $meta->hasField('id')
                        && $meta->hasField('name')
                        && $meta->hasField('sort_no')
                    ) {
                        $metadataName = str_replace('\\', '-', $meta->getName());
                        $masterdata[$metadataName] = $meta->getTableName();
                    }
                }
            }
        }

        $options = $builder->get('masterdata')->getOptions();
        $options['choices'] = array_flip($masterdata);

        $builder
            ->add('masterdata', ChoiceType::class, $options);
    }

    /**
     * {@inheritdoc}
     */
    public static function getExtendedTypes(): iterable
    {
        return [MasterdataType::class];
    }
}

EC-CUBEのバージョンにより、拡張するフォームの指定方法(77~80行目)が異なります。(上記はEC-CUBE 4.2.1で確認。)
上手くいかない場合は、公式サイト をご確認のうえ、コードを修正してください。

ポイントとなるのは50行目if ($namespace == 'Eccube\Entity' || $namespace == 'Customize\Entity')です。

元のフォームでは、if ($namespace == 'Eccube\Entity')となっており、Customize/Entityディレクトリに格納したエンティティ(mtb_maker_status)が参照されません。この拡張ファイルで、Customize/Entityディレクトリにあるエンティティも参照するよう修正しています。

STEP

キャッシュの削除

ここまでで準備完了です。
管理画面からキャッシュを削除して、マスタデータ管理を確認しましょう。

キャッシュの削除方法
管理画面のキャッシュ管理からキャッシュを削除できます。

「システム設計」の「マスタデータ管理」を開き、ドロップダウンリストの最後に追加したテーブルが表示されていればOKです。

データベース更新後のプルダウンリスト
リストの最後に「mtb_maker_status」が追加されています。
データベース更新後のマスタデータ登録画面
「mtb_maker_status」を選択すると、IDとNameの設定ができるようになっています。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次