Shopping : les données 1/2
Pour inaugurer la sortie de Laravel 7 je vous propose une nouvelle application. Cette fois ça sera une application de commerce en ligne. Je suis en train d’en réaliser une et à cette occasion je me suis rendu compte que c’est vraiment intéressant et fait émerger un nombre considérable de questionnements. Jusque là je m’étais contenté d’utiliser Prestashop mais cette usine à gaz m’a posé tellement de problèmes que j’ai décidé de créer mon propre code.
Évidemment je ne vais pas ici présenter une application très étendue mais circonscrire les possibilités et imposer quelques contraintes. En effet ça peut rapidement devenir très volumineux. Donc au niveau des possibilités on va avoir en gros :
- une interface uniquement en français
- application de la TVA
- pour les possibilités de paiement : chèque, virement, mandat administratif et carte bancaire (Stripe)
- pour la facturation : utilisation d’une application tierce (vosfactures.fr). Pourquoi ce choix ? La loi anti-fraude à la TVA impose trop de contraintes pour gérer soi-même les factures, je précise que je n’ai aucun lien commercial avec ce site, c’est juste que j’ai trouvé là tout ce dont j’avais besoin pour un tarif raisonnable
- gestion complète des commandes
- gestion du catalogue mais sans catégories (on part du principe qu’il y a peu de produits)
- gestion des clients
- gestion des pays d’expédition
- gestion des tarifs postaux (utilisation exclusive de Colissimo)
- …
Voilà les grandes lignes de ce que je vous propose de réaliser et il est fort probable que ça évolue en cours de route…
Installation de Laravel
Dans un premier temps on va installer la dernière version de Laravel :
composer create-project --prefer-dist laravel/laravel shopping
On attend que tout se crée et se mette en place…
Si vous obtenez la page d’accueil c’est parfait :
On va aussi installer le package pour l’interface :
composer require laravel/ui
Et générer les élément de base par exemple avec Bootstrap (de toute façon on changera les vues) avec l’authentification :
php artisan ui bootstrap --auth
Pour finir on charge les dépendances :
npm install
Et on génère les assets en mode développement :
npm run dev
Maintenant vous devriez avoir une interface correcte avec Bootstrap et l’authentification.
On va aussi créer une base de données MySQL et l’appeler aussi shopping.
Dans le fichier .env on met à jour les identifiants :
DB_DATABASE=shopping DB_USERNAME=root DB_PASSWORD=
Les utilisateurs
On a par défaut une migration pour la table users. Mais on ne va pas utiliser la vérification des email, donc on supprime la colonne email_verified_at.
D’autre part on ajoute ces colonnes :
- firstname : pour le prénom
- newsletter : pour l’inscription à la lettre d’information
- admin : pour identifier les administrateurs (on n’aura donc que 2 rôles : les simples utilisateurs et les administrateurs)
- last_seen : la date et l’heure du dernier passage (pratique pour savoir qui est en ligne)
Ce qui nous donne cette migration :
Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('firstname'); $table->string('email')->unique(); $table->string('password'); $table->boolean('newsletter'); $table->boolean('admin')->default(false); $table->timestamp('last_seen')->nullable(); $table->rememberToken(); $table->timestamps(); });
On va aussi compléter UserFactory en conséquence :
... use App\Models\User; ... $factory->define(User::class, function (Faker $faker) { return [ 'name' => $faker->lastName, 'firstname' => $faker->firstName, 'email' => $faker->unique()->safeEmail, 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'remember_token' => Str::random(10), 'newsletter' => $faker->boolean(), 'last_seen' => $faker->dateTimeBetween('-6 months'), 'admin' => false, 'created_at' => $faker->dateTimeBetween('-4 years', '-6 months'), ]; });
Comme on aura pas mal de modèles on va déplacer User dans un dossier dédié :
Il nous faut donc changer l’espace de nom du modèle, mais aussi compléter la propriété $fillable pour l’assignement de masse. D’autre part comme on ajoute une colonne de date (last_seen) on va la déclarer dans la propriété $dates pour bénéficier de Carbon :
namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'firstname', 'email', 'password', 'newsletter', 'last_seen', ]; /** * The attributes that should be mutated to dates. * * @var array */ protected $dates = [ 'last_seen', ]; ...
Comme on a déménagé le modèle User il faut aussi modifier le fichier config/auth.php pour que l’authentification continue à fonctionner :
'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ],
Les pays
Comme on peut expédier dans plusieurs pays il y a des différences au niveau des frais de port et des taxes. On a donc besoin d’une table (et d’un modèle associé) pour les pays :
php artisan make:model Models\Country -m
On va se contenter de deux colonnes (nom et taxe) :
public function up() { Schema::create('countries', function (Blueprint $table) { $table->id(); $table->string('name', 100); $table->decimal('tax'); }); }
Et dans le modèle la propriété $fillable :
protected $fillable = [ 'name', 'tax', ]; public $timestamps = false;
On met la propriété $timestamps à false parce qu’on ne met pas les colonnes des dates.
On va se passer de factory pour cette table.
Les adresses
Les utilisateurs pourront définir plusieurs adresses (facturation, expédition…). On crée donc une table et un modèle :
php artisan make:model Models\Address -m
On va avoir besoin de pas mal de colonnes :
public function up() { Schema::create('addresses', function (Blueprint $table) { $table->id(); $table->boolean('professionnal')->default(false); $table->enum('civility', ['Mme', 'M.']); $table->string('name', 100)->nullable(); $table->string('firstname', 100)->nullable(); $table->string('company', 100)->nullable(); $table->string('address'); $table->string('addressbis')->nullable(); $table->string('bp', 100)->nullable(); $table->string('postal', 10); $table->string('city', 100); $table->string('phone', 25); $table->timestamps(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->foreignId('country_id')->constrained()->onDelete('cascade'); }); }
Voyons ça en détail :
- professionnal : indique si c’est une adresse professionnelle (dans ce cas nom et prénoms sont facultatifs mais company obligatoire)
- civility : monsieur ou madame (optionnel)
- name : le nom (optionnel si adresse professionnelle)
- firstname : le prénom (optionnel si adresse professionnelle)
- company : la société (que si adresse professionnelle)
- address : l’adresse
- addressbis : complément optionnel de l’adresse
- bp : boîte postale optionnelle
- postal : code postal
- city : ville
- phone : téléphone
On a aussi deux clés étrangères pour les relations avec l’utilisateur et le pays.
On va créer un factory pour créer des adresses :
php artisan make:factory AddressFactory --model=Models\Address
Avec ce code qui permet de générer des adresses assez variées :
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Models\Address; use Faker\Generator as Faker; $factory->define(Address::class, function (Faker $faker) { $professionnal = $faker->boolean(); if(!$professionnal || ($professionnal && $faker->boolean())) { $name = $faker->lastName; $firstName = $faker->firstName; } else { $name = null; $firstName = null; } return [ 'professionnal' => $professionnal, 'civility' => $faker->boolean() ? 'Mme': 'M.', 'name' => $name, 'firstname' => $firstName, 'company' => $professionnal ? $faker->company : null, 'address' => $faker->streetAddress, 'addressbis' => $faker->boolean() ? $faker->secondaryAddress : null, 'bp' => $faker->boolean() ? $faker->numberBetween(100, 900) : null, 'postal' => $faker->numberBetween(10000, 90000), 'city' => $faker->city, 'country_id' => mt_rand(1, 4), 'phone' => $faker->numberBetween(1000000000, 9000000000), ]; });
On renseigne aussi la propriété $fillable dans le modèle Address :
protected $fillable = [ 'name', 'firstname', 'professionnal', 'civility', 'company', 'address', 'addressbis', 'bp', 'postal', 'city', 'phone', 'country_id', ];
Les produits
Évidemment on va avoir des produits :
php artisan make:model Models\Product -m
On va prévoir ces colonnes :
- name : le nom
- price : le prix TTC
- weight : le poids pour le calcul des frais de port
- active : pour savoir si le produit est actif et doit être proposé à la vente
- quantity : la quantité disponible
- quantity_alert : la quantité qui déclenche une alerte à l’administrateur
- image : le nom de l’image du produit qui complètera le lien vers l’image
- description : la description du produit
Ce qui donne :
Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->decimal('price'); $table->decimal('weight'); $table->boolean('active')->default(false); $table->integer('quantity')->defaut(0); $table->integer('quantity_alert')->default(10); $table->string('image')->nullable(); $table->text('description'); $table->timestamps(); });
On crée aussi un factory :
php artisan make:factory ProductFactory --model=Models\Product
Avec ce code :
$factory->define(Product::class, function (Faker $faker) { return [ 'name' => $faker->sentence(3), 'price' => mt_rand(100, 1000) / 10.0, 'weight' => mt_rand(1, 4) / 1.8, 'quantity' => 50, 'active' => $faker->boolean(), 'image' => strval(mt_rand(1, 5)) . '.jpg', 'description' => $faker->paragraph(), ]; });
Et la propriété $fillable dans le modèle Product :
protected $fillable = [ 'name', 'price', 'quantity', 'weight', 'active', 'quantity_alert', 'image', 'description', ];
Les états
Une commande passe par plusieurs états, on crée donc aussi une table (et un modèle associé) :
php artisan make:model Models\State -m
Avec 4 colonnes :
Schema::create('states', function (Blueprint $table) { $table->id(); $table->string('name', 100); $table->string('slug', 50); $table->string('color', 20); $table->integer('indice'); });
Voyons ça :
- name : le nom de létat à afficher
- slug : pour référencer l’état hors affichage
- color : un code couleur pour renforcer l’affichage de l’état
- indice : le degré de l’état. Selon l’état on ne disposera que d’un certain nombre d’autre état possible. Par exemple si on a déjà confirmer un paiement on ne pourra pas changer de mode de paiement. Cet indice va simplifier le codage.
On complète aussi $fillable dans le modèle State :
protected $fillable = [ 'name', 'slug', 'color', 'indice', ]; public $timestamps = false;
On met la propriété $timestamps à false parce qu’on ne met pas les colonnes des dates.
On ne crée pas de factory pour cette table.
Les commandes
Les commandes constituent la partie la plus importante de l’application :
php artisan make:model Models\Order -m
On prévoie ces colonnes :
- reference : une référence unique pour la commande
- shipping : les frais de port
- total : le coût total TTC des produits
- tax : le taux de TVA appliqué aux produits (on ne prévoit pas de taux par produit)
- payment : le mode de paiement (carte, mandat, virement ou chèque)
- purchase_order : le numéro éventuel du bon de commande
- pick : si le produit est récupéré sur place
- invoice_id : l’identifiant de la facture (pour pouvoir la récupérer avec l’API)
- invoice_number : le numéro de la facture
On va aussi prévoir deux clés étrangères pour les utilisateurs et les états.
Schema::create('orders', function (Blueprint $table) { $table->id(); $table->timestamps(); $table->string('reference', 8); $table->decimal('shipping'); $table->decimal('total'); $table->decimal('tax'); $table->enum('payment', [ 'carte', 'mandat', 'virement', 'cheque' ]); $table->string('purchase_order', 100)->nullable(); $table->boolean('pick')->default(false); $table->integer('invoice_id')->nullable(); $table->string('invoice_number', 40)->nullable(); $table->foreignId('state_id')->constrained()->onDelete('cascade'); $table->foreignId('user_id')->constrained()->onDelete('cascade'); });
On va aussi prévoir un factory pour disposer de commande d’exemple :
php artisan make:factory OrderFactory --model=Models\Order
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Models\Order; use Faker\Generator as Faker; use Illuminate\Support\Str; $factory->define(Order::class, function (Faker $faker) { $pick = $faker->boolean(); $payment = ['carte', 'mandat', 'virement', 'cheque'][mt_rand(0, 3)]; if($payment === 'carte') { $state_id = [4, 5, 6, 8, 9, 10][mt_rand(0, 5)]; } else if($payment === 'mandat') { $state_id = [2, 6, 7, 8, 9, 10][mt_rand(0, 5)]; if($state_id > 6) { $purchaseOrder = Str::random(6); } } else if($payment === 'virement') { $state_id = [3, 6, 8, 9, 10][mt_rand(0, 4)]; } else if($payment === 'cheque') { $state_id = [1, 6, 8, 9, 10][mt_rand(0, 4)]; } if($payment === 'carte' && in_array($state_id, [8, 9, 10])) { $invoice_id = $payment === 'carte' && in_array($state_id, [8, 9, 10]) ? $faker->numberBetween(10000, 90000) : null; $invoice_number = Str::random(6); } else { $invoice_id = null; $invoice_number = null; } return [ 'reference' => strtoupper(Str::random(8)), 'shipping' => $pick ? 0 : mt_rand (500, 1500) / 100, 'payment' => $payment, 'state_id' => $state_id, 'user_id' => mt_rand(1, 20), 'purchase_order' => isset($purchaseOrder) ? $purchaseOrder : null, 'pick' => $pick, 'total' => 0, 'tax' => [0, .2][mt_rand(0, 1)], 'invoice_id' => $invoice_id, 'invoice_number' => $invoice_number, 'created_at' => $faker->dateTimeBetween('-2 years'), ]; });
Le code est assez chargé pour obtenir un minimum de cohérence, en particulier selon le mode de paiment et les états. Ca deviendra plus compréhensible quand on verra la population des tables.
Les adresses pour les commandes
Pour chaque commande on va avoir une ou deux adresses (s’il y a une adresse spécifique pour la livraison). On ne peut pas se contenter de créer une relation avec la table des adresses parce que celles-ci peuvent changer ensuite et on doit figer les choses pour la commande et surtout la facture.
En conséquence on crée une table pour mémoriser ces adresses :
php artisan make:model Models\OrderAddress -m
Les colonnes vont faire écho à celles de la table addresses :
Schema::create('order_addresses', function (Blueprint $table) { $table->id(); $table->boolean('facturation')->default(true); $table->boolean('professionnal')->default(false); $table->enum('civility', ['Mme', 'M.']); $table->string('name', 100)->nullable(); $table->string('firstname', 100)->nullable(); $table->string('company', 100)->nullable(); $table->string('address'); $table->string('addressbis')->nullable(); $table->string('bp', 100)->nullable(); $table->string('postal', 10); $table->string('city', 100); $table->string('phone', 25); $table->timestamps(); $table->foreignId('order_id')->constrained()->onDelete('cascade'); $table->foreignId('country_id')->constrained()->onDelete('cascade'); });
La différence c’est qu’elle est liée à une commande au lieu d’un utilisateur.
On complète la propriété $fillable du modèle OderAddress :
protected $fillable = [ 'name', 'firstname', 'professionnal', 'civility', 'company', 'address', 'addressbis', 'bp', 'postal', 'city', 'phone', 'country_id', 'facturation', ];
On va se passer de factiry pour cette table.
Les produits pour les commandes
Pour les produits pour les commandes on a le même raisonnement que pour les adresses, on ne peut pas se contenter d’une relation avec la table des produits parce qu’il peut y avoir dees changements ultérieurs et on doit figer les choses. d’autre part on doit mémoriser le prix total et la quantité commandée.
Alors on crée une table et un modèle :
php artisan make:model Models\OrderProduct -m
Avec ces colonnes :
- name : le nom du produit
- total_price_gross : le prix TTC total ne ténant compte de la quantité
- quantité : la quantité commandée pour ce produit
Schema::create('order_products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->decimal('total_price_gross'); $table->integer('quantity'); $table->timestamps(); $table->foreignId('order_id')->constrained()->onDelete('cascade'); });
Et évidemment on a la clé étrangère pour la liaison avec la commande.
On complète la propriété $fillable du modèle OderProduct :
protected $fillable = [ 'name', 'total_price_gross', 'quantity', ];
Les frais de port
Le poids
Pour les frais de port on va avoir deux table. Une première pour définir des plages de poids :
php artisan make:model Models\Range -m
Avec juste une colonne pour le poids maximal :
Schema::create('ranges', function (Blueprint $table) { $table->id(); $table->decimal('max'); });
Et dans le modèle Range :
protected $fillable = [ 'max', ]; public $timestamps = false;
On met la propriété $timestamps à false parce qu’on ne met pas les colonnes des dates.
Colissimo
On va prévoir une table pour les tarifs Colissimo :
php artisan make:model Models\Colissimo -m
Avec ces colonnes :
- price : le prix
- country_id : la clé étrangère pour le pays
- range_id : la clé étrangère pour la plage de poids
Schema::create('colissimos', function (Blueprint $table) { $table->id(); $table->decimal('price'); $table->foreignId('country_id')->constrained()->onDelete('cascade'); $table->foreignId('range_id')->constrained()->onDelete('cascade'); });
Et évidemment dans le modèle Colissimo :
protected $fillable = [ 'price', 'country_id', 'range_id', ]; public $timestamps = false;
La boutique
On doit aussi prévoir une table (et un modèle) pour tous les renseignements concernant la boutique :
php artisan make:model Models\Shop -m
On aura de nombreuses colonnes (et a priori une seule ligne puisque une seule boutique) :
- name : nom de la boutique
- address : adresse de la boutique
- holder : nom officiel de la boutique
- email : email de contact
- bic : le BIC pour les virements
- iban : l’IBAN pour les virements
- bank : nom de la banque
- bank_address : adresse de la banque
- phone : téléphone de contact
- facebook : lien vers la page Facebook
- home : texte pour la page d’accueil
- home_infos : texte d’information pour la page d’accueil
- home_shipping : texte d’information sur les frais de port pour la page d’accueil
- invoice : si la boutique va générer des factures
- card : si la boutique va accepter le paiement par carte bancaire
- transfer : si la boutique va accepter le paiement par virement
- check : si la boutique va accepter le paiement par chèque
- mandat : si la boutique va accepter le paiement par mandat administratif
Schema::create('shops', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('address'); $table->string('holder'); $table->string('email'); $table->string('bic'); $table->string('iban'); $table->string('bank'); $table->string('bank_address'); $table->string('phone', 25); $table->string('facebook'); $table->string('home'); $table->text('home_infos'); $table->text('home_shipping'); $table->boolean('invoice')->default(true); $table->boolean('card')->default(true); $table->boolean('transfer')->default(true); $table->boolean('check')->default(true); $table->boolean('mandat')->default(true); });
On crée un factory :
php artisan make:factory ShopFactory --model=Models\Shop
Avec ce code :
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Models\Shop; use Faker\Generator as Faker; use Illuminate\Support\Str; $factory->define(Shop::class, function (Faker $faker) { return [ 'name' => $faker->sentence(2), 'address' => $faker->address, 'email' => $faker->email, 'phone' => $faker->phoneNumber, 'holder' => strtoupper($faker->sentence(3)), 'bic' => strtoupper(Str::random(8)), 'iban' => $faker->iban, 'bank' => $faker->sentence(2), 'bank_address' => $faker->address, 'facebook' => $faker->url, 'home' => $faker->sentence(3), 'home_infos' => $faker->text, 'home_shipping' => $faker->text, ]; });
Et dans le modèle Shop :
protected $fillable = [ 'name', 'address', 'email', 'holder', 'bic', 'iban', 'bank', 'bank_address', 'phone', 'facebook', 'home', 'home_infos', 'home_shipping', 'invoice', 'card', 'transfer', 'check', 'mandat', ]; public $timestamps = false;
Les pages
On va avoir des pages d’information (conditions de vente, mentions légale…). On crée donc une tale pour mémoriser le contenu de ces pages :
php artisan make:model Models\Page -m
On va se contenter de 3 colonnes classiques :
Schema::create('pages', function (Blueprint $table) { $table->id(); $table->string('slug'); $table->string('title'); $table->text('text'); });
Et dans le modèle Page :
protected $fillable = [ 'title', 'slug', 'text', ]; public $timestamps = false;
On crée un factory :
php artisan make:factory PageFactory --model=Models\page
Avec ce code :
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Models\Page; use Faker\Generator as Faker; $factory->define(Page::class, function (Faker $faker) { return [ 'text' => $faker->paragraph(10), ]; });
Les paiements
Il ne nous reste plus qu’à prévoir une table pour mémoriser les identifiant de paiment des commandes dans le cas de paiment par carte bancaire :
php artisan make:model Models\Payment -m
Schema::create('payments', function (Blueprint $table) { $table->id(); $table->timestamps(); $table->string('payment_id'); $table->foreignId('order_id')->constrained()->onDelete('cascade'); });
Et dans le modèle Payment :
protected $fillable = [ 'payment_id', ];
Les notifications
Comme on va utiliser le système de notifications de Laravel on va aussi créer la table correspondante :
php artisan notifications:table
Là c’est Laravel qui s’occupe de tout !
Conclusion
On a maintenant toutes les tables et les factories nécessaires pour avoir des données d’exemple. Dans le prochain article on mettra en place les relations, quelques accessors et mutators et on complètera avec une population complète de la boutique. On aura ainsi tout en place pour commencer à coder.
36 commentaires
gaetk
Bonjour, cet article marchera avec Laravel 8 ?
bestmomo
Bonjour,
Il y aura des adaptations à prévoir pour Laravel 8.
Laravel@com
Bonjour comment allez vous??. Lorsque je veux creer un model je me retrouve avec deux dossier Models(un 1er dossier contenant user.php et un 2em dossier contenant(order.php, contry…. ). Cela est il normal d’avoir cest deus dossiers models??.
jondelweb
C’est parce que tu as installé Laravel 8.0 .
Ils ont déjà intégré le dossier Models dans cette version.
Ici tu es sur un tuto pour Laravel 7.
Tu peux quand même le faire mais tu vas devoir adapter certaine partie (comme la façon de noter les routes par exemples…)
bestmomo
Pour le routage on peut facilement revenir à l’ancien codage. C’est expliqué dans la page d’upgrade.
arn0
Bonjour,
J’ai une question sur le produit, pourquoi mettre le prix TTC et non le HT ?
bestmomo
Salut,
J’avais commencé avec le prix HT mais je suis tombé ensuite sur des soucis d’arrondis (par exemple si on prend plusieurs exemplaires d’un même produit) et j’ai trouvé plus pratique de mémoriser le prix TTC. Finalement le prix HT n’est utile que pour le récapitulatif de la commande et la facturation, la réalité du prix est dans ce que paie effectivement le client.
arn0
Merci pour ta réponse.
Cela ne posera pas de soucis pour la comptabilité ?
Mais c’est vrai que c’est un casse tête, j’ai un site e commerce comme premier site à réaliser, j’aurai aimé avoir ce que vous avez fait pour m’aiguiller.
Merci pour votre partage.
bestmomo
Au niveau comptable ça ne change rien, c’est juste une histoire de calcul. Les deux options sont possibles, partir du HT ou du TTC. L’important c’est d’arriver au bout à avoir des valeurs correctes. Le plus logique semble de partir du HT et d’ajouter la TVA selon son taux ou de ne pas en ajouter dans le cas par exemple d’une expédition à l’étranger, mais ça m’a semblé finalement moins fluide à coder. Finalement je me dis que j’aurais dû mettre ça comme option de saisie…
eelisland
Attention: WordPress a remplacé dans ma réponse les guillemets (touche 3 du clavier azerty) par les sigles « »
eelisland
Hello,
pour info, dans ma configuration, linux/bash:
php artisan make:model Models\Country -m produit le fichier App/ModelsCountry.php
php artisan make:model « Models\Country » -m produit le fichier attendu App/Models/Country.php
J’ai également modifié les fichiers:
vendor/composer/ autoload_classmap.php
vendor/composer/ autoload_static.php
pour que le déplacement de App/User.php dans App/Models/User.php soit pris en compte.
eelisland
Attention: WordPress a remplacé dans ma réponse les guillemets (touche 3 du clavier azerty) par les sigles « »
bestmomo
Salut,
Ça arrive de temps en temps ces différences avec Linux.
Pour mettre à jour l’autoload il faut utiliser
composer dumpautoload
.dokmattlab
Bonjour,
Petite erreur =>
« On va se passer de factiry pour cette table. »
=> mettre factory
Juste au dessus du titre
« Les produits pour les commandes »
Cdlt
Matt
bestmomo
Merci, c’est réparé !
oufana
Salut;
j’ai pas le dossier Models dans app.
merci
bestmomo
Bonsoir,
Ce dossier n’existe pas par défaut, il faut le créer.
ted
merci bestmomo !
j’ai pu corriger certains problèmes. il reste ceux ci qui sont lie a mon système donc je les ignores tout simplement
λ npm install
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {« os »: »darwin », »arch »: »any »} (current: {« os »: »win32″, »arch »: »x64″})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\watchpack\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {« os »: »darwin », »arch »: »any »} (current: {« os »: »win32″, »arch »: »x64″})
audited 1240 packages in 12.798s
found 3 vulnerabilities (1 low, 2 moderate)
run `npm audit fix` to fix them, or `npm audit` for details
si c’est pas trop demander pourquoi nous utilisons les commandes npm?
j’ai parcourus la documentation et franchement ça ne m’avance pas beaucoup.
je suppose que c’est pour les css mais si c’est le cas ne n’y a t il pas un autre moyen de procéder qui gêner peut d’erreurs?
je le dis car je les utilises par ce que je vous fais confiance. je ne sais pas trop comment je pourrais les utiliser dans une autre application.
merci pour le temps que vous nous accordez
bestmomo
Salut,
Pour gérer les librairies CSS et Javascript, npm est l’outil le plus utilisé et en général il fonctionne bien si on a des versions à jour de node et npm. On peut aussi se passer de ce genre d’outil si on utilise peu de librairies et les charger avec des CDN, au niveau performances il n’y aura pas de grandes différences.
ted
j’ai également eu problème similaire avec npm run dev
es ce qu cela peut créer des problèmes par la suite ?? car j’ai décidé de continuer malgré tout
ted
bsr bestmomo ainsi qu’a tous ceux qui suivent ce cours! svp bestmomo quand j’exécute la commande
npm install
j’obtiens les sorties suivantes
npm WARN deprecated popper.js@1.16.1: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1
npm WARN deprecated chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {« os »: »darwin », »arch »: »any »} (current: {« os »: »win32″, »arch »: »x64″})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules\watchpack\node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {« os »: »darwin », »arch »: »any »} (current: {« os »: »win32″, »arch »: »x64″})
npm WARN sass-loader@8.0.2 requires a peer of node-sass@^4.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN sass-loader@8.0.2 requires a peer of fibers@>= 3.1.0 but none is installed. You must install peer dependencies yourself.
added 1117 packages from 500 contributors and audited 1120 packages in 135.698s
found 1 low severity vulnerability
run `npm audit fix` to fix them, or `npm audit` for details
j’ai chercher sur google on ma proposer pour popper les commandes suivantes
npm uninstall popper.js
npm install @popperjs/core
quand j’executer ces commandes j’obtiens
npm WARN bootstrap@4.4.1 requires a peer of popper.js@^1.16.0 but none is installed. You must install peer dependencies yourself …
clairement que popper.js 1.16.1 est requit pour bootstrap
comment je peux résoudre ces problèmes
merci d’avance
bestmomo
Salut,
Il faudrait peut-être vider le cache de npm (npm cache clear), souvent ça règle des trucs.
Hamdi
Bonjour à tous,
Cela fait quelques temps que je n’ai plus utiliser Laravel; En voyant ce nouveau cours j’ai décidé de m’exercer. Mais je me suis confronter à une erreur qui m’empêche d’avancer. Je vous poste l’erreur en espérant que vous m’apportez une reponse.
Voici mon erreur: SQLSTATE[HY000] [1049] Unknown database ‘shopping’ (SQL: create table `migrations` (`id` int unsigned not null auto_increment primary key, `migration` varchar(255) not null, `batch` int not null) default character set utf8mb4 collate ‘utf8mb4_unicode_ci’). Et pourtant j’ai tout fait comme indiquer mais quand je fais php artisan migrate:install j’ai l’erreur ci-dessous.
Merci de m’éclairer s’il vous plait. Merci d’avance
bestmomo
Bonjour,
Apparemment la base shopping n’a pas été créée.
Hamdi
Oui, mais j’ai tout fait normalement. Comment régler ce problème s’il vous plait ?
bestmomo
Comment la base a-t-elle été créée ?
Hamdi
Bonjour, j’ai tout fait selon ce cours et c’est à la fin que j’ai fait un php artisan migrate:install qui n’a malheureusement pas fonctionné. Parcontre la création des models et des factories ne m’a posé aucun problème.
oksam
télécharge le fichier zip du projet en suite lance ton serveur local, créer la base de donnée shopping et fait la migration ça va fonctionné
vkuate
C’est à vous de créer en invite mysql ou dans phpmyadmin
oksam
Merci Best pour ce nouveau tuto.
lionelAKE
Ou se trouve le fichier .zip du projet?
bestmomo
Au début de chaque article je mets le lien pour télécharger le ZIP du code final de l’article. Pour les données le lien est dans le deuxième article.
ronald169
Wooooooooo bestmomo la alors j’avoue suis sans voix :).
j’ai une question au niveau des rôles pour utilisateur celui qui créer sa boutique est administrateur je suppose et est-il capable de nommé un autre administratuer ? vue que il risque d’avoir plusieurs boutiques, et c’est quoi le lien entre les autre administrateur (ceux qu’il aura donné les privilège d’administration) et la boutique ? vue que admin est de type Boolean ?
ne serait-il pas mieux concernant l’administration d’utiliser un package tierce comme (laravel-permission) histoire de découvrir aussi ce package ?
qu’a cela ne tienne. Je me ferais un plaisir de suivre chaque avancé de ce cours et vraiment j’aimerai y participer si vous le voulez bien sur….
bestmomo
Salut,
L’idée est de rester simple avec une seule boutique et un ou deux administrateurs sans partir dans des déclinaisons de rôles.
Toute participation est évidemment la bienvenue mais je suis déjà pas mal avancé dans le projet et certaines choses ne pourront pas trop changer.
ronald169
okay je comprens mieux. Mais comment participer
bestmomo
Il doit bien traîner des bugs dans mon code et sans doute des stratégies plus efficaces ou des lacunes de sécurité…