Doctrine - Get old value in onFlush event listener - symfony

I'm trying to implement a feature that let's the user specify his mutual status and select a another user, just like that one in Facebook.
My database schema is like:
UserInfo entity:
class UserInfo
{
/**
* #ORM\OneToOne(targetEntity="User", inversedBy="user_info")
*/
protected $user;
/**
* #ORM\Column(type="text", nullable=true)
* #Assert\NotBlank
*/
protected $status; //Value taken from a dropdown list
/**
* #ORM\OneToOne(targetEntity="User", inversedBy="relationship_with_table")
*/
protected $relationship_user;
}
User entity:
class User
{
/**
* #ORM\OneToOne(targetEntity="UserInfo", mappedBy ="user", cascade={"persist","remove"})
*/
protected $user_info;
/**
* #ORM\OneToOne(targetEntity="UserInfo", mappedBy="relationship_user")
*/
protected $relationship_with_table;
}
UserInfoType :
class UserInfoType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $option)
{
$builder
->add("birthday", "birthday")
->add("gender", "choice", array("choices" => array("0" => "Male", "1" => "Female")))
->add("status", "choice", array("choices" => array(
"Single" => "Single",
"In relationship" => "In relationship",
"Engaged" => "Engaged",
"Married" => "Married"
)))
->add("relationship_user", "thrace_select2_entity", array(
"class" => 'Zgh\FEBundle\Entity\User',
'label' => 'User',
'empty_value' => 'Select user',
"configs" => array(
"width" => '100%',
),
))
->add("city", "text")
->add("work", "text")
->add("facebook", "url")
->add("twitter", "url")
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
"data_class" => 'Zgh\FEBundle\Entity\UserInfo',
"cascade_validation" => true,
));
}
public function getName()
{
return "user_info";
}
}
Now here's the event listener, It checks the user status and change the other user one, It works as expected. But only has one flaw, If the user is married to (A) and then changed it to married to (B), The user (A) still gets the Married to and don't get reset.
All what i want to do is before attaching user relationship to (B), I want to retrieve (A) and reset it. How can this be done inside onFlush event.
class DoctrinePreUpdateHandler implements EventSubscriber
{
public function getSubscribedEvents()
{
return array(
"onFlush",
);
}
public function onFlush(OnFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
$updates = $uow->getScheduledEntityUpdates();
foreach ($updates as $entity) {
if($entity instanceof UserInfo){
$target_user_info = null;
if($entity->getStatus() == "Single"){
if($entity->getRelationshipUser() != null){
$target_user_info = $entity->getRelationshipUser()->getUserInfo();
$target_user_info->setStatus("Single");
$target_user_info->setRelationshipUser(null);
}
$entity->setRelationshipUser(null);
} else {
$target_user_info = $entity->getRelationshipUser()->getUserInfo();
$target_user_info->setStatus($entity->getStatus());
$target_user_info->setRelationshipUser($entity->getUser());
}
if($target_user_info != null){
$em->persist($target_user_info);
$uow->computeChangeSet($em->getClassMetadata(get_class($target_user_info)), $target_user_info);
}
}
}
}
}

Doctrine UoW has a method propertyChanged(...) that tracks changes to entity properties.
These changes are stored in the entityChangeSets-Property of the UoW.
I think it should be possible to call $uow->getEntityChangeSet($entity) which returns an array where keys are $entity's properties and values are [$oldValue, $newValue].
I'm not sure if you have to call computeChangeSet() for the old relationship user, but i hope you can figure this out and leave a comment?

Related

Merge form CollectionType with existing collection

