Entity Field type hidden in Symfony2 - symfony

I want to make a hidden value for my Foreign Key Entity in controller.
My previous controller is like this (works fine):
->add('id_grup', 'entity', array('class' => 'Sifo\AdminBundle\Entity\MstGrup'))
I want to assign a hidden value to my form like this:
->add('id_grup', 'hidden', array('data' => $id))
But it gives me an error:
ContextErrorException: Catchable Fatal Error: Argument 1 passed to
Sifo\AdminBundle\Entity\DftGrupMapel::setIdGrup() must be an instance
of Sifo\AdminBundle\Entity\MstGrup, string given, called in
C:\Sifony\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php
on line 360 and defined in
C:\Sifony\src\Sifo\AdminBundle\Entity\DftGrupMapel.php line 179
How can I assign a value to a foreign key entity which is hidden?

Finally it works! I need define the entity default before create form and don't add again in FormBuilder:
public function manageAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('SifoAdminBundle:MstGrup')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find MstGrup entity.');
}
$entity_new = new DftGrupMapel();
$entity_new->setIdGrup($entity);
$new_form = $this->createFormBuilder($entity_new)
->setAction($this->generateUrl('admin_grup_mapel_manage', array('id' => $id)))
->setMethod('POST')
->getForm();
$new_form->handleRequest($request);
if ($new_form->isValid()) {
$em_new = $this->getDoctrine()->getManager();
$em_new->persist($entity_new);
$em_new->flush();
return $this->redirect($this->generateUrl('admin_grup_mapel_manage', array('id' => $id)));
}
return $this->render('SifoAdminBundle:DftGrupMapel:manage.html.twig', array(
'entity' => $entity,
'new_form' => $new_form->createView(),
));
}

Related

Symfony 3 update Action

