2

I have a form type, but would like to use the container within this form to detect the current user ID (FOSUserBundle). I'm not sure if it's best to inject the container into the form or the user class directly, but I can't get either to work. Below is my form type:

class AddValueType extends AbstractType
{
    private $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //build form, get user ID
    }
}

Services.yml:

parameters:
    AddValueType.class: Main\MyBundle\Form\Type\AddValueType

services:
    main.form.addValueType:
        class: "%AddValueType.class%"
        arguments: ['@service_container']

I'm getting the error Warning: Missing argument 1 for Main\MyBundle\Form\Type\AddValueType::__construct() so it's obviously not being passed to the form type correctly. I'm pretty new to dependency injection but can't work out where I'm going wrong? I've got others working in my application in the same way for services.

UPDATE

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add(
                $builder->create('aDate', 'hidden' ,array('empty_data' => new \DateTime() ))->addViewTransformer( new DateTimeToStringTransformer() )
            )
            ->add('field1', 'hidden')
            ->add('field2', 'hidden')
            ->add('submit', 'submit')
            ->getForm();

        $builder->addEventListener(FormEvents::PRE_BIND, function(FormEvent $event) {

            $data = $event->getData();
            $data['addedByUser'] = $userId;//this is what I need to fetch
            //some other simple logic to set data after form is sent
            $event->setData($data);
        });
    }

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

created in my controller with:

$form = $this->createForm(new AddValueType(), $myDoctrineEntity/Class);

5
  • Looks good to me. Have you tried cleaning your cache? Commented Dec 12, 2014 at 13:59
  • @Machiel yeah, php app/console cache:clear and deleted the files from app/cache manually too. I'm working in app_dev.php but have tried it for production too and still no luck Commented Dec 12, 2014 at 14:13
  • 1
    Ah, sorry, you should check this: symfony.com/doc/current/cookbook/form/… You have to define your service as a form. Commented Dec 12, 2014 at 14:18
  • You should not inject the container into your services. Why don't you inject @security.context service ? then you can get the current user (getToken()->getUser()) Commented Dec 12, 2014 at 17:25
  • @smarber Yeah I'll do that, but at the moment I can't get anything to inject...even with the above and Waaghals suggestions. Commented Dec 12, 2014 at 17:44

2 Answers 2

4

You need to tag the service as a form.

main.form.addValueType:
    class: "%AddValueType.class%"
    arguments: ['@service_container']
    tags:
        - { name: form.type, alias: valueType }

The name of the form needs valueType. You're now able to use the form by it's name instead of creating a new instance manually.

And indeed injecting the service container is bad practice.

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

7 Comments

Consider injecting the security.context service instead of the full container. That will give you access to the current user via the token.
I don't understand tagging too well but tried this before with no luck. I've tried again with cache clears but no luck. I'm using the value returned from the getName() function as the alias value.
@john Could you update your question with the way you create the form?
@john I actually ment from the controller. When tagging the service you can create you form like this $form = $this->createForm('valueType', $entity); instead of $this->createForm(new AddValueType (), $entity. I wanted to know was if you created your form as in my second example?
@john using new AddValuetype() initializes the object itself, it won't use the service container to get your form instance. By tagging your service, Symfony will pick it up as a form and will make it available under its alias. When you don't tag your service it won't be posible to create a form by its alias. So in your case your where missing two items, the tag and using the form by its alias when creating a form.
|
0

Don't declare your form as service, however create a new service and inject form.factory and your form into it like this:

service.xml

<service id="my_form_handler" class="namespace\FormHandler">
     <argument type="service" id="form.factory" />
     <argument id="yourFormClass">\namespace\of\your\form\class</argument>
</service>

Your form handler:

class FormHandler
{
    private $formFactory;
    private $formType;

    public function __construct($formFactory, $formType) {....}

    public function test()
    {
        $form = $this->formFactory->create(new $this->formType, $entity, $options);
        ....
    }

This worked for me

1 Comment

I'm not sure you will be able to create your form using the form factory like this. Because it isn't tagged it won't be picked up by Symfony.

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.