Site e-commerce

Recherche d'un "prof particulié" pour conseils/questions

a marqué ce sujet comme résolu.

Tu utilises $query->fetch(), qui ne te retourne jamais qu'une seule ligne  ;)

Pour sélectionner un élément dans une liste de choix, il faut que, à la génération de la liste, on vérifie si la valeur choisie est la même que l'élément qu'on affiche. Pour ça, pas trop de souci :

1
2
3
4
5
6
7
8
<?php
foreach ($choix as $valeur => $etiquette) {
    echo "$etiquette ($valeur";
    if ($valeur_choisie == $valeur) {
        echo " — choisie !";
    }
    echo ")\n";
}

Pré-sélection d'option

Maintenant, quand on a une liste où on peut choisir plusieurs éléments (ce qui est le cas quand on a un <select multiple="multiple"> comme une série de <input type="checkbox" />), on ne va plus avoir une seule valeur choisie, mais une série. Du coup, on va devoir regarder si la valeur qu'on affiche est dans cette série.

1
2
3
4
5
6
7
8
<?php
foreach ($choix as $valeur => $etiquette) {
    echo "$etiquette ($valeur";
    if (in_array($valeur, $valeurs_choisies)) {
        echo " — choisie !";
    }
    echo ")\n";
}

Pré-sélection d'options multiples


Edit

Ici aussi, évite de poster deux sujets à la suite à deux heures d'intervalle, tu as l'édition qui permet d'ajouter du contenu à un message  ;)

+1 -0

Merci d'avoir répondu ! :)

Je suis pas sûr d'avoir tout compris pas contre :/

1
2
3
4
5
6
7
8
<?php                   
foreach ( $categories as $categorie ) { 
    if (in_array($categorie['idMPL_Category'], $produit)) {
?>
    <label class="checkbox">
    <input checked="" type="checkbox" name="productcategory[]" value="<?php echo $categorie['idMPL_Category']; ?>"><?php echo  $categorie["MPL_CategoryName"]; ?>   
    </label>
<?php } }?>

Là j'ai bien mes catégories associées déjà coché mais je n'ai évidemment plus les autres… C'est cette histoire de checked, no checked qui me bloque aussi je vois vraiment pas.. :(

Analyse un peu ton code : avec le if directement dans la boucle for, tu n'auras effectivement que les catégories sélectionnées qui s'afficheront. Regarde un peu mieux mon exemple : j'ai du code entre la déclaration du for et le if (et du code après), qui affiche ce qui est commun aux deux cas : catégorie choisie ou pas  ;)

+0 -0

Ca me semble compliqué !

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php                   
    foreach ( $categories as $check => $categorie) { 
        echo "$categorie ($check";
    if (in_array($categorie['idMPL_Category'], $produit)) {
?>
    <label class="checkbox">
    <input checked="" type="checkbox" name="productcategory[]" value="<?php echo $categorie['idMPL_Category']; ?>"><?php echo  $categorie["MPL_CategoryName"]; ?>   
    </label>
<?php }
    echo ")\n";
}?>

Là j'ai une erreur Array to string conversion à la ligne 3 je suis pas sûr de comprendre ce que je fais à cette ligne hum..

Edit : Je ferais le html specialchars quand tout sera ok, merci Artragis :)

+0 -0

Allons plus loin dans la réflexion.

Entre une catégorie non-choisie et une catégorie choisie, qu'est-ce qu'il y a comme différence ?

1
2
3
4
5
6
7
8
9
<label class="checkbox">
    <input
            checked="checked"
            type="checkbox"
            name="productcategory[]"
            value=""
        />
        Ma catégorie
</label>

Mise en exergue de la différence entre les catégories choisies et pas choisies

Ce qui veut dire qu'entre le for et le if, il faut mettre les lignes 1 et 2, et après la fermeture du if et avant la fermeture du for, les lignes 4 à 9.

Ensuite, il faut regarder comment fonctionne in_array(). Il faut vérifier si la catégorie sur laquelle tu fais l'itération (à passer en premier paramètre) est dans la liste des catégories du produit (qu'il faut extraire d'une manière ou d'une autre des données du produit)

+0 -0

Voulant tester quelque chose, j'ai supprimé tous mes produits manuellement un par un. J'ai ensuite voulu rajouter un produit pour pouvoir continuer mes test sur la modification et là j'ai une erreur SQL qui apparaît

1
Erreur Mysql : SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`lepetit`.`mpl_category_has_mpl_products`, CONSTRAINT `fk_MPL_Category_has_MPL_Products_MPL_Products1` FOREIGN KEY (`MPL_Category_idMPL_Category`) REFERENCES `mpl_products` (`idMPL_Products`) )

Etant donnée que je n'ai pas touché à mes requêtes, je comprends pas :( Ca me fait carrément perdre en motivation ! Un problème d'insert dans ma base au niveau de l'ajout de catégorie(s) associée(s) à mon produit dans –Ajout produit–. Vous avez une idée ?

J'te remercie Ymox, j'me tâte d'essayer tout ça :D

