8797 sujets

Développement web côté serveur, CMS

Bonjour,

Je travaille sur un calendrier/agenda.
J'ai fais en sorte qu'on puisse saisir un événement dans une base de données. Je souhaite maintenant afficher ces événements sur mon calendrier via les styles css.
J'ai donc fais une boucle "for" qui tourne sur tous les jours du mois.
L'événement est bien trouvé et s'affiche correctement mais le jour suivant est doublé.

Par exemple pour les événements du 16, 18 et 20 septembre, mon calendrier va afficher le 16 correctement suivi du 17, alors que les deux événements suivants double la date soit 2x le 18 et 2x le 20...
upload/2770-001.jpg

Voici mon code :

//mois et jour actuels
$moisactuel = date('n');
$jouractuel = date('d');

//pour afficher les evenements existants
$sql = 'SELECT * FROM agenda WHERE mois_even = '.$month.' AND annee_even = '.$year.' ORDER BY jour_even ASC';
$result = mysql_query ($sql, $cnx) or die('Erreur : '.mysql_error());
$result2 = mysql_query ($sql, $cnx) or die('Erreur : '.mysql_error());
$RsAgenda2 = mysql_fetch_array($result2);

$tab_agenda = array();
while ($RsAgenda = mysql_fetch_array($result)) {
	array_push($tab_agenda, $RsAgenda[1]);
}

//affiche tous les jours du mois actuel
for ($i = 1; $i <= $jours_mois; $i++) { //de 1 a 30 (ou 31) jours

	//si c'est un evenement
	foreach($tab_agenda as $value) {//pour chaque evenement
		if ($value==$i) { 
			//si c'est aujourd'hui
			if (($jouractuel==$i) && ($moisactuel==$month)) { 
				echo ('<td width="15" class="caseActifEven"><a href="">'.$i.'</a></td>');
			} else { //si ce n'est pas aujourd'hui
				echo ('<td width="15" class="caseEven"><a href="">'.$i.'</a></td>');
			}
			$case++;
			if ($case%7==0){ //si on arrive a dimanche aller a la ligne
				echo ('</tr><tr>');
			}//fin du if
		}//fin du if 
	}//fin du foreach

	//si ce n'est pas un evenement
	if (!($RsAgenda2[1]==$i) && ($RsAgenda2[2]==$month)) { 	
		//si c'est aujourd'hui
		if (($jouractuel==$i) && ($moisactuel==$month)) { 
			echo ('<td width="15" class="caseActif">'.$i.'</td>');
		} else { //si ce n'est pas aujourd'hui
			echo ('<td width="15" class="case">'.$i.'</td>');
		}

		$case++;
		if ($case%7==0){ //si on arrive a dimanche aller a la ligne
			echo ('</tr><tr>');
		}//fin du if
	}//fin du if

}//fin du for


Pouvez-vous me dire ce qui ne va pas ?
Merci.
Modifié par Taly (18 Sep 2006 - 11:16)
Administrateur
Bonjour,

je n'ai pas pris le temps de comprendre pourquoi ça fonctionnait avec le 16 et pas le reste mais sinon:
- tu fais 2 fois la même requête MySQL plutôt que de copier le résultat? Enfin y a peut-être un cache efficace ...
- est-ce que tu as besoin de $tab_agenda dans le reste du script? Parce que là tu y mets les événements pour d'autres mois que celui qui t'intéresse, c'est pas utile a priori.
- avec foreach, tu passes en revue tous les événements pour savoir s'il y en a un qui correspond au jour $i puis (inconditionnellement et d'une autre manière) tu évalues dans la condition d'un if() si ce n'en est pas un: bizarre. Les doublons semblent provenir de ce if() qui ne fonctionne pas.
Fais un log de toutes les fois où ce (!cond1 && cond2) est à TRUE et fais un var_dump du contenu de ton log après avoir affiché le tableau.

Init°:
log = Array();
$compteur = 0;

dans le if():
log[$compteur] = Array($RsAgenda2[1], $RsAgenda2[2]);
$compteur++;