In my project, foreign key should hidden in the form type and have default value so the first id in the table refernced.
In the New Action all good but is in the update action that I block.
I've tried like tkis to give default value for my foreign key in update but It don't works, I have an error: Expected argument of type "AppBundle\Entity\Cursus", "string" given
public function editAction(Request $request, Etudiant $etud)
{
$deleteForm = $this->createDeleteForm($etud);
$editForm = $this->createForm('AppBundle\Form\EtudiantType', $etud);
$editForm->handleRequest($request);
$first = $this->getDoctrine()->getRepository(Cursus::class)->findOneBy([]);
$etud->setIdcursus($first);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('etudiant_edit');
}
return $this->render('etudiant/edit.html.twig', array(
'etudiant' => $etud,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
EDIT
Symfony 3.3.10
form Type
$builder->add('nom')
->add('prenom')
->add('adresse')
->add('matricule')
->add('domaine')
->add('idcursus', HiddenType::class);
The problem
The wrong is in my idcursus whom should hidden and have default value(the first id in cursus entity).

symfony2 + EntityType + queryBuilder and default top value/entry

I have an entity (Category) where the user can choice a parent (always Category) for the new/edit action where the link is the vocabolaryId field.
This is my CategoryType.
class CategoryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$vocId = $options['data']->getVocabularyId();
$builder
->add('name')
->add('vocabularyId',HiddenType::class,[
'data' => $vocId,
])
->add('description')
->add('weight',null,[
'label' => 'Posizione'
])
;
$builder->add('parent',EntityType::class,array(
'class' => 'AppBundle:Category',
'query_builder' => function (EntityRepository $er) use ($vocId) {
return $er->createQueryBuilder('c')
->where('c.vocabularyId = ?1')
->orderBy('c.name')
->setParameter(1,$vocId);
}
));
}
To get the list of all category that have the same vocabularyId I use the "query_builder" parameter.
When I submit the form to symfony without choice a parent (or with an empty table) it replies me with : " This value is not valid." (for the parent field).
How can I set a "null" parent ? I mean a category that have no parent.
EDIT:I have added "'required' => false," like say by Stephan Vierkant, but now I have another error: "Warning: spl_object_hash() expects parameter 1 to be object, string given"
this is my controller's newAction function:
/**
* Creates a new Category entity.
*
* #Route("/new", name="admin_category_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request, $vocId)
{
$category = new Category($vocId);
$form = $this->createForm('AppBundle\Form\CategoryType', $category);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
dump($category);
exit();
$em->persist($category);
$em->flush();
return $this->redirectToRoute('admin_category_show', array('vocId' => $vocId, 'id' => $category->getId()));
}
return $this->render('category/new.html.twig', array(
'category' => $category,
'form' => $form->createView(),
'vocId' => $vocId
));
}
Set required (docs) to false:
$builder->add('parent',EntityType::class,array(
'class' => 'AppBundle:Category',
'required' => false,
'query_builder' => function (EntityRepository $er) use ($vocId) {
return $er->createQueryBuilder('c')
->where('c.vocabularyId = ?1')
->orderBy('c.name')
->setParameter(1,$vocId);
}
));
You can set a placeholder (docs) if you don't want an empty option.

Symfony: use of query builder in a Form

I have a form that I am building using the FormBuilder:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('rosters', 'entity', array(
'class' => 'ReliefAppsPlatformBundle:Roster',
'property' => 'display',
'query_builder' => function(RosterRepository $r) use ($user) {
return $r->createQueryBuilder('r')
->leftJoin('r.members', 'm')
->addSelect('m')
->where('(m.rights = :adminRight or m.rights = :managerRight) and m.user = :user')
->setParameter('adminRight', RosterMember::ADMIN_LEVEL)
->setParameter('managerRight', RosterMember::MANAGER_LEVEL)
->setParameter('user', $user);
},
'required' => true,
'expanded' => true,
'multiple' => true
))
->add('save', 'submit')
;
}
As you can see I my QueryBuilder I use $user (the current user) as a parameter.
My controler looks like that:
public function createAction(Request $request, Event $event)
{
$alert = new RosterEvent;
$alert->setEvent($event);
$user = $this->getUser();
$form = $this->createForm(new RosterEventType(), $alert, $user);
$form->handleRequest($request);
if ($form->isValid()) { ....
My issue is that I need to pass the $user to the formbiulder. But I get "Catchable Fatal Error: Argument 3 passed to Symfony\Bundle\FrameworkBundle\Controller\Controller::createForm() must be of the type array, object given,..."
I know the problem is how I pass $user from the controller to the formbuilder. But I have no clue how to do that.
Any ideas?
As mentioned in the documentation, the third parameter ($options = array()) of method createForm need an array and not a object.
This line is wrong
$form = $this->createForm(new RosterEventType(), $alert, $user);
The $options parameter can be used for example like this
$form = $this->createForm(new TaskType(), $task, array(
'action' => $this->generateUrl('target_route'),
'method' => 'GET',
));
If you want pass a parameter to the form, you can try something like this
Controller
$form = $this->createForm(new RosterEventType($user), $alert);
Form
protected $user;
public function __construct (User $user)
{
$this->user = $user;
}
Hope it will help.
The third parameter of createForm is expecting an array of options so use this when creating the form:
$form = $this->createForm(new RosterEventType(), $alert, array('user'=>$user));
Then you will need to get your RosterEventType to allow the 'user' option to be provided. You can do this by overriding the setDefaultOptions function of your AbstractType and provided a default value for the option. For example you can add the following to your RosterEventType class:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'user' => false,
));
}
If you do this then you can access the user object in your buildForm function using $options['user'].

symfony2 Entity Object vs. integer crashes

I have defined a entity like :
/**
* #ORM\ManyToOne(targetEntity="Pr\UserBundle\Entity\Client")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
private $client_id;
.....
public function setClientId($clientId = null)
{
$this->client_id = $clientId;
return $this;
}
There are two controllers with which I can create a new db entry. the first one is "admin-only" where the admin can create a db entry with a client id of his choice:
->add('client_id', 'entity', array(
'data_class' => null,
'attr' => array(
'class' => 'selectstyle'),
'class' => 'PrUserBundle:Client',
'property' => 'name',
'required' => true,
'label' => 'staff.location',
'empty_value' => 'admin.customer_name',
'empty_data' => null
)
)
......
// Handling the form
$em = $this->getDoctrine()->getManager();
$saniType->setName($form->get('name')->getData());
$saniType->setClientId($form->get('client_id')->getData());
$saniType->setCreated(new \DateTime(date('Y-m-d H:m:s')));
$saniType->setCreatedBy($user->getUsername());
$em->persist($saniType);
$em->flush();
The second one is for the client itself, where he's not able to set a different client id. Therefor I just removed the form field "client_id" and replace it by the users->getClientId():
$saniType->setSpecialClientId($form->get('client_id')->getData());
When I add an entry as admin, it work fine. If I try to add one as "client", it crashes with following error message
Warning: spl_object_hash() expects parameter 1 to be object, integer given in /var/www/symfony/webprojekt/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 1389
I'm a newby in symfony, so I haven't got the strength to figure out what happens. I only knew that in the first case, admin will submit a object (entity). In the second (client) case, I set an integer as I get one by
$user = $this->container->get('security.context')->getToken()->getUser();
Is there a solution for it so that I can handle entity object AND given integers like it comes when the client add an entry?
You should change you relation defnition to:
/**
* #ORM\ManyToOne(targetEntity="Pr\UserBundle\Entity\Client")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
private $client;
.....
public function setClient($client = null)
{
$this->client = $client;
return $this;
}
Then in form:
->add('client', 'entity', array(
'data_class' => null,
'attr' => array('class' => 'selectstyle'),
'class' => 'PrUserBundle:Client',
'property' => 'name',
'required' => true,
'label' => 'staff.location',
'empty_value' => 'admin.customer_name',
'empty_data' => null
)
)
Handling the form:
form = $this->createForm(new SaniType(), $entity);
$form->handleRequest($request);
if ($form->isValid()) {
// perform some action...
return $this->redirect($this->generateUrl('some_success'));
}
More about handling form: http://symfony.com/doc/current/book/forms.html#handling-form-submissions
Also worth nothing:
for auto update properties like createdBy / updatedBy i would recommend you to use Doctrine Extension: https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/blameable.md
You don't have to know the client id. You have to set the Client himself.
/**
* #ORM\ManyToOne(targetEntity="Pr\UserBundle\Entity\Client")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
private $client;
.....
public function setClient(\Pr\UserBundle\Entity\Client $client = null)
{
$this->client = $client;
return $this;
}
I found a Solution:
Symfony2: spl_object_hash() expects parameter 1 to be object, string given in Doctrine
It's a workaround but it's ok for the moment.

passing data from controller to Type symfony2

if i show a field of type "entity" in my form, and i want to filter this entity type based on a argument I pass from the controller, how do i do that.. ?
//PlumeOptionsType.php
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('framePlume', 'entity', array(
'class' => 'DessinPlumeBundle:PhysicalPlume',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('pp')
->where("pp.profile = :profile")
->orderBy('pp.index', 'ASC')
->setParameter('profile', ????)
;
},
));
}
public function getName()
{
return 'plumeOptions';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Dessin\PlumeBundle\Entity\PlumeOptions',
'csrf_protection' => true,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'plumeOptions_item',
);
}
}
and inside the controller, i create the form :
i have that argument that i need to pass in my action code:
$profile_id = $this->getRequest()->getSession()->get('profile_id');
...
and then i create my form like this
$form = $this->createForm(new PlumeOptionsType(), $plumeOptions);
the $plumeOptions is just a class to persist. But it has a one-to-one relationship with another class called PhysicalPlume. Now, when i want to display the 'framePlume' in my code, i want to show a filtered PhysicalPlume entity.
You can pass parameters to the form class as follows:
//PlumeOptionsType.php
protected $profile;
public function __construct (Profile $profile)
{
$this->profile = $profile;
}
Then use it in the query_builder of your buildForm:
$profile = $this->profile;
$builder->add('framePlume', 'entity', array(
'class' => 'DessinPlumeBundle:PhysicalPlume',
'query_builder' => function(EntityRepository $er) use ($profile) {
return $er->createQueryBuilder('pp')
->where("pp.profile = :profile")
->orderBy('pp.index', 'ASC')
->setParameter('profile', $profile)
;
},
));
And finally in your controller:
// fetch $profile from DB
$form = $this->createForm(new PlumeOptionsType($profile), $plumeOptions);
You can use $plumeOptions to pass everything your argument, but you'll need to add a getDefaultOptions() in PlumeOptionsType to specify the default value for your option.
See for instance https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php to see what this method should look like.

Resources