Symfony checkbox for some entity - php

I have list developer, not all developer, developer who have some parameters by filter and I need create check box for this some developer and post developer in another action, in this action identification developer who have true checkbox, I try this but have null check develoepr
class SelectByIdentityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('id', 'entity', array(
'required' => false,
'class' => 'ArtelProfileBundle:Developer',
'property' => 'id',
'property_path' => '[id]', # in square brackets!
'multiple' => true,
'expanded' => true
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => null,
'csrf_protection' => false
));
}
/**
* #return string
*/
public function getName()
{
return 'select';
}
}
and action where I visible my developers
/**
* Finds and displays a Project entity.
*
* #Route("/{id}/show", name="admin_project_show")
* #Method({"GET", "POST"})
* #Template()
* #ParamConverter("entity", class="ArtelProfileBundle:Project")
*/
public function showAction($entity, Request $request)
{
//some logic
$developers = $profileRepository->findBySkillsAndTag($developer, $skill_form);
$form = $this
->createForm(
new SelectByIdentityType(),
$developers
)
->createView()
return array(
'entity' => $entity,
'form' => $form,
'developers' => $developers,
);
}
and if I check developer click SEND and then in the controller action which receives the POSTed data:
/**
* Send email for Developers.
*
* #Route("/{id}/send", name="admin_project_send_email")
* #Method({"GET", "POST"})
* #Template()
* #ParamConverter("entity", class="ArtelProfileBundle:Project")
*/
public function sendAction($entity, Request $request)
{
$em = $this->getDoctrine()->getManager();
$developer = $request->getSession()->get('developer');
$form = $this
->createForm(new SelectByIdentityType())
;
$form->bind($request);
if ($form->isValid()) {
$data = $form->getData();//$data['id'] I have 0
$ids = array();
foreach ($data['id'] as $developer) {
$ids[] = $entity->getId();
}
$request->getSession()->set('admin/foo_list/batch', $ids);
}
Why in $data['id'] I have 0 ??
and my template
{% for entity in developers %}
<tr>
<td>{{ form_widget(form.id[entity.id]) }}</td>
Any ideas ??

You can filter the entities displayed in an entity field by using the query_builder option. That way you can just normally render the whole form and you get a checkbox list of only the entities that your query returns. If you need to display it in a special way, you can override the form templates.
Unfortunately, as far as I know you can't use DQL or repository methods in the query_builder option. You have to write the query-builder code directly into the form definition.
An example:
$builder->add('id', 'entity', array(
'required' => false,
'class' => 'ArtelProfileBundle:Developer',
'multiple' => true,
'expanded' => true
'query_builder' => function($repo)
{
return $repo->createQueryBuilder('d')
->where('x = y');
}
));

Related

Symfony 3 ChoiceType - Attribute empty_data ignored

I have a problem with my search form. It is possible that my select contains nothing.
This is why I would like to display a default message when it is empty.
However when I set my 'empty_data' attribute, nothing happens, always my empty select.
My FormType :
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('organisation',ChoiceType::class,array(
'choices' => $options['distributeurs'],
'choice_label' => function ($value, $key, $index) {
return $value->getOrganisation();
},
'choice_value' => 'id',
'empty_data' => 'No distributor found'
));
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'distributeurs' => 'ProjectBundle\Entity\Organisation\Organisation',
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'projectbundle_organisation_search';
}
And at the level of the controller :
$distributeurs = $em->getRepository('ProjectBundle:Organisation\Organisation')->createQueryBuilder('a')
->where('a.id IN (:distributeurs)')->setParameter('distributeurs',$organisationDistriId)->getQuery()->execute();
$form = $this->createForm('ProjectBundle\Form\Organisation\OrganisationDistributeurType', null, array(
'distributeurs' => $distributeurs,
'action' => $this->generateUrl('admin_organisations_index'),
'method' => 'GET',
));
The form and information work correctly, there is just the 'empty_data' attribute that is not displayed.
The 'placeholder' attribute works but that's not what I want.
Do you have an idea ?
Thanks !
Try to post your code next time and not a picture because that is not clear.
In your Form Builder try to create the select in this way (Placeholder is implemented from version 2.6):
$builder->add('organisation', ChoiceType::class, array(
'placeholder' => 'Choose an option',
));

Symfony2 Form Option Resolution

