I have created a simple user/role form. The form shows the user's detail correctly and displays all the possible roles, but for some reason it does not pre-select the users' current role. For the relationship between the user and role I had the following in the user entity class:
/**
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users", cascade={"persist","remove"})
* #ORM\JoinTable(name="user_role")
*/
protected $roles;
The formtype class was built using:
$builder->add('firstname')
->add('lastname')
->add('email')
->add('roles');
The database looks like this:
Any hints/assistance would be appreciated.
You need to define your roles fields as entity
http://symfony.com/doc/current/reference/forms/types/entity.html
change this line ->add('roles'); to:
->add('roles', 'entity', array(
'multiple' => true,
'expanded' => true,
'property' => 'name',
'class' => 'Your_Path\Entity\Roles',
));
it should work.
Second option:
you can try to create role type form as mentioned here and then do something like this
$builder->add('roles', 'collection', array('type' => new RoleType()));
its recomended to read this this about mapped option and other as by_reference
Had the same problem in symfony4, adding this did the trick for me:
'choice_value' => function ($choice) {
return $choice;
},
Related
I could not really find my specific case on the internet and therefore decided on writing my own question.
I have a form to create a Member object. This member object has a reference to an application object. Both are saved in 2 different databases.
Creating a Member object is no issue only when I edit and fill out the form, do I encounter an error ->
Entity of type "Application"
passed to the choice field must be managed. Maybe you forget to
persist it in the entity manager
Here is my Form Code
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('membberName', null, array('label' => false))
->add('memberDescription', TextareaType::class, array('label' => false))
->add('memberVisible', null, array('label' => false))
->add('memberApp', EntityType::class, [
'label' => false,
'class' => Application::class,
'choice_label' => function (Application $application) {
return sprintf('(%d) %s', $application->getAppId(), $application->getAppurlUrl());
},
'choices' => $this->applicationRepository->getAll(),
])
->add('Save', SubmitType::class, [
'attr' => ['class' => 'create-button']
]);
}
I found a lot of cases about this issue but none of them could help me.
I only encounter this issue if I load an entity that is related to another one outside their own database.
To summarize: calling the create view page and pressing on submit works.
Calling the edit view causes the above mentioned issue.
Do I have to define or configure anything so my form can load correctly?
Try setting up custom em for your entity form field memberApp in options to your second database entity manager.
like described in docs: https://symfony.com/doc/current/reference/forms/types/entity.html#em
em type: string | Doctrine\Common\Persistence\ObjectManager default:
the default entity manager
If specified, this entity manager will be used to load the choices
instead of the default entity manager.
Another way, probably would be to set ['mapped' => false] for this field and handling flush manually with correct database's em in controller or service
I have a few Entities and I try to setup relations between users and permissions. I want to have possibility to assign group of permissions to user, so I created entity User, GroupAssociationsUser, Permissions. I though that best way is to create relation ManyToOne in GroupAssociationsUser to Users and to Permissions. Bellow you can see code of GroupAssociationsUser entity:
/**
* #ORM\ManyToOne(targetEntity="Permissions", inversedBy="group_assoc_user")
* #ORM\JoinColumn(name="group_permissions", referencedColumnName="id", nullable=FALSE)
*/
private $group_permissions;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="group_assoc_user")
* #ORM\JoinColumn(name="user_assoc", referencedColumnName="id", nullable=FALSE)
*/
private $user_assoc;
Then I also created relation in User entity:
/**
* #ORM\OneToMany(targetEntity="GroupAssociationsUser", mappedBy="user_assoc")
*/
private $group_assoc_user;
public function __construct()
{
$this->group_assoc_user = new ArrayCollection();
}
Finally in Permission entity:
/**
* #ORM\OneToMany(targetEntity="GroupAssociationsUser", mappedBy="group_permissions")
*/
private $group_assoc_user;
public function __construct()
{
$this->group_assoc_user = new ArrayCollection();
}
So basically I want to have select list on my user edit page and I want to have possibility to select permission group to assign to user.
So I created form with:
->add('group_assoc_user', EntityType::class, array(
'class' => 'AppBundle:Permissions',
'choice_label'=> 'group_name',
'placeholder' => 'no rights',
))
And the problem is that no mater what I do, I have got only list of exiting permissions or if I change code to :
->add('group_assoc_user', EntityType::class, array(
'class' => 'AppBundle:GroupAssociationsUser',
'choice_label'=> 'Permissions.group_name',
'placeholder' => 'no rights',
));
I have got listed only assigned permission without not assigned. What am I doing wrong?
Even if I got all permissions names how I can force doctrine to mark already assigned field?
Try to set Multiple to true.
http://symfony.com/doc/current/reference/forms/types/entity.html#multiple
->add('group_assoc_user', EntityType::class, array(
'class' => 'AppBundle:GroupAssociationsUser',
'choice_label'=> 'Permissions.group_name',
'placeholder' => 'no rights',
'multiple' => true,
));
You may also like the
'expanded' => true
option
I am using symfony to build the functions as below:
I have Product and ShippingWays.
One Product could have more ShippingWays and One ShippingWay only match one product.
ProductEntity:
/**
* #ORM\OneToMany(targetEntity="ShippingWay",mappedBy="product")
*/
private $shippingWays;
ShippingWay Entity:
/**
* #ORM\ManyToOne(targetEntity="Product", inversedBy="shippingWays")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
**/
private $product;
Then I build both the ProductType and ShippingWayType.
ProductType
->add('shippingWays', EntityType::class, array(
'label' => ' Shipping Ways',
'translation_domain' => 'forms',
'class' => 'CoreBundle:ShippingWay',
'choice_label' => 'name',
'multiple' => true,
'required' => false,
))
ProductController
/**
* #Route("/admin/product/new", name="admin_product_new")
* #Template()
*/
public function newAction(Request $request)
{
$product = new Product();
$shippingWay= new ShippingWay();
$form = $this->createForm(ProductType::class, $product);
$shippingForm = $this->createForm(ShippingWayType::class, $shippingWay);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($product );
$em->flush();
return $this->redirect($this->generateUrl('admin_product'));
}
}
return(array('form' => $form->createView(),'users'=>$users,'shippingForm '=>$shippingForm ->createView()));
}
I'd like to add/edit the Shipping Way in the product page.
If there is no suitable shipping ways then I have to create a new one in the product page.
Something like this :
enter image description here
Currently I have 2 problems:
How to manage the Shipping way with Form as usual in Product page? Is there a general way to handle the forms under OneToMany & ManyToOne relationships?
I select Shipping way A when I add Product X, Then I could select Shipping Way A as before when I add product Y. I found that procuct_id with Shipping Way A always be Null.
Could someone give me some suggestions and references?
Thank you very much.
For your first problem : In your ProductType, you should not use EntityType for ShippingWay as it just display the list of existing entries related to ShippingWay entities.
If you want to add/edit, it would be better to use CollectionType, as specified here: How to Embed a Collection on a Symfony Form
In your case, your ProductType would be:
->add('shippingWays', CollectionType::class, array(
'label' => ' Shipping Ways',
'translation_domain' => 'forms',
'entry_type => 'CoreBundle:ShippingWay',
'choice_label' => 'name',
'allow_add' => true,
'allow_delete' => true
))
I'm new to symfony2 and I'm building my first online store with it. I have products and I want to add product sizes, one product can have many sizes and one size can have many products. For example: two products cat have 'M' size.
class Product {
...
/**
* #ORM\ManyToMany(targetEntity="Size", inversedBy="products", cascade={"persist", "merge"})
* #ORM\JoinTable(name="sizes")
*/
private $sizes;
}
//in another file
class Size {
/**
* #ORM\ManyToMany(targetEntity="Product", mappedBy="sizes")
*/
protected $products;
}
ProductController.php
...
->add('sizes', CollectionType::class, [
'entry_type' => SizeType::class,
'label' => 'Sizes',
'allow_add' => true,
])
...
SizeType.php
public function buildForm(FormBuilderInterface $builder, array $options) {
$repo = $this->em->getRepository('AppBundle:Size');
$q = $repo->createQueryBuilder('c')
->getQuery();
$sizes = $q->getResult();
$builder->add('name', EntityType::class, array(
'class' => 'AppBundle:Size',
'choice_label' => 'name',
));
}
Right now I'm getting
Catchable Fatal Error: Object of class AppBundle\Entity\Size could not be converted to string I can fix if I implement __toString() but I don't know if this is the right thing to do, and if I do this, when editing the product, the dropdown doesn't select the right size.
My question is, is this the right way to implement product - sizes function to online store?
Try with this code:
$builder->add('name', EntityType::class, array(
'class' => 'AppBundle:Size',
'choice_label' => 'name',
'property' => 'needed_property_name' //just write the needed property name there
));
So I've figured out better way to do it, 'entity' type with multiple => true
->add('sizes', 'entity', [
'class' => Size::class,
'label' => 'Размери',
'choice_label' => 'name',
'multiple' => true,
'expanded' => false,
//'allow_add' => true,
])
This way multiple sizes can be selected, with bootstrap-multiselect I've made it good looking and perfectly works for me now.
I'd love to hear if there is a better way.
Product annotations looks wrong. The JoinTable is a lookup table for many-to-many relation:
The convention is to name it after linked tables: products_sizes in your case:
class Product {
...
/**
* #ORM\ManyToMany(targetEntity="Size", inversedBy="products", cascade={"persist", "merge"})
* #ORM\JoinTable(name="products_sizes")
*/
private $sizes;
}
I want from the user to select a type of questionnaire, so I set a select that contains questionnaires types.
Types are loaded from a an entity QuestionType .
$builder
->add('questionType', 'entity', array(
'class' => 'QuizmooQuestionnaireBundle:QuestionType',
'property' => 'questionTypeName',
'multiple' => false,
'label' => 'Question Type'))
->add('type', 'hidden')
;
What am not able to achieve is to set a default value to the resulted select.
I have googled a lot but I got only preferred_choice solution which works only with arrays
I made it by setting a type in the newAction of my Controller I will get the seted type as default value.
public function newAction($id)
{
$entity = new RankingQuestion();
//getting values form database
$em = $this->getDoctrine()->getManager();
$type = $em->getRepository('QuizmooQuestionnaireBundle:QuestionType')->findBy(array('name'=>'Ranking Question'));
$entity->setQuestionType($type); // <- default value is set here
// Now in this form the default value for the select input will be 'Ranking Question'
$form = $this->createForm(new RankingQuestionType(), $entity);
return $this->render('QuizmooQuestionnaireBundle:RankingQuestion:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
'id_questionnaire' =>$id
));
}
You can use data attribute if you have a constant default value (http://symfony.com/doc/current/reference/forms/types/form.html)
but it wont be helpful if you are using the form to edit the entity ( not to create a new one )
If you are using the entity results to create a select menu then you can use preferred_choices.
The preferred choice(s) will be rendered at the top of the list as it says on the docs and so the first will technically be the default providing you don't add an empty value.
class MyFormType extends AbstractType{
public function __construct($foo){
$this->foo = $foo;
}
$builder
->add('questionType', 'entity', array(
'class' => 'QuizmooQuestionnaireBundle:QuestionType',
'property' => 'questionTypeName',
'multiple' => false,
'label' => 'Question Type'
'data' => $this->foo))
->add('type', 'hidden')
;
}
In controller
$this->createForm(new MyFormType($foo));
The accepted answer of setting in the model beforehand is a good one. However, I had a situation where I needed a default value for a certain field of each object in a collection type. The collection has the allow_add and allow_remove options enabled, so I can't pre-instantiate the values in the collection because I don't know how many objects the client will request. So I used the empty_data option with the primary key of the desired default object, like so:
class MyChildType
extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('optionalField', 'entity', array(
'class' => 'MyBundle:MyEntity',
// Symfony appears to convert this ID into the entity correctly!
'empty_data' => MyEntity::DEFAULT_ID,
'required' => false,
));
}
}
class MyParentType
extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('children', 'collection', array(
'type' => new MyChildType(),
'allow_add' => true
'allow_delete' => true,
'prototype' => true, // client can add as many as it wants
));
}
}
Set a default value on the member variable inside your entity (QuestionType), e.g.
/**
* default the numOfCourses to 10
*
* #var integer
*/
private $numCourses = 10;