Bonjour,

Voila je rencontre un petit problème avec mon code.
J'ai un soucis de validation qui ne fonctionne pas lorsque je crée un nouvel objet "resa" mais qui fonctionne si je modifie un objet existant.

Je ne trouve pas d'où ça vient!?

Ce que je fais

Mon entité

<?php

namespace Damias\ResaBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Damias\ResaBundle\Validator\Constraints as ResaAssert;

/**
 * Reservation
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Damias\ResaBundle\Entity\ReservationRepository")
 * @ResaAssert\ResaUnique
 */
class Reservation
{
...

Ma constrainte

<?php

namespace Damias\ResaBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class ResaUnique extends Constraint
{
    public $message = 'Réservation en conflit (chambre déjà occupée dans cette période)';

    public function getTargets()
    {
        return self::CLASS_CONSTRAINT;
    }

    public function validatedBy()
    {
        return 'damiasresa_resaunique';
    }
}

Mon Validateur

<?php

namespace Damias\ResaBundle\Validator\Constraints;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class ResaUniqueValidator extends ConstraintValidator
{
    private $requestStack;
    private $em;

    public function __construct(RequestStack $requestStack, EntityManagerInterface $em)
    {
        $this->requestStack=$requestStack;
        $this->em=$em;
    }

    public function validate($value, Constraint $constraint)
    {
        $dateArrivee=clone $value->getDateArrivee();
        $dateArrivee->modify('+1 day');
        $dateDepart=clone $value->getDateDepart();
        $dateDepart->modify('-1 day');
        $ressources=$value->getRessources()->getValues();
        $id_ressources=array();
        foreach ($ressources as $ressource)
        {
            $id_ressources[]=$ressource->getId();
        }
        $autre_resa=$this   ->em
                            ->getRepository('DamiasResaBundle:Reservation')
                            ->autreResa($id_ressources, $dateArrivee, $dateDepart);

        if (count($autre_resa)>1)
        {
                $this->context  ->buildViolation($constraint->message)
                                ->atPath('Ressources')
                                ->addViolation();
        }

Mon action en édition qui fonctionne

   public function reservationAction($id)
    {
        // SESSION
        $session = $this->get('session');

        $em = $this ->getDoctrine()
                    ->getManager();
        $resa = $em ->getRepository('DamiasResaBundle:Reservation')->find($id);

        $form_reservation = $this   ->createForm(new ReservationType, $resa);

        $request = $this->get('request');
        if($request->getMethod()=='POST')
        {            
            //Récupération de la Réservation - Modification
            if($this ->get('request') ->get('damias_resabundle_reservation')!==null)
            {
                $form_reservation->handleRequest($request);
                if ($form_reservation->isSubmitted() && $form_reservation-> isValid())
                {
                    $em=$this->getDoctrine()->getManager();
                    $em->flush();
                    $date=$resa->getDateArrivee();
                    $session->set('date', $date);
                    $response = $this->redirect($this->generateUrl('damias_resa_homepage'));
                    return $response;
                }
            }
        }

        $response = $this->render(
            'DamiasResaBundle:Default:reservation_edit.html.twig',
            array(
                'form_reservation' => $form_reservation->createView(),
                'resa' => $resa
            )
        );
        return $response;
    }

Mon action en ajouter où la validation ne fonctionne pas

 public function ajouter_reservationAction()
    {
        // SESSION
        $session = $this->get('session');
        if ($session->get('resa')!=null) {
            $resa = new Reservation($session->get('resa'));
        }
        else {
            $resa = new Reservation();
        }
        $client = new Client();
        $request = $this->get('request');

        $form_client = $this        ->createForm(new ClientType,$client);
        $form_reservation = $this   ->createForm(new ReservationType, $resa);

        // Récupération des choix
        if($request->getMethod()=='GET')
        {
            // Récupération de la date de début
            if($this ->get('request') -> get('choix') !==null)
            {
                $choix=$this ->get('request') -> get('choix');
                $date_arrivee=$choix['date_encours']['date'];
                $date_arrivee = new \Datetime($date_arrivee);
                $date_depart = clone $date_arrivee;
                $date_depart->modify('+1 day');
                $ressourceId=$choix['ressource'];
                $em = $this ->getDoctrine()
                            ->getManager();
                $ressource = $em->getRepository('DamiasResaBundle:Ressource')->find($ressourceId);
                $id_categories=$choix['categories'];
                $resa   ->setDateArrivee($date_arrivee)
                        ->setDateDepart($date_depart)
                        ->addRessource($ressource);
                $session->set('resa', $resa);

                $categories = $ressource->getCategories();

                $form_reservation = $this   ->createForm(new ReservationType, $resa);
            }
        }
        // Récupération du formulaire
        if($request->getMethod()=='POST')
        {            
            // Récupération du nouveau client
            if($this ->get('request') ->get('damias_resabundle_client')!==null)
            {
                if ($form_client->handleRequest($request)-> isValid())
                {
                    $em=$this->getDoctrine()->getManager();
                    $em->persist($client);
                    $em->flush();
                    $resa->setClient($client);
                    $session->set('resa', $resa);
                }
            }

            //Récupération de la Réservation
            if($this ->get('request') ->get('damias_resabundle_reservation')!==null)
            {
                $form_reservation->handleRequest($request);
                if ($form_reservation->isSubmitted() && $form_reservation-> isValid())
                {
                    $em=$this->getDoctrine()->getManager();
                    $em->persist($resa);
                    $em->flush();
                    $date=$resa->getDateArrivee();
                    $session->set('date', $date);
                    $session->set('resa', null);
                    $response = $this->redirect($this->generateUrl('damias_resa_homepage'));
                    return $response;
                }
            }
        }

        $response = $this->render(
            'DamiasResaBundle:Default:reservation_new.html.twig',
            array(
                'form_reservation' => $form_reservation->createView(),
                'form_client' => $form_client->createView()
            )
        );
        return $response;
    }

Ce que je veux

Avant un enregistrement de nouvelle réservation, je veux vérifier que la ressource utilisé est disponible dans l'interval de dates de départ et d'arrivée.

Ce que j'obtiens

Lorsque je crée une nouvelle réservation dans une chambre (ressource) à une période déjà occuppé, la réservation est enregistrée.
Si je modifie une réservation pour que la période déborde sur une autre réservation, ma validation fonctionne et mle retourne une erreur sur mon formulaire.

Une idée? une piste?
Merci

1 réponse


Bon ben, ça fait un moment que je cherchais a comprendre mon erreur... et enfin c'est résolu!

Ca venait de mon validateur:
j'avais mis: if (count($autre_resa)>1)

if (count($autre_resa)>0)
        {
                $this->context  ->buildViolation($constraint->message)
                                ->atPath('Ressources')
                                ->addViolation();
        }