[RESOLU] Affichage d'un menu et sous-menu dynamiques

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [RESOLU] Affichage d'un menu et sous-menu dynamiques

Re: Affichage d'un menu et sous-menu dynamiques

par max303 » 06 janv. 2022, 21:09

Génial!!! Au top! Grand Merci ynx pour ta patience et pour ce que tu m'a appris.
Les images s'affichent correctement. Bien à toi :)

Re: Affichage d'un menu et sous-menu dynamiques

par ynx » 06 janv. 2022, 20:55

Super si tu as compris l'utilisation des fonctions !
Oui pas de paramètre dans execute() si pas de marqueur :param dans la requête sql.

Et en effet, tu n'as pas fait d'erreur, c'est moi qui t'ai fait glisser une erreur de syntaxe dans ta requête IN depuis hier (juste après avoir relevé ta première erreur de syntaxe avec OR IN).
Donc je me corrige, on ne peut pas écrire :
WHERE id_annonce = IN (5,6,7,1) -- incorrect
Il faut écrire :
WHERE id_annonce IN (5,6,7,1) -- correct

Re: Affichage d'un menu et sous-menu dynamiques

par max303 » 06 janv. 2022, 19:17

Don si j'ai bien compris, on fait tout simplement tel dans le code en dessous dans la fonction getPhotosAnnonces($annonces) :

Code : Tout sélectionner

$req = $bdd->prepare($sql); $req->execute(); $res = $req->fetchAll(PDO::FETCH_GROUP);
Oui, j'ai bien passé $annonces en paramètre
Voici le code:

Code : Tout sélectionner

