Décrivez ici votre problème ou ce que vous cherchez à faire.

Bonjour à tous,

Je cherche à filtrer un créneau horaire grâce au code suivant sur une table contenant des données en mode tabulaire.

"" ->andWhere(':heuredepartmidi <= :heureclient and :heurefinmidi >= :heureclient') ""

or il me renvoie un tableau vide...

Si je fais (':heuredepartmidi >= :heureclient') par contre ça me ramène bien un tableau avec les informations correctes...

Doit on appliquer un format spécial aux champs Time pour qu'ils soient correctement interprétés ?
J'ai essayé de toutes les manières en mettant des new \datetime() mais ça n'a pas l'air d'être compatible avec les champs Time déclarés dans la base !

Cela oblige t'il à transformer les champs horaires de la table en Datetime au lieu de time ?

Merci d'avance pour vos réponses.

"```"
public function checkerExistenceCreneau(string $dateClient, string $heureClient)
{
//$heureClient = new \DateTime($heureClient);
//$dateClient = new \DateTime($dateClient);

    //Rechercher si la date choisie par le client est comprise dans un possible intervalle de créneaux
    //et récupérer l'id du créneau
    $q1 = $this->createQueryBuilder('d')
        ->setParameter('val', $dateClient)
        ->where('d.date_debut <= :val AND d.date_fin >= :val')
        ->getQuery()
        ->getOneOrNullResult();

    //Si résultat de requête $q1 non vide alors :
    if ($q1 != null) {

        //Récupération de la ligne de la table dans laquelle se trouve le créneau actif
        $idCreneau = $q1->getId();

        //Recherche du numéro de jour de la semaine correspondant à la date entrée par le client:
        $jour = date("N", strtotime($dateClient));

        //Rapatriement de tous les créneaux correspondants au jour choisi
        //Recherche linéaire dans la table tabulaire des créneaux pour récupérer les intervalles d'horaires et nombre de couverts

        switch ($jour) {
            case 1:
                $colHeureDepartMidi = "c.lundi_midi_debut";
                $colHeureFinMidi = "c.lundi_midi_fin";
                $colNbrCouvertsMidi = "c.nbr_couverts_lundi_midi";

                $colHeureDepartSoir = "c.lundi_soir_debut";
                $colHeureFinSoir = "c.lundi_soir_fin";
                $colNbrCouvertsSoir = "c.nbr_couverts_lundi_soir";
                break;

            case 2:
                $colHeureDepartMidi = "c.mardi_midi_debut";
                $colHeureFinMidi = "c.mardi_midi_fin";
                $colNbrCouvertsMidi = "c.nbr_couverts_mardi_midi";

                $colHeureDepartSoir = "c.mardi_soir_debut";
                $colHeureFinSoir = "c.mardi_soir_fin";
                $colNbrCouvertsSoir = "c.nbr_couverts_mardi_soir";
                break;

            case 3:
                $colHeureDepartMidi = "c.mercredi_midi_debut";
                $colHeureFinMidi = "c.mercredi_midi_fin";
                $colNbrCouvertsMidi = "c.nbr_couverts_mercredi_midi";

                $colHeureDepartSoir = "c.mercredi_soir_debut";
                $colHeureFinSoir = "c.mercredi_soir_fin";
                $colNbrCouvertsSoir = "c.nbr_couverts_mercredi_soir";
                break;

            case 4:

                $colHeureDepartMidi = "c.jeudi_midi_debut";
                $colHeureFinMidi = "c.jeudi_midi_fin";
                $colNbrCouvertsMidi = "c.nbr_couverts_jeudi_midi";

                $colHeureDepartSoir = "c.jeudi_soir_debut";
                $colHeureFinSoir = "c.jeudi_soir_fin";
                $colNbrCouvertsSoir = "c.nbr_couverts_jeudi_soir";
                break;

            case 5:

                $colHeureDepartMidi = "c.vendredi_midi_debut";
                $colHeureFinMidi = "c.vendredi_midi_fin";
                $colNbrCouvertsMidi = "c.nbr_couverts_vendredi_midi";

                $colHeureDepartSoir = "c.vendredi_soir_debut";
                $colHeureFinSoir = "c.vendredi_soir_fin";
                $colNbrCouvertsSoir = "c.nbr_couverts_vendredi_soir";
                break;

            case 6:

                $colHeureDepartMidi = "c.samedi_midi_debut";
                $colHeureFinMidi = "c.samedi_midi_fin";
                $colNbrCouvertsMidi = "c.nbr_couverts_samedi_midi";

                $colHeureDepartSoir = "c.samedi_soir_debut";
                $colHeureFinSoir = "c.samedi_soir_fin";
                $colNbrCouvertsSoir = "c.nbr_couverts_samedi_soir";
                break;

            case 7:

                $colHeureDepartMidi = "c.dimanche_midi_debut";
                $colHeureFinMidi = "c.dimanche_midi_fin";
                $colNbrCouvertsMidi = "c.nbr_couverts_dimanche_midi";

                $colHeureDepartSoir = "c.dimanche_soir_debut";
                $colHeureFinSoir = "c.dimanche_soir_fin";
                $colNbrCouvertsSoir = "c.nbr_couverts_dimanche_soir";
                break;
            default:
                return;
        }

        //Requête qui rapatrie les créneaux et nbr de couverts pour le jour et heure choisis :
        $heureClient=new \DateTime($heureClient);                  

        $q2 = $this->createQueryBuilder('c')
            ->select($colHeureDepartMidi, $colHeureFinMidi, $colHeureDepartSoir, $colHeureFinSoir, $colNbrCouvertsMidi, $colNbrCouvertsSoir)
            ->setParameters([
                'idcreneau' => $idCreneau,                  
                'heureclient'=>$heureClient, 
                'heuredepartmidi'=> $colHeureDepartMidi,
                // 'heurefinmidi'=> $colHeureFinMidi, 
                // 'nbrcouvertsmidi'=> $colNbrCouvertsMidi,

                // 'heuredepartsoir'=> $colHeureDepartSoir,
                // 'heurefinsoir'=> $colHeureFinSoir,
                // 'nbrcouvertssoir'=> $colNbrCouvertsSoir,
            ])    

            ->andWhere(':heureclient <= :heuredepartmidi')
            // ->orWhere(':heureclient >= :heuredepartsoir and :heureclient <= :heurefinsoir')
            ->andWhere('c.id = :idcreneau')
            ->getQuery()
            ->getResult();

        echo ('idCreneau =' . $idCreneau);
        dd($q2);         

        echo ('Des résultats ont été trouvés'), die;

        return $q1;
        return $q2;
    } else {
        echo ("Aucun créneau libre de réservation n'a été trouvé, veuillez choisir un autre jour ou consulter la liste des créneaux disponibles en cliquant sur le link qui s'affiche en bas de ce formulaire.");
    }
}

}
"```"

