I have a M2M relationship, but when I create an item the relationship is not saved and I can't find where's the problem.
The Model:
class Serie
{
/**
* #ORM\ManyToMany(targetEntity="Magazine", mappedBy="series")
* */
protected $magazines;
/**
* Constructor
*/
public function __construct()
{
$this->magazines = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add magazines
*
* #param MyList\DBBundle\Entity\Magazine $magazines
* #return Serie
*/
public function addMagazine(\MyList\DBBundle\Entity\Magazine $magazines)
{
$this->magazines[] = $magazines;
return $this;
}
/**
* Remove magazines
*
* #param MyList\DBBundle\Entity\Magazine $magazines
*/
public function removeMagazine(\MyList\DBBundle\Entity\Magazine $magazines)
{
$this->magazines->removeElement($magazines);
}
/**
* Get magazines
*
* #return Doctrine\Common\Collections\Collection
*/
public function getMagazines()
{
return $this->magazines;
}
}
The Magazine class:
class Magazine
{
/**
* #ORM\ManyToMany(targetEntity="Serie" , inversedBy="magazines")
* #ORM\JoinTable(name="magazines_series")
* */
protected $series;
public function __construct()
{
$this->series = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add series
*
* #param MyList\DBBundle\Entity\Serie $series
* #return Magazine
*/
public function addSerie(\MyList\DBBundle\Entity\Serie $serie)
{
$serie->addMagazine($this);
$this->series[] = $serie;
return $this;
}
/**
* Remove series
*
* #param MyList\DBBundle\Entity\Serie $series
*/
public function removeSerie(\MyList\DBBundle\Entity\Serie $series)
{
$this->series->removeElement($series);
}
/**
* Get series
*
* #return Doctrine\Common\Collections\Collection
*/
public function getSeries()
{
return $this->series;
}
}
The Controller
class SerieController extends Controller
{
public function newAction()
{
$entity = new Serie();
$form = $this->createForm(new SerieType(), $entity);
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
/**
* Creates a new Serie entity.
*
* #Route("/create", name="serie_create")
* #Method("POST")
* #Template("DBBundle:Serie:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Serie();
$form = $this->createForm(new SerieType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('serie_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
}
And the Form:
class SerieType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('start')
->add('end')
->add('type')
->add('status')
->add('magazines','entity',array(
'class' => 'DBBundle:Magazine',
'multiple' => true,
'property' => 'name'
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MyList\DBBundle\Entity\Serie'
));
}
public function getName()
{
return 'mylist_dbbundle_serietype';
}
}
I know there are some questions about this (i.e. Symfony2-Doctrine: ManyToMany relation is not saved to database), but none of them have solved my problem.
This is because you never persist() the magazine, the form added it already to the entity but Doctrine still needs to manage it.
add this in the if ($form->isValid()):
...
$magazines = $entity->getMagazines();
foreach($magazines as $magazine){
$em->persist($magazine);
}
...
$em->flush();
Related
I am developing a web app on Symfony. I have 2 entities that is question about, "Line" and "Dosier". So, 1 dosier can have many lines.
Now I'm implementing the CRUD for the Line entity, so Line entity has a "dropdown" with all Dosiers from DataBase.
The problem is that in dropdown are all dosiers from any users, but I need in this dropdown to have just options that has user_id = currentUser_id.
So, my controller action :
/**
* #Route("/add-line", name="addLine")
*/
public function createLineAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$user = $this->getUser();
$line = new Line();
$form = $this->createForm(LineType::class, $line);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$em->persist($line);
$em->flush();
return $this->redirectToRoute('homepage');
}
return $this->render('AppBundle:default:formLines.html.twig', array(
'form' => $form->createView(),
));
}//create dossier action
My LineType (form builder)
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class LineType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')->add('dosier')
->add('dosier', EntityType::class, array(
'class' => 'AppBundle:Dosier',
'query_builder' => function($repo) {
return $repo->dosiersOfCurrentUser();
},
'choice_label' => 'name',
))
->add('save', SubmitType::class, array(
'label' => 'Save',
'attr'=> array('class'=>'btn btn-success submitButton')
)
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Line'
));
}
public function getBlockPrefix()
{
return 'appbundle_line';
}
}
My Line.php (entity)
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Line
*
* #ORM\Table(name="line")
* #ORM\Entity(repositoryClass="AppBundle\Repository\LineRepository")
*/
class Line
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Dosier", inversedBy="lines")
* #ORM\JoinColumn(name="dosier_id", referencedColumnName="id")
*/
private $dosier;
/**
* #ORM\OneToMany(targetEntity="Loan", mappedBy="line")
*/
private $loans;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
public function __construct()
{
$this->loans = new ArrayCollection();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Line
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Add loan
*
* #param \AppBundle\Entity\Loan $loan
*
* #return Line
*/
public function addLoan(\AppBundle\Entity\Loan $loan)
{
$this->loans[] = $loan;
return $this;
}
/**
* Remove loan
*
* #param \AppBundle\Entity\Loan $loan
*/
public function removeLoan(\AppBundle\Entity\Loan $loan)
{
$this->loans->removeElement($loan);
}
/**
* Get loans
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getLoans()
{
return $this->loans;
}
/**
* Set dosier
*
* #param \AppBundle\Entity\Dosier $dosier
*
* #return Line
*/
public function setDosier(\AppBundle\Entity\Dosier $dosier = null)
{
$this->dosier = $dosier;
return $this;
}
/**
* Get dosier
*
* #return \AppBundle\Entity\Dosier
*/
public function getDosier()
{
return $this->dosier;
}
}
and my repository : DosierRepository.php
<?php
namespace AppBundle\Repository;
use Doctrine\ORM\EntityRepository;
class DosierRepository extends \Doctrine\ORM\EntityRepository
{
public function dosiersOfCurrentUser() {
return $this->createQueryBuilder('dosier')
->where('dosier.userId = 1 ')
->orderBy('dosier.name', 'DESC');
}
}
How can I get the current user, or at least the current user id, to make a query like ... select from Dosier where dosier.user_id = $???
In controller where you are buiding your form you need pass the user object to your form type
$tokenStorage = $this->get('security.token_storage');
$form = $this->createForm(new LineType($tokenStorage), $line);
//... other stuff
Now in your form type recieve this tokenStorage object and retrieve user object and pass to your repo function
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
//.. other use statements
class LineType extends AbstractType
{
private $user;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->user = $tokenStorage->getToken()->getUser();
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$userId = $this->user->getId();
$builder
->add('name')->add('dosier')
->add('dosier', EntityType::class, array(
'class' => 'AppBundle:Dosier',
'query_builder' => function($repo) use($userId) {
return $repo->dosiersOfCurrentUser($userId);
},
'choice_label' => 'name',
))
->add('save', SubmitType::class, array(
'label' => 'Save',
'attr'=> array('class'=>'btn btn-success submitButton')
)
);
}
}
In repo apply your filter
class DosierRepository extends \Doctrine\ORM\EntityRepository
{
public function dosiersOfCurrentUser($userId) {
return $this->createQueryBuilder('dosier')
->where('dosier.userId = :userId ')
->setParameter('userId',$userId)
->orderBy('dosier.name', 'DESC');
}
}
I started project with predefined database structure and generated Entities from database structure using commands from console. I am creating bus company. Bus can have many amenities (i.e. Many buses can have many amenities).
I have a ManyToMany table and for some reason data inside that table is not saving. Other form data is saved in other table but this one still remains empty.
Does someone knows where is the problem?
Here is the code:
BusVehicles.php
/**
* Many Buses have Many Amenities.
* #ORM\ManyToMany(targetEntity="BusVehicles", mappedBy="bus_amenities")
* #ORM\JoinTable(
* name="bus_amenities",
* joinColumns={
* #ORM\JoinColumn(name="bus_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="amenities_id", referencedColumnName="id")
* }
* )
*/
private $amenities;
/**
* Add items
*
* #param \AdminBundle\Entity\Amenities $amenities
*/
public function addAmenities(Amenities $amenities)
{
if ($this->amenities->contains($amenities)) {
return;
}
$this->amenities->add($amenities);
$amenities->addBusAmenities($this);
}
/**
* Remove amenities
*
* #param \AdminBundle\Entity\Amenities $amenities
*/
public function removeAmenities(Amenities $amenities)
{
if (!$this->amenities->contains($amenities)) {
return;
}
$this->amenities->removeElement($amenities);
$amenities->removeBusAmenities($this);
}
/**
* Get Amenities
*
* #return ArrayCollection
*/
public function getAmenities()
{
return $this->amenities;
}
// ...
public function __construct() {
$this->amenities = new ArrayCollection();
}
}
Amenities.php
/**
* #var ArrayCollection
*
* #ORM\ManyToMany(targetEntity="BusVehicles", mappedBy="amenities")
*/
private $bus_amenities;
public function __construct() {
$this->bus_amenities = new ArrayCollection();
}
/**
* Get bus amenities
*
* #return ArrayCollection
*/
public function getBusAmenities()
{
return $this->bus_amenities;
}
/**
* Add bus amenities
*
* #param \AdminBundle\Entity\BusVehicles
*/
public function addBusAmenities(BusVehicles $amenities)
{
if ($this->bus_amenities->contains($amenities)) {
return;
}
$this->bus_amenities->add($amenities);
$amenities->addAmenities($this);
}
/**
* Remove bus amenities
*
* #param \AdminBundle\Entity\BusVehicles
*/
public function removeBusAmenities(BusVehicles $amenities)
{
if (!$this->bus_amenities->contains($amenities)) {
return;
}
$this->bus_amenities->removeElement($amenities);
$amenities->removeAmenities($this);
}
Controller:
class BusController extends Controller
{
/**
* #Template
*/
public function addAction(Request $request)
{
$bus = new BusVehicles();
$form = $this->createForm(BusVehiclesType::class, $bus);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
/* $amenities = $em->getAmenities();
foreach($amenities as $amenitie){
$em->persist($amenitie);
}*/
$em->persist($bus);
$em->flush();
// Adding flash message to our user
$request->getSession()
->getFlashBag()
->add('success', 'New vehicle successfully added');
// return $this->redirectToRoute('bus_add');
}
return [
'form' => $form->createView(),
];
}
}
EDIT 1: Added form
class BusVehiclesType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('licencePlate')
->add('manufacturer')
->add('company', EntityType::class, array(
'class' => 'AdminBundle:Companies',
'choice_label' => 'name',
))
->add('busType', EntityType::class, array(
'class' => 'AdminBundle:BusTypes',
'choice_label' => 'type',
))
->add('emissionClass', EntityType::class, array(
'class' => 'AdminBundle:BusEmissionClasses',
'choice_label' => 'name',
))
->add('fuelType', EntityType::class, array(
'class' => 'AdminBundle:BusFuelTypes',
'choice_label' => 'fuel_type',
))
->add('amenities', EntityType::class, array(
'class' => 'AdminBundle:Amenities',
'choice_label' => 'name',
'multiple' => true,
));
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AdminBundle\Entity\BusVehicles'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'adminbundle_busvehicles';
}
}
I think the problem is in your BusVehicles.php, Check relation and change as per below:
/**
* Many Buses have Many Amenities.
* #ORM\ManyToMany(targetEntity="Amenities", inversedBy="bus_amenities", cascade={"persist"})
*
*/
private $amenities;
And in Aminities Entity change as per below:
/**
* #var ArrayCollection
*
* #ORM\ManyToMany(targetEntity="BusVehicles", mappedBy="amenities", cascade={"persist"})
*/
private $bus_amenities;
I am using this custom form generated by console crud generator:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SubtaskType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name')->add('description') ;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Subtask'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_subtask';
}
}
After generating the crud I added a bidirectional association between Task and Subtask, and I modified the controller accordingly. So when I add a Subtask it should always be added to the Task that is in the url. Here is how it looks like with routes in annotations:
/**
* Subtask controller.
*
* #Route("/task/{taskId}/subtask")
*/
class SubtaskController extends Controller
{
.
.
.
/**
* Creates a new subtask entity.
*
* #Route("/new", name="subtask_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request, $taskId)
{
$subtask = new Subtask();
$form = $this->createForm('AppBundle\Form\SubtaskType', $subtask);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($subtask);
$em->flush($subtask);
return $this->redirectToRoute('subtask_show', array('id' => $subtask->getId(), 'taskId' => $taskId));
}
return $this->render('subtask/new.html.twig', array(
'subtask' => $subtask,
'form' => $form->createView(),
'taskId' => $taskId
));
}
.
.
.
}
At this moment This code inserts a row in the subtask table successfully with a null value for task_id (the foreign key for task).
How can I adapt this code so that it inserts the right task_id?
Here is the work around that I found:
I added manually this method in the Subtask Entity
/**
* Set task
*
* #param Task $task
*
* #return Subtask
*/
public function setTask($task)
{
$this->task = $task;
return $this;
}
And than I modified the newAction method in this way:
/**
* Creates a new subtask entity.
*
* #Route("/new", name="subtask_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request, $taskId)
{
$subtask = new Subtask();
$em = $this->getDoctrine()->getManager();
$task = $em->getReference('AppBundle\Entity\Task', $taskId);
$subtask->setTask($task);
$form = $this->createForm('AppBundle\Form\SubtaskType', $subtask);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($subtask);
$em->flush($subtask);
return $this->redirectToRoute('subtask_show', array('id' => $subtask->getId(), 'taskId' => $taskId));
}
return $this->render('subtask/new.html.twig', array(
'subtask' => $subtask,
'form' => $form->createView(),
'taskId' => $taskId
));
}
This gives me the expected result.
Any better way to achieve this?
I have a problem with Symfony2, I want to make a tag system but I can not manage to do I tried a lot but there are a lot of errors.
please can you help me and thank you in advance
the last error display :
Catchable Fatal Error: Argument 1 passed to Project\RmBundle\Entity\Posts::setTags() must be an instance of Project\RmBundle\Entity\Tags, string given, called in C:\wamp\www\Test\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php on line 438 and defined in C:\wamp\www\Test\src\Project\RmBundle\Entity\Posts.php line 390
Posts.php
class Posts{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var ArrayCollection $tags
*
* #ORM\ManyToMany(targetEntity="Project\RmBundle\Entity\Tags", inversedBy="posts")
*/
private $tags;
/**
* Constructor
*/
public function __construct()
{
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add tags
*
* #param \Portfolio\GeneralBundle\Entity\Tags $tags
* #return Article
*/
public function addTag(\Project\RmBundle\Entity\Tags $tags)
{
$this->tags[] = $tags;
return $this;
}
/**
* Remove tags
*
* #param \Project\RmBundle\Entity\Tags $tags
*/
public function removeTag(\Project\RmBundle\Entity\Tags $tags)
{
$this->tags->removeElement($tags);
}
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
/**
* Set tags
*
* #param \Project\RmBundle\Entity\Tags $tags
* #return Tags
*/
public function setTags(\Project\RmBundle\Entity\Tags $tags)
{
$this->tags[] = $tags;
return $this;
}}
and I have 2 FormType
PostsType.php
class PostsType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tags', 'text');
}}
TagsType.php
class TagsType extends AbstractType{
private $om;
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new StringToTagsTransformer($this->om);
$builder->addModelTransformer($transformer);
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Project\RmBundle\Entity\Tags'
));
}
public function getName()
{
return 'tags';}}
and i create a transform for that
class StringToTagsTransformer implements DataTransformerInterface{
private $om;
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
public function reverseTransform($ftags)
{
$tags = new ArrayCollection();
$tag = strtok($ftags, ",");
while($tag !== false) {
$itag = new Tags();
$itag->setName($tag);
if(!$tags->contains($itag))
$tags[] = $itag;
$tag = strtok(",");
}
return $tags;
}
public function transform($tags)
{
$ftags = "";
if($tags != null) {
foreach($tags as $tag)
$ftags = $ftags.','.$tag->getName();
}
return $ftags;}}
and finally my controller
PostsController.php
public function addBlogAction(Request $request){
$em = $this->getDoctrine()->getManager();
$posts = new Posts();
$form = $this->createForm(new PostsType, $posts, array(
'action' => $this->generateUrl('project_add_post'),
'method' => 'POST'
));
$em->getRepository('ProjectRmBundle:Tags')->filter($posts->getTags());
if('POST' == $request->getMethod()){
$form->handleRequest($request);
if ($form->isValid()) {
foreach($posts->getTags() as $tag){
$em->persist($tag);
}
}
$em->persist($posts);
$em->flush();
return $this->redirect($this->generateUrl('project_posts'));
}
}
return $this->render('ProjectRmBundle:Posts:add.html.twig', array('form'=>$form->createView())); }
In your PostsType you've defined the tags field as having type text. You want it to use your TagsType, so you should do this:
class PostsType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tags', 'tags');
}}
That is assuming you've declared it as a service.
Update:
You need to put the text field in TagsType. You would do something like this:
class TagsType extends AbstractType{
...
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$builder
->add('name', 'text');
}
...
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm new of Symfony and php, and I'm trying to understand, without outcome, the array collection.
Now I have two entity, Mission and User, in relation ManytoMany. I have a form to create new Missions and a form to create new User.
Now I have to create a "modifyMissionAction" that allows me to set the Users for that missions, but I didn't understand how to do it.
I read the documentation here but it doesn't help. How could I do?
Thank you
This is my User Entity is:
abstract class User extends BaseUser
{
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*
* #ORM\ManyToMany(targetEntity="Acme\ManagementBundle\Entity\Mission", inversedBy="users", orphanRemoval=true)
* #ORM\JoinTable(name="user_mission")
*/
private $missions;
/**
* Add missions
*
* #param \Acme\ManagementBundle\Entity\Mission $missions
* #return User
*/
public function addMission(\Acme\ManagementBundle\Entity\Mission $missions)
{
$this->missions[] = $missions;
return $this;
}
//...
And my Mission Entity:
<?php
namespace Acme\ManagementBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* #ORM\Entity
*/
class Mission {
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #var integer
*/
protected $id;
/**
* #ORM\Column(type="string", length=60)
* #var String
*/
protected $name;
/**
* #ORM\Column(type="string", length=600)
* #var String
*/
protected $description;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*
* #ORM\ManyToMany(targetEntity="Acme\ManagementBundle\Entity\User", mappedBy="missions", cascade={"all"}, orphanRemoval=true)
*/
private $users;
public function __construct(){
$this -> users = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Mission
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return Mission
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Add users
*
* #param \Acme\ManagementBundle\Entity\User $users
* #return Mission
*/
public function addUser(\Acme\ManagementBundle\Entity\User $users)
{
$this->users[] = $users;
return $this;
}
/**
* Remove users
*
* #param \Acme\ManagementBundle\Entity\User $users
*/
public function removeUser(\Acme\ManagementBundle\Entity\User $users)
{
$this->users->removeElement($users);
}
/**
* Get users
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
public function __toString()
{
return $this->name;
}
}
first of all don't forget to add __constructor for both of classes and init ArrayCollection:
//src/WebHQ/NewBundle/Entity/Mission.php
//...
public function __construct()
{
$this->users = new ArrayCollection();
}
//...
I assume that you want to add controller action witch allows you to relate user object or objects to mission object. Please read embbed forms part of Symfony book
Then create your Action. Most important is to add form element, with is embedded form of users entity:
// src/WebHQ/NewBundle/Controller/MissionController.php
//...
public function newAction(Request $request)
{
$object = new \WebHQ\NewBundle\Entity\Mission();
$form = $this->createFormBuilder($object)
->add('name', 'text')
//...
// Users objects embed form
->add('users', 'user')
//...
->add('save', 'submit')
->getForm();
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($object);
$em->flush();
return $this->redirect($this->generateUrl('web_hq_new_mission_index'));
}
}
return $this->render('WebHQNewBundle:Mission:new.html.twig', array(
'form' => $form->createView(),
//...
));
}
public function editAction($id, Request $request)
{
$object = $this->getDoctrine()
->getRepository('WebHQNewBundle:Mission')
->find($id);
$form = $this->createFormBuilder($object)
->add('name', 'text')
//...
->add('users', 'user')
//...
->add('save', 'submit')
->add('delete', 'submit')
->getForm();
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$form->get('save')->isClicked() ? $em->persist($object) : $em->remove($object);
$em->flush();
return $this->redirect($this->generateUrl('web_hq_new_mission_index'));
}
}
return $this->render('WebHQNewBundle:Mission:edit.html.twig', array(
'form' => $form->createView(),
//...
));
}
//...
Check your routing. You should have route for edit action with {id} param. If name of param not fits you change it in route and in function definition:
// src/WebHQ/NewBundle/Resources/config/route.yml
//...
web_hq_new_mission_new:
pattern: /mission/new
defaults: { _controller: WebHQNewBundle:Mission:new }
web_hq_new_mission_edit:
pattern: /mission/{id}/edit
defaults: { _controller: WebHQNewBundle:Mission:edit }
//...
Then define Form Type for User objects:
// src/WebHQ/NewBundle/Form/Type/UserType.php
namespace WebHQ\NewBundle\Form\Type;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class UserType extends AbstractType
{
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'class' => 'WebHQNewBundle:User',
'property' => 'name',
'empty_value' => 'Choose',
'required' => true,
'multiple' => true,
'query_builder' => function (Options $options) {
return function(EntityRepository $er) use ($options) {
return $er->createQueryBuilder('c')
->orderBy('c.name', 'ASC');
};
},
));
}
public function getParent()
{
return 'entity';
}
public function getName()
{
return 'user';
}
}
And register a type in service.yml:
# src/WebHQ/NewBundle/Resources/config/services.yml
#...
services:
web_hq_new.form.type.user:
class: WebHQ\NewBundle\Form\Type\UserType
tags:
- { name: form.type, alias: user }
#...
Good Luck!