I'm using the FOSUserBundle and I'm trying to customize a user registration form with an is_admin option. I'm at a loss as to why the option value is not passed from the createForm() function call to the buildForm() function.
Below is the corresponding code in the controller:
$has_admin_rights = $this->get('security.authorization_checker')
->isGranted('ROLE_SUPER_ADMIN');
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->createUser();
...
$form = $formFactory->createForm(
new RegistrationFormType(), $user, array('is_admin' => $has_admin_rights));
Below is the custom form class which should, in theory, resolve the is_admin option. However it seems like the option is not properly passed.
class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if($options['is_admin'] === true)
{
$builder->add('uniqueRole', 'choice', array(
'choices' => array('ROLE_ADMIN' => 'user.role.admin',
'ROLE_TEACHER' => 'user.role.teacher',
'ROLE_STUDENT' => 'user.role.student'),
'label' => 'form.label.role',
'expanded' => false,
'multiple' => false,
'mapped' => false
));
$builder->remove('plainPassword')->add('plainPassword', 'hidden', array('data' => 'defaultPwd'));
} else {
// Default value is indeed set,
// and options[is_admin] always equals to false
if (array_key_exists("is_admin", $options)){
echo 'Set!';
} else {
echo 'Not Set!';
}
}
$builder->add('save', 'submit', array('label' => 'actions.add'));
}
protected function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired(array(
'is_admin'));
$resolver->setDefaults(array(
'is_admin' => false,
'data_class' => 'VMB\UserBundle\Entity\User',
'intention' => 'registration',
));
}
// BC for SF < 2.7
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$this->configureOptions($resolver);
}
public function getParent()
{
return 'fos_user_registration';
}
public function getName()
{
return 'vmb_user_registration';
}
}
I've also tried passing the parameter to a constructor this way
$form = $formFactory->createForm(new RegistrationFormType($has_admin_rights), $user);
however the symfony2 appCache initializes the form object without the proper param value (which falls back to defined null default value).
What am I doing wrong?
I think it's just a matter of invoking the wrong service.
You obtained the instance of FormFactory through:
$formFactory = $this->get('fos_user.registration.form.factory');
but this is not Symfony's FormFactory. In the matter of fact if you look at it's source here, you will see this:
public function createForm()
{
return $this->formFactory->createNamed($this->name, $this->type, null, array('validation_groups' => $this->validationGroups));
}
Basically, createForm does not expect any arguments at all.
So, instead, you should use Symfony's own form.factory (source):
$has_admin_rights = $this->get('security.authorization_checker')->isGranted('ROLE_SUPER_ADMIN');
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->createUser();
$form = $formFactory
->createBuilder(new RegistrationFormType(), $user, array('is_admin' => $has_admin_rights))
->getForm();
Hope this helps...

Symfony 2 - Differents fields for search form than list

