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.

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

3 Comments

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?
I accepted your answer, but I'd still appreciate any extra input on my comment. Thanks!
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 symfony.com/doc/current/book/service_container.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.