symfony2 forms from entity - forms

Okay, so I'm using symfony2 and I'm trying to create an option box in this form based off another Entity...
So in my controller I have:
<?php
namespace Ecs\CrmBundle\Controller\Report;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Ecs\CrmBundle\Form\Report\TimeClockReportType;
class TimeClockReportController extends Controller
{
public function indexAction()
{
$request = $this->get('request');
$em = $this->getDoctrine()->getEntityManager();
$start = null;
$end = null;
$dateRangeForm = $this->createForm(new TimeClockReportType());
if ($request->getMethod() == 'POST')
{
$dateRangeForm->bindRequest($request);
$formData = $dateRangeForm->getData();
$start = $formData['dateRange']['startDate'];
$end = $formData['dateRange']['endDate'];
}
return $this->render('EcsCrmBundle:Reports:TimeClockReport.html.twig', array(
'start' => $start,
'end' => $end,
'form' => $dateRangeForm->createView(),
));
}
}
and my TimeClockReportType.php looks like:
<?php
namespace Ecs\CrmBundle\Form\Report;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Ecs\CrmBundle\Form\Parts\DateRangeType;
use Ecs\CrmBundle\Form\Parts\DepartmentSelectionType;
class TimeClockReportType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('dateRange', new DateRangeType())
->add('salesCompany', new DepartmentSelectionType(true));
}
public function getName()
{
return 'ecs_crmbundle_TimeClockReportType';
}
}
and my DepartmentSelectionType looks like:
<?php
namespace Ecs\CrmBundle\Form\Parts;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class DepartmentSelectionType extends AbstractType
{
private $canSeeAll = false;
public function __construct($canSeeAll = false)
{
$this->canSeeAll = $canSeeAll;
}
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('department', 'entity',
array(
'class' => "EcsAgentManagerBundle:EmployeeDepartment",
'required' => false,
'multiple' => true,
'expanded' => true,
'label' => "Department"))
;
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Ecs\AgentManagerBundle\Entity\EmployeeDepartment',
);
}
public function getName()
{
return 'ecs_crmbundle_departmentselectiontype';
}
}
The problem that i'm coming up with, is i'm getting just a blank white screen... But, if i remove the:
->add('salesCompany', new DepartmentSelectionType(true)) from the TimeClockReportType it works just fine... But I can't see any errors or why it doesn't work..

A blank page indicates a parse error / engine error has occurred. I would suggest altering your php.ini file to have display_errors on.
Be sure to restart your webserver after.

Related

Simple form in symfony2

I have a problem with a simple form. I have a class called JurisdictionUser() and my class form is JurisdictionUserNewType().
If I put the next code, its work fine:
$jurisdiction_user = new JurisdictionUser();
$form = $this->createFormBuilder($jurisdiction_user)
->add('name', 'text')
->add('email', 'text', array('required' => false))
->add('save', 'submit')
->getForm();
but, if I put the next code:
$jurisdiction_user = new JurisdictionUser();
$form = $this->createFormBuilder(new JurisdictionUserNewType(), $jurisdiction_user);
It give me the next error:
ContextErrorException: Catchable Fatal Error: Argument 2 passed to Symfony\Bundle\FrameworkBundle\Controller\Controller::createFormBuilder() must be of the type array, object given, called in /home/sierra/dev_env/iyc-open010/src/Radmas/BackofficeAdminBundle/Controller/UserAdminController.php on line 119 and defined in /home/sierra/dev_env/iyc-open010/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php line 175
I need help xD. My class JurisdictionUserNewType().
<?php
/**
* Created by PhpStorm.
* User: diego
* Date: 15/01/14
* Time: 16:21
*/
namespace Radmas\BackofficeAdminBundle\Form\Type;
use Radmas\BackofficeAdminBundle\Form\Transformer\CapitalToSmallLetterTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class JurisdictionUserNewType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new CapitalToSmallLetterTransformer();
$builder
->add('name', 'text');
$builder->add(
$builder->create('email', 'text', array('required' => false))
->addModelTransformer($transformer)
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Radmas\Open010Bundle\Document\JurisdictionUser'
));
}
public function getName()
{
return 'jurisdictionUserNew';
}
}
You should use
$this->createForm(new JurisdictionUserNewType(), $jurisdiction_user)
in controller, instead of createFormBuilder.

Embedding chained form to another form

