ドロップダウンリスト(プルダウン)とデータベースを連携する方法について紹介します。
いちいち手動でリストを作る必要がなく、データベースが更新されればリストの内容も自動更新されるようになります。
管理画面(商品登録)をカスタマイズし、メーカーIDをドロップダウンリストで選択→登録できるようにした状態。
「dtb_Maker」という新しいテーブルを新規作成し、そこに保存されているメーカー名をリストとして表示させています。
管理画面(商品登録)に新しい入力フォームを追加する方法や、データベースに新しいテーブルを追加する方法、商品テーブルに新規項目を追加する方法については以下記事で紹介しています。同じ環境で行う場合は、まず以下記事よりご覧ください。
デバッグモードを設定しておくと、エラーが起きたときに詳細情報が表示されるようになります。
エラー箇所を探しやすくなるので、開発前に設定しておくのをオススメします。
デバッグモードの設定方法については 以下記事 で解説しています。
カスタマイズ後は、デバッグモードの解除を忘れないように。
ドロップダウンリストを表示するフォームを作成する
まずはドロップダウンリストを表示するためのフォームを作成します。
詳細は こちらの記事 で解説していますが、追加したいフォームタイプに以下コードを記述します。
$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」を修正しています。
使いたいRepositoryをuseで読み込みます。
use Customize\Repository\MakerRepository;
本記事では、先程作成した「MakerRepository」を読み込みます。
ProductTypeExtensionクラス内で、読み込んだRepositoryを初期化します。
class ProductTypeExtension extends AbstractTypeExtension
{
/**
* @var MakerRepository
*/
protected $makerRepository;
/**
* @param MakerRepository $makerRepository
*/
public function __construct(MakerRepository $makerRepository)
{
$this->makerRepository = $makerRepository;
}
なお、ステップ1とステップ2については以下記事にて解説しています。
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のメソッドについては以下記事にて解説しています。
リストデータを格納した$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の基本的な機能が一通り理解できていないと難しいと思います。ぜひ他の記事を参考に、トライしてみてください!