[RESOLU] Filtre requete par date

Mammouth du PHP | 643 Messages

07 sept. 2016, 20:56

Salut à tous.
Je me bat depuis un moment avec mes requetes afin de filtrer par date ( aujourd'hui, demain, ce week-end )

J'ai donc procéder ainsi pour mes requetes:
Apparament problème de concaténation ds les switch pour filtre par date enfin je ne sais pas trop ...
$sql = "SELECT * FROM `loisirs`  JOIN `regions` ON `regions`.`region_id` = `loisirs`.`id_region` WHERE `loisirs`.`date_fin_sortie` > NOW() AND `loisirs`.`valide` = 1";
  	$sql .= !empty($_REQUEST['region']) ? ' AND `regions`.`url` = "'.$_REQUEST['region'].'"' : NULL;
    $sql .= !empty($_REQUEST['departement']) ? ' AND `loisirs`.`id_departements` = '.$_REQUEST['departement'] : NULL;
    $sql .= !empty($_REQUEST['loisir']) ? ' AND `loisirs`.`genre_loisir` = "'.$_REQUEST['loisir'].'"' : NULL;

	if(!empty($_REQUEST['ville'])) {
	$sql .= ' AND loisirs.city = \''. getRealValue($_REQUEST['ville']). '\'';
	}
	
	// Filtre par date
	switch ($typeDate) :
	default:
	case "aujourdhui" :
	$sql . = "AND date_debut_sortie = '".date('Y-m-d h:i:s',strtotime('today'))."'";
	break;
	
	case "demain":
	$sql .= "AND date_debut_sortie = '".date('Y-m-d h:i:s',strtotime('tomorrow'))."'";
	break;
	
	case "we" :
	$sql .= "AND date_debut_sortie BETWEEN '".date('Y-m-d h:i:s',strtotime('next Saturday'))."' AND ".date('Y-m-d h:i:s',strtotime('next Monday'))."'"; //démarre à minuit
	break;
	endswitch;
  
    $req = $bdd->query($sql);
et mon code pour mes boutons, filtre en lui même:
<form method="post"
            Aujourd'hui <input type="radio" name="date" value="aujourdhui" ><br>
            Demain <input type="radio" name="date" value="demain" ><br>
            Ce week-end <input type="radio" name="date" value="we" >
            <input type="submit" value"=Envoyer" >
            </form>
          
          <?php
          $typeDate = $_POST["date"];
		  
		  // Si aucune filtre de selectionner alors on affiche tout
		  $typeDate = (in_array($typeDate, array("aujourdhui", "demain", "we")) ? $typeDate : NULL );
		  
		  // on affiche la date selectionner
          echo $typeDate;
		  ?>
Je pense pas être trop loin mais je bloque la.
Comment faire pour résondre mon problème de concaténation svp.


Merci à vous

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

08 sept. 2016, 09:14

salut,

première chose : tu as une erreur de syntaxe dans le case aujourd'hui (tu as mis . = au lieu de .= ;) )

dans ton commentaire tu indique : si aucun choix on affiche tout. Tu ne peux pas obtenir ce comportement avec ton switch. C'est forcément un des choix et "aujourd'hui" si la valeur correspondant a rien (ou a nul dans ton cas).
tout les cas de switch ne commence pas par un espace du coup le AND se collé a ce qu'il y a avant et donc tu aura une erreur SQL.

il faut éviter d'utiliser l'opérateur comme tu le fais, parce que :
- c'est moche
- c'est difficile à lire
- y a un risque de merder

Utilise des if c'est dexu lignes deux plus mais beaucoup plus simple à lire et a comprendre et impossible de se tromper quand tu écris (sauf si tu te vautre sur la condition mais c'est le cas dans les deux).
Le ternaire est a réserver pour des cas simple avec des vrai alternative de cas par défaut mais je ne pense pas que l'on ne puisse pas s'en passer.
d'ailleurs dans ton et pour suivre la logigue de l'emploi de sucre syntaxique tu peux faire plus court
'expression (expr1) ? (expr2) : (expr3) est évaluée à expr2 si expr1 est évaluée à TRUE, et expr3 si expr1 est évaluée à FALSE.
Depuis PHP 5.3, il est possible d'omettre la partie centrale de l'opérateur ternaire. L'expression expr1 ?: expr3 retourne expr1 si expr1 vaut TRUE, et expr3 sinon.
donc
$sql .= !empty($_REQUEST['region']) ? ' AND `regions`.`url` = "'.$_REQUEST['region'].'"' : NULL;
devient
$sql .= !empty($_REQUEST['region']) ?: ' AND `regions`.`url` = "'.$_REQUEST['region'].'"';

même si
if(!empty($_REQUEST['region'])){
$sql .= ' AND `regions`.`url` = "'.$_REQUEST['region'].'"';
}
est plus clair / simple à lire.

c'est d'ailleurs ce que tu fait pour le dernier cas ;)

pour le cas week-end tu as oublié une ' avant la seconde date du coup la requête sql déconne.

Dans ce genre de casil est important d'afficher la requête pour la tester dans un client SQL c'est beaucoup plus simple et du temps de gagné à coup sur (vérification de syntaxe et que le résultat soit conforme a tes attente).