Entourez votre code en utilisant "```" pour bien le mettre en forme. (ne copiez pas trop de code)



**Ce que je veux**

Décrivez ce que vous cherchez à obtenir.

**Ce que j'obtiens**

Décrivez vos éventuelles erreurs ou ce que vous obtenez à la place de ce que vous attendez :(

6 réponses


Salut.

Il faut souvent faire gaffe avec orWhere donc je te conseille de voir la requête générée en affichant ->getSQL(); au lieu de ->getResult();.

Ensuite dans ton code tu mets ->andWhere(':heureclient <= :heuredepartmidi'). Or si je comprends bien heuredepartmidi c'est l'heure du départ du service donc tu veux plutôt ->andWhere(':heuredepartmidi >= :heureclient') non ?

Sinon RAV mais pour que ton code soit moins verbeux et aussi compréhensible tu peux utiliser une lookup table et virer ton switch :

$jours = [
    1 => 'lundi',
    2 => 'mardi',
    //etc
];

$nomJour = $jours[$jour] ?? null;
if (!$nomJour) {
    return;
}

$colHeureDepartMidi = "c.{$nomJour}_midi_debut";
$colHeureFinMidi = "c.{$nomJour}_midi_fin";
$colNbrCouvertsMidi = "c.nbr_couverts_{$nomJour}_midi";

$colHeureDepartSoir = "c.{$nomJour}_soir_debut";
$colHeureFinSoir = "c.{$nomJour}_soir_fin";
$colNbrCouvertsSoir = "c.nbr_couverts_{$nomJour}_soir";

Bonjour et merci beaucoup pour votre réponse qui va m'être très utile concernant la lookup-table, cependant concernant la comparaison de date ça ne marche toujours pas...

On dirait comme si il était incapable de lire les formats heure/time puisque il ne me retourne rien même en simplifiant la requête (en ne comparant pour l'instant que le créneau d'ouverture du matin)
"" ->andWhere(':heureclient between :heuredepartmidi and :heurefinmidi') ""
Il me semble que l'utilisation de between évite toute confusion :)

Je ne sais même pas comment récupérer les paramètres :heuredepartmidi ou :heurefinmidi pour m'assurer qu'ils sont dans le bon format vu que la SQL les affiche malheureusement qu'en tant que "?" :

"" "SELECT c0_.lundi_midi_debut AS lundi_midi_debut_0, c0_.lundi_midi_fin AS lundi_midi_fin_1, c0_.lundi_soir_debut AS lundi_soir_debut_2, c0_.lundi_soir_fin AS lundi_soir_fin_3, c0_.nbr_couverts_lundi_midi AS nbr_couverts_lundi_midi_4, c0_.nbr_couverts_lundi_soir AS nbr_couverts_lundi_soir_5 FROM creneaux c0_ WHERE (? BETWEEN ? AND ?) AND c0_.id = ? ""

Comment être sûr qu'il interprète bien les paramètres en tant que format time (car leur type est Time dans la table MySql...) ?

Merci d'avance

Alors, n'utilise pas de paramètres pour heuredepartmidi et heurefinmidi, laisse SQL s'en charger et met juste le nom des colonnes respectives.

Ensutie, pour la valeur de heureclient, Tu as deux solutions :

1 - Transformer l'objet DateTime que tu as en heure :
Petit exemple :

<?php
echo (new DateTime)->format('H:i:s');

2 - Utiliser la méthode TIME de SQL :

->andWhere("TIME(:heureclient) between {$colHeureDepartMidi} and {$colHeureFinMidi}");

Je te conseille fortement la deuxième solution

Merci beaucoup pour votre réponse qui m'a permis de pas mal avancer...

J''en profite pour demander si il est vrai que l'on ne peut faire aucune opération sur les dates (hormis avec un bundle) dans le queryBuilder ? En ce qui me concerne j'ai essayé de soustraire une heure au résultat remonté par l'une des colonnes de la table et aucune fonction n'était acceptée !...

Je ne connais pas assez Symfony pour donner une réponse. Cependant, si tu retires du temps à un objet DateTime, ça ne devrait poser aucun soucis : DateTime Add Interval

N'hésite pas à utiliser les fonctions sur les dates qui existent directement dans ta BDD
Pour MySql (et donc MariaDB) :

Justement, pour pouvoir utiliser ces fonctions il faut dire à Doctrine comment les gérer car il ne le sait pas par défaut.

Tu installes DoctrineExtensions et en avant.