【EC-CUBE 4】ドロップダウンリストの選択肢をデータベースから取得する方法

【トップ画像】EC-CUBE 4でドロップダウンリストの選択肢をデータベースから取得する方法

ドロップダウンリスト(プルダウン)とデータベースを連携する方法について紹介します。
いちいち手動でリストを作る必要がなく、データベースが更新されればリストの内容も自動更新されるようになります。

管理画面(商品登録)をカスタマイズし、メーカーIDをドロップダウンリストで選択→登録できるようにした状態。

「dtb_Maker」という新しいテーブルを新規作成し、そこに保存されているメーカー名をリストとして表示させています。

カスタマイズ後の管理画面(商品登録)

管理画面(商品登録)に新しい入力フォームを追加する方法や、データベースに新しいテーブルを追加する方法、商品テーブルに新規項目を追加する方法については以下記事で紹介しています。同じ環境で行う場合は、まず以下記事よりご覧ください。

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

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

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

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

目次

ドロップダウンリストを表示するフォームを作成する

まずはドロップダウンリストを表示するためのフォームを作成します。
詳細は こちらの記事 で解説していますが、追加したいフォームタイプに以下コードを記述します。

$builder
  ->add('maker_id', ChoiceType::class, [
    'choices' =>
    [
      'SampleCorp' => 1,
      'Noveblo Ltd.' => 2,
      'TEST Company' => 3,
    ],
    'required' => false,
    'placeholder' => '選択してください'
  ]);

本記事の例では、こちらの記事で作成した「ProductTypeExtension.php」のaddメソッドを上記コードに修正しています。
なお、ChoiceTypeを使うにはuseでChoiceTypeクラスを読み込んでおく必要があるので、以下コードも忘れないようにしましょう。

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

これで、ドロップダウンリスト自体は実装できたかと思います。

ただこのコードを見てわかるとおり、リストの内容は直接addメソッド内に記述されています。
次は、このリストをデータベースから取得できるようにします。

リストの内容をデータベースから取得する

まずデータベースからデータを取得するには、Repositoryという機能を使います。

本記事の「dtb_Maker」のような新規に作成したテーブルにはRepositoryがないので、まずはRepositoryを作成する必要があります。(すでに作成済の場合、以下はスキップしてください。)

Repositoryの新規作成

以下コードを記述した「MakerRepository.php」を作成し、「app/Customize/Repository」下に保存します。

<?php

namespace Customize\Repository;

use Customize\Entity\Maker;
use Eccube\Repository\AbstractRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

/**
 * MakerRepository
 */
class MakerRepository extends AbstractRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Maker::class);
    }

}

Repositoryの作成と活用法については、以下記事も参考にしてみてください。

フォームタイプでRepositoryを使い、リストデータを取得する

Repositoryを用意できたら、フォームタイプを以下の通り修正していきます。
本記事では「ProductTypeExtension.php」を修正しています。

STEP
useでRepositoryを読み込む

使いたいRepositoryをuseで読み込みます。

use Customize\Repository\MakerRepository;

本記事では、先程作成した「MakerRepository」を読み込みます。

STEP
Repositoryの初期化設定

ProductTypeExtensionクラス内で、読み込んだRepositoryを初期化します。

class ProductTypeExtension extends AbstractTypeExtension
{
  /**
   * @var MakerRepository
   */
  protected $makerRepository;
  
  /**
   * @param MakerRepository $makerRepository
   */
  public function __construct(MakerRepository $makerRepository)
  {
      $this->makerRepository = $makerRepository;
  }

なお、ステップ1とステップ2については以下記事にて解説しています。

STEP
Repositoryを使ってリストデータを取得する

RepositoryのfindAllメソッドを使って「dtb_Maker」の全レコードを取得し、配列$choicesに「メーカー名 => ID」となるようデータを格納します。

$makers = $this->makerRepository->findAll();
$choices = [];
foreach ($makers as $maker) {
    $name = $maker->getName();
    $id = $maker->getId();
    $choices[$name] = $id; 
}

なお、findAllなどRepositoryのメソッドについては以下記事にて解説しています。

STEP
取得したリストデータをaddメソッドにセットする

リストデータを格納した$choicesをaddメソッドの’choices’にセットし、完成です。

$builder
  ->add('maker_id', ChoiceType::class, [
    'choices'  => $choices,
    'required' => false,
    'placeholder' => '選択してください'
  ]);

以上でカスタマイズは終了です。

上述のとおりフォームタイプの修正点が多く、コードの記述ミスや記述場所を間違いやすいです。
以下に「ProductTypeExtension.php」の全コードを載せておくので、参考にしてください。

ProductTypeExtension.php(修正後)
<?php

namespace Customize\Form\Extension\Admin;

use Eccube\Form\Type\Admin\ProductType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Customize\Repository\MakerRepository;

class ProductTypeExtension extends AbstractTypeExtension
{
  /**
   * @var MakerRepository
   */
  protected $makerRepository;

  /**
   * @param MakerRepository $makerRepository
   */
  public function __construct(MakerRepository $makerRepository) {
      $this->makerRepository = $makerRepository;
  }

  public static function getExtendedTypes(): iterable
  {
      return [ProductType::class];
  }

  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $makers = $this->makerRepository->findAll();
    $choices = [];
    foreach ($makers as $maker) {
        $name = $maker->getName();
        $id = $maker->getId();
        $choices[$name] = $id; 
    }

    $builder
      ->add('maker_id', ChoiceType::class, [
      'choices'  => $choices,
      'required' => false,
      'placeholder' => '選択してください'
      ]);
  }
}

まとめ

以上、ドロップダウンリスト(プルダウン)の選択肢をデータベースから取得する方法について紹介しました。

本記事で取り上げた実装例は、データベース拡張やRepository、FormTypeなど、Symfonyの基本的な機能が一通り理解できていないと難しいと思います。ぜひ他の記事を参考に、トライしてみてください!

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