Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

サービスに登録したカスタムFormTypeを使う

via. カスタムフォームフィールドタイプの作成方法 | Symfony2日本語ドキュメント

やってみたメモ。基本的な流れは以下のとおり。

手順1:Symfony\Component\Form\AbstractTypeのサブクラスを作成する

コード全体は以下のとおり。AbstractTypeクラスはSymfony\Component\Form\FormTypeInterfaceをgetNameメソッドを除いて実装しているため、ここでgetNameメソッドを実装する必要がある。

<?php

namespace Acme\FormTypeBundle\Form\Type;

use Symfony\Component\Form\AbstractType;

/**
 * 性別FormType
 *
 * services.ymlで以下のように定義
 *
 * services:
 *     form.type.gender:
 *         class: Acme\FormTypeBundle\Form\Type\GenderType
 *         arguments:
 *             - "%genders%"
 *         tags:
 *             - { name: form.type, alias: gender }
 *
 * @version $Id$
 */
class GenderType extends AbstractType
{
    private $genderChoices;

    public function __construct(array $genderChoices)
    {
        $this->genderChoices = $genderChoices;
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'choices' => $this->genderChoices
        );
    }

    public function getName()
    {
        return 'acme_formtypebundle_gendertype';
    }

    /**
     * フォームでの表示形式を指定
     */
    public function getParent(array $options)
    {
        return 'choice';
    }
}

手順2:Bundle/Resources/config/services.xml(もしくはservices.yml)に作成したFormTypeをサービスとして登録する

カスタムフォームフィールドタイプの作成方法 | Symfony2日本語ドキュメントではGenderTypeのコンストラクタに渡す引数をapp/config/config.ymlに定義しているが、Bundle下のservices.(yml|xml)にも定義できる。以下、Bundle/Resources/config/services.xmlに定義した例。

<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

  <parameters>
    <parameter key="genders" type="collection">
      <parameter key="m">男性</parameter>
      <parameter key="f">女性</parameter>
    </parameter>
  </parameters>

  <services>
    <service id="acme_formtype.type.gender" class="Acme\FormTypeBundle\Form\Type\GenderType">
      <argument>%genders%</argument>
      <tag name="form.type" alias="gender" />
    </service>
  </services>

</container>

手順3:FormTypeで呼び出す

FormBuilderクラスのaddメソッドの第2引数に登録した際のtag.aliasを指定する。ちなみに、getParentメソッドをオーバーライドしない場合の戻り値は"form"になっている。

<?php

namespace Acme\FormTypeBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Acme\FormTypeBundle\Entity\MPrefRepository;

/**
 * formtype登録用Formクラス
 *
 * @version $Id$
 */
class FormtypeType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            /**
             * サービスに登録したFormType"gender"を利用する
             */
            ->add('gender', 'gender',
                array(
                    'label' => '性別',
                    'required' => true,
                ))
        ;
    }

    public function getName()
    {
        return 'acme_formtypebundle_formtypetype';
    }
}

これで

のように表示される。