Pass custom options to a symfony2 form - forms

in symfony 1.4 it was possible to parameterize a form class definition, via the options of the form. Is there any way to pass custom options to my custom form type??? i've tried to use the options parameter of the buildForm method, but i'm not very sure what this array is, and apparently it is not for what i want... Thanks!

The solution is simple, if you want your custom option to be available also in Twig template, you must use
$builder->setAttribute() in buildForm method
and
$view->set() method in buildView() method, too.
<?php
namespace Acme\DemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType as FormAbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
// For Symfony 2.1 and higher:
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
/**
* ImagePreviewType
*
*/
class ImagePreviewType extends FormAbstractType
{
/**
* {#inheritDoc}
* For Symfony 2.0
*/
//public function getDefaultOptions(array $options)
//{
// $options = parent::getDefaultOptions($options);
// $options['base_path'] = 'path/to/default/dir/';
//
// return $options;
//}
/**
* {#inheritDoc}
* For Symfony 2.1 and higher
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'base_path' => '',
));
}
/**
* {#inheritDoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
// For Symfony 2.0:
// $view->set('base_path', $form->getAttribute('base_path'));
// For Symfony 2.1 and higher:
$view->vars['base_path'] = $options['base_path'];
}
/**
* {#inheritDoc}
*/
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->setAttribute('base_path', $options['base_path'])
;
}
/**
* {#inheritDoc}
*/
public function getName()
{
return 'image_preview';
}
public function getParent(array $options)
{
// for Symfony 2.0:
// return 'field';
// for Symfony 2.1 and higher:
return 'form';
}
}
Template for custom form type (file ...Acme/DemoBundle/Resources/views/Form/fields.html.twig):
{% block image_preview_widget %}
{% spaceless %}
<img src="{{ base_path ~ value }}" alt="" {{ block('widget_container_attributes') }} />
{% endspaceless %}
{% endblock %}
Register your template for custom form types in app/config/config.yml
twig:
debug: %kernel.debug%
strict_variables: %kernel.debug%
form:
resources:
- 'AcmeDemoAdminBundle:Form:fields.html.twig'
Usage: Display preview of user's image while editing his profile:
// src/Acme/DemoBundle/Form/Type/UserType.php
namespace Acme\DemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class UserType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('user_profile_image_file_name', new ImagePreviewType(), array(
'base_path' => 'some/other/dir',
));
}
}
2014-08-18: Updated for Symfony 2.1 or higher

UPDATE: Please note that this solution only works in Symfony 2.0.x, which is obsolete, use setDefaultOptions instead of getDefaultOptions.
Justly, Symfony 2 form types accept options that you can use for anything you want inside the form type. You need to override getDefaultOptions method to specify your type options.
For example, I have a type MyCustomType that accept my_option, this option has a default value of false, the implementation of MyCustomType can be something like this.
class MyCustomType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
if($options['my_option']){
//do something
} else {
//do another thing
}
...
}
public function getDefaultOptions(array $options)
{
return array(
'my_option' => false
);
}
public function getName()
{
return 'mycustomtype';
}
}
Later, you will need to specify the option when you create the form in the controller, using the third parameter of buildForm:
$form = $this->buildForm(new MyCustomType(), null, array(
'my_option' => true
));
If you not specify the my_option option, it takes the default value (false).

Using symfony 2.8, I succeeded by using the proposed solution extending the configureOptions() method.
class ElementType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'my_custom_option_parameter' => null,
));
}
}
I needed to use the ElementType, as a collection and embedded form. I recognized that it was not possible to pass the my_custom_option_parameter to the CollectionType, because I did not customize configureOptions() of CollectionType, but of my ElementType. If you need to pass the my_custom_option_parameter through a CollectionType, you may succeed by defining my_custom_option_parameter in entry_options (see Documentation CollectionType Field) array of CollectionType.
Example passing my_custom_option_parameter through a CollectionType:
class OuterFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
$builder->add('elements', CollectionType::class, array(
'entry_type' => ElementType::class,
// ...
'entry_options' => array(
'my_custom_option_parameter' => 'value is now set!'
)
));
//...
}
}

