[RESOLU] Base de données JSON

Petit nouveau ! | 8 Messages

08 nov. 2018, 16:32

Bonjour :)

Je développe actuellement un site vitrine pour un restaurant et je dois permettre à ses employés de modifier la carte eux même sur le site.
J'ai donc créer une base de données au format JSON qui répertorie toute les données de la carte (catégorie, nom, prix)
J'ai réussis à récupérer et afficher ces données dans un espace administrateur et maintenant j'aimerais créer un formulaire PHP qui permet de les mettre à jour, les supprimer ou en ajouter de nouvelles dans le fichier JSON mais je ne sais pas comment faire...
Je sais le faire avec une base de données MySQL et des requêtes préparées PHP mais est-ce que ca fonctionne pareil avec JSON ?

Merci d'avance

Mammouth du PHP | 968 Messages

08 nov. 2018, 19:17

non car il faut tout réécrire quand on modifie le json alors qu'avec sql, il est possible de ne modifier qu'un seul enregistrement.
pour le faire avec du json, il faut décoder le json dans un objet php, appliquer les modifications selon le contenu du formulaire à l'objet php, sauver l'objet php en json.

Petit nouveau ! | 8 Messages

09 nov. 2018, 13:25

OK mais du coup pourrait tu me montrer un exemple de comment procéder ? J'ai cherché sur internet mais je ne trouve pas grand chose... :?
J'ai un fichier menu.json dont je récupère les données comme ceci :
$menu = file_get_contents("db-json/menu.json");
$parsedMenu = json_decode($menu);

$entrees = $parsedMenu->{"entrees"};
$plats = $parsedMenu->{'plats'};
$patisseries = $parsedMenu->{"desserts"}[0]->{"patisseries"};
$yaourts = $parsedMenu->{"desserts"}[1]->{"yaourts"};
$fromages = $parsedMenu->{"desserts"}[2]->{"fromages"};
$sandwichs = $parsedMenu->{"sandwichs"};
$panninis = $parsedMenu->{"panninis"};
$boissons = $parsedMenu->{"boissons"};
$salades = $parsedMenu->{"salades"};
$light = $parsedMenu->{"light"};
$pates = $parsedMenu->{"pates"};
$asiat = $parsedMenu->{"asiat"};
$formules = $parsedMenu->{"formules"};
Ensuite je boucle sur chaque catégorie du menu (entrées, plats, etc...) pour afficher des input contenant les noms des plats dans mon formulaire ainsi que un bouton modifier et supprimer en face de chaque input.
foreach($patisseries as $patisserie)
{
  echo
  '
  <li class="spaceBetween bottom30">
    <input type="text" name="nom" value="' . $patisserie->{"nom"} . '" class="right30" />
    <button class="right10"> Modifier </button>
    <button> Supprimer </button>
  </li>
  ';
}
Comment se passe le traitement du formulaire en PHP ??? J'aimerais juste avoir une ligne de conduite pas la solution toutes faites mais la je ne visualise pas du tout comment faire...

Merci ! :D

Mammouth du PHP | 524 Messages

09 nov. 2018, 13:53

Salut TooKi, tu t'es lancé dans quelque chose d'assez périlleux. Quid de l'ajout d'élément ? une nouvelle patisseries, etc.
De plus pour le moment à priori tu ne stockes que des noms mais si tu dois stocker également des prix ?

Bref à mon avis le plus simple c'est qu'ils éditent le json à l'aide d'un outils prévu à cet effet puis qu'ils transmettent le nouveau json. Mais c'est également problématique car tu dois t'assurer que les noeuds principaux (entrees, plats, etc) ne changent pas.
Je suis tombé la dessus via une recherche rapide : https://jsoneditoronline.org/

C'est pas ingérable mais v'la la prise de tête. Soit tu fais un truc très cadré pour que l'utilisateur ne puisse pas casser le json mais tu va devoir bien te prendre la tête. Soit tu te prends moins la tête mais le risque est que le client casse le json à la première modification.

Une idée bête mais assez simple. Pour chaque noeud qui doit être éditable, tu crées un textarea ou tu mets 1 nom par ligne. Par exemple les patisseries tu fais :

Code : Tout sélectionner

patisserie1 patisserie2 etc
L'utilisateur peut facilement les modifier, en ajouter, changer leur ordre.
Quand il valide le champ tu charges le json, tu modifies le noeud patisserie ($json->desserts->patisseries = explode("\n", $_POST['patisseries']);) et tu réenregistres le json.

