Laravel 5

Fichier Json

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Bonjour la commu !

    Je suis un débutant ++ sur Laravel et je suis en train d'essayer de build un site internet.

    Voilà ma question, je souhaiterais charger un fichier json dans un controller et charger la description d'un objet avec son nom. Je vous explique :

    Le fichier json (une partie)

    "data": {
    "1001": {
    "name": "Bottes de vitesse",
    "description": "<groupLimit>Limité à 1 paire de bottes.</groupLimit><br><br><unique>Propriété passive UNIQUE - Déplacements améliorés :</unique> +25 vitesse de déplacement",
    "colloq": ";Boots of Speed;bottes de vitesse",
    "plaintext": "Augmente légèrement la vitesse de déplacement.",
    "into": [
    "3006",
    "3047",
    "3020",
    "3158",
    "3111",
    "3117",
    "3009",
    "3173",
    "4001"
    ],
    "image": {
    "full": "1001.png",
    "sprite": "item0.png",
    "group": "item",
    "x": 0,
    "y": 0,
    "w": 48,
    "h": 48
    },
    "gold": {
    "base": 300,
    "purchasable": true,
    "total": 300,
    "sell": 210
    },
    "tags": [
    "Boots"
    ],
    "maps": {
    "10": true,
    "11": true,
    "12": true
    }
    "stats": {
    "FlatMovementSpeedMod": 25
    }
    }

    Je voudrais par exemple écrire dans mon fichier blade description:Bottes de vitesse et que celui ci me renvoie : Limité à 1 paire de bottes. Propriété passive UNIQUE - Déplacements améliorés : +25 vitesse de déplacement.
    Ou encore image-full:Bottes de vitesse et qu'il me retourne : 1001.png

    Voilà, je sais que la syntaxe d'exemple que je vous ai donné n'est pas la bonne, comme je vous ai dit je débute et je n'y connais pas grand chose encore. Je ne sais même pas si ceci est réalisable.

    Merci de l'attention que vous y porterez.

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    Salut,

    Pour utiliser des infos en json avec php classiquement on transforme avec json_decode() pour obtenir une stdClass ou un tableau.

    Une bonne idée quand on utilise Laravel est de transformer les données en collection :

    $maCollection = collect(json_decode($json, true))

    Ensuite toutes les méthodes des collections deviennent disponibles...

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Merci de ta réponse, cependant, ca ne résoud pas mon problème je n'y comprends rien x)

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    Les collections sont très puissantes et permettent une approche déclarative du code, dans le cas de ton fichier JSON je suppose qu'il se compose en gros ainsi avec des références numériques et des informations par référence :

    $json = '{
    "data": {
    "1001": {
    "name": "Bottes de vitesse",
    "description": "<groupLimit>Limité à 1 paire de bottes.</groupLimit><br><br><unique>Propriété passive UNIQUE - Déplacements améliorés :</unique> +25 vitesse de déplacement",
    "image": {
    "full": "1001.png",
    "sprite": "item0.png",
    "group": "item",
    "x": 0,
    "y": 0,
    "w": 48,
    "h": 48
    }
    },
    "1002": {
    "name": "Bottes de promenade",
    "description": "<groupLimit>Limité à 2 paires de bottes.</groupLimit><br><br><unique>Propriété passive UNIQUE - Déplacements améliorés :</unique> +25 vitesse de déplacement",
    "image": {
    "full": "1002.png",
    "sprite": "item0.png",
    "group": "item",
    "x": 0,
    "y": 0,
    "w": 48,
    "h": 48
    }
    }
    }
    }';

    Si je pars de ce fichier et que je veux récupérer les informations à partir d'un nom spécifique par exemple Bottes de vitesse. Je vais écrire ce genre de code :

    $name = 'Bottes de vitesse';

    $article = collect(json_decode($json, true)['data'])
    ->first(function ($value, $key) use($name) {
    return $value['name'] == $name;
    });

    dd($article);

    Je transforme le JSON en collection et je fais une recherche avec la fonction first. A la sortie j'ai un tableau avec les renseignements :

    array:3 [▼
    "name" => "Bottes de vitesse"
    "description" => "<groupLimit>Limité à 1 paire de bottes.</groupLimit><br><br><unique>Propriété passive UNIQUE - Déplacements améliorés :</unique> +25 vitesse de déplacement"
    "image" => array:7 [▼
    "full" => "1001.png"
    "sprite" => "item0.png"
    "group" => "item"
    "x" => 0
    "y" => 0
    "w" => 48
    "h" => 48
    ]
    ]

    Je peux envoyer ce tableau dans une vue Blade :

    return view('mavue', compact('article'));

    Dans la vue :

    <p>Nom : {{ $article['name']}}</p>
    <p>Description : {!! $article['description'] !!}</p>
    <p>Image : {{ $article['image']['full'] }}</p>

    Ce qui donne en visuel :

    Nom : Bottes de vitesse
    Description : Limité à 1 paire de bottes.
    Propriété passive UNIQUE - Déplacements améliorés : +25 vitesse de déplacement
    Image : 1001.png
  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Ce que tu viens de me donner m'aide beaucoup en effet, seulement je dois le faire pour un peu près 1000 objets si tu veut le fichier complet se trouve ici. Donc avec la technique que tu m'as donné, je vais devoir créer un nombre incalculable de variables en sachant qu'il faut que je le fasse avec les items.

    Il n'est pas possible de créer un input dans la variable $name et charger le fichier json en entier pour qu'au final dans la vue ca rende :

    <p> Nom : {{ 'Bottes de vitesse'->['name'] }}</p>
    <p> Description {{!! 'Bottes de vitesse'->['description'] !!}}</p>
    <p>Image : {{'Bottes de vitesse'->['image']['full'] }}</p>

    Et que celui ci rende la même vue que celle que tu m'as donné au dessus.

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    Si tu accèdes à une API pour récupérer les données et sélectionner un produit pour afficher ses caractéristiques alors je ne vois pas l'intérêt de passer par Laravel et une vue, autant partir sur du SPA.

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Je ne sais pas ce qu'est que le SPA, je souhaite faire des guides avec ce json et malheureusement je devrais les utiliser plusieurs fois dans plusieurs pages différentes. Je n'utilise pas d'api j'ai juste les fichiers json pour me permettre d'effectuer ce que je veux..

    En fait ce sont des guides sur league of legends et le json appartiens au client même du jeu.

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    Côté Javascript tu es plutôt classique jQuery ou alors approches plus modernes Vue ou React ?

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Je ne sais pas je n'utilise que trs peu le js d'habitude ou alors je prends des scripts tout faits sur internet :/

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    La tendance actuelle est plutôt d'en utiliser de plus en plus justement pour rendre les application réactives.

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Dac mais en quoi ca résoudrais mon problème ? xD

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    Parce que tu pourrais avoir une liste déroulante avec tous les noms et clic pour faire apparaître les éléments, avec un peu d'ajax pour faire tourner le truc.

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Intégrer ceci dans laravel c'est faisable ?

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    On peut tout faire avec Laravel ;)

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Dac mais comment x)

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    En gros on commence par envoyer une page avec la liste déroulante remplie avec les noms. Ensuite un clic sur un nom envoie une requête Ajax à Laravel qui renvoie les informations pour raffraichir la partie de la page concernée.

    Avec SPA (Single Page Application) c'est tout le JSON qu'on envoie et en local Javascript gère l'affichage, ça évite les va et vient avec le serveur.

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Oui fin c'est du chinois pour moi ca j'ai aucune idée de comment faire ca x)

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    Oui je complèterai ma réponse...

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    Pour l'exemple je pars d'une installation toute fraîche de Laravel...

    En partant du principe qu'on a le fichier JSON en public/json/data.json. On change dans config/filesystems.php pour faciliter l'accès :

    'disks' => [
    'local' => [
    'driver' => 'local',
    'root' => public_path(),
    ],

    Dans les routes (routes/web.php) :

    Route::get('/', 'HomeController@index')->name('home');
    Route::get('infos/{id}', 'HomeController@infos');

    Le contrôleur (HomeController) :

    <?php

    namespace App\Http\Controllers;

    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Storage;

    class HomeController extends Controller
    {
    public function index()
    {
    $names = $this->getData()->pluck('name');
    return view('home', compact('names'));
    }

    public function infos($id)
    {
    $values = $this->getData()->forPage($id + 1, 1)->first();
    return view('values', compact('values'));
    }

    protected function getData()
    {
    $data = Storage::get('json/data.json');
    return collect(json_decode($data, true)['data']);
    }
    }

    La vue home modifiée :

    @extends('layouts.app')

    @section('content')
    <div class="container">
    <div class="row justify-content-center">
    <div class="col-md-8">
    <div class="card">
    <div class="card-header">Recherche par nom</div>
    <div class="card-body">
    <form>
    <div class="form-group">
    <select id="names" class="custom-select">
    <option selected>Choisissez un nom</option>
    @foreach($names as $name)
    <option value="{{ $loop->index }}">{{ $name }}</option>
    @endforeach
    </select>
    </div>
    </form>
    <div id="infos"></div>
    </div>
    </div>
    </div>
    </div>
    </div>
    @endsection

    @section('scripts')

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script&gt;

    <script>
    $(function(){
    $('#names').change(function() {
    $.get('{{ url('infos') }}/'+ $(this).val(), function(data) {
    $('#infos').html(data);
    });
    });
    })
    </script>

    @endsection

    Et une nouvelle vue values :

    <p>Nom : {{ $values['name']}}</p>
    <p>Description : {!! $values['description'] !!}</p>
    <p>Image : {{ $values['image']['full'] }}</p>

    Ca fonctionne de façon très simple mais ça serait bien plus efficace avec une approche SPA. Si je trouve du temps je développerai cet aspect.

    Edit : j'ai écrit un petit article sur le sujet.

  • Avatar de WilliamMaquin
    Membre depuis :
    02/12/2018
    Messages :
    40

    Bravo pour le site ! Je le connaissais mais je ne savais pas que c'était toi qui l'avait fait ! J'ai un souci avec ton code cependant, j'ai utilisé la deuxime manière que tu as démontré sur ton site et à l'adresse /vueversion il n'y a rien.

    Je ne sais pas d'ou ca peut provenir j'ai peut être pas placé le json au bon endroit. Comme je n'avais pas de folder json j'en ai crée un dans ressources/assets/js/components/json/ puisque le app.js est dans /components/ je ne sais pas si le problème viens de là..

Vous ne pouvez pas répondre à ce sujet.