basing on #pulzarraider answer I created code with changes for Symfony 3.
You need to change
OptionsResolverInterface for OptionsResolver
FormBuilder for FormBuilderInterface
In my case:
namespace MediaBundle\Form;
use Symfony\Component\Form\AbstractType as FormAbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
class ImageType extends FormAbstractType {
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'max_images' => ''
));
}
public function buildView(FormView $view, FormInterface $form, array $options) {
$view->vars['max_images'] = $options['max_images'];
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->setAttribute('max_images', $options['max_images'])
;
}
public function getName() {
return 'image_preview';
}
public function getParent() {
return TextareaType::class;
}
}

Using Symfony 3, I was able to pass custom options to the form by setting a default option in the OptionsResolver injected into configureOptions method of my form type class:
In the Controller:
//Compile whatever your options are here. Assume an array is returned
$customOptions = $this->getMyCustomOptions($args);
//Build the form:
$form = $this->createForm(MyCustomFormType::class, array('my_custom_options' => $customOptions));
MyCustomFormType.php:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => DataModel::class,
'my_custom_options' => []
]);
}
//custom options is now set in "$options" array:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('my_custom_fields', Type\ChoiceType::class, [
'choices' => $options['my_custom_options'],
'mapped' => false //if not part of the data model.
. . .
So, it looks like you can define a contract with your form and the data provider to set arbitrary data on the form.
I've just successfully implemented this procedure. Note that on the return trip, since you've set 'mapped' => false, in the formBuilder, $form->getData() will not return the selection. To get the selected value:
$mySelectedValue = $form->get('my_custom_options')->getViewData();
in your controller. Why this is is beyond me . . .

I have tried using that options array with no success as it seemed that it could carry only small, predefined subset of keys. This was, by all means, unacceptable for me...
However, you can pass all the options via forms __construct method and store it in class properties for later use. Then, from buildForm you can access it using $this->"propertyName"...
It's up to you to decide whether you want to pass single array or just few variables to __construct...
This is just a rough example:
class Foobar{
private $update = false;
public function __construct($update = false){
$this->update = $update;
}
public function buildForm(FormBuilder builder, array options){
if ( $update ){
// something
}else{
// well, this is not an update - do something else
}
}
}

Related

Form builder for Symfony login page