D'ailleurs tu pourrais à priori simplifier la structure du json des desserts. Visiblement tu as quelque chose de la forme :

Code : Tout sélectionner

{ desserts: [ { patisseries: [ 1, 2, 3, ... ] }, { yaourts: [ 1, 2, 3, ... ] } ] } desserts[0]->patisseries[0]
Tu pourrais plus simplement faire :

Code : Tout sélectionner

{ desserts: { patisseries: [ 1, 2, 3, ... ], yaourts: [ 1, 2, 3, ... ] } } desserts->patisseries[0]

Petit nouveau ! | 8 Messages

09 nov. 2018, 15:00

Salut Saian !

Oui je me rend compte que je me suis lancé dans quelque chose d'assez périlleux, galère et prise de tête ! |*()
J'aurais bien aimé faire ça avec MySQL comme je suis habitué à le faire mais j'ai vu partout que c'était trop lourd pour une utilisation comme la mienne... :-k Et comme je veux faire les choses bien je me suis lancé dans le JSON et puis c'est une occasion d'apprendre quelque chose de nouveau :wink:

Pour l'ajout d'éléments j'ai juste oublié de vous montrer mon formulaire mais c'est juste un input et un bouton d'envoi très simple à coté de chaque catégories.

Pour les prix, ils ne seront finalement pas affichés sur le site donc pas de problème la dessus. :P

Je ne pense pas que la solution de laissé les employés modifier le JSON eux-même soit envisageable. Il faut que je leur créer un espace très simple sans qu'ils aient à toucher une ligne de code.

Pour ce qui est de ta solution, elle ressemble à la mienne puisque je créer déjà un input pour chaque noeuds éditable de mon JSON avec mes foreach.
Ce que je voulais c'est justement le petit bout de code que tu as partagé pour modifier une entrée JSON :)
D'ailleurs si tu pouvait me montrer également le code pour supprimer une entrée et aussi pour en ajouter une, ce serait génial ! :)

Pour la structure de mes desserts, je préfère garder la mienne je trouve qu'elle est plus logique, je me débrouillerai avec :D

Mammouth du PHP | 524 Messages

09 nov. 2018, 15:12

Bah justement si tu fais un input par patisserie, les suppressions, modifications et ajouts sont prise de tête car pour modifier ou supprimer le bon tu dois connaitre son index pour aller modifier ou supprimer le bon.
Tu devrais donc avoir dans ta boucle un input hidden avec l'index de l'élément que tu dois transmettre lors de l'ajout suppression.
Ainsi tu peux faire $json->desserts->patisseries[index] = 'valeur modifiée'; pour la modification.
Pour la suppression tu peux peut être faire un unset($json->desserts->patisseries[index]).
Pour l'ajout, bon courage, il faudrait à minima que tu ajoutes un champ libre pour ajouter. Ensuite tu pourrais faire un $json->desserts->patisseries[] = 'nouvelle valeur'.
Et je te passe les éventuels problèmes que tu pourrais avoir selon la manière dont tu gères ton formulaire et son rafraichissement, le plus simple étant de rafraichir systématiquement toute la page afin que les index soient bien mis à jour.

La solution du textarea est bcp plus simple à gérer et l'utilisateur devrait quand même être capable de respecter cette règle simple : un élément par ligne.

Petit nouveau ! | 8 Messages

10 nov. 2018, 14:31

Salut Saian et merci de m'apporter ton aide !

Ta méthode semble pas mal mais j'ai du mal à la mettre en place... Surtout qu'en plus de récupérer l'id des tableau, je dois également récupérer la catégorie dans laquelle je me trouve (entrees, plats, etc...) Du coup j'ai rajouter un autre input hidden avec comme value la catégorie.

Je vais montrer un exemple avec seulement les entrées histoire d'aller à l'essentiel, je pense que je ne suis pas loin !

Voici mon code réduit au plus simple
<?php
  $menu = file_get_contents("db-json/menu.json");
  $parsedMenu = json_decode($menu);

  $entrees = $parsedMenu->{"entrees"};

  if(isset($_POST["modifier"]))
  {
    $id = $_POST["id"];

    if ($_POST["categorie"] == "entrees")
    {
      $entrees[$id]->{"nom"} = $_POST["nom"];
    }
  }
?>

