【EC-CUBE 4】FormTypeを使ってフォームを生成する方法

エンティティのフォーム作成をもっと簡略化するには?

この記事では、「新たにエンティティのタイプクラスを作ってフォームを自動生成する」方法について紹介しています。

デフォルトではOrderTypeやContactTypeなどのFormTypeと呼ばれるファイルが用意されており、それぞれ注文や問い合わせのフォームを呼び出すときに使われています。一方、自身でオリジナルテーブルを作成した場合はそれに紐づくFormTypeはないため、本記事で簡単なFormTypeを作成します。

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

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

目次

FormTypeとは

一般に『エンティティ名 + Type.php』という名前で作成され、エンティティ自体をTextTypeやIntegerTypeのように1つのタイプとして定義したものです。タイプは以下のような形で構成されます。

class タイプ名 extends AbstractType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    // Formの生成コードを記述
  }

  public function configureOptions(OptionResolver $resolver)
  {
    // 必要な情報を設定
  }
}

ここで定義したタイプクラスをControllerで呼び出す(createFormメソッドを使用する)ことで、Controllerではフォーム生成のコードを省き、フォーム生成部分のコードを切り分けることができます。

タイプクラスを新規に作成する

本記事では、オリジナルテーブルとして『dtb_Maker』を使い、新しいレコードが追加できるようControllerとTwigを準備した状態からの手順となります。詳しくは以下記事をご覧ください。

MakerTypeの作成

「MakerType.php」という名前で以下ファイルを作成し、「app/Customize/Form/Type」に格納します。(フォルダがなければフォルダも作成します。)

<?php

namespace Customize\Form\Type;

use Customize\Entity\Maker;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\OptionsResolver\OptionsResolver;

class MakerType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array('label' => 'メーカー名'))
            ->add('code', TextType::class, array('label' => 'メーカーコード'))
            ->add('save', SubmitType::class, array('label' => 'Register'));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Maker::class,
        ));
    }
}

このタイプクラスでは、以下2つのメソッドが定義されています。

buildFormメソッド

引数で渡されたFormBuilderからaddを呼び出し、フォームの項目を生成します。こちらの記事で作成したControllerのフォーム生成部分をそっくり移行した形です。

configureOptionsメソッド

setDefaultsというメソッドを呼び出し、’data_class’という値にデータとして設定されるクラスをセットします。

タイプクラスをControllerで利用する

次はControllerでタイプクラスを呼び出すように修正し、フォーム生成はタイプクラス側で行います。

MakerRegisterControllerの修正

こちらの記事で用意したControllerを以下の通り修正します。

<?php

namespace Customize\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Eccube\Controller\AbstractController;
use Customize\Entity\Maker;

// MakerTypeを追加し、TestTypeとSubmitTypeは削除
use Customize\Form\Type\MakerType;

class MakerRegisterController extends AbstractController
{
  /**
   * @Route("/maker_register", name="maker_register")
   * @Template("maker_register.twig")
   */
  public function create(Request $request)
  {
    $maker = new Maker();

    // createFormBuilderの代わりにcreateFormを使用
    // 引数にはMakerTypeクラスとMakerインスタンスを引数に指定
    // add~getForm()までは削除
    $form = $this->createForm(MakerType::class, $maker);
    $form->handleRequest($request);

    if ($request->getMethod() == 'POST') {
      $maker = $form->getData();
      $manager = $this->getDoctrine()->getManager();
      $manager->persist($maker);
      $manager->flush();
      return [
        'message' => '登録完了しました!',
        'form' => $form->createView(),
      ];
    } else {
      return [
        'message' => 'メーカー情報を新規登録します。',
        'form' => $form->createView(),
      ];
    }
  }
}

コード中にも記載しましたが、修正箇所は以下の2箇所です。

use箇所
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

を削除し、

use Customize\Form\Type\MakerType;

を追加します。(フォーム生成はMakerTypeで行うため。)

フォーム生成箇所
$form = $this->createFormBuilder($maker)
      ->add('name', TextType::class, array('label' => 'メーカー名'))
      ->add('code', TextType::class, array('label' => 'メーカーコード'))
      ->add('save', SubmitType::class, array('label' => 'Register'))
      ->getForm();

を、

$form = $this->createForm(MakerType::class, $maker);

に書き換えます。

以上で準備完了です。
念の為キャッシュを削除してからページにアクセスし、問題なく機能するか確認しましょう。

まとめ

本記事では、新しくFormTypeを作成してみました。

タイプクラスを定義すると、createFormメソッドを使う一文のみでフォームが生成できるようになります。コードがスッキリして他にも使い回せるので、ぜひ積極的に使っていきたい機能ですね。

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