Edit :

En gros ce serait sur cette requête mais c'est le fait que "ça fonctionnait avant mais plus maintenant" qui me frustre ><

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php
function ajouter_product_has_category($category, $id){
    global $pdo;
    try {
        $query = $pdo->prepare("INSERT INTO mpl_category_has_mpl_products (MPL_Category_idMPL_Category, MPL_Products_idMPL_Products)
            VALUES (:category, :id)");
        $query->bindValue(':category', $category, PDO::PARAM_STR);
        $query->bindValue(':id', $id, PDO::PARAM_INT);
        $query->execute();
        return true;
    }
    catch(PDOException $e) {
        die('Erreur Mysql : '.$e->getMessage());
    }
    $query->closeCursor();
}
+0 -0

Regarde attentivement les valeurs que tu tentes d'insérer dans ta fonction ajouter_product_has_category(), je pense que l'une des deux n'est pas présente dans les IDs soit des produits, soit des catégories, et du coup, tu ne peux pas faire l'insertion, ce qui me paraît logique.

+0 -0

C'est vraiment bizarre je suis allez insérer manuellement dans la table qui joint produit à catégorie une association d'id… et je tombe sur ça.

En gros il me propose de sélectionner les ids de produits alors que je suis censé avoir les ids de catégorie (qui vont actuellement de 1 à 5) ! :o

Ta table MPL_Category_has_MPL_Product a une clé primaire, et une clé étrangère avec deux contraintes depuis les deux tables liées…
Dans MySQL Workbench, supprime la table MPL_Category_has_MPL_Products et créé une liaison n:m entre Category (première table à sélectionner) et Product. La table ainsi (re-)créé sera correcte.

Il est tout à fait possible que certaines tables n'aient pas de clé primaire ou une clé primaire composite, c'est justement le cas ici (il y a des clés qui sont orange pour les deux colonnes de MPL_Category_has_MPL_Products dans ma version de MySQL Workbench)

+1 -0

Hey !

J'ai essayé du coup de continuer ma modification produit, je n'ai plus d'erreur. Lorsque j'ai une catégorie associé, l'affichage est correct :)

Cependant, lorsque j'en ai deux ou plus, je n'ai que la première de coché :o

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php                   
foreach ( $categories as $check => $categorie) { 
?>
    <label class="checkbox">
    <input
<?php
    if (in_array($categorie['idMPL_Category'], $produit)) {
?>
    checked="checked"
<?php
    }
?>
     type="checkbox" name="productcategory[]" value="<?php echo $categorie['idMPL_Category']; ?>"><?php echo  $categorie["MPL_CategoryName"]; ?>
    </label>
<?php
}
?>

Du coup, est-ce vraiment dans le code ci-dessus que ça coince ? :o Ne serait-il pas plutôt ma requête qu'il faudrait revoir.. j'essaie de tracer ce que je fais mais je n'en tire pas grand chose :/

Oui, c'est que $produit ne contient probablement qu'une seule parmi toutes les catégories.

Il faudrait voir pour construire un tableau avec toutes les catégories du produit. Je ne sais pas si PDO permet de faire des regroupements sur plusieurs colonnes, mais l'idéal serait que dans $produit tu aies array( /* … les différentes données du produit */, 'categories' => array(/* les données des catégories */)), et ainsi utiliser $produit['categories'] comme second argument de in_array().

Autrement, il faudrait construire ce tableau des catégories à partir des résultats de ta requête mentionnée un peu avant.

+1 -0

Je ne sais pas si PDO permet de faire des regroupements sur plusieurs colonnes

Je crois que PDO::FETCH_GROUP sert à ça non ? Je ne l'ai encore jamais utilisé je voudrais pas m'avancer…

Si je construis un tableau de catégories à partir des résultats de ma requête, y'aurait-il des inconvénients ? :o

+0 -0

Je ne sais pas si PDO permet de faire des regroupements sur plusieurs colonnes

Je crois que PDO::FETCH_GROUP sert à ça non ? Je ne l'ai encore jamais utilisé je voudrais pas m'avancer…

Moufle

Je connais la constante, mais je ne suis pas sûr que son utilisation sur plusieurs colonnes en même temps soit possible

+0 -0

Hey, n'ayant toujours pas réglé ce problème je voudrais néanmoins essayer de corriger un autre bug. Dans ma page "afficher tous les produits", je fais appelle à cette requète :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
function product_has_category(){
    global $pdo;
    try {
        $query = $pdo->prepare("SELECT * 
            FROM MPL_Category_has_MPL_Products, MPL_Category, MPL_Products
            WHERE MPL_Category_idMPL_Category = idMPL_Category
            AND MPL_Products_idMPL_Products = idMPL_Products
            ORDER BY idMPL_Category");
        $query->execute();
        $produits = $query->fetchAll();
        return $produits;
    }
    catch( PDOException $e ) {
        die('Erreur Mysql : '.$e->getMessage());
    }
    $query->closeCursor();
};

Le soucis étant que si j'ajoute un produit avec plusieurs catégories associées, j'aurais dans la page "afficher tous les produits", plusieurs lignes indiquant un seul même produit.

Ex : Pour le produit "sopalin" appartenant à la catégorie Hygiène et la catégorie Encombrant, j'aurais deux lignes. Je voudrais une seule ligne, et dans la colonne catégorie, tous les produits associées au produit.

Comment pensez-vous que je pourrais changer la requête pour récupérer ce que je veux ? :o

Je vous remercie d'avance :)

Alors dans un premier temps, utilise ici aussi une "vraie" jointure :p

Ensuite, tu as le genre de problème courant de produits dans des catégories. Pour avoir toutes les catégories d'un produit quand celui-ci est "présent plusieurs fois", il faut que ta requête soit ordonnée (ce qui est le cas). Et tu boucles sur tes résultats.
Tu regardes si le produit courant est le même que le produit précédent. Si oui, alors c'est une nouvelle catégorie, tu n'affiches que son nom. Si non, c'est un nouveau produit, il te faut afficher toutes les informations.

+1 -0

Merci pour ta réponse Ymox :)

Alors dans un premier temps, utilise ici aussi une "vraie" jointure :p

Je m'empresse de le faire ;)

Tu regardes si le produit courant est le même que le produit précédent. Si oui, alors c'est une nouvelle catégorie, tu n'affiches que son nom. Si non, c'est un nouveau produit, il te faut afficher toutes les informations.

Pouahlala, comment je peux faire ça ? Ne serait-ce que "regarder" si le produit courant est le même que le produit précédent :o Actuellement il sont classé par catégorie, pour que ça fonctionne avec ta méthode il faudrait qu'ils soient classé par produit en plus si je comprends bien.

Je pensais faire une boucle dans une boucle mais j'ai vite renoncer en voyant le résultat ^^ Pour l'instant ça ressemble à ça :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<tbody>
<?php foreach ( $produits as $produit ) { ?>
    <tr>
      <td><?php echo $produit["MPL_ProductName"]; ?></td>
      <td><?php echo $produit["MPL_CategoryName"]; ?></td>
      <td class="hidden-phone"><?php echo $produit["MPL_ProductPrice"]; ?> &#x20AC;</td>
          <td class="centered">
        <button value="<?php echo $produit['idMPL_Products']; ?>" formaction="?module=product&amp;action=modifier&amp;id=<?php echo $produit['idMPL_Products']; ?>" formmethod="post" class="btn btn-primary btn-xs" type="submit"><i class="fa fa-pencil"></i></button>                                  
      </td>
      <td>
        <div class="centered">
            <label>
                <input type="checkbox" name="choix[]" value="<?php echo $produit['idMPL_Products']; ?>">
            </label>
        </div>
      </td>
   </tr>
<?php } ?>
</tbody>

Pouahlala, comment je peux faire ça ? Ne serait-ce que "regarder" si le produit courant est le même que le produit précédent :o

Moufle

Ben il faut faire en sorte que le programme se souvienne de ce qu'il avait manipulé juste avant… Avec une variable, par exemple  ;)

Actuellement il sont classé par catégorie, pour que ça fonctionne avec ta méthode il faudrait qu'ils soient classé par produit en plus si je comprends bien.

Moufle

Là, j'avoue que ça dépend de ce que tu souhaites. Mais tu as dit vouloir une ligne avec le produit et toutes ses catégories, du coup, oui.

Je pensais faire une boucle dans une boucle mais j'ai vite renoncer en voyant le résultat ^^

Moufle

Tu n'en as effectivement pas besoin, il suffit de bien réfléchir à qu'est-ce qu'il se passe dans la boucle principale.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
$reponse = $bdd->query(/* La requête */);
/* On initialise la variable comme étant une chaîne vide en dehors de la boucle… */
$precedent = '';
while ($donnees = $reponse->fetch())
{
    /* … parce qu'on en a besoin ici pour tester si on a changé de produit. Et
     * à la première itération, c'est presque le cas. Le fait d'avoir défini
     * comme une chaîne vide avant permet de faire en sorte que l'ID du
     * premier produit est considéré comme différent de celui d'avant qui,
     * pourtant n'existe pas */
    if ($precedent != $donnees['MPL_product_id']) {
        if ($precedent !== '') {
            echo '</td></tr>';
        }
        echo '<tr><th>'
            . htmlspecialchars($donnees['MPL_product_name'])
            . '</th></tr>';
    }
    /* On affiche de toute manière la catégorie */
    echo htmlspecialchars($donnees['MPL_Category_name']);
    /* Si on avait mis cette ligne en début de boucle, on aurait une condition
     * qui serait toujours respectée, donc on n'afficherait jamais le nom de
     * l'article. Et là, donc, on aura le nom du produit de la boucle
     * précédente dans la boucle suivante (tu suis ?) */
    $precedent = $donnees['MPL_Category_id'];
}
$reponse->closeCursor();

Une gestion d'éléments catégorisés (ici dans un tableau)

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte