Symfony Form Choices Entity - forms

I try to use the 'choices' option into my form :
class FicheInterventionType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('services', EntityType::class, array(
'class' => 'GestionBundle:Service',
'choice_label' => 'nom',
'multiple' => true,
'choices' => $options['services'],
'required' => false))
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'FichesBundle\Entity\FicheIntervention',
'services' => null
));
}
}
controller :
$form = $this->createForm(FicheInterventionType::class, $ficheObservation,
array('services' => $this->getUser()->getCategorie()->getServices()));
but I get all services present in my database, not the services passed with the parameter $option.
I don't know why.

Related

Symfony 3 : Adding checkboxes to form form database

I'm struggling with symfony forms. I want to build a form for an user. This user as a arraycollection field that gather products (nom, description).
I would like to create a form that create a checkbox for each of the products passed to the form builder. Actually it just created input fields without labels... Here is the code of my UserType class :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nom')->add('prenom')->add('mail')->add('tel1')->add('tel2', TextType::class, array('required' => false))
->add('username')->add('password', PasswordType::class)
->add('groupe', ChoiceType::class, array(
'choices' => array('Administrateur' => 'ROLE_SUPER_ADMIN', 'Gérant' => 'ROLE_ADMIN', 'Opérateur' => 'ROLE_USER'),
'expanded' => true,
))
->add('produits', CollectionType::class, array(
'entry_type' => ProduitType::class
))
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'gestcoupons_userbundle_user';
}
Here is my ProduuctType code :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nom')->add('prenom')->add('mail')->add('tel1')->add('tel2', TextType::class, array('required' => false))
->add('username')->add('password', PasswordType::class)
->add('groupe', ChoiceType::class, array(
'choices' => array('Administrateur' => 'ROLE_SUPER_ADMIN', 'Gérant' => 'ROLE_ADMIN', 'Opérateur' => 'ROLE_USER'),
'expanded' => true,
))
->add('produits', CollectionType::class, array(
'entry_type' => ProduitType::class
))
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'gestcoupons_userbundle_user';
}
Here is my UserController code :
public function ajouterAction(Request $request){
$this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');
$em = $this->getDoctrine()->getManager();
$produits = $em->getRepository('ProduitBundle:Produit')->findAll();
$societes = $em->getRepository('SocieteBundle:Societe')->findAll();
$user = new User();
foreach ($produits as $produit) {
$user->getProduits()->add($produit);
}
$form = $this->createForm('GestCoupons\UserBundle\Form\UserType', $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush($user);
return $this->redirect('dashboard_admin');
}
return $this->render('user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
}
Thanks ahead for your help.
You should use Symfony\Bridge\Doctrine\Form\Type\EntityType instead of CollectionType.
In your UserType
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use AppBundle\Entity\Produit;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nom')
->add('prenom')
->add('mail')
->add('tel1')
->add('tel2', TextType::class, array(
'required' => false
))
->add('username')
->add('password', PasswordType::class)
->add('groupe', ChoiceType::class, array(
'choices' => array(
'Administrateur' => 'ROLE_SUPER_ADMIN',
'Gérant' => 'ROLE_ADMIN',
'Opérateur' => 'ROLE_USER'
),
'expanded' => true,
))
->add('produits', EntityType::class, array(
'class' => Produit::class,
'multiple' => true,
'expanded' => true,
'label' => 'nom' //If you don't have a __toString method in your Produit Entity
))
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'gestcoupons_userbundle_user';
}
This way you will have a checkbox for each Product entity in your database and only the one you checked will be associated to your user

Add or remove fields in Symfony 3 form type according to the environment

On my site, people can post comments on my posts, and I can reply to them from my back office.
I want people to fill a recaptcha on the front-office, so I used EWZRecaptchaBundle, and made the following CommentaireType :
<?php
namespace Babdelaura\BlogBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaType;
use EWZ\Bundle\RecaptchaBundle\Validator\Constraints\IsTrue as RecaptchaTrue;
class CommentaireType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('auteur', TextType::class)
->add('email', EmailType::class, array('required' => false))
->add('site', TextType::class, array('required' => false))
->add('contenu', TextareaType::class)
->add('recaptcha', EWZRecaptchaType::class, array(
'mapped' => false,
'constraints' => array(new RecaptchaTrue())
))
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Babdelaura\BlogBundle\Entity\Commentaire'
));
}
/**
* #return string
*/
public function getBlockPrefix()
{
return 'babdelaura_blogbundle_commentaire';
}
}
But now, I have a recaptcha on my back-office too, and I don't want it.
Before Symfony 3 and FQCN for types I used to do new CommentaireType(true) in my back office, retrieve the boolean in CommentaireType::__construct, and add the recaptcha if is was true. But now I can't do this anymore.
Does somebody have a clean solution to handle that case ?
Thank you !
You can use options when you call your service to pass a boolean for example like this :
$form = $this->createForm(new CommentaireType(), $commentaire, array(
'recaptcha' => false,
));
and then in your CommentaireType:
class CommentaireType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('auteur', TextType::class)
->add('email', EmailType::class, array('required' => false))
->add('site', TextType::class, array('required' => false))
->add('contenu', TextareaType::class);
if($options['recaptcha']) {
$builder
->add('recaptcha', EWZRecaptchaType::class, array(
'mapped' => false,
'constraints' => array(new RecaptchaTrue())
));
}
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Babdelaura\BlogBundle\Entity\Commentaire',
'recaptcha' => false,
));
}
/**
* #return string
*/
public function getBlockPrefix()
{
return 'babdelaura_blogbundle_commentaire';
}
}

