前回はEntityRepositoryからContainerを参照できるようにしました。
今回はFormTypeからContainerを参照できるようにします。
環境
Symfony 2.3.17
実装する
Containerを参照可能なFormTypeクラスを作成
AbstractContainerAwareType.php
<?php
namespace Some\MyBundle\Component\Form;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Form\AbstractType;
abstract class AbstractContainerAwareType extends AbstractType implements ContainerAwareInterface
{
/**
* Container
* @var ContainerInterface
*/
protected $container;
/**
* {@inheritdoc}
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* Get Container
* @return ContainerInterface
*/
public function getContainer()
{
return $this->container;
}
}
AbstractContainerAwareTypeにContainerを設定するFormFactoryクラスを作成
MyFormFactory.php
<?php
namespace Some\MyBundle\Component\Form;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Form\FormFactory;
use Symfony\Component\Form\FormRegistryInterface;
use Symfony\Component\Form\ResolvedFormTypeFactoryInterface;
class MyFormFactory extends FormFactory
{
/**
* Container
* @var ContainerInterface
*/
private $container;
/**
* @param FormRegistryInterface $registry
* @param ResolvedFormTypeFactoryInterface $resolvedTypeFactory
* @param ContainerInterface $container
*/
public function __construct(FormRegistryInterface $registry, ResolvedFormTypeFactoryInterface $resolvedTypeFactory, ContainerInterface $container)
{
parent::__construct($registry, $resolvedTypeFactory);
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function createNamedBuilder($name, $type = 'form', $data = null, array $options = array())
{
if ($type instanceof AbstractContainerAwareType) {
$type->setContainer($this->container);
}
return parent::createNamedBuilder($name, $type, $data, $options);
}
}
サービスに登録
services.yml
services:
form.factory: # FrameworkBundleで定義されているものを再定義
class: Some\MyBundle\Component\Form\MyFormFactory
arguments: [ @form.registry, @form.resolved_type_factory, @service_container ]
使用する
AbstractContainerAwareTypeを継承したクラス内で$this->getContainer()
するとContainerを参照できます。
SomeType.php
<?php
namespace Some\MyBundle\Form\Type;
use Some\MyBundle\Component\Form\AbstractContainerAwareType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class SomeType extends AbstractContainerAwareType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$container = $this->getContainer();
$builder
->add('someColumn', 'choice', [
'choices' => $container->getParameter('some.parameter'),
])
;
$logger = $container->get('logger');
$logger->debug('FormTypeからログ出力!');
}
/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver
->setDefaults([
'data_class' => 'Some\MyBundle\Entity\SomeTable',
])
;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'some';
}
}