après ton for():
echo '<pre>';
var_dump($log);
echo '/<pre>';
Administrateur
Parcourir 30 fois avec foreach n'étant pas très efficace et vu que tes données de départ ont l'air assez précises, j'aurais fais:
- avoir la liste des événements du mois dans un tableau (et que ceux-là)
- créer un tableau dont les clés sont les jours du mois et les valeurs true (ou peu importe). $tab['16'] = TRUE; par exemple
- trier ce tableau par les valeurs une bonne fois pour toutes (lors de la création si possible à l'étape précédente)
- se placer au début du tableau
- for ($i=1 to ~30) { while($i < cle_actuelle) { afficher_jour($i, 'normal'); $i++; } afficher_jour($i, 'evenement'); cle_actuelle=next(cle du tableau); if(cle_actuelle === FALSE) { for($j =$i to ~30) { afficher_jour($j, 'normal'); } }
(si le tableau a des clés numériques '5' et '12', 1 à 4 sont des cellules normales, 5 un événement, 6 à 11 normal et 12 un événement)

et pour function afficher_jour($jour, $type) {
static modulodimanche = 0;
if normal { ... }
if evenement { ... }
if($modulodimanche%7 ...) {finligne}
$modulodimanche++;
}

EDIT: mon script ne gérait pas bien ce qui se passe après la dernière clé je crois, faudrait regarder la doc sur next() Smiley confused
EDIT2: utiliser le triple égal === et euh j'ai baclé le truc avec une boucle sur $j je crois Smiley langue
Modifié par Felipe (14 Sep 2006 - 11:44)
Merci Felipe pour tes explications mais je suis désolée je suis pas une pro du PHP et je t'avoue que j'ai du mal à te suivre... j'ai l'impresson de lire une formule mathématique écrite par un grand physicien lol Smiley langue

Est ce que tu pourrais faire plus simple pour que mes humbles petites cellules grises puissent enregistrer l'information ?

Merci à toi. Smiley confused
Salut,
Felipe à raison, déjà ça ne sert à rien de faire deux fois la même requête à la base de données, surtout que c'est la d'ou provient ton erreur:


//si ce n'est pas un evenement
if (!($RsAgenda2[1]==$i) && ($RsAgenda2[2]==$month)) 

En fait $RsAgenda2[1] doit correspondre à 16 dans ton code : c'est pour cela que 16 n'est jamais doublé. En fait cette condition ne teste que le jour 16.
En suivant ta logique, pour éviter les doublons, il faudrait dans la boucle foreach sur $tab_agenda tester la condition if ($value!=$i) pour les jours sans évenements.
Mais le foreach consomme inutilement des ressources: en php il existe une fonction pour savoir si une valeur apartient à un tableau:
bool in_array ( mixed needle, array haystack [, bool strict] )
(voir le manuel php)
Si je peux me permettre de corriger ton code cela donne:

//mois et jour actuels
$moisactuel = date('n'); //peut être mettre date('j') pour avoir le jour sans le 0 initial;
$jouractuel = date('d');

//pour afficher les evenements existants
$sql = 'SELECT * FROM agenda WHERE mois_even = '.$month.' AND annee_even = '.$year.' ORDER BY jour_even ASC';
$result = mysql_query ($sql, $cnx) or die('Erreur : '.mysql_error());
// $result2 = mysql_query ($sql, $cnx) or die('Erreur : '.mysql_error());
// $RsAgenda2 = mysql_fetch_array($result2);

$tab_agenda = array();
while ($RsAgenda = mysql_fetch_array($result)) {
	array_push($tab_agenda, $RsAgenda[1]);
}

for ($i = 1; $i <= $jours_mois; $i++) { //de 1 a 30 (ou 31) jours
	if (in_array($i, $tab_agenda, TRUE)) {//si c'est un evenement	
        if (($jouractuel==$i) && ($moisactuel==$month)) { //si c'est aujourd'hui
            echo ('<td width="15" class="caseActifEven"><a href="">'.$i.'</a></td>');
        } else { //si ce n'est pas aujourd'hui
            echo ('<td width="15" class="caseEven"><a href="">'.$i.'</a></td>');
        }   
    } else {//si ce n'est pas un evenement
        if (($jouractuel==$i) && ($moisactuel==$month)) { 
            echo ('<td width="15" class="caseActif">'.$i.'</td>');
        } else { //si ce n'est pas aujourd'hui
            echo ('<td width="15" class="case">'.$i.'</td>');
        }
    }
        
    $case++;
    if ($case%7==0){ //si on arrive a dimanche aller a la ligne
        echo ('</tr><tr>');
    }
}//fin du for


Cordialement Smiley sweatdrop
Merci beaucoup ilhooq pour ton code. C'est très sympa à toi !
Malheureusement j'ai un problème : les événements ne s'affichent plus, seule la date du jour est mise en valeur.

upload/2770-01.gif

Je n'ai pas trouvé comment débuger ton code. Une suggestion ?
En faite, si je viens de trouver...
J'ai simplement modifier la fonction in_array (j'ai supprimer la variable TRUE) et ça fonctionne.

for ($i = 1; $i <= $jours_mois; $i++) { //de 1 a 30 (ou 31) jours
	if (in_array($i, $tab_agenda)) {//si c'est un evenement	
        if (($jouractuel==$i) && ($moisactuel==$month)) { //si c'est aujourd'hui
            echo ('<td width="15" class="caseActifEven"><a href="">'.$i.'</a></td>');
        } else { //si ce n'est pas aujourd'hui
            echo ('<td width="15" class="caseEven"><a href="">'.$i.'</a></td>');
        }   
    } else {//si ce n'est pas un evenement
        if (($jouractuel==$i) && ($moisactuel==$month)) { 
            echo ('<td width="15" class="caseActif">'.$i.'</td>');
        } else { //si ce n'est pas aujourd'hui
            echo ('<td width="15" class="case">'.$i.'</td>');
       }
    }//fin du if
        
    $case++;
    if ($case%7==0){ //si on arrive a dimanche aller a la ligne
        echo ('</tr><tr>');
    }
}//fin du for


Un grand merci à vous tous Smiley lol