Symfony2 form builder constraints don't work in collection of forms

I want to embed a Collection of Forms. That works fine! But the problem is, that the validation of a non mapped field ist not working. The code:
UserType.php
class UserType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('contactPersons', CollectionType::class, array(
'entry_type' => ContactPersonCreateType::class,
'allow_add' => true,
'prototype' => true,
'cascade_validation' => true,
))
...
}
ContactPersonCreateType.php
class ContactPersonCreateType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('kind', 'text', array(
'mapped' => false,
'required' => true,
'constraints' => array(
new NotBlank(),
new Length(array('min' => 3)),
)
))
...
}
I don't know why, but it will not be validated!
Can somebody help?

Symfony2 : data not binded to form with handleRequest()

I have created a complex symfony form with nested collection. When i create my form with data from orm it works :
$categories = $this->getDoctrine()->getRepository('xx:CategoryNutritionProgram')->findAll();
$form = $this->createForm(new CategoryCollectionFormType(), array('categories' => $categories));
CategoryCollectionFormType :
class CategoryCollectionFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('categories', 'collection', array(
'type' => new CategoryFormType(),
'cascade_validation' => true,
'allow_add' => true,
'by_reference' => false,
'allow_delete' => true,
'prototype_name' => '__i__'
));
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
public function getName()
{
return 'simulator_category_collection';
}
}
CategoryFormType :
class CategoryFormType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', 'hidden');
$builder->add('nutritionPrograms', 'collection', array(
'type' => new NutritionProgramFormType(),
'cascade_validation' => true,
'allow_add' => true,
'by_reference' => false,
'allow_delete' => true,
'prototype_name' => '__j__'
));
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'xx\Entity\CategoryNutritionProgram'
));
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
public function getName()
{
return 'simulator_category';
}
}
etc ...
But handleRequest() function doesn't work and $data are empty when i submit form. Where is the problem ? my code seems good
$data = array('categories' => array());
$form = $this->createForm(new CategoryCollectionFormType(), $data);
$form->handleRequest($request);
Below the data sent on POST request :
simulator_category_collection[categories][0][name]:cat1
simulator_category_collection[categories][0][nutritionPrograms][0][name]:prog1
simulator_category_collection[categories][0][nutritionPrograms][0][applications][0][name]:app1
simulator_category_collection[categories][0][nutritionPrograms][0][applications][0][product]:1
simulator_category_collection[categories][0][nutritionPrograms][0][applications][0][dose]:5
simulator_category_collection[categories][0][nutritionPrograms][0][applications][0][unit]:5
simulator_category_collection[categories][0][nutritionPrograms][0][applications][1][name]:app2
simulator_category_collection[categories][0][nutritionPrograms][0][applications][1][product]:2
simulator_category_collection[categories][0][nutritionPrograms][0][applications][1][dose]:6
simulator_category_collection[categories][0][nutritionPrograms][0][applications][1][unit]:6
simulator_category_collection[categories][0][nutritionPrograms][1][name]:prog2
simulator_category_collection[categories][0][nutritionPrograms][1][applications][0][name]:app3
simulator_category_collection[categories][0][nutritionPrograms][1][applications][0][product]:3
simulator_category_collection[categories][0][nutritionPrograms][1][applications][0][dose]:7
simulator_category_collection[categories][0][nutritionPrograms][1][applications][0][unit]:7
simulator_category_collection[categories][1][name]:cat2
simulator_category_collection[categories][1][nutritionPrograms][0][name]:prog3
simulator_category_collection[_token]:xxx
Thx for help
Resolved, instead of trying to get data from orginal object like this :
$data = array('categories' => array());
$form = $this->createForm(new CategoryCollectionFormType(), $data);
$form->handleRequest($request);
// here array $data is empty
I have to use $form->getData() because my array is passed by value

Symfony: Field Collection, returning on selected value

I am using a collection with type field type. This is retrieving fields from a table. I am able to add/edit the fields.
What I would like to do is only return certain fields in the collection.
eg only the fields where the column reference_id = 2
The reason I would like to do this is because I am grouping the returned values to their group.
So I will be returning multiple collections grouped by their group.
DetailsType.php
$builder
->add('FieldText', 'collection', array(
'type' => new FieldTextType(),
'prototype' => true,
'allow_add' => true,
'allow_delete' => true,
))
FieldTextType.php
$builder
->add('label', 'text')
->add('value', 'text')
;
Edit - Added the type
DetailsType.php
class VillaDetailsType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('CollectionOne', 'collection', array(
'type' => new FieldTextType(),
'prototype' => true,
'allow_add' => true,
'allow_delete' => true,
))
->add('CollectionTwo', 'collection', array(
'type' => new FieldCheckboxType(),
'prototype' => true,
'allow_add' => true,
'allow_delete' => true,
))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'some/entity'
));
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
public function getName()
{
return 'base';
}
FieldTextType.php
class FieldTextType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('label', 'text')
->add('value', 'text')
;
}
/**
* {#inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Some/Entity'
));
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
public function getName()
{
return 'detail';
}