Suppose to have an entity in Symfony2 that has a field bestfriend
, which is a User
entity selected from a list of User
entities that satisfy a complex requirement.
You can render this field in a form by specifying that it is an entity field type, i.e.:
$builder->add('bestfriend', 'entity', array(
'class' => 'AcmeHelloBundle:User',
'property' => 'username',
));
This form field is rendered as a <select>
, where each one of the displayed values is in the form:
<option value="user_id">user_username</option>
So, one would render the field by using the <optgroup>
tags to highlight such special feature of the friends.
Following this principle, I created a field type, namely FriendType
, that creates the array of choices as in this answer, which is rendered as follows:
$builder->add('bestfriend', new FriendType(...));
The FriendType
class creates a <select>
organized with the same <option>
s but organized under <optgroup>
s.
Here I come to the problem! When submitting the form, the framework recognize that the user field is not an instance of User, but it is an integer. How can I let Symfony2 understand that the passed int is the id of an entity of type User?
Here follows my solution.
Notice that it is not mentioned in the Symfony2 official docs, but it works! I exploited the fact that the entity field type is child of choice
.
Hence, you can just pass the array of choices
as a param.
$builder->add('bestfriend', 'entity', array(
'class' => 'AcmeHelloBundle:User',
'choices' => $this->getArrayOfEntities()
));
where the function getArrayOfEntities()
is a function that fills the choice list with the friends of my friends, organized by my friends:
private function getArrayOfEntities(){
$repo = $this->em->getRepository('AcmeHelloBundle:User');
$friends = $repo->findAllFriendByComplexCriteria(...);
$list = array();
foreach($friends as $friend){
$name = $friend->getUsername();
if(count($friend->getFriends())>0){
$list[$name] = array();
foreach($friend->getFriends() as $ff){
$list[$name][$ff->getUsername()] = $ff;
}
}
}
return $list;
}
I know the example could be meaningless, but it works...
PS: You need to pass the entity manager to let it working...