In my application I have two bundles (UserBundle and LocationBundle), there is OneToOne association between them.
LocationFormType has chained country,state,city fields the form works fine independently but when I try to embed the form (LocationFormType) to UserRegistrationForm I don't have access to country object to retrieve related state of country.
Error: Call to a member function getCountry() on a non-object
I like to use the LocationFormType in both mode, embed to another form or independent, Could any body help me to fix my code
//LocationFormType
class LocationFormType extends AbstractType {
protected $em;
function __construct (EntityManager $em)
{
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('country', 'entity', array(
'empty_value' => '--Choose--',
'class' => 'AppLocationBundle:Country',
'query_builder' => function(EntityRepository $er)
{
return $er->createQueryBuilder('c')
->where('c.enabled = 1');
},
'label' => 'form.country',
'translation_domain' => 'AppLocationBundle'
));
$builder->addEventSubscriber(new LocationChainedFieldSubscriber($this->em));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\LocationBundle\Entity\Location'
));
}
public function getName()
{
return 'app_location_form';
}
}
Location Form Event Subscriber
//EventSubscriber
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormInterface;
use Doctrine\ORM\EntityManager;
use App\LocationBundle\Entity\Country;
use Doctrine\ORM\EntityRepository;
class LocationChainedFieldSubscriber implements EventSubscriberInterface {
protected $em;
function __construct (EntityManager $em)
{
$this->em = $em;
}
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SET_DATA => 'preSetData',
FormEvents::PRE_SUBMIT => 'preSubmit',
);
}
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
$location = $event->getData();
// Problem occurs here when try to get data, the event data are null
//How to handle data passed from parent form to child form
//Might have an empty account(when we insert a new country)
$country = $location->getCountry() ? $location->getCountry() : null;
$this->addElement($form, $country);
}
public function preSubmit(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
//The data is not yet hydrated into the entity.
$country = $this->em->getRepository('AppLocationBundle:Country')->find($data->getCountry());
$this->addElement($form, $country);
}
protected function addElement(FormInterface $form, Country $country = null)
{
$states = array();
if($country)
{
//fetch the states form specific a country
$repo = $this->em->getRepository('AppLocationBundle:State');
$states = $repo->findByCountry($country, array('name' => 'asc'));
}
//Add the state element
$form->add('state', 'entity', array(
'choices' => $states,
'empty_value' => '--Choose--',
'class' => 'AppLocationBundle:State',
'mapped' => false
));
}
}
Using the Form location as service
services:
app_location.form:
class: App\LocationBundle\Form\Type\LocationFormType
arguments: ['#doctrine.orm.entity_manager']
tags:
- { name: form.type, alias: app_location_form }
embed to user registration form
//UserRegistrationForm
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//other fields here
->add('name', 'text')
->add('location', 'app_location_form', array(
'data_class' => 'App\LocationBundle\Entity\Location',
'label' => 'form.location',
'translation_domain' => 'AppUserBundle'
));
public function getName()
{
return 'app_user_profile';
}
}
//UserRegistrationForm
$builder->add('location', 'collection', array('location' => new LocationFormType ()));

How to pass an array of entities from findAll() to a collection field of a form

I have a very basic form that allows me to create categories, which help to group resources. I want to extend the functionality past just creating a new one to applying a sort order to the categories as well. I'm pretty close to getting it, but I'm stuck on trying to pass the array of the Category entities to the form to allow me to display them.
I think my issue stems from not passing the right info into the form when it is created, but I can see the viewData of the categories I have that get passed to it when I inspect through xdebug.
My Controller:
<?php
class MyController extends Controller
{
public function resourcesAction(Request $request)
{
$category_repository = $this->getDoctrine()->getRepository('AppBundle:ResourceCategory');
$form_sort = $this->createForm('resource_category_sort', $category_repository->findAll());
return $this->render(
'AppBundle::resources.html.twig',
array(
'form_sort' => $form_sort->createView()
)
);
}
}
My Category Form:
<?php
namespace AppBundle\Form\Type\Admin;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ResourceCategoryFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('name', 'text', array('label' => 'Category Name:'))
->add('order', 'hidden')
->add('create', 'submit');
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$category = $event->getData();
$form = $event->getForm();
if ($category->getId() !== null) {
$form->remove('name')
->add('name', 'hidden');
}
});
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'AppBundle\Entity\ResourceCategory'
)
);
}
public function getName()
{
return 'resource_category';
}
}
My Collection of Categories Form:
<?php
namespace AppBundle\Form\Type\Admin;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ResourceCategorySortFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('categories', 'collection', array('type' => new ResourceCategoryFormType()))
->add('apply', 'submit');
}
public function getName()
{
return 'resource_category_sort';
}
}
You have to use an array with "categories" key :
<?php
class MyController extends Controller
{
public function resourcesAction(Request $request)
{
$category_repository = $this->getDoctrine()->getRepository('AppBundle:ResourceCategory');
$data = array();
$data["categories"] = $category_repository->findAll();
$form_sort = $this->createForm('resource_category_sort', $data);
return $this->render(
'AppBundle::resources.html.twig',
array(
'form_sort' => $form_sort->createView()
)
);
}
}