How do you create a custom login page built using the form builder and form helper functions to render the view? I finally figured it out! My solution is below.
Why is it needed?
Well I wanted to use the form builder to create the Symfony login page as I wanted to use the form helper functions to render the view. This way my fields would always use the correct template (manually writing the form - as per the Symfony book example - means if the main template was updated the changes to the login form would have to be done manually - and there's a chance of forgetting that!)
You can do it even more simpler and better (with built in error handling) and the solution is right in Symfony :) ... look at this class as an example UserLoginType:
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien#symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;
/**
* Form type for use with the Security component's form-based authentication
* listener.
*
* #author Henrik Bjornskov <henrik#bjrnskov.dk>
* #author Jeremy Mikola <jmikola#gmail.com>
*/
class UserLoginType extends AbstractType
{
private $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username', 'Symfony\Component\Form\Extension\Core\Type\TextType')
->add('password', 'Symfony\Component\Form\Extension\Core\Type\PasswordType')
->add('_target_path', 'Symfony\Component\Form\Extension\Core\Type\HiddenType')
;
$request = $this->requestStack->getCurrentRequest();
/* Note: since the Security component's form login listener intercepts
* the POST request, this form will never really be bound to the
* request; however, we can match the expected behavior by checking the
* session for an authentication error and last username.
*/
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($request) {
if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(Security::AUTHENTICATION_ERROR);
} else {
$error = $request->getSession()->get(Security::AUTHENTICATION_ERROR);
}
if ($error) {
$event->getForm()->addError(new FormError($error->getMessage()));
}
$event->setData(array_replace((array) $event->getData(), array(
'username' => $request->getSession()->get(Security::LAST_USERNAME),
)));
});
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
/* Note: the form's csrf_token_id must correspond to that for the form login
* listener in order for the CSRF token to validate successfully.
*/
$resolver->setDefaults(array(
'csrf_token_id' => 'authenticate',
));
}
}
I used the createFormBuilder without a class (see Symfony - Using a Form without a Class) so I could render just the needed fields for login:
/**
* #Route("/login", name="login")
*/
public function loginAction(Request $request)
{
if ($this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
$this->addFlash('warning', 'You are already fully logged in.');
return $this->redirectToRoute('my_homepage');
} else {
$authenticationUtils = $this->get('security.authentication_utils');
$defaultData = array('username' => $authenticationUtils->getLastUsername());
$form = $this->createFormBuilder($defaultData)
->add('username', \Symfony\Component\Form\Extension\Core\Type\TextType::class)
->add('password', \Symfony\Component\Form\Extension\Core\Type\PasswordType::class)
->add('logIn', \Symfony\Component\Form\Extension\Core\Type\SubmitType::class)
->getForm();
if (!is_null($authenticationUtils->getLastAuthenticationError(false))) {
$form->addError(new \Symfony\Component\Form\FormError(
$authenticationUtils->getLastAuthenticationError()->getMessageKey()
));
}
$form->handleRequest($request);
return $this->render('login.html.twig', array(
'form' => $form->createView(),
)
);
}
}
Then I rendered the form in the usual way, except I used the full_name form twig variable (see Symfony - Form Variables Reference) to set the correct field names of _username and _password:
{% extends 'base.html.twig' %}
{% block title %}Log in to {{ app.request.host }}{% endblock %}
{% block body %}
<h1>Account Log In</h1>
{{ form_start(form) }}
{{ form_row(form.username, {'full_name': '_username'}) }}
{{ form_row(form.password, {'full_name': '_password'}) }}
{{ form_errors(form) }}
{{ form_end(form) }}
{% endblock %}
I'm not sure what version this is restricted to - I'm using the current 3.0.
EDIT
In case you're wondering.. yes you can use a FormBuilderInterface to create the form in case you want to use the same form elsewhere (with a different template). That's fairly standard. Just create your LoginType file (or whatever you choose to call it):
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class LoginType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username', TextType::class)
->add('password', PasswordType::class)
->add('logIn', SubmitType::class);
}
}
And then get your form using createForm() instead:
$form = $this->createForm(\AppBundle\Form\LoginType::class, $defaultData);
If you want to do clean things, I recommend to use a dedicated factory to build your form :
Controller :
public function signInAction(SignInFormFactory $formFactory): Response
{
$form = $formFactory->createForm();
return $this->render('Security/SignIn.html.twig', array(
'form' => $form->createView(),
));
}
Form Factory :
<?php
namespace App\Form\Factory;
use App\Form\SignInForm;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SignInFormFactory
{
protected $formFactory;
protected $authenticationUtils;
public function __construct(FormFactoryInterface $formFactory, AuthenticationUtils $authenticationUtils)
{
$this->formFactory = $formFactory;
$this->authenticationUtils = $authenticationUtils;
}
public function createForm(): FormInterface
{
$form = $this->formFactory->create(SignInForm::class);
$form->get('_username')->setData($this->authenticationUtils->getLastUsername());
if ($error = $this->authenticationUtils->getLastAuthenticationError()) {
$form->addError(new FormError($error->getMessageKey()));
}
return $form;
}
}
Form type :
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SignInForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('_username', TextType::class)
->add('_password', PasswordType::class)
->add('_remember_me', CheckboxType::class, array(
'required' => false,
'data' => true,
))
->add('submit', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'csrf_field_name' => '_csrf_token',
'csrf_token_id' => 'authenticate',
));
}
public function getBlockPrefix(): string
{
return '';
}
}
This example works fine with the default configuration of the login form in your security.yaml.

