Bonjour,

Je suis actuellement entrain de développer mon site et je dois traiter les données de ma base de données avant de les envoyers.

Je fais donc des tests avant de le faire sur CakePHP sur des pages de test avec des requêtes traditionnelles.

Voici donc ce que j'ai fais, bien sûr elle fonctionne bien :

$req = $pdo->prepare('SELECT * FROM equipements WHERE nom = "Petite Amulette du Hibou"');
$req->execute();
$donnees = $req->fetch();

$explodeCraft = explode("+", $donnees['liste_ingredient']); // On sépare chaque craft
$taille_explode_craft = count($explodeCraft); // On compte le nombre de craft

if (!empty($donnees['liste_ingredient'])) {

    for ($taille=0; $taille < $taille_explode_craft; $taille++) { 
        $explode_craft_item = explode("x", $explodeCraft[$taille]); // On sépare le nombre d'ingrédient requis et le nom de l'ingrédient.

        $req2=$pdo->prepare('SELECT * FROM ressources WHERE nom = "'.$explode_craft_item['1'].'" ');
        $req2->execute();
        $resultcraft=$req2->fetch();
            echo ''.$explode_craft_item[0].' x '.$explode_craft_item[1].'';
            echo $resultcraft['categorie'];
    }
}else{
    echo "Cette équipement ne se craft pas";
}

Mon seul problème c'est que je ne sais pas comment reproduire cela avec CakePHP, alors si quelqu'un pourrait m'aider ou au moins m'expliquer comment on fait.

J'ai réussi à faire la première requête mais la deuxième requête dans le "for" je ne vois pas comment la faire.

Merci d'avance.

Cordialement,

22 réponses


Bonsoir.
Tu peux soit regarder sur la doc de CakePHP ou alors regarder les tutoriels et/ou la formation concernant CakePHP, les requêtes SQL y sont expliquées et détaillées.

Tchoupi
Auteur

J'ai passé ma soirée hier sur la doc mais je ne trouve pas ce que je souhaite...
Et j'ai déjà regarder la formation mais il n'explique pas je crois ce que je souhaite.

Je ne vois pas quel est le problème, tu fais de simples requêtes SQL SELECT, pour ce qui concerne le reste de ton code PHP, je ne vois pas en quoi ça change que tu sois sur CakePHP ou non.
La seule différence notable, ce serait que tu mette ton code dans une action du controller au lieu de l'avoir dans un fichier de vue.

Tchoupi
Auteur

C'est la question que je me pose hier justement si je dois mettre tout monde dans mon controller ou si je peux faire mon code la view mais à ce moment là, comment je peux faire la deuxième requête.

Au lieu de mettre les echo dans ton for tu stockes dans des variables, ensuite à l'extérieur de la boucle tu envoies les variables via un $this->set(compact('categories', 'items')); par exemple et ton message dans le cas où la liste d'ingrédient est vide, tu l'envoies via un message flash de la session $this->Session->setFlash('Cette équipement ne se craft pas');.

Ceci bien sûr dans l'action du controller, dans la vue tu récupères tes variables et tu fais le traitement nécessaire.

Tchoupi
Auteur

Mhh oui, j'avais pensé à ça mais je ne voyais pas comment le faire, mais je pense que ça ne va pas fonctionner car dans ma vue en faite tout mon contenu est dans un foreach, je liste tous mes équipements et pour chaque équipement j'ai des Statistiques, des conditions, une description et un craft. Le code que j'ai posé plus haut est uniquement pour le craft, en sachant que dans ma vu je n'envoi pas pour qu'un item mais pour une centaine.

Je ne sais pas si tu as compris lol.

J'ai quand même essayer ce que tu m'as dis mais comment je peux faire pour ceci :

$req = $pdo->prepare('SELECT * FROM equipements WHERE nom = "Petite Amulette du Hibou"');
$req->execute();
$donnees = $req->fetch();

$explodeCraft = explode("+", $donnees['liste_ingredient']); // On sépare chaque craft
$taille_explode_craft = count($explodeCraft); // On compte le nombre de craft

Moi j'avais fais la partie requête dans le controller et à partir de l'explode dans ma vue. ça à donné ça :
Controller :

$equipements = $this->Equipement->find('all', [
            'conditions' => ['Equipement.categorie' => 'Amulette'],
            'order' => ['Equipement.lvl ASC']
            ]
        );

$this->set(compact('equipements'));

Vue :

<?php foreach ($equipements as $k => $item): ?>