I have three entity for a project : Book, Author and Theme. For information, Author and Theme are linked with Book in Many to One/One to Many. A book has one or more author and one or more themes.
And I have generated crud about theses for basics functions (add, edit and delete) and default views/form.
But I need to do some functions search, three exactly:
Search Book with part of the Title
Search Book with one Author
Search Book with one or more Theme.
I coded the three functions and working good but I have a problem about the fields used in search forms.
The first one is correct, it show a input field where we put the title and the book list as result is correct but the two others …
Because of the relationship the field are drop list where the user choose a item and search it, the result is correct but I wish for the second to have an input field for search the author name and the last to display checkbox so I’ve made research but I can’t understand why in my forms type, I can’t change the kind of field I want.
Here my two Forms Type :
Search with one Author : I just want to display an input field and not a list but get error each time
<?php namespace Projet\BibliothequeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class BookByAuthorType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('authors')
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Projet\BibliothequeBundle\Entity\Book'
));
}
/**
* #return string
*/
public function getName()
{
return 'authors';
}
}
Search Book with one or more Theme : I tried to display chechbox by link the 'themes' array to result of checkbox but don't work too.
<?php namespace Projet\BibliothequeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class BookByThemeType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// $themes = array();
// $themes=$builder->add('themes');
$builder
->add('themes', 'choice', [
'choices' => 'themes',
'multiple' => true,
'expanded' => true
])
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Projet\BibliothequeBundle\Entity\Book'
));
}
/**
* #return string
*/
public function getName()
{
return 'themes';
}
}
UPDATE : My BookController functions maybe it's the origin of my problems.
// AUTHOR SEARCH FUNCTIONS
public function SearchByAuthorAction() {
$entity = new Book();
$form = $this->CreateSearchAuthorForm($entity);
return $this->render('ProjetBibliothequeBundle:Book:searchbyauthor.html.twig', array(
'form' => $form->createView(),
));
}
private function CreateSearchAuthorForm(Book $entity) {
$form = $this->createForm(new BookByAuthorType(), $entity, array(
'action' => $this->generateUrl('book_submit_search_by_author'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Search'));
return $form;
}
public function SubmitSearchByAuthorAction(Request $request) {
$entity = new Book();
$form = $this->CreateSearchAuthorForm($entity);
$form->handleRequest($request);
$author = $form->get('authors')->getData();
$repository = $this->getDoctrine()
->getEntityManager()
->getRepository('ProjetBibliothequeBundle:Book');
$Booklist = $repository->findByAuthor($author);
return $this->render('ProjetBibliothequeBundle:Book:resultbyauthor.html.twig',
array('Booklist' => $Booklist));
}
//THEME SEARCH FUNCTIONS
public function SearchByThemeAction() {
$entity = new Book();
$form = $this->CreateSearchThemeForm($entity);
return $this->render('ProjetBibliothequeBundle:Book:searchbytheme.html.twig', array(
'form' => $form->createView(),
));
}
private function CreateSearchThemeForm(Livre $entity) {
$entities = $this->getDoctrine()->getManager()->getRepository('ProjetBibliothequeBundle:Book')->findAll();
$form = $this->createForm(new BookByThemeType(), $entity, array(
'action' => $this->generateUrl('book_submit_search_by_theme'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Search'));
return $form;
}
public function SubmitSearchByThemeAction(Request $request) {
$entity = new Book();
$form = $this->CreateSearchThemeForm($entity);
$form->handleRequest($request);
$theme = $form->get('themes')->getData();
$repository = $this->getDoctrine()
->getEntityManager()
->getRepository('ProjetBibliothequeBundle:Book');
$Booklist = $repository->findByTheme($theme);
return $this->render('ProjetBibliothequeBundle:Book:resultbytheme.html.twig',
array('Booklist' => $Booklist));
}
There is no need to set data_class for GET operations. Just create a basic form, may be like this:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('themes', 'choice', [
'choices' => 'themes',
'multiple' => true,
'expanded' => true
])
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(['method' => 'GET', 'csrf_protection' => false]);
}
in your action catch values from URL, pass them to findBy method or manually build you query:
public function someAction(Request $request)
{
...
$form->createForm(new FORM_TYPE, null);
....
$filters = $request->query->get($form->getName());
$result = $entityManager->getRepository(REPOSITORY)->findBy($filters, $orderBy, $limit, $offset);
...
}

Save user's ID in database with Symfony 2.6

still getting to grips with Symfony so please excuse me if this is already asked. I don't quite understand how to send data to forms to be processed properly so am need of a bit of guidance.
My issue is i wish to save my logged in user's ID into the database when they are creating a new gecko (so that this gecko's profile shows for only this user logged in). I am using FOSUserBundle by the way.
I know i can get the current user's id by using something like $user = $this->getUser()->getId(); However, i would like to save this into the database.
createAction:
public function createAction(Request $request)
{
$entity = new Gecko();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('gecko_show', array('name' => $entity->getName())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
GeckoType:
<?php
namespace Breedr\GeckoBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class GeckoType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('aquisitionDate')
->add('morph')
->add('sex', 'choice', array(
'choices' => array(
'Male' => 'Male',
'Female' => 'Female'
)
))
->add('genetics')
->add('bio')
->add('bred', 'checkbox', array(
'required' => false
))
->add('hatchling', 'checkbox', array(
'required' => false
))
->add('clutch', 'text', array(
'data' => 0,
'required' => false
))
->add('imageFile', 'file', array(
'required' => false
))
->add('user_id', 'hidden', array(
'data' => $user,
))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Breedr\GeckoBundle\Entity\Gecko'
));
}
/**
* #return string
*/
public function getName()
{
return 'breedr_geckobundle_gecko';
}
}
I would really appreciate any help with this. I just can't understand how the data is used/sent. Thanks in advance :)
Andy
Firstly sorry if you know this, but you'll need correct relationships set up between your Gecko and User entities.
Note your #ORM annotation may be different from mine (or you could be using YAML or whatever). My use is:
use Doctrine\ORM\Mapping as ORM;
This should be in your Gecko entity
/**
* #ORM\ManyToOne(targetEntity="Your\NameSpace\Entity\User", inversedBy="geckos")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
This should be in your User entity
/**
* #ORM\OneToMany(targetEntity="Your\NameSpace\Entity\Gecko",mappedBy="user")
*/
protected $geckos;
Note you'll need to generate getters & setters etc.
To save your new Gecko:
$gecko = new Gecko();
$gecko->setUser($this->getUser());
$form = $this->createForm(new GeckoType(), $gecko);
$entityManager = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$form->submit($request);
if ($form->isValid()) {
$entityManager->persist($gecko);
$entityManager->flush();
// do something with success
} else {
// show errors by flash message or whatever
}
}
I'd suggest you read up on the symfony forms documentation & the databases & doctrine documentation as that has most of the information you need for getting started.

Creating works fine but Updating fails when using exactly same entity and form

Example below works fine when I try to create a new car in database. If I leave brands select box blank in the webform, I get "The Brand field is required" error after submitting which is perfectly fine and as expected.
Problem:
If I repeat exactly same steps like described above when trying to update a selected record, I should still get "The Brand field is required" error after submitting, instead I'm getting "ContextErrorException: Catchable Fatal Error: Argument 1 passed to Car\BrandBundle\Entity\Cars::setBrands() must be an instance of Car\BrandBundle\Entity\Brands, null given, called in .... line on public function setBrands(\Car\BrandBundle\Entity\Brands $brands)"
Any reason why or any solution?
CAR UPDATE CONTROLLER (DOESN'T WORK)
private function getForm($car, $id)
{
return $this->createForm(new CarsType(), $car,
array('action' => $this->generateUrl('cars_independent_update_process',
array('id' => $id))));
}
public function processAction(Request $request, $id)
{
$repo = $this->getDoctrine()->getRepository('CarBrandBundle:Cars');
$car = $repo->findOneBy(array('id' => $id));
if (! $car)
{
return new Response('There is no such car in database');
}
$form = $this->getForm($car, $id);
$form->handleRequest($request);
if ($form->isValid() !== true)
{
return $this->render('CarBrandBundle:Independent:cars_update.html.twig',
array('page' => 'Cars Update Independent', 'form' => $form->createView()));
}
exit('FINE');
}
CAR CREATE CONTROLLER (WORKS FINE)
class CarsCreateController extends Controller
{
private function getForm()
{
return $this->createForm(new CarsType(), new Cars(),
array('action' => $this->generateUrl('cars_independent_create_process')));
}
public function processAction(Request $request)
{
$form = $this->getForm();
$form->handleRequest($request);
if ($form->isValid() !== true)
{
return $this->render('CarBrandBundle:Independent:cars_update.html.twig',
array('page' => 'Cars Update Independent', 'form' => $form->createView()));
}
exit('FINE');
}
ENTITY
class Cars
{
/**
* #ORM\ManyToOne(targetEntity="Brands", inversedBy="cars")
* #ORM\JoinColumn(name="brands_id", referencedColumnName="id", nullable=false)
* #Assert\NotBlank(message="The Brand field is required.")
*/
protected $brands;
/**
* #param \Car\BrandBundle\Entity\Brands $brands
*/
public function setBrands(\Car\BrandBundle\Entity\Brands $brands)
{
$this->brands = $brands;
return $this;
}
/**
* #return \Car\BrandBundle\Entity\Brands
*/
public function getBrands()
{
return $this->brands;
}
}
FORM TYPE
class CarsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAction($options['action'])
->setMethod('POST')
->add('brands', 'entity',
array(
'error_bubbling' => true,
'class' => 'CarBrandBundle:Brands',
'property' => 'name',
'multiple' => false,
'expanded' => false,
'empty_value' => '',
'query_builder' => function (EntityRepository $repo)
{
return $repo->createQueryBuilder('b')
->orderBy('b.name', 'ASC');
}
))
->add('model', 'text', array('label' => 'Model', 'error_bubbling' => true))
->add('year', 'date', array('label' => 'Year', 'error_bubbling' => true))
->add('button', 'submit', array('label' => 'Submit'))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'Car\BrandBundle\Entity\Cars'));
}
public function getName()
{
return 'cars';
}
}
In your update version you don't transmit the id when you generate your route for the form action. Will be something like that :
private function getForm($car)
{
return $this->createForm(new CarsType(), $car,
array('action' => $this->generateUrl('cars_independent_update_process', array('id' => $car->getId()))));
}
Problem was related to Constraint so I added it to the class and it work fine now.
/**
* Class Cars
*
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
* #ORM\Table(name="cars", uniqueConstraints={#ORM\UniqueConstraint(columns={"model", "brands_id"})})
* #UniqueEntity(fields={"model","brands"}, message="The Model and the Brand combination already exists in database.")
*/
class Cars
{
/**
* #var object
* #ORM\ManyToOne(targetEntity="Brands", inversedBy="cars")
* #ORM\JoinColumn(name="brands_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
* #Assert\NotBlank(message="The Brand field is required.")
*/
protected $brands;

Categories