1

I have set up an Event Subscriber in a Symfony 2.0 project that is used by a Form Type to determine whether or not to include a field, such as is discussed here.

In order to determine whether to include, however, I would like to compare an Entity value with a route parameter.

I am aware of passing variables through types as discussed here, but I would prefer to access directly from the subscriber.

My Form Type:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Odst\Bundle\DyfieldBundle\Form\EventListener\DyfieldFilterSubscriber;

class DyStringFieldType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $subscriber = new DyfieldFilterSubscriber($builder->getFormFactory());
        $builder->addEventSubscriber($subscriber);
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'Odst\Bundle\DyfieldBundle\Entity\DyStringField',
        );
    }

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

My Event Subscriber:

use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
use Odst\Bundle\DyfieldBundle\Form\Type\DyStringFieldType;

class DyfieldFilterSubscriber implements EventSubscriberInterface
{
    private $factory;

    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        return array(FormEvents::PRE_SET_DATA => 'preSetData');
    }

    public function preSetData(DataEvent $event)
    {
        $data = $event->getData();
        $form = $event->getForm();

        if (null === $data) {
            return;
        }

        $fieldPageNameId = $data->getModel()->getDyFieldSet()->getDyFieldPage()->getNameId();
        // This doesn't work, but this is where I need to get the parameter
        $pageNameId = $this->get('request')->get('pageNameId');

        if ($pageNameId == $fieldPageNameId) {
            $form->add($this->factory->createNamed('text', 'value'));
        }
    }
}

Thanks very much for your help.

Community
  • 1
  • 1
amatretheus
  • 13
  • 1
  • 3

1 Answers1

3

You can make your DyfieldFilterSubscriber a service and inject the Request in constructor or setter.

Edit:

The Form Type

public function __construct(DyfieldFilterSubscriber $event)
{
$this->event = $event;
}

The Dy field filter subscriber

public function __construct(Request $request)
{
    $this->request = $request;
}

public function setFormFactory(FormFactoryInterface $formFactory)
{
    $this->formFactory = $formFactory;
}

Services:

services:
    your_form_type:
    class:     FQCN\To\Your\FormType
    arguments: [@dy_field_filer_subscriber]

    dy_field_filer_subscriber:
        class:     FQCN\To\Your\Class
        arguments: [@request]

Best regard

Benjamin Lazarecki
  • 2,950
  • 1
  • 20
  • 27
  • I appreciate the help; I guess my problem then is that I am new to setting up services. I am trying to register the subscriber as-is but don't know what to do about the constructor now, which requires a FormFactoryInterface implementing object. Also, when the subscriber's a service, will I need to change my DyStringFieldType code to access it differently? – amatretheus Feb 22 '13 at 00:06
  • I accepted your answer, but I'd still appreciate any extra input on my comment. Thanks! – amatretheus Apr 04 '13 at 15:02
  • Create the constructor with the `Request` in param. Define the service in app/config/config.yml or XBundle/Resources/config/my_service.xml and Inject this service in the FormType Contructor. (You also can define your formType as a service). Here the doc http://symfony.com/doc/current/book/service_container.html – Benjamin Lazarecki Apr 11 '13 at 08:18