سؤال

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.

Context

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.

What I want to do

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.

Problem

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?

Note

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

Code

Here is the simplification of my code.

Entity\Utilisateur.php

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;
}

Entity\Evenement.php

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;
}

Entity\Disponibilite.php

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;
}

Form\DisponibiliteType.php

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?
        ;
}

In the controller

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"));
}
هل كانت مفيدة؟

المحلول

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));
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top