Reputation: 2667
I have looked a couple of question on stack overflow. Many questions seems to be close to what I am asking, but I can't find my answer throughout them. So here I am asking a brand new question.
Please feel free to ask me for more info if I omitted something important.
I am building a Symfony2 Web application that manages some users avalability to some events on a calendar. So I have 3 entities to represent that. "Utilisateur" that means user which is an extension of FOSUserBundle, "Evenement" which means event and an intermediary object that stores status of the relation between those last two. The intermediate entity name is "Disponibilite" which means availability.
When a user clicks on an event on the calendar, it brings him to a page where he can specify if he is available or not from a dropdown list and then write a brief comment to motivate his decision. He then submits his availability and the server saves his availability for the event.
In my form for submiting my availability, I can't seem to find a way to inject information about the related objects (Evenement and Utilisateur). I don't want to make an entity choice field since the User and Event are already chosen. I want to make a sort of hidden entity field. Is that possible? Is it the good way to do?
The user may or may not have a Disponibilite row in the database. If we look for availability of User A for Event E and there is no result, it means that this user has never given his availability for this event. In the case that there is a result, it means that the user has already given his availability and is currently modifying his availability for the event.
I am starting with Symfony2, so I may be missing something very basic
Here is the simplification of my code.
This is an heritage of the BaseUser from FOSUserBundle
class Utilisateur extends BaseUser
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
An entity that represents an event.
class Evenement
{
/**
* @ORM\Id
* @ORM\OneToMany(targetEntity="Musique\GestionBundle\Entity\Disponibilite", mappedBy="evenement")
*/
private $disponibilite;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
}
An entity that represents the relation between Evenement and Utilisateur.
class Disponibilite
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Musique\GestionBundle\Entity\Evenement",inversedBy="disponibilite")
*/
private $evenement;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Musique\UtilisateurBundle\Entity\Utilisateur")
*/
private $utilisateur;
}
The for I use to get information about availability for a certain event for a certain user
class Disponibilite extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('disponibilite','choice', array(
'choices' => array("DispOui"=>"Disponible","DispCondition"=>"Incertain","DispNon"=>"Non-Disponible"),
'required' => true))
->add('raison')
// Add entity field here? hidden field?
;
}
Action to load the view of DisponibiliteType (the form)
function disponibiliteAction($id){
$repo_evenement = $this->getDoctrine()->getManager()->getRepository('MusiqueGestionBundle:Evenement');
$repo_dispo = $this->getDoctrine()->getManager()->getRepository('MusiqueGestionBundle:Disponibilite');
$disponibilite = $repo_dispo->findBy(
array('evenement'=>$id,'utilisateur'=>$this->getUser())
);
$evenement = $repo_evenement->find($id);
if(count($disponibilite) > 0){
$disponibilite = $disponibilite[0];
} else {
$disponibilite = new Disponibilite();
$disponibilite->setEvenement($evenement);
$disponibilite->setUtilisateur($this->getUser());
}
$form = $this->createForm(new DisponibiliteType(),$disponibilite);
return $this->render('MusiqueGestionBundle:Calendrier:disponibilite.html.twig',array('form' => $form->createView(),'evenement'=> $evenement));
}
Action triggered when the form is posted
function sendDisponibiliteAction(){
$request = $this->getRequest();
$repo_evenement = $this->getDoctrine()->getManager()->getRepository('MusiqueGestionBundle:Evenement');
$evenement = $repo_evenement->find($request->get('evenement'));
$repo_utilisateur = $this->getDoctrine()->getManager()->getRepository('MusiqueUtilisateurBundle:Utilisateur');
$utilisateur = $repo_utilisateur->find($request->get('utilisateur'));
$disponibilite = new Disponibilite();
$disponibilite->setEvenement($evenement);
$disponibilite->setUtilisateur($utilisateur);
$form = $this->createForm(new DisponibiliteType(),$disponibilite);
$form->bind($request);
if($form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($disponibilite);
$em->flush();
}
return $this->redirect($this->generateUrl("calendrier"));
}
Upvotes: 1
Views: 418
Reputation: 10084
That's not so hard, actually. I've made it with just one action, if you want, you can split it like you did before.
function disponibiliteAction($id)
{
$em = $this->getDoctrine()->getManager();
$repo_evenement = $em->getRepository('MusiqueGestionBundle:Evenement');
$repo_dispo = $em->getRepository('MusiqueGestionBundle:Disponibilite');
$evenement = $repo_evenement->findOneById($id);
if (is_null($evenement)) {
throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
}
$disponibilite = $repo_dispo->findOneBy(
array('evenement'=>$evenement,'utilisateur'=>$this->getUser())
);
if (is_null($disponibilite)) {
$disponibilite = new Disponibilite();
$disponibilite->setEvenement($evenement);
$disponibilite->setUtilisateur($this->getUser());
}
$form = $this->createForm(new DisponibiliteType(),$disponibilite);
if ($this->getRequest()->isMethod('post')) {
$form->submit($this->getRequest());
if ($form->isValid()) {
if ($disponibilite->getId() === null) {
$em->persist($disponibilite);
}
$em->flush();
return $this->redirect($this->generateUrl("calendrier"));
}
}
return $this->render('MusiqueGestionBundle:Calendrier:disponibilite.html.twig',array('form' => $form->createView(),'evenement'=> $evenement));
}
Upvotes: 2