Save form data temporary - symfony

The user has the ability to filter a list of data. For this use case i build a form type "UserFilterType", which look like this.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('firstName', 'text', array('attr' => array('maxlength' => 255)))
->add('roles', 'entity', array(
'class' => 'ApplicationUserBundle:Role',
'property' => 'name',
'label' => false,
'multiple' => false,
'expanded' => false,
'empty_value' => 'msg.role.all',
'translation_domain' => 'role', 'required' => false)
));
}
So far everything works very well. The user can filter the output. But if the user wants to sort the output, eg by first name. A get request executed and filter options lost. I will save the filter options temporary, maybe in a session.
I try the following option:
$session = $this->getRequest()->getSession();
$session->set('userFilter', serialize($form->getData());
.....
$form->setData(unserialize($session->set('userFilter')));
The form fields are filled out correctly, but if i execute the filter again with a post request i get the following error message
"Entities passed to the choice field must be managed. Maybe persist them in the entity manager?"
Does anyone have any idea how I should proceed? I hope I could describe my problem understandable.

Instead of field type 'entity', you might want to use 'choice' and set the querybuilder for the choicelist in the form.
This is caused by the fact, that 'entity' type field expects an Entity as a value. When you unserialize the data, even if it was an Entity from the database, the EntityManager doesn't know this(the unserialized object is just an instance of ApplicationUserBundle:Role, it might not be in the database yet) so this is not a "managed" entity.
You can also add the EntityManager that you found a "lost lamb" and add it back to the manager by:
$filters = unserialize($session->set('userFilter'));
$roles = $filters['roles'];
$entityManager->merge($roles);
This way you tell the EntityManager that this object is already persisted(through ->persist) and EntityManager should treat it as an object fetched from the database
but you need to test it

Related

How to prefill field of type EntityType from PHP

In my form, I have a field of type EntityClass:
$builder
->add(
'user',
EntityType::class,
[
'required' => false,
'label' => 'User',
'placeholder' => 'Please choose',
'choice_label' => 'email',
'choice_value' => 'id',
'class' => 'AppBundle:User',
]
)
;
This field works fine - until I try to pre-fill it from my PHP code. Then it stays empty, and only shows "Please choose".
Pre-filling looks like this:
$user = $this->userRepository->find(...);
$form->get('user')->setData($user);
But it also does not work if I call ->setData($user->getId()), or even ->setData($user->getEmail()).
So how do I prefill a field of type EntityType?
You should not prefill Form, you should prefill Model, if you need it.
$user = $this->userRepository->find(...);
$entity = new YourEntity();
$entity->setUser($user);
$form = $this->createForm(YourEntity::class, $entity);
And it's not about EntityType. It's about any Type in Symfony - there is no way to bind a default value for them. Data is binded on Model.
UPD from comment: It's not true, that Form could be used without Model. It could be used without Doctrine Entity or any other ORM (or not ORM) Entity. But they still operate with data, i.o. with model.
\Symfony\Component\Form\FormFactoryInterface has definition
public function create($type = 'form', $data = null, array $options = array());
So some kind of $data is always present when you're using Form Component.

Symfony 2.6: Collection as Form

i have an array with entities. I know that symfony has a collection type, but that what i want doesn't work as intended. I have created a FormType for a single entity and a FormType for the collection (formtype code for the collection):
$builder
->add('list', 'collection', array(
'label' => 'list',
'type' => new SingleItemType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
));
Now i have tried to create a Form
$arr = array(new Item(), new Item(), new Item());
$this->createForm(new CollectionListType(), $arr);
But this doesn't work; I get an error which means i should set "Item" as data_class, if i do this, an another error appears which means i should set data_class to null.
Another approach was to create a dummy entity which holds my array of Item-Entities but this doesn't works too.
Is there a simple approach to display a list of entities as collection form?
Greetings
I'm not sure totally understand your problem but I think you must create first an Entity with getList()/setList(). In your collection field, you can add a new "default" entity passing a value to "data" key in option array.

Add roles in FOSUserBundle

I feel the same as a forum user who posted this:
I implemented FOSUserBundle, and I want to add to RegisrationFormType roles that are taken from a table. When I had it like this:
->add('roles', 'choice', array('label' => 'Rol', 'required' => true,
'choices' => array( 'ROLE_ADMIN' => 'ADMINISTRADOR','ROLE_SUPERADMIN' => 'SUPERADMINISTRADOR',
'ROLE_USER' => 'USUARIO'), 'multiple' => true))
And it works! But they must leave the BD, I can not put the Entity field because roles should be an array, not an object. How I can generate the array with the roles taken from a table? In FosUSerbundle as you would add roles?
Thanks ....
I write because that user had no answer. I followed [the steps of official documentation] (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md) and adding the above lines in the register of FOSUserBundle works, but I want to work this from the database.
And then I used to create groups this. Two additional tables were created and even now joined a group or role in the list, but not how to show the login to register a new user.
Has anyone solved it?
So you have the roles in a table? You could inject the EntityManager in the form type and use it to fetch the choices.
->add('roles', 'choice', array(
'label' => 'Rol',
'choices' => $this->getRoles(),
'multiple' => true,
'required' => true,
))
Then create a method which gives you the data the way you need.
Something like:
public function getRoles()
{
$roles = array();
$er = $this->em->getRepository('AppBundle:Role');
$results = $er->createQueryBuilder('r')
// conditions here
->getQuery()
->getResult();
// process the array?
foreach ($results as $role) {
$roles[$role->getId()] = $role->getLabel();
}
return $roles;
}

ManyToMany nullable not allowed

I have a scenario like this:
tracks ManyToMany instruments
I create the form in this way:
$builder
->add('instruments', 'entity_hidden', array(
'attr' => array('class' => 'one_req'),
'label' => 'form.instrument',
'translation_domain' => 'label',
'required' => false,
'class' => 'Acme\DemoBundle\Entity\Instrument'
))
"hidden_entity" is given by a custom transformer that you can find here: gist
although I believe that is not the problem.
The problem is that the user may not even choose any instrument (such asamong other specified with "required" => false).
When I go to save my returns this error:
Neither the property 'instruments' nor one of the methods 'setInstruments()',
'__set()' or '__call()' exist and have public access in
class 'Acme\DemoBundle\Entity\SoundtrackVersion'.
I do not understand why ..
Where am I doing wrong?
It sounds very obvious, but error can not lie. Check that Acme\DemoBundle\Entity\SoundtrackVersion entity has property instruments and methods setInstruments() and getInstruments().

Symfony2 form validation - this value is not valid

I got a form in Symfony but it won't validate and I don't know why.
From UserBundle/Entity/Task.php
/**
*
* #ORM\ManyToMany(targetEntity="Project\TaskBundle\Entity\Task", inversedBy="users")
* #ORM\JoinTable(name="project_users_tasks")
*
*/
protected $tasks;
From UserBundle/Form/CreateUserFormType.php which is my formbuilder:
$builder->add('tasks', 'entity', array(
'class' => 'TaskBundle:Task',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('b')
->andWhere('b.owner = :owner')
->setParameter('owner', $this->securityContext->getToken()->getUser())
->addOrderBy('b.updated', 'ASC');
},
'expanded' => false,
'multiple' => false
));
The post request in my browser:
------WebKitFormBoundary6IBT2Ycy78N9AI7u
Content-Disposition: form-data; name="createUser[tasks][]"
14
The result I get for the form is an error concerning the tasks:
"This value is not valid"
I got no other validation what so ever. So why can't the task 14(which is clean the dishes for example) be assigned to my user? I mean the id of the task should work or not?
Edit:
Symfony doesn't seem to recognize the data, that's why. A print_r of $form->getData();
[tasks:protected] => Doctrine\Common\Collections\ArrayCollection Object
(
[_elements:Doctrine\Common\Collections\ArrayCollection:private] => Array
(
)
)
But how can that be? I can see that my browser is posting the data.
At first glance, there are two brackets too much in your submitted field name: createUser[tasks][] should be createUser[tasks], since the entity field is a collapsed, single-valued entity field.
Also try to debug Symfony's request object. var_dump($request->request->get('createUser')) should return something like
array(
'tasks' => 14,
)
If, on the other hand, you really want to submit one or more tasks, set the "multiple" option on the entity field to true. Then the request data should be something like
array(
'tasks' => array(
0 => 14,
)
)

Resources