<form method="post" action="interface-admin.php">
  <ul>
    <?php
      foreach($entrees as $i => $entree)
      {
        echo
        '
          <li>
            <input type="text" name="nom" value="' . $entree->{"nom"} . '" />
            <input type="hidden" name="id" value="' . $i . '" />
            <input type="hidden" name="categorie" value="entrees" />
            <button name="modifier"> Modifier </button>
          </li>
        ';
      }
    ?>
  </ul>
</form>
Le problème c'est que quelque soit le bouton modifier sur lequel j'appuie, PHP récupère toujours le dernier id de la liste...
Modifié en dernier par TooKi le 10 nov. 2018, 14:59, modifié 3 fois.

Mammouth du PHP | 968 Messages

10 nov. 2018, 14:45

c'est $parsedMenu qu'il faut modifier, pas $_POST

Petit nouveau ! | 8 Messages

10 nov. 2018, 14:58

J'ai mis à jour mon précédant message le problème maintenant c'est que quoi que je fasse c'est toujours le dernier élément de ma liste qui est modifié.

Mammouth du PHP | 968 Messages

10 nov. 2018, 15:32

print_r($entrees);
qu'est-ce que cela affiche ?

Petit nouveau ! | 8 Messages

10 nov. 2018, 15:45

Array ( [0] => stdClass Object ( [nom] => Oeufs du jour ) [1] => stdClass Object ( [nom] => Oeufs tomate cerise du jour ) [2] => stdClass Object ( [nom] => Carottes rapées ) [3] => stdClass Object ( [nom] => Taboulet oriental ) [4] => stdClass Object ( [nom] => Taboulet vert ) [5] => stdClass Object ( [nom] => Taboulet meridionnal ) [6] => stdClass Object ( [nom] => Mini penne ) [7] => stdClass Object ( [nom] => Pommes de terre au thon ) [8] => stdClass Object ( [nom] => Salade de lantilles aux échalottes ) [9] => stdClass Object ( [nom] => Tartare de concombre ) [10] => stdClass Object ( [nom] => Salade Alaska ) [11] => stdClass Object ( [nom] => Tomates mozarella pesto ) )

Mammouth du PHP | 968 Messages

10 nov. 2018, 15:50

il faut mettre
<form method="post" action="interface-admin.php">
dans la boucle, sinon il y a plein de champs avec le même nom et le script php ne prend pas celui attendu avec $_POST["id"]

Petit nouveau ! | 8 Messages

10 nov. 2018, 15:59

Yes ca semble fonctionner ! :D

Par contre il reste un dernier petit problème... La modification se fait sur le moment mais le fichier JSON n'est pas réellement modifié, d'ailleurs dès que je recharge la page, mon input se réinitialise :?

Mammouth du PHP | 968 Messages

10 nov. 2018, 16:03

s'il n'y a pas l'inverse de :
$menu = file_get_contents("db-json/menu.json");
$parsedMenu = json_decode($menu);
quand une modification est apportée, c'est normal.

Petit nouveau ! | 8 Messages

10 nov. 2018, 18:59

Yeaaah ça fonctionne merci beaucoup ! :D

Voila le code final pour ceux à qui ca pourrait servir
<?php
  $menu = file_get_contents("db-json/menu.json");
  $decodedMenu = json_decode($menu);

  $entrees = $decodedMenu->{"entrees"};

  if(isset($_POST["modifier"]))
  {
    $id = $_POST["id"];

    if ($_POST["categorie"] == "entrees")
    {
      $entrees[$id]->{"nom"} = $_POST["nom"];
    }

    $encodedMenu = json_encode($decodedMenu);
    file_put_contents("db-json/menu.json", $encodedMenu);
  }
?>

<form method="post" action="interface-admin.php">
  <ul>
    <?php
      foreach($entrees as $i => $entree)
      {
        echo
        '
          <li>
            <input type="text" name="nom" value="' . $entree->{"nom"} . '" />
            <input type="hidden" name="id" value="' . $i . '" />
            <input type="hidden" name="categorie" value="entrees" />
            <button name="modifier"> Modifier </button>
            <button name="supprimer"> Supprimer </button>
          </li>
        ';
      }
    ?>
  </ul>
</form>
Par contre c'est surement normal mais du coup ça à casser tout les sauts de ligne et tout que j'avais fait dans mon fichier JSON pour en faire un gros bloc compact. Ya pas moyen de le garder sous sa forme initiale ???