データベースからデータを取得するカスタムFormTypeをサービスに登録して使う
前のエントリの続き。
カスタムFormTypeのコンストラクタ引数にDoctrine\ORM\EntityManagerオブジェクトを渡せばOK。
以下、都道府県を選択するカスタムFormTypeを作る場合の例。
手順1:Symfony\Component\Form\AbstractTypeのサブクラスを作成する
引数がDoctrine\Common\Persistence\ObjectManagerインターフェースとなっているが、EntityManagerクラスはObjectManagerインターフェースを実装している。
MPrefは都道府県一覧を格納したテーブル(m_pref)に対するEntityクラス。
<?php namespace Acme\FormTypeBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; use Doctrine\Common\Persistence\ObjectManager; use Acme\FormTypeBundle\Form\DataTransformer\PrefToIdTransformer; /** * 都道府県FormType */ class PrefType extends AbstractType { private $om; public function __construct(ObjectManager $om) { $this->om = $om; } public function getDefaultOptions(array $options) { $prefs = $this->om->getRepository('AcmeFormTypeBundle:MPref') ->createQueryBuilder('a') ->where("a.deleteFlag = '0' ") ->orderBy("a.id ") ->getQuery()->execute(); $choices = array(); foreach ($prefs as $pref) { $choices[$pref->getId()] = $pref->getPrefName(); } return array( 'choices' => $choices, 'label' => '都道府県', 'empty_value' => '選択してください', 'property' => 'prefName', 'multiple' => false, 'expanded' => false, ); } public function getName() { return 'acme_formtypebundle_preftype'; } public function getParent(array $options) { return 'choice'; } }
手順2:Bundle/Resources/config/services.xml(もしくはservices.yml)
services.service.argument.typeにdoctrine.orm.entity_managerを指定すると、適切なEntityManagerオブジェクトが渡されるようになる。
<?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"> <services> <service id="acme_formtype.type.pref" class="Acme\FormTypeBundle\Form\Type\PrefType"> <argument type="service" id="doctrine.orm.entity_manager"/> <tag name="form.type" alias="pref" /> </service> </services> </container>
手順3:FormTypeで呼び出す
前のエントリと同様。
<?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"pref"を利用する */ ->add('prefecture', 'pref', array( 'required' => false, )) ; } public function getName() { return 'acme_formtypebundle_formtypetype'; } }
こんな感じでいろいろなカスタムFormTypeを作ってサービスに登録し、フォームを表示する際に必要なサービスを組み合わせていく、という使い方が良いんじゃないだろうか?と思った。
一応、ソースをgithubに入れといた。