Overload a form in symfony

I would like to overload a form of the bundle FOSComment. I would like to know i have to create a new bundle Comment or if i can do it from my working/main bundle ?
Sorry for my english.
Thank you,
David
namespace FOS\CommentBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class CommentType extends AbstractType
{
private $commentClass;
public function __construct($commentClass)
{
$this->commentClass = $commentClass;
}
/**
* Configures a Comment form.
*
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('body', 'textarea')
->add('lien', 'text', array('required' => false,
'empty_data' => null));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
parent::setDefaultOptions($resolver);
$resolver->setDefaults(array(
'data_class' => $this->commentClass,
));
}
public function getName()
{
return "fos_comment_comment";
}
}
For the moment i put my field lien directly in the vendor file which i know is not the good way.
i think all you need to do is override the service definition of the form you want to overload:
e.g. (if you have a services.yml)
fos_comment.form_type.comment.default
class: Project/MyBundle/Form/CustomFormType
arguments:[%fos_comment.model.comment.class%]
tags:
- { name: form.type, alias: fos_comment_comment }

Reusable form choices in symfony2 forms

I have the following code that's working... but I think it can be done better.
(Description below).
Class Address
{
protected province;
public function getProvince()...
}
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$build->add(Province, new ProvinceType());
...
}
}
class ProvinceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$provinceList = array(... //very long list
...
$build->add(Province, 'choice', array(
'choices' => $provinceList;
));
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\Bundle\Entity\Address'
));
}
}
class PersonType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$Province = array(... //very long list
...
$build->add('Address', new AddressType());
$build->add('FromProvince', new AddressType());
}
}
I have two problems with the code above:
Using this in twig PersonType form I have to do form_widget(person.Address.ProvinceType.ProvinceType) to use it. This just looks so wrong.
To validate the province I have to go one method deeper than I should have to.
In the end I just want to be able to validate fields that make sense such as:
Acme\Bundle\Entity\Person:
property:
provinceBorn:
- NotBlank: ~ //Wish to reuse province list here for straight-forward validation.
Address:
Valid: ~
Acme\Bundle\Entity\Address:
property:
province:
- NotBlank: ~ //As well as here.
To shorten the path to your ProvinceType, you should maybe define it as a base widget that would extend Symfony's choice type (see the doc on this). The best you'd get here would be something like {{ form_widget(person.address.province) }}.
To make choices reusable, it would be smart to extract your ProvinceType into a service (see Symfony's doc on how to do this) and pass the list of provinces as a parameter into the ProvinceType's __construct method (that would be defined in your bundle's services.yml). That way you would be able to extract your provinces into an external storage.
On validation, keep in mind that the YAML you've supplied here has mostly nothing to do with Form component, it's about your entity. So, duplicating NotBlank constraints actually makes sense, because you're not linking Person's provinceBorn property to an Address entity, you're saving a separate field.
Though, if you define a custom field type, you can make it required by default by moving the constraint into the Type you extracted to a service. Such constraint can be defined like this:
<?php
class ProvinceChoiceType extends AbstractType
{
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'constraints' => [
new NotBlank(['message' => 'Title is required']),
],
]);
}
...
I have done the something similar in this way (I'll use your example):
Class Address
{
protected province;
public function getProvince()...
}
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$provinceList = array(... //very long list
...
$build->add('province', 'choice', array(
'choices' => $provinceList, 'empty_value' => null, 'required' => true,
));
...
}
}
class PersonType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$Province = array(... //very long list
...
$build->add('address', new AddressType());
$build->add('fromProvince', new AddressType());
}
}
And you send the data:
...
$form = $this->createForm(new PersonType(), $entity);
return array(
'form' => $editForm->createView(),
);
And use this in Twig as below:
{{ form_widget(form.address.province) }}
Finally, I think your validation are correct, but if you need something more specific, you could use the getters method as in the Symfony documentation is specified, in the validation section http://symfony.com/doc/current/book/validation.html#getters
Extended answer from before with explanations.
Inheriting form
http://symfony.com/doc/current/cookbook/form/inherit_data_option.html
Code
With your code it should look something like this
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$build->add(Province, new ProvinceType(), [
'inherit_data' => true
// this is an alterrnative for having it bellow inside configure options
// use one or another, what suit you better
]);
...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'inherit_data' => true
]);
}
// in sf > 2.7 use public function configureOptions(OptionsResolver $resolver)
}
class ProvinceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$provinceList = array(... //very long list
...
$build->add(Province, 'choice', array(
'choices' => $provinceList;
));
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\Bundle\Entity\Address',
'inherit_data' => true
));
}
}
class PersonType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$Province = array(... //very long list
...
$build->add('Address', new AddressType());
$build->add('FromProvince', new AddressType());
}
}
This you addressType inherits fields from provinceType, and PersonType inherits from both addressType (including its inherited fields from provinceType).
Template
So it should be possible to do this inside template
{{ form_row(form.Province)}}
Validation
The best way would be to so validation constrains on your relations with the Valid constrain.
This will force the validations on the children also
http://symfony.com/doc/current/reference/constraints/Valid.html
The other option is setting cascade_validation on the form, but this wont forward your validation groups if any.
Either way, you would then need define validation only on each entity once.

How do I pass a value to Form Builder in Symfony2?

I'm using a Form Builder to create a form for use in an application. In the form, the user needs to be able to select a list of events that they are associated with. However, I'm unable to figure out how exactly I can pass the user's ID to the form builder?
My code is like this at the moment:
EvType.php
<?php
// src/Acme/MembersBundle/Form/Type/EvType.php
// This is to handle forms for the Members Form
namespace Acme\MembersBundle\Form;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class EvType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$centre = $this->centre;
$builder->add('id', 'integer', array('required'=>false));
$builder->add('list','entity', array('class'=>'Acme\InstructorBundle\Entity\MapLists', 'property'=>'name',
'query_builder' => function(EntityRepository $br) {
return $br->createQueryBuilder('ml')
->where('ml.user = :user')
->setParameter('user','1' );
}));
$builder->add('eventHorse', 'text', array('required'=>false));
}
public function getName()
{
return 'ev';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\InstructorBundle\Entity\MapListCentreMembers',
'csrf_protection' => false,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'task_item',
));
}
}
->setParameter('user','1' ); is where I want to be able to pass the User's ID from the form. For now, I've statically assigned the user ID.
DefaultController.php
// User ID
$userid = $mem['userID'];
// Get Tests from Entity for Form use
$memberEV = $dm->getRepository('InstructorBundle:MapListMembers')->find($memberint);
// Generate Form to edit Tests & Achievements
$ev = $this->createForm( new EvType(), $memberEV);
you can simply pass a value in the __construct.
See below:
EvType.php
class EvType extends AbstractType
{
private $user;
public function __construct($user)
{
$this->user = $user;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$user = $this->user;
....
}
DefaultController.php
$ev = $this->createForm( new EvType($user), $memberEV);

How access my Service (DependencyInjection) inside my Type classes?

I have a Service (DependencyInjection) that i create, and i use that on my controllers as:
$this->get("service_name")->someMethod()
I want to know how to use that on my Form classes.
Here my example form of class:
namespace Company\SampleBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class AnswerType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options) {
// I want use: $this->get("service") here, how can i use that?
$builder->add('answer', 'textarea');
}
public function getName() {
return 'answer';
}
public function getDefaultOptions(array $options) {
return array(
'data_class' => 'Company\SampleBundle\Entity\Answer',
);
}
}
Thanks
You can use the $options to achieve this. This implies you modify the getDefaultOptions accordingly.
public function getDefaultOptions(array $options) {
return array(
'service' => null,
'data_class' => 'Company\SampleBundle\Entity\Answer',
);
}
In your controller, when you call createForm()
use the $options argument, like this:
$this->createForm('Answer', null, array('service' => $service))