I would need some help about management of CollectionType. In order to make my question as clear as possible, I will change my situation to fit the official Symfony documentation, with Tasks and Tags.
What I would like :
A existing task have alrady some tags assigned to it
I want to submit a list of tags with an additional field (value)
If the submitted tags are already assigned to the task->tags collection, I want to update them
It they are not, I want to add them to the collection with the submitted values
Existing tags, no part of the form, must be kept
Here is the problem :
All task tags are always overwritten by submitted data, including bedore the handleRequest method is called in the controller.
Therefore, I can't even compare the existing data using the repository, since this one already contains the collection sent by the form, even at the top of the update function in the controller.
Entity wize, this is a ManyToMany relation with an additional field (called value), so in reality, 2 OneToMany relations. Here are the code :
Entity "Task"
class Task
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\OneToMany(mappedBy: 'task', targetEntity: TaskTags::class, orphanRemoval: false, cascade: ['persist'])]
private Collection $TaskTags;
/**
* #return Collection<int, TaskTags>
*/
public function getTaskTags(): Collection
{
return $this->TaskTags;
}
public function addTaskTag(TaskTags $TaskTag): self
{
// I have voluntarily remove the presence condition during my tests
$this->TaskTags->add($TaskTag);
$TaskTag->setTask($this);
return $this;
}
public function removeTaskTag(TaskTags $TaskTag): self
{
if ($this->TaskTags->removeElement($TaskTag)) {
// set the owning side to null (unless already changed)
if ($TaskTag->getTask() === $this) {
$TaskTag->setTask(null);
}
}
return $this;
}
}
Entity "Tag"
class Tag
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\OneToMany(mappedBy: 'tag', targetEntity: TaskTags::class, orphanRemoval: false)]
private Collection $TaskTags;
/**
* #return Collection<int, TaskTags>
*/
public function getTaskTags(): Collection
{
return $this->TaskTags;
}
public function addTaskTag(TaskTags $TaskTag): self
{
$this->TaskTags->add($TaskTag);
$TaskTag->setTag($this);
return $this;
}
public function removeTaskTag(TaskTags $TaskTag): self
{
if ($this->TaskTags->removeElement($TaskTag)) {
// set the owning side to null (unless already changed)
if ($TaskTag->getTag() === $this) {
$TaskTag->setTag(null);
}
}
return $this;
}
}
Entity "TaskTags"
class TaskTags
{
#[ORM\Id]
#[ORM\ManyToOne(inversedBy: 'TaskTags')]
#[ORM\JoinColumn(nullable: false)]
private Task $task;
#[ORM\Id]
#[ORM\ManyToOne(inversedBy: 'TaskTags')]
#[ORM\JoinColumn(nullable: false)]
private Tag $tag;
// The addional field
#[ORM\Column(nullable: true)]
private ?int $value = null;
public function getTask(): ?Task
{
return $this->task;
}
public function setTask(?Task $task): self
{
if(null !== $task) {
$this->task = $task;
}
return $this;
}
public function getTag(): ?Tag
{
return $this->tag;
}
public function setTag(?Tag $tag): self
{
if(null !== $tag) {
$this->tag = $tag;
}
return $this;
}
public function getValue(): ?string
{
return $this->value;
}
public function setValue(?string $value): self
{
$this->value = $value;
return $this;
}
}
FormType "TaskFormType"
class TaskFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
...
->add('TaskTags', CollectionType::class, [
'by_reference' => false,
'entry_type' => TaskTagsFormType::class,
'entry_options' => ['label' => false],
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Task::class,
'csrf_protection' => false
]);
}
}
FormType "TaskTagsFormType"
class TaskTagsFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('task')
->add('tag')
->add('value')
;
}
Controller
#[Route('/tasks/edit/{id}/tags', name: 'app_edit_task')]
public function editasktags(Request $request, EntityManagerInterface $em, TaskTagsRepository $TaskTagsRepo): Response
{
...
// Create an ArrayCollection of the current tags assigned to the task
$task = $this->getTask();
// when displaying the form (method GET), this collection shows correctly the tags already assigned to the task
// when the form is submitted, it immediately becomes the collection sent by the form
$ExistingTaskTags = $TaskTagsRepo->findByTask($task);
$form = $this->createForm(TaskFormType::class, $task);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// here begins all I have tried ... I was trying to compare the value in the DB and in the form, but because of the repo being overwritten I can't
$task = $form->getData();
$SubmittedTaskTags = $userForm->getTaskTags();
$CalculatedTaskTags = new ArrayCollection();
foreach ($ExistingTaskTags as $ExistingTaskTag) {
foreach ($SubmittedTaskTags as $SubmittedTaskTag) {
if ($ExistingTaskTag->getTag()->getId() !== $SubmittedTaskTag->getTag()->getId()) {
// The existing tag is not the same as submitted, keeping it as it in a new collection
$CalculatedTaskTags->add($ExistingTaskTag);
} else {
// The submitted tag is equal to the one in DB, so adding the submitted one
$SubmittedTaskTag->setTask($task);
$CalculatedTaskTags->add($SubmittedTaskTag);
}
}
}
$em->persist($task);
$em->flush();
}
return $this->render('task/edittasktags.twig.html', [
'form' => $form,
'task' => $this->getTask()
]);
}
My main issue is that I am not able to get the existing data one the form has been submitted, in order to perform a "merge"
I have tried so many things.
One I did not, and I'd like to avoid : sending the existing collection as hidden fields.
I don't like this at all since if the data have been modified in the meantime, we are sending outdated data, which could be a mess in multi tab usage.
Thank you in advance for your help, I understand this topic is not that easy.
NB : the code I sent it not my real code / entity. I've re written according to the Symfony doc case, so there could be some typo here and there, apologize.
Solution found.
I added 'mapped' => false in the FormType.
And I was able to retrieve the form data using
$SubmittedTags = $form->get('TaskTags')->getData();
The repository was not overwritten by the submitted collection.