function getPhotosAnnonces($annonces) { global $bdd; echo 'Le tableau des annonces <br>'; var_dump($annonces); echo 'Le tableau des identifiants des annonces <br>'; var_dump(array_column($annonces, 'id')); echo 'Les identifiants des annonces séparés par une virgule <br>'; var_dump(implode(',', array_column($annonces, 'id'))); $sql = 'SELECT id_annonce,filepath as IMG FROM images_annonces WHERE id_annonce = IN (' . implode(',', array_column($annonces, 'id')) . ')'; try { $req = $bdd->prepare($sql); $req->execute(); $res = $req->fetchAll(PDO::FETCH_GROUP); var_dump($res); } catch (Exception $e) { echo "Erreur dans la requête " . $sql; } // le temps des tests pour voir le résultat return $res; } function affichageAnnonce($id_cat){ global $bdd; $annonces = getAnnonceCategorie($id_cat); $images = getPhotosAnnonces($annonces); $res = []; foreach ($annonces as $R) { $res[$R['id']] = $R; $imgs = !empty($images[$R['id']]) ? $images[$R['id']] : NULL; if(!empty($imgs)){ foreach($imgs as $I){ $res[$R['id']]['images'][] = !empty($I['IMG']) ? $I['IMG'] : null; } }else{ $res[$R['id']]['images'] = null; } } return $res; }
J'ai donc ça qui apparait comme erreur:
1-Erreur dans la requête SELECT id_annonce,filepath as IMG FROM images_annonces WHERE id_annonce = IN (5,6,7,1)

2-( ! ) Notice: Undefined variable: res in C:\wamp64\www\Projetsite\
==> Il s'agit de $res de la fonction getPhotosAnnonces($annonces)

Où se trouve donc ce grain de sable qui empêche l'affichage des images?

Merci, grace à toi, en débogant, j'ai compris l'utilisation de implode qui me faisait peur.

Re: Affichage d'un menu et sous-menu dynamiques

par ynx » 06 janv. 2022, 18:25

Si tu regardes les messages et les numéros de ligne indiquées pour ces nouvelles erreurs, tu peux voir qu'il s'agit d'une erreur sur la ligne utilisant array_column et implode, rien à voir donc avec le execute() qui devrait bien être vide si tu n'as plus de marqueurs dans ta requête sql.

L'utilisation de array_column et implode permet de transformer la liste des annonces $annonces en une chaine de caractère contenant les identifiants des annonces. Il faut pour cela que la variable $annonces soit une liste de tableau associatif (ce qui semblait être le cas car tu utilises PDO::FETCH_ASSOC dans la fonction pour récupérer les annonces).

D'après le message d'erreur, la variable $annonces serait une chaine de caractère (string) et non un tableau (array) contenant les annonces.
La variables $annonces est bien le résultat de la fonction getAnnonceCategorie() ?
Tu as bien passé cette variable $annonces en paramètre à ta fonction getPhotosAnnonces($annonces) dans ta fonction affichageAnnonce() (cf. la dernière ligne de mon précédent code) ?

Sinon un peu de var_dump() pour déboguer la fonction et pour te montrer l'utilisation des fonctions :
function getPhotosAnnonces($annonces) {
  global $bdd;

  echo 'Le tableau des annonces <br>';
  var_dump($annonces);
  echo 'Le tableau des identifiants des annonces <br>';
  var_dump(array_column($annonces, 'id'));
  echo 'Les identifiants des annonces séparés par une virgule <br>';
  var_dump(implode(',', array_column($annonces, 'id')));

  $sql = 'SELECT id_annonce,filepath as IMG
  FROM images_annonces
  WHERE id_annonce = IN (' . implode(',', array_column($annonces, 'id')) . ')';
  // ... suite de la fonction
  return $res;
}

Re: Affichage d'un menu et sous-menu dynamiques

par max303 » 06 janv. 2022, 17:11

Lorsqu'aucun paramètre est passé:

Code : Tout sélectionner

$req->execute(); $res = $req->fetchAll(PDO::FETCH_GROUP);
j'ai les erreurs suivantes:
Warning: array_column() expects parameter 1 to be array, string given in
Warning: implode(): Invalid arguments passed in
Notice: Undefined variable: res in C:

Lorsqu'un paramètre est ajouté:

Code : Tout sélectionner

$req->execute($annonces); $res = $req->fetchAll(PDO::FETCH_GROUP);
Les erreurs:
Warning: array_column() expects parameter 1 to be array, string given in
Warning: implode(): Invalid arguments passed in C:

Re: Affichage d'un menu et sous-menu dynamiques

par ynx » 06 janv. 2022, 12:20

Ton execute n'est pas bon : il n'y a plus de marqueur :id_cat dans la requête, il n'est donc plus nécessaire de passer ce paramètre dans le execute.

Re: Affichage d'un menu et sous-menu dynamiques

par max303 » 06 janv. 2022, 01:05

Si la dernière option est meilleure et que je n'aurai pas de surprises avec plus tard,, je la choisie, car la première n'a pas marché:

Code : Tout sélectionner

function getPhotosAnnonces($annonces) { global $bdd; $sql = 'SELECT id_annonce,filepath as IMG FROM images_annonces WHERE id_annonce = IN (' . implode(',', array_column($annonces, 'id')) . ')'; try { $req = $bdd->prepare($sql); $req->execute( array('id_cat'=>$id_cat) ); $res = $req->fetchAll(PDO::FETCH_GROUP); var_dump($res); } catch (Exception $e) { echo "Erreur dans la requête " . $sql; } // le temps des tests pour voir le résultat return $res; }
Est-ce que le execute est bon ?

Code : Tout sélectionner

$req->execute( array('id_cat'=>$id_cat) );
.
J'obtiens les erreurs suivantes:
Notice: Undefined variable: id_cat in C:

Notice: Undefined variable: res in C dans

Re: Affichage d'un menu et sous-menu dynamiques

par ynx » 05 janv. 2022, 22:40

Tu ne peux pas enchainer deux conditions IN comme ceci :
WHERE id_annonce IN (...) OR IN (...) -- incorrect
Si besoin de faire deux sous-requêtes, on pourrait éventuellement l'écrire comme ceci :
WHERE id_annonce IN (...) OR id_annonce IN (...) -- correct

Dans ton cas, la sous-requête utilisée dans la clause IN de la fonction getPhotosAnnonces() devrait être la même requête que celle utilisée dans la fonction getAnnonceCategorie(), à l'exception de la clause SELECT pour sélectionner seulement l'identifiant dans la sous-requête.
Si par exemple, la requête pour les annonces dans ta fonction getAnnonceCategorie() est :
SELECT A.*, C.nom_fr AS CATEGORIE, V.ville_fr AS VILLE
FROM annonces A
LEFT JOIN categories C ON C.id = A.id_categorie
LEFT JOIN villes V ON V.id = A.id_ville
WHERE A.id_categorie = :id_cat OR id_parent = :id_cat
ORDER BY A.created_date DESC
La requête sql dans la fonction getPhotosAnnonces() pourrait être :
SELECT id_annonce,filepath as IMG
FROM images_annonces
WHERE id_annonce IN (
    SELECT id 
    FROM annonces A
    LEFT JOIN categories C ON C.id = A.id_categorie
    LEFT JOIN villes V ON V.id = A.id_ville
    WHERE A.id_categorie = :id_cat OR id_parent = :id_cat
)
Le ORDER BY dans la sous-requête n'est pas utile.

Dupliquer la première requête en sous-requête dans ta deuxième fonction devrait fonctionner mais sera compliquer à maintenir. Il faudra que tu penses à modifier correctement ta requête aux deux endroits à chaque changement.

Une autre solution serait de changer le paramètre passé à la fonction getPhotosAnnonces($id_cat).

Au lieu de lui passer l'identifiant de la catégorie des annonces, ce qui oblige à répéter la requête pour sélectionner les annonces en fonction de la catégorie, tu pourrais simplement lui passer les identifiants des annonces que tu as déjà récupéré juste avant avec la fonction getAnnonceCategorie().
Un exemple :
// $annonces : la liste des annonces retournée par la fonction getAnnonceCategorie()
// liste de tableau associatif (si PDO::FETCH_ASSOC est utilisé dans getAnnonceCategorie) avec une clé 'id' pour chaque annonce
function getPhotosAnnonces($annonces) {
	global $bdd;
	$sql = 'SELECT id_annonce,filepath as IMG
	FROM images_annonces
	WHERE id_annonce = IN (' . implode(',', array_column($annonces, 'id')) . ')';
	// ... suite de la fonction
	return $res;
}

function affichageAnnonce($id_cat) {
	global $bdd;
	$annonces = getAnnonceCategorie($id_cat);
	$images = getPhotosAnnonces($annonces); // on passe la liste des annonces en paramètre
	// ...	

Re: Affichage d'un menu et sous-menu dynamiques

par max303 » 05 janv. 2022, 20:13

ça marche, mais ça retourne des images vides pour toutes les catégories dont l'id_parent=0.

Quand on vardump la fonction getPhotosAnnonce, on obtient un tableau vide.

Et quand je modifie la fonction getPhotosAnnonce, ça ne marche pas non plus:

Code : Tout sélectionner

function getPhotosAnnonces($id_cat){ global $bdd; $sql = 'SELECT id_annonce,filepath as IMG FROM images_annonces WHERE id_annonce IN (SELECT id FROM annonces A WHERE A.id_categorie = :id_cat ) OR IN (SELECT id_parent FROM categories C WHERE C.id_parent = :id_cat ) ';

Re: Affichage d'un menu et sous-menu dynamiques

par ynx » 05 janv. 2022, 17:21

Il ne semble pas nécessaire de changer le lien ou d'ajouter un paramètre id_parent pour les menus des catégories parents.

Pour afficher les annonces des sous-catégories lorsqu'on sélectionne une catégorie parent, il faut modifier la clause WHERE de la requête sql dans la fonction getAnnonceCategorie().
Par exemple, on pourrait modifier cette requête pour sélectionner les annonces dont la catégorie est égale à la catégorie choisie ou les annonces dont la catégorie parent est égale à la catégorie choisie, soit :
WHERE A.id_categorie = :id_cat OR C.id_parent = :id_cat
Puisque tu as fais une jointure avec la table categories, il me semble que cette clause WHERE devrait fonctionner mais c'est aussi fort probable que je me trompe, n'hésites pas à tester pour vérifier que tu obtiens bien les résultats attendus.

Re: Affichage d'un menu et sous-menu dynamiques

par max303 » 05 janv. 2022, 16:15

Ok ça marche, et pour les catégories parents avec id_parent=0, faudrait-il faire une nouvelle requête avec une fonction, ou faudrait changer
le lien?

Code : Tout sélectionner

echo "<li class='menu'><a href= 'affichage.php?id={$menu['id']}'>{$menu['nom']}</a>";
Si nous devons changer le lien, y-a-t-il un moyen de faire

Code : Tout sélectionner

href= 'affichage.php?id_parent=0 && id=
Quelle serait le bon code.
L'objectif c'est lorsqu'on clique sur une des catégories principale, toutes les sous-catégories s'affichent. Ex: je clique sur véhicules, DONC, les motos, les vélos, les voitures... VONT s'afficher.

Re: Affichage d'un menu et sous-menu dynamiques

par ynx » 05 janv. 2022, 14:28

Dans ce cas il faut déboguer la fonction getPhotosAnnonce.

La requête sql pour récupérer les images des annonces ne semble pas correcte :
SELECT id_annonce, filepath as IMG FROM images_annonces WHERE id_annonce = :id_cat
-> Ici tu compares l'identifiant de l'annonce id_annonce avec l'identifiant de la catégorie id_cat, la comparaison n'est donc pas correcte puisqu'il s'agit de deux types d'identifiant différent.

Tu pourrais peut-être modifier cette requête comme ceci :
SELECT id_annonce, filepath as IMG FROM images_annonces WHERE id_annonce IN (SELECT id FROM annonces A WHERE A.id_categorie = :id_cat)
-> Ici, dans la sous-requête entre parenthèse, on récupère uniquement les identifiants des annonces de la catégorie choisie, puis on utilise l'opérateur sql IN pour récupérer toutes les images correspondants à ces annonces.

Re: Affichage d'un menu et sous-menu dynamiques

par max303 » 05 janv. 2022, 01:33

J'ai modifié le code qui se trouve là haut comme tu peux le voir, l'annonce s'affiche mais sans images. Quand je fais un vardump de la fonction getPhotosAnnonce, ça retourne un tableau vide.

Re: Affichage d'un menu et sous-menu dynamiques

par max303 » 05 janv. 2022, 00:50

J'ai encore mal formulé. Je tombe sur une page où il y a uniquement mon header et mon footer. La maquette sur laquelle doit apparaitre l'annonce de la catégorie choisie (i.e l'affichage), est vide.
Peux-tu me confirmer que l'erreur n'est pas dans mon code? Ai-je bien écrit mes fonctions et ma page d'affichage? Si non, que faudrait-il que je fasse?

Re: Affichage d'un menu et sous-menu dynamiques

par ynx » 05 janv. 2022, 00:10

Si rien ne s'affiche, c'est qu'il y a surement une erreur php.
Essaye d'afficher les erreurs php ou regarde dans les logs de ton serveur web :
tutoriels/page-blanche-script-php-comme ... 73178.html