Symfony2: How call the repository of an entity in the FormType

I tried to call the repository of my entity Category in the class form of my entity BonCommande, but this error ocuured:
Notice: Undefined property: Application\VehiculeBundle\Form\BonCommandeType::$em in C:\wamp\www\Symfony_test\src\Application\VehiculeBundle\Form\BonCommandeType.php line 74
This is my code:
The class BonCommandeType.php:
namespace Application\VehiculeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Application\VehiculeBundle\Entity\Category;
class BonCommandeType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Name of the user
$builder->add('observation', 'text');
/* Add additional fields... */
$builder->add('save', 'submit');
// Add listeners
$builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
$builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
}
protected function addElements(FormInterface $form, Category $categorie = null) {
// Remove the submit button, we will place this at the end of the form later
$submit = $form->get('save');
$form->remove('save');
// Add the province element
$form->add('categorie', 'entity', array(
'data' => $categorie,
'empty_value' => '-- Choose --',
'class' => 'ApplicationVehiculeBundle:Category',
'property' => 'intitule',
'mapped' => false)
);
// Cities are empty, unless we actually supplied a province
$vehicules = array();
if ($categorie) {
// Fetch the cities from specified province
$repo = $this->em->getRepository('ApplicationVehiculeBundle:Vehicule');
$cities = $repo->findByCategory($categorie);
}
// Add the city element
$form->add('vehicule', 'entity', array(
'empty_value' => '-- Select a categorie first --',
'class' => 'ApplicationVehiculeBundle:Vehicule',
'choices' => $vehicules,
));
// Add submit button again, this time, it's back at the end of the form
$form->add($submit);
}
function onPreSubmit(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
// Note that the data is not yet hydrated into the entity.
$categorie = $this->em->getRepository('ApplicationVehiculeBundle:Category')->find($data['categorie']);
$this->addElements($form, $categorie);
}
function onPreSetData(FormEvent $event) {
$account = $event->getData();
$form = $event->getForm();
// We might have an empty account (when we insert a new account, for instance)
$categorie = $account->getVehicule() ? $account->getVehicule()->getCategorie() : null;
$this->addElements($form, $categorie);
}
...
}
This is the instruction that causes the error:
$categorie = $this->em->getRepository('ApplicationVehiculeBundle:Category')->find($data['categorie']);
FormComponent is an independent component and it doesn't provide any entityManager to use. You have to inject it or pass it by $options if you want to use it..
In your case it would be correct if you directly pass it to the type's __construct or pass by $options array or declare your type as a service and inject entity manager to it:
class BonCommandeType extends AbstractType
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
...
}
or
$this->createForm(TYPE, DATA, ['em' => $em]);
From your code I assume you are missing this:
//Somewhere at the begging of your BonCommandeType
protected $em;
...
public function __construct(EntityManager $em)
{
$this->em = $em;
}
Keep in mind that when you create a new form object you should use smth like :
BonCommandeType($this->getDoctrine()->getManager()) // if inside a controller

How do I pass a value to Form Builder in Symfony2?

I'm using a Form Builder to create a form for use in an application. In the form, the user needs to be able to select a list of events that they are associated with. However, I'm unable to figure out how exactly I can pass the user's ID to the form builder?
My code is like this at the moment:
EvType.php
<?php
// src/Acme/MembersBundle/Form/Type/EvType.php
// This is to handle forms for the Members Form
namespace Acme\MembersBundle\Form;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class EvType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$centre = $this->centre;
$builder->add('id', 'integer', array('required'=>false));
$builder->add('list','entity', array('class'=>'Acme\InstructorBundle\Entity\MapLists', 'property'=>'name',
'query_builder' => function(EntityRepository $br) {
return $br->createQueryBuilder('ml')
->where('ml.user = :user')
->setParameter('user','1' );
}));
$builder->add('eventHorse', 'text', array('required'=>false));
}
public function getName()
{
return 'ev';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\InstructorBundle\Entity\MapListCentreMembers',
'csrf_protection' => false,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'task_item',
));
}
}
->setParameter('user','1' ); is where I want to be able to pass the User's ID from the form. For now, I've statically assigned the user ID.
DefaultController.php
// User ID
$userid = $mem['userID'];
// Get Tests from Entity for Form use
$memberEV = $dm->getRepository('InstructorBundle:MapListMembers')->find($memberint);
// Generate Form to edit Tests & Achievements
$ev = $this->createForm( new EvType(), $memberEV);
you can simply pass a value in the __construct.
See below:
EvType.php
class EvType extends AbstractType
{
private $user;
public function __construct($user)
{
$this->user = $user;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$user = $this->user;
....
}
DefaultController.php
$ev = $this->createForm( new EvType($user), $memberEV);