les ` sont inutiles elle ne servent que si tu as la bonne idées d'utiliser des noms de champs / table qui sont des mots réservés de mysql

ton code ré écrit plus clairement pour être ainsi
<?php
$sql = 'SELECT * FROM loisirs  JOIN regions ON regions.region_id = loisirs.id_region WHERE loisirs.date_fin_sortie > NOW() AND loisirs.valide = 1';
if (!empty($_REQUEST['region'])) {
    $sql .= ' AND regions.url = \''.$_REQUEST['region'].'\'';
}
if (!empty($_REQUEST['departement'])) {
    $sql .= ' AND loisirs.id_departements = '.$_REQUEST['departement'];
}
if (!empty($_REQUEST['loisir'])) {
    $sql .= ' AND loisirs.genre_loisir = \''.$_REQUEST['loisir'].'\'';
}

if (!empty($_REQUEST['ville'])) {
    $sql .= ' AND loisirs.city = \''. getRealValue($_REQUEST['ville']). '\'';
}

// Filtre par date
switch ($typeDate) {
    case 'demain':
        $sql .= ' AND date_debut_sortie = \''.date('Y-m-d h:i:s', strtotime('tomorrow')).'\'';
    break;

    case 'we':
        $sql .= ' AND date_debut_sortie BETWEEN \''. date('Y-m-d h:i:s', strtotime('next Saturday')).'\' AND \''.date('Y-m-d h:i:s', strtotime('next Monday')).'\''; //démarre à minuit
    break;
    case 'aujourdhui':
    default:
        $sql .= ' AND date_debut_sortie = \''. date('Y-m-d h:i:s', strtotime('today')).'\'';
    break;
}

$req = $bdd->query($sql);
@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 643 Messages

08 sept. 2016, 15:57

Nikel,
Cette prise de tête pour pas grand chose franchement, merci !!!

Du coup j'ai réussi à faire mon truc.
J'ai une dernuere question comment puis je faire pour faire en sorte que la case selectionner du formulaire reste coché une fois le formulaire traité.
J'ai donc comme code maitenant :
<form method="post" >
           <div class="col-md-2">Toutes <input type="radio" name="date" value="toutes"></div>
             <div class="col-md-2">Aujourd'hui <input type="radio" name="date" value="aujourdhui"></div>
             <div class="col-md-2">Demain <input type="radio" name="date" value="demain"></div>
             <div class="col-md-2">Ce week-end <input type="radio" name="date" value="we"></div>
            <input type="submit" value"=Envoyer" >
            </form>
// Filtre rapide de date
	if (empty($_POST["date"])) { $_POST["date"] = NULL; } 
		$typeDate = $_POST["date"];
			 if (empty($typeDate)) {
		$typeDate = NULL;
			}else{
			$typeDate = $typeDate; 
		}

// Filtre par date
	switch ($typeDate) {
		case 'demain':
			$sql .= ' AND date_debut_sortie = \''.date('Y-m-d', strtotime('tomorrow')).'\'';
		break;
	
		case 'we':
			$sql .= ' AND date_debut_sortie BETWEEN \''. date('Y-m-d', strtotime('next Saturday')).'\' AND \''.date('Y-m-d', strtotime('next Monday')).'\''; //démarre à minuit
		break;
		
		case 'aujourdhui':
		$sql .= ' AND date_debut_sortie = \''.date('Y-m-d').'\'';
		break;
		
		default:
			$sql .= NULL;
		break;
	}

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

09 sept. 2016, 08:45

il faut tester la valeur de $_POST['date'] pour chaque radio et si la valeur correspond tu "check" (checked="checked")

je ferais une truc dans ce goût là
<?php 
function checkDateRadioIfIsSame($form, $expected){
    if(!empty($form['date']) && $form['date'] == $expected){
        echo ' checked="checked"';
    }
}
 ?>
<form method="post" >
    <div class="col-md-2">Toutes <input type="radio" name="date" value="toutes" <?php checkDateRadioIfIsSame($_POST,"toutes");?>/></div>
    <div class="col-md-2">Aujourd'hui <input type="radio" name="date" value="aujourdhui" <?php checkDateRadioIfIsSame($_POST,"aujourdhui");?>/></div>
    <div class="col-md-2">Demain <input type="radio" name="date" value="demain" <?php checkDateRadioIfIsSame($_POST,"demain");?>/></div>
    <div class="col-md-2">Ce week-end <input type="radio" name="date" value="we" <?php checkDateRadioIfIsSame($_POST,"we");?>/></div>
    <input type="submit" value"=Envoyer" >
</form>
@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 643 Messages

09 sept. 2016, 17:46

Re, nikel trop bien :p
Juste je voulais rajouter par defaut la case "toutes" de cocher quand on arrive sur la page.
Du coup j'ai fait :
<?php 
function checkDateRadioIfIsSame($form, $expected){
    if(!empty($form['date']) && $form['date'] == $expected){
        echo ' checked="checked"';
    }
	else if (empty($form['date'])) {
		checkDateRadioIfIsSame($_POST,"toutes");
	}
}
 ?>
Mais bon manque un je ne sais quoi dans:
// Si date est vide !
else if (empty($form['date'])) {
		checkDateRadioIfIsSame($_POST,"toutes");
	}

Mammouth du PHP | 1339 Messages

10 sept. 2016, 22:19

<form method="post" >
<?php 
	$_POST['date'] = !empty($_POST['date']) ? $_POST['date'] : 'toutes';
	$aRadio = array('toutes' => 'Toutes', 'aujourdhui' => 'Aujourd\'hui', 'demain' => 'Demain', 'we' => 'Ce week-end');
	foreach($aRadio as $k => $v) {
		$checked = !empty($_POST['date']) && ($_POST['date'] == $k) ? ' checked="checked"' : NULL;
echo '    <div class="col-md-2">'.$v.' <input type="radio" name="date" value="'.$k.'"'.$checked.' /></div>'."\n";		
	}
?>
    <input type="submit" value"=Envoyer" >
</form>
Bon sinon tu me fais un message privé et on se fait un TeamViewer