$explodeCraft = explode("+", $item['Equipement']['liste_ingredient']); // On sépare chaque craft
$taille_explode_craft = count($explodeCraft); // On compte le nombre de craft

<?php endforeach ?>

Donc vu que je met mon code dans le controller comment je peux remplacer cette ligne là ? $item['Equipement']['liste_ingredient']

Désolé de poser tant de question mais là je vois vraiment pas comment faire...

Merci pour ton aide.

Tu n'as pas compris, je ne t'ai pas dit de faire la première requête SQL et d'envoyer ses données à la vue.
Tu fais la seconde requête SQL et tu envoies les données à la vue (bien que tu peux faire la partie que tu faisais de son traitement avant d'envoyer à la vue).

Tchoupi
Auteur

Bon franchement je vois pas comment faire je suis vraiment bloqué... Je vais continuer à essayer...

Merci quand même.

Déja, ta première requête SQL concernant la table equipements change entre le code du début et celui que tu viens de montrer, de cette manière, je ne vois pas comment t'aider.
Au début du veut récupérer un enregistrement d'après la valeur du champ nom et dans celle que tu fais avec CakePHP, tu fais par rapport à la valeur du champ categorie.

Tchoupi
Auteur

Oui en faite si j'ai fais une requête par rapport au champ nom c'est uniquement pour faire mes tests pour exploiter ma BDD et surtout pour éviter d'avoir toutes les amulettes d'afficher ce qui ralenti l'affichage et ça ne me sert à rien d'afficher tout.

Ma vue est réèlement comme ça :

<?php foreach ($equipements as $k => $item): ?>

      <div class="item">
          <div class="item-title">
              <?= $item['Equipement']['nom'] ?> <span class="item-level">Niv.<?= $item['Equipement']['lvl'] ?></span>
          </div>
          <div class="item-menu rotate">
              <a data-tab="item-craft">Crafts</a>
              <a class="active" data-tab="item-effet">Effets</a>
              <a data-tab="item-description">Description</a>
          </div>
          <div class="item-image">
              <?= $this->Html->image('pictos/image-anneau.png') ?>
          </div>
          <div class="item-effet item-onglet">
              <div class="item-effets">
                  <ul>
                      <?php 
                        $str_replace = str_replace("+", "", $item['Equipement']['effets']);
                        $explodeStats = explode("&", $str_replace);

                        if ($item['Equipement']['effets'] == null) {
                          echo "<li>Aucun effet pour cette Amulette</li>";
                        }else{
                          for ($i=0; $i < count($explodeStats); $i++) { 
                            echo "<li>".$explodeStats[$i]."</li>";
                          }
                        }
                      ?>
                  </ul>
              </div>

              <div class="item-conditions">
                  <ul>
                      <?php 
                        $explodeCritere = explode("&", $item['Equipement']['critere']);

                        if ($item['Equipement']['critere'] == null) {
                          echo "<li>Aucun pré-réquis pour cette Amulette</li>";
                        }else{
                          for ($i=0; $i < count($explodeCritere); $i++) { 
                            echo "<li>".$explodeCritere[$i]."</li>";
                          }
                        }
                      ?>
                  </ul>
              </div>
          </div>

          <div class="item-description item-onglet">
              <p><?= $item['Equipement']['description'] ?></p>
          </div>

          <div class="item-craft item-onglet active">
                <!-----
                --   ICI JE MET MON CODE
                ---------- ?>
          </div>
          <div class="clear"></div>

      </div>

      <?php endforeach ?> 

Dans la div "item-craft item-onglet active" je dois mettre ceci :

$explodeCraft = explode("+", $donnees['liste_ingredient']); // On sépare chaque craft
$taille_explode_craft = count($explodeCraft); // On compte le nombre de craft

if (!empty($donnees['liste_ingredient'])) {

    for ($taille=0; $taille < $taille_explode_craft; $taille++) { 
        $explode_craft_item = explode("x", $explodeCraft[$taille]); // On sépare le nombre d'ingrédient requis et le nom de l'ingrédient.

        $req2=$pdo->prepare('SELECT * FROM ressources WHERE nom = "'.$explode_craft_item['1'].'" ');
        $req2->execute();
        $resultcraft=$req2->fetch();
            echo ''.$explode_craft_item[0].' x '.$explode_craft_item[1].'';
            echo $resultcraft['categorie'];
    }
}else{
    echo "Cette équipement ne se craft pas";
}

Du coup mon problème c'est mettre ce code avec CakePHP.

Et pour simplifier les choses, je suppose que tu ne peux pas (ou ne dois pas) modifier la structure et le contenu des ces tables.

Tchoupi
Auteur

Le problème c'est que mes table sont remplies... mes tables contiennent un peu plus de 3000 lignes chacune...

Si je comprends bien, même en filtrant via une catégorie, tu vas avoir un retour de beaucoup d'enregistrements via la table equippements.
C'est ça ?

Tchoupi
Auteur

Oui voilà par exemple pour la catégorie "Amulette" de la table equipements je vais avoir un peu plus de 300 lignes.

Tchoupi
Auteur

Je suis en train de penser si bien sûr je réussi. Car en faite il me faut concrètement afficher le craft de mon équipements. un équipement peu avoir 8 crafts au maximum.
En sachant qu'un craft est comme suit :

  • Le nombre de ressource requise
  • La ressource en question
  • Le type de ressources

En sachant si je veux récupérer le type de ressource je dois faire une requête dans ma table ressources pour connaître le type de ressources en question.

Je pourrais faire sinon créer 16 colonnes dans ma table equipements comme suit :

  • craft_1
  • categorie_craft_1
  • craft_2
  • categorie_craft_2
  • ... etc jusqu'à 8

Et faire une requête qui met à jour base table equipement pour remplir ces colonnes ?
Mais est ce que avoir du coup 16 colonnes en plus ne ralentierai pas mon site ?

Oui voilà par exemple pour la catégorie "Amulette" de la table equippements je vais avoir un peu plus de 300 lignes.

Je te conseille donc de faire une pagination pour la requête sur la table equippements et pour ce qui concerne la section pour les crafts, d'en faire l'appel via une requête en ajax, en rendant le résultat par exemple, dans une "boite modale" ou quelque chose du genre, ce qui te permettra d'alléger ta page au niveau du contenu de celle-ci.
De cette manière, tu récupères les infos directes au données des équippements, tu fais un bouton ou un lien qui permet via un retour en ajax, de récupérer les données pour le craft.

Tchoupi
Auteur

Oui toute manière je n'afficherai pas les 300 d'un coup, je les affichent pas tranche de niveau.

Mais en quoi la requête en ajax résoudra mon problème ?
Je n'ai encore jamais utilisé d'ajax, je vais me renseigné à ce niveau là, j'ai vu que grafikart à fais un tuto sur l'ajax avec cakephp.

Parce qu'en mettant ta deuxième requête dans une autre fonction du controlleur, tu éviteras pour commencer, une surcharge de la fonction actuelle du controlleur, ensuite, en faisant une requête en ajax pour la seconde requête SQL, la requête SQL ne sera exécutée que par l'action de l'utilisateur et seulement pour l'enregistrement "cliqué" par ce même utilisateur.
Ce qui t'évite des surcharges SQL pour plusieurs enregistrements en une seule fois.

Tchoupi
Auteur

Ah d'accord, et vu que l'a je fonctionne sous onglet pour regarder le craft faudrat aller cliquer sur onglet donc ça devrai marcher du coup.
Je vais regarder ça mais bon je promets rien ... sachant que je ne connais pas du tout l'ajax...

Tchoupi
Auteur

Je réfléchi depuis 2 jours sur ce que tu m'as dis, mais sachant que ma deuxième requête contient une variable, mon problème bloquera toujours.
Car faut que la function puisse récupérer la variable.

Je ne vois pas où est le problème, javascript n'a pas qu'une action unidirectionnelle.
Tu peux lui dérfinir la valeur de la variable via un attribut du lien de l'onglet, puis tu l'injectes dans l'URL appelée dans l'ajax.
De cette manière, l'URL appelée par ajax, pourra par exemple être :

url : "<?= $this->Html->url(array('controller' => 'equippements', 'action' => 'ressources', taVariableJavascript)) ?>",

taVariablejavascript, contiendrait la valeur de la variable que tu veux faire passer à l'action de ton controlleur.

Tchoupi
Auteur

Ouais, mais bon étant complètement larguer avec l'Ajax depuis 2 jours, j'en ai un peu plein à la tête lol.
Mais bon j'arriverai bien à bout ...

Mais sinon pour faire simple, ce n'est pas possible de faire une requête directement dans la vue. Même si je pense que ce ne soit pas recommandé... Mais ça me simplifierai tout.
Parce que là je me casse la tête simplement à cause d'une requête.