ManyToMany new value must be an array or an instance of \Traversable, "NULL" given

I have a ManyToMany relation in my Symfony 4.2.6 application and I would like for it to be possible to have this to be null.
So my first entity SpecialOffers is as follows :
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\SpecialOfferRepository")
*/
class SpecialOffer
{
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Neighbourhood", inversedBy="specialOffers")
*/
private $neighbourhood;
public function __construct()
{
$this->neighbourhood = new ArrayCollection();
}
/**
* #return Collection|Neighbourhood[]
*/
public function getNeighbourhood(): Collection
{
return $this->neighbourhood;
}
public function addNeighbourhood(Neighbourhood $neighbourhood): self
{
if (!$this->neighbourhood->contains($neighbourhood)) {
$this->neighbourhood[] = $neighbourhood;
}
return $this;
}
public function removeNeighbourhood(Neighbourhood $neighbourhood): self
{
if ($this->neighbourhood->contains($neighbourhood)) {
$this->neighbourhood->removeElement($neighbourhood);
}
return $this;
}
}
It is related to the neighbourhood class :
/**
* #ORM\Entity(repositoryClass="App\Repository\NeighbourhoodRepository")
*/
class Neighbourhood implements ResourceInterface
{
/**
* #ORM\ManyToMany(targetEntity="App\Entity\SpecialOffer", mappedBy="neighbourhood")
*/
private $specialOffers;
public function __construct()
{
$this->specialOffers = new ArrayCollection();
}
/**
* #return Collection|SpecialOffer[]
*/
public function getSpecialOffers(): Collection
{
return $this->specialOffers;
}
public function addSpecialOffer(SpecialOffer $specialOffer): self
{
if (!$this->specialOffers->contains($specialOffer)) {
$this->specialOffers[] = $specialOffer;
$specialOffer->addNeighbourhood($this);
}
return $this;
}
public function removeSpecialOffer(SpecialOffer $specialOffer): self
{
if ($this->specialOffers->contains($specialOffer)) {
$this->specialOffers->removeElement($specialOffer);
$specialOffer->removeNeighbourhood($this);
}
return $this;
}
}
And finally the form is
class SpecialOfferType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'neighbourhood',
EntityType::class,
[
'class' => Neighbourhood::class,
'label' => 'form.neighbourhood.label',
'translation_domain' => 'Default',
'required' => false,
'placeholder' => 'form.neighbourhood.all'
]
);
}
}
But when I don't select a specific neighbourhood for the Special offer in my form I get the following error :
Could not determine access type for property "neighbourhood" in class "App\Entity\SpecialOffer": The property "neighbourhood" in class "App\Entity\SpecialOffer" can be defined with the methods "addNeighbourhood()", "removeNeighbourhood()" but the new value must be an array or an instance of \Traversable, "NULL" given.
Is there anyway I can make it so that my special offer either contains and array of neighbourhoods or just null ?
I feel like I'm overlooking something really obvious, any help would be greatly appreciated
Test =>
$builder
->add(
'neighbourhood',
EntityType::class,
[
'class' => Neighbourhood::class,
'label' => 'form.neighbourhood.label',
'translation_domain' => 'Default',
'required' => false,
'multiple' => true,
'placeholder' => 'form.neighbourhood.all'
]
);
Since your fields on the entities are both many-to-many, thus expecting an array (or similar) and the form field is of EntityType, which will return one Entity of the expected type or null, I feel like there is some form of asymmetry.
I would consider using the CollectionType from the start or at least setting the multiple option on the form to true, so that the return value is an array.
Another option would be to add a DataTransformer to the form field, which turns null into an empty array and one entity into an array of one entity, and vice-versa.

Symfony Form with ManyToMany Mapping

Symfony 3.4 Doctrine 1.9
I have found a lot of articles about this. But nothing could resolve my
problem.
I have two Entities User and Company which are mapped as Many2Many.
Both Entities should be filled with a form submit. Therefor I have the following FormTypes:
CustomerRegistrationType
This includes the CollectionType with entry_type of CompanyFormType, which returns the Company:class
class CustomerRegistrationType extends AbstractType
{
private $translator;
private $session;
public function __construct(TranslatorInterface $translator,Session $session)
{
$this->session = $session;
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('mandant',HiddenType::class,array('data'=>
->add('newsletter',CheckboxType::class,array('label' => false,'required' => false))
->add('company', CollectionType::class, array('entry_type' => CompanyFormType::class, 'entry_options' => array('label' => false)));
}
CompanyFormType
class CompanyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('telephone', TextType::class,array('required' => false))
->add('company_name', TextType::class,array('label' => false,'required' => false))
->add('company_supplement', TextType::class,array('label' =>
->add('send_info', CheckboxType::class,array('label' => false,'required' => false))
->add('send_invoice', CheckboxType::class,array('label' => false,'required' => false))
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Company'));
}
}
Many2Many mapping
class User extends BaseUser
{
public function __construct()
{
parent::__construct();
$this->company = new ArrayCollection();
}
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Company",inversedBy="users")
* #ORM\JoinTable(name="user_comp_comp_user",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="company_id", referencedColumnName="id")}
* )
*/
protected $company;
public function getCompany()
{
return $this->company;
}
public function setCompany($company)
{
$this->company = $company;
return $this;
}
public function addCompany(Company $company)
{
if ($this->company->contains($company)) {
return;
}
$this->company[] = $company;
return $this;
}
public function removeCompany(Company $company)
{
if (!$this->company->contains($company)) {
return;
}
$this->company->removeElement($company);
return $this;
}
class Company
{
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* #var \Doctrine\Common\Collections\Collection|Company[]
* #ORM\ManyToMany(targetEntity="User",mappedBy="company")
*/
protected $users;
}
In the Controller I want to save all Data to the different Entities.
Therefor I do:
public function registerAction(Request $request)
{
$user = $this->userManager->createUser();
$form = $this->createForm(CustomerRegistrationType::class,$user);
$form->handleRequest($request);
$company = $user->getCompany();
$company->setSendInvoice(true);
$company->setSendInfo(true);
if ($form->isSubmitted()){
$user->addCompany($company);
$this->userManager->updateUser($user);
....
}
return $this->render('Registration/register.html.twig',[
'form' => $form->createView()
]);
}
I does not matter, which way I try, eachtime I get an error. In this example, the company data is empty. Other ways are in conflict with the ArrayCollection() of $this->company in User()
User {#907 ▼
#id: null
#company: ArrayCollection {#926 ▼
-elements: []
}
#groups: null
#mandant: null
#salutation: null
#first_name: null
#last_name: null
#fullname: null
#created: DateTime #1544539763 {#901 ▶}
#telephone: null
Update:
In Twig form I have no access to
{{ form_widget(form.company.company_name, {'attr': {'class': 'form-control'}})}}
Neither the property "company_name" nor one of the methods "company_name()", "getcompany_name()"/"iscompany_name()"/"hascompany_name()" or "__call()" exist and have public access in class "Symfony\Component\Form\FormView".
This comes up before form submit.
I found the solution here:
https://groups.google.com/forum/#!topic/symfony2/DjwwzOfUIuQ
So I used an array based form in the controller
$form = $this->createFormBuilder()
->add('user', CustomerRegistrationType::class, array(
'data_class' => 'AppBundle\Entity\User'
))
->add('company', CompanyFormType::class, array(
'data_class' => 'AppBundle\Entity\Company'
))
->getForm();
The different Objects can catched like this:
$form->handleRequest($request);
$user = $form->get('user')->getData();
$company = $form->get('company')->getData();
and then
if ($form->isSubmitted()){
...
$user->addCompany($company);
$this->userManager->updateUser($user);
}
That's it

How to persist an entity which contains properties displayed in a form as select list

I'm a newby on symfony.
I'm working on a project using symfony 2.7.6.
I have an object/entity "Trajet" which contains 2 properties(which are source of my headaches!!).
Theses 2 properties are VilleDepart and VilleArrivee (integers linked to my database with doctrine (ORM annotation in the object class))
In my form i want them to be displayed as a dropdown list. So i used a formbuilder with the two entity field type.
But when i try to persist the "Trajet" object in the controller (using entity manager), i get this an sql error (because it consider the two properties VilleDepart and VilleArrivee as entity instead of integer)...
I clearly see where the problem is... the sql query is
INSERT INTO trajet (traj_villedepart , traj_villearrivee) VALUES ({}, {})
Instead of
INSERT INTO trajet (traj_villedepart , traj_villearrivee) VALUES (1, 2)
For example
Here his my class trajet
class Trajet {
/**
* #ORM\Id #ORM\Column(name="idtrajet", type="integer")
* #ORM\GeneratedValue
*/
private $ID;
/**
* #ORM\Column(name="traj_idvilledepart", type="integer")
*/
private $VilleDepart;
/**
* #ORM\Column(name="traj_idvillearrivee", type="integer")
*/
private $VilleArrivee;
//Getters and setters....
}
Here is my abstract type of Trajet for the form
class TrajetType extends AbstractType
{
private $manager;
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('DescriptionVoiture', 'textarea')
->add('VilleDepart', 'entity', array(
'class' => 'MyBundle:Ville',
'property' => 'Nom',
'em' => 'pgsql',
'query_builder' => function(VilleRepository $er){
return $er->getVillesOrderByOrdre();
},
))
->add('VilleArrivee', 'entity', array(
'class' => 'MyBundle:Ville',
'property' => 'Nom',
'em' => 'pgsql',
'query_builder' => function(VilleRepository $er){
return $er->getVillesOrderByOrdre();
},
))
}
public function getName()
{
return 'trajet';
}
}
And finally my controller
class TrajetController extends Controller {
public function AddEditTrajetAction($idTrajet = null) {
$manager = $this->getDoctrine()->getManager('pgsql');
$trajet = new Trajet();
//Initialize the object $trajet with the get ID....
$form = $this->createForm(new TrajetType($manager), $trajet);
$request = $this->getRequest();
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isValid()) {
$manager->persist($trajet);
$manager->flush();
//Return to the view...
}
}
}
}
Please help! I become crazy!! thanks
I finally found the solution: Make an unidirectional oneToone relationship between Trajet and Ville I Modified the class Trajet like that
class Trajet {
/**
*#ORM\OneToOne(targetEntity="xxx\Entity\Ville")
*#ORM\JoinColumn(name="traj_idvilledepart", ReferencedColumnName="idville", nullable=false)
*/
private $VilleDepart;
//The same for VilleArrivee...
//Getters and setters....
}
And then in the controlleur
$manager->persist($trajet);
$manager->flush();
Will work easily

How can i remove a form item which is a oneToMany relation

I have two entities. Container and Schooltype. The entity container have a "oneToMany" relation to entity Schooltype.
Entity Container:
/**
* #ORM\OneToMany(targetEntity="App\MyBundle\Entity\SchoolType", mappedBy="container", cascade={"persist", "remove"})
*/
protected $schooltype;
Entity Schooltype:
/**
* #ORM\ManyToOne(targetEntity="App\MyBundle\Entity\Container", inversedBy="schooltype")
* #ORM\JoinColumn(name="container_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $container;
Now i create a form for container, so i can add one or many schooltypes. In my entity Container i modify the "removeSchooltype" method, it's look like.
Entity Container, remove method for schooltype:
public function removeSchooltype(\App\MyBundle\Entity\SchoolType $schooltype)
{
$this->schooltype->removeElement($schooltype);
$schooltype->setContainer(null);
}
Form ContainerType:
->add('schooltype', 'entity', array(
'class' => 'AppMyBundle:Schooltype',
'choices' => $schoolTypes,
'label' => 'msg.schoolType',
'translation_domain' => 'messages',
'multiple' => true,
'expanded' => false)
)
I try to handle the store process in my controller.
Container controller, edit method:
$object = new Container();
// Exists any object?
if (!$object) {
$this->get('session')->getFlashBag()->add('danger', $this->get('translator')->trans('notfound'));
return $this->redirect($this->generateUrl('app_container_list'));
}
$form = $this->createForm($this->get('form.type.container'), $object)->add('save', 'submit', array('label' => 'save', 'translation_domain' => 'messages', 'attr' => array('class' => 'btn btn-primary')));
$form->handleRequest($request);
// Check if form isValid
if ($form->isValid()) {
// Store object
$em = $this->getDoctrine()->getManager();
$em->persist($object);
// Flush statements
$em->flush();
$em->clear();
$this->get('session')->getFlashBag()->add('info', $this->get('translator')->trans('objectEdited', array()));
return $this->redirect($this->generateUrl('app_container_list'));
}
return $this->render('AppMyBundle:Container:edit.html.twig', array("form" => $form->createView()));
Everything works fine, i can add one or many schooltypes in my container and this was saved successfull. But if i remove a schooltype from selectbox in form and post my form the relation between container and schooltype will not be removed, have someone a hint why this happens?
1 Country to N League. Example below shows you how things are done. Just apply to yours. If you want the full CRUD example for 1 to N relationships, it is here.
Country
class Country
{
protected $id;
/**
* #ORM\OneToMany(
* targetEntity="League",
* mappedBy="country",
* cascade={"persist", "remove"}
* )
*/
protected $league;
public function __construct()
{
$this->league = new ArrayCollection();
}
public function addLeague(League $league)
{
$this->league[] = $league;
return $this;
}
public function removeLeague(League $league)
{
$this->league->removeElement($league);
}
public function getLeague()
{
return $this->league;
}
}
League
class League
{
/**
* #ORM\ManyToOne(
* targetEntity="Country",
* inversedBy="league"
* )
* #ORM\JoinColumn(
* name="country_id",
* referencedColumnName="id",
* onDelete="CASCADE",
* nullable=false
* )
*/
protected $country;
public function setCountry(Country $country)
{
$this->country = $country;
return $this;
}
public function getCountry()
{
return $this->country;
}
}
LeagueType
class LeagueType extends AbstractType
{
private $country;
public function __construct()
{
$this->country = [
'class' => 'FootballFrontendBundle:Country',
'property' => 'name',
'multiple' => false,
'expanded' => false,
'required' => false,
'empty_value' => '',
'query_builder' => function (EntityRepository $repo)
{
return $repo->createQueryBuilder('c')->orderBy('c.name', 'ASC');
}
];
}
public function buildForm(FormBuilderInterface $builder, array $options = [])
{
$builder
->setMethod($options['method'])
->setAction($options['action'])
->add('whatever properties you have in your entitiy')
->add('country', 'entity', $this->country);
}
public function getName()
{
return 'league';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
['data_class' => 'Football\FrontendBundle\Entity\League']
);
}
}
Controller delete/remove method
/**
* Deletes country.
*
* #param int $id
*
* #Route("/delete/{id}", requirements={"id"="\d+"})
* #Method({"GET"})
*
* #return RedirectResponse|Response
* #throws LeagueException
*/
public function deleteAction($id)
{
try {
$em = $this->getDoctrine()->getEntityManager();
$repo = $em->getRepository('FootballFrontendBundle:League');
$league = $repo->findOneByIdAsObject($id);
if (!$league instanceof League) {
throw new LeagueException(sprintf('League read: league [%s] cannot be found.', $id));
}
$em->remove($league);
$em->flush();
} catch (DBALException $e) {
$message = sprintf('DBALException [%s]: %s', $e->getCode(), $e->getMessage());
} catch (ORMException $e) {
$message = sprintf('ORMException [%s]: %s', $e->getCode(), $e->getMessage());
} catch (Exception $e) {
$message = sprintf('Exception [%s]: %s', $e->getCode(), $e->getMessage());
}
if (isset($message)) {
throw new LeagueException($message);
}
return $this->redirect($this->generateUrl('where ever you want'));
}

Resources