====== Laravel ====== tuto sur youtube: * [[https://www.grafikart.fr/tutoriels/decouverte-laravel-502|tuto grafikart laravel 5]]:-/ * [[https://www.youtube.com/watch?v=gUbn0z8IRd4| Laravel 7 tutorial #3 file and folder structure]] * [[https://youtu.be/onfxxWxGyqw| Laravel 7 tutorial #5 controller]] * [[https://youtu.be/31DQQAWsAxE| Laravel 7 tutorial #21 start with database]] * [[https://youtu.be/2DWYcBiMwEo| Laravel 7 tutorial #22 Query Builder… CRUD]] * [[https://www.youtube.com/watch?v=_YXKLpOpJY0| Laravel 8 tuto contrôle d'accès]] ===== Création d'un projet ===== Il suffit de lancer la commande composer : composer create-project laravel/laravel mon-projet cd mon-projet # ajout module doctrine composer require doctrine/dbal Ça utilisera la dernière version de Laravel Pour démarrer le serveur en dev php artisan serve --port=8000 ===== Bases de données ===== Accès à la base de données :\\ Les paramètres sont définis dans le fichier .env (.env.local, utiliser s'il existe) Créer un modèle (càd du pt de vue bdd, une table) et sa migration: php artisan make:model Article --migration le fichier créer est placé dans le répertoire **app** Pour créer les attributs (ce qui est appelé //migration//), il faut aller dans le répertoire **database/migrations** On peut s'aider de l'aide de Laravel:\\ [[https://laravel.com/docs/8.x/migrations#available-column-types]]\\ et de blueprint dans l'api de laravel:\\ [[https://laravel.com/api/8.x/Illuminate/Database/Schema/Blueprint.html]] à la création de l'appli, trois tables sont automatiquement prévues: //users//, //passwords// et //failed_jobs// Pour les clés étrangères, il faut bien être en innodb ET pré-définir l'attribut recevant la clé comme **->unsigned()** ((https://stackoverflow.com/questions/11894250/general-error-1005-cant-create-table-using-laravel-schema-build-and-foreign)) php artisan db:wipe // !! Drop all tables, views, and types php artisan migrate ==== Seeder (données de test ou de base) ==== php artisan make:seeder MesDonneesSeeder crée le fichier dans **database/seeds** à compléter\\ puis: php artisan db:seed # ou php artisan db:seed --category=MesDonneesSeeder::class [[https://laravel.com/docs/8.x/seeding]] ==== Modifier une table ==== ((src: Laravel aux éd. eni §2.2.4 page 115)) Il est souvent nécessaire d'ajouter/enlever des attributs à une table de la base de données. On commence par créer une migration: php artisan make:migration On appelle, au lieu de la méthode //create//, la méthode //table// : public function up() { Schema::table('nom_de_la_table', function(Blueprint $table) { $table->string('attribut_à_ajouter')->nullable()->comment('nom de l\'attribut en fr…'); }); } liste des "modifiers" : https://laravel.com/docs/8.x/migrations#column-modifiers\\ Pour supprimer un attribut : public function down() { Schema::table('nom_de_la_table', function (Blueprint $table) { $table->dropColumn('attribut_à_ajouter'); }); // en deux passes s'il y a une clé étrangère : Schema::table('sample', function (Blueprint $table) { $table->dropForeign(['supposed_origin_id']); }); Schema::table('sample', function (Blueprint $table) { $table->dropColumn('supposed_origin_id'); }); // ou il peut être plus simple (et plus propre) de simplement supprimer toute la table en opposition de sa `creation`: Schema::drop('nom_de_la_table'); } et on applique la modification avec php artisan migrate si on veut revenir en arrière, on fait: php artisan migrate:rollback ==== "Squashing migrations" ou comment rationaliser les migrations ==== Créer un schéma correspondant aux cumul de migration, et supprime les migrations qui ne sont donc plus utiles : php artisan schema:dump --prune ===== Controlleurs ===== php artisan make:controller NomController ou si on veut créer le CRUD: php artisan make:controller NomController --resource qui crée les 7 méthodes (Create:create/store, Read:index,show(id), Update:edit(id)/update, Delete: destroy)\\ les fichiers sont créé dans **app/Http/Controllers** ==== Accéder aux données d'un model ==== Voici quelques requêtes qui deviennent très simple avec Eloquent : // récupérer un objet grâce à son id : $ceramic_category = CeramicCategory::find($id); // mais on va vite avoir besoin de rechercher par son nom ou un autre attribut : $ceramic_category = CeramicCategory::where('name', 'C.ENG.GLAC')->first(); // ou par la date : $ceramic_description = CeramicDescription::where('created_at', '>', '2021-06-22')->first(); // et pour générer une liste de choix : $ceramic_categories = CeramicCategory::all()->sortBy('name'); et on obtient un objet, donc on en profite : // pour accéder à l'id : $ceramic_category->id; // ou au nom : $ceramic_category->name; Visualiser la requête : $query->toSql(); ou $query->toRawSql();((https://stackoverflow.com/questions/18236294/how-do-i-get-the-query-builder-to-output-its-raw-sql-query-as-a-string))\\ FIXME on peut ajouter le module ((tuto grafikart laravel10 à la 25è mn: https://youtu.be/QJA8JWrghak)) composer require barryvdh/laravel-debugbar --devqui permet notamment de visualiser les requêtes SQL !\\ Si la barre ne s'affiche pas, sudo chmod -R 777 storage ===== Vues ===== Pour plus d'infos sur [[informatique:css#tailwind|TailWind]] Les vues sont générées avec les modèles (templates) en Blade :\\ https://laravel.com/docs/8.x/blade Les //assets// à partir de la version 10, utilisent //Vite// : https://grafikart.fr/tutoriels/front-vite-laravel-2133 ==== Les composants ==== * [[https://grafikart.fr/tutoriels/component-blade-laravel-2134|tuto grafikart]] * https://laravel.com/docs/10.x/blade#component-attributes Dans le contrôleur, je passe une variable, par exemple le titre (//title//) de la page : return view('museum', [ 'title' => 'Les Musées', 'museums' => $museums, ]); Dans la vue //museum.blade.php//, on fait appel au modèle de vue //app.blade.php// en lui passant le titre : qui est récupéré dans //app.blade.php// {{ $attributes['title'] ?? config('app.name', 'Artefacts v3') }} ==== Formulaires ==== [[informatique:laravel:spatie-html|Spatie laravel-html]] === Messages (succes, warning…) === [[https://youtu.be/l_v0ywlcVWY|tuto (youtube) grafikart sur les formulaires]] à 7’20" Lors du //redirect// après la sauvegarde, on peut ajouter un message de succès ou l'alerte/erreur. ===== Authenfication ===== Je me suis basé en partie sur la page https://laravel.com/docs/7.x/authentication\\ mais après vérification de la présence le laravel/ui dans composer.json, j'ai renommé resources/views/layouts/app.blade.php avant de lancer ((https://stackoverflow.com/a/64944715/6614155))pha ui:auth puis regardé le diff avec le fichier app.blade.php d'avant pour remettre les dépendances (css, js) et le titre.\\ Le bandeau intègre bien login/register, et les contrôleurs ont bien été créés. Si on a un nom de table différent de //users//, il faut bien le définir :\\ https://stackoverflow.com/a/44932219/6614155\\ Pour désactiver/activer les routes //register//, //reset//, //verify//, cf. https://gitlab.huma-num.fr/leyango/cahier/-/issues/119 ===== Traductions ===== Pour passer l'application en multi-langues\\ ==== Configurer les locales ==== https://laravel.com/docs/8.x/localization#configuring-the-locale ==== Installer les fichiers de traduction ==== Le projet https://laravel-lang.com (pour lequel j'ai collaboré… https://github.com/Laravel-Lang/lang/pull/2601) composer require --dev laravel-lang/lang ==== Copier les fichiers ==== Sans doute pas la meilleure pratique (pas de mises à jour lors de composer update), mais c'est assez simple :\\ https://laravel.com/docs/8.x/localization#introduction\\ donc copier les fichiers json dans //resources/lang// (ou ./lang/ à partir de laravel v10) :\\ cp vendor/laravel-lang/lang/locales/fr/json.json resources/lang/fr/fr.json ==== Adapter la route ==== Modifier //routes/web.php// : Route::get('/{locale?}', function ($locale = null) { if (isset($locale) && in_array($locale, array_keys(config('app.locales')))) { app()->setLocale($locale); } return view('welcome'); })->where([ 'locale' => '[a-zA-Z]{2}']); // en l'absence du where… ça capte pas mal de route !!!! Dans une vue (blade), on peut visualiser la locale en mettant : {{ Config::get('app.locale') }} ===== Helpers ===== On a souvent besoin de fonctions pour mettre en forme des données (//to_canonical//, //extract_csv//…). Si c'est très spécifique, la fonction peut être intégrée à la classe d'un contrôleur, mais il est souvent intéressant de la mettre à disposition de l'ensemble du projet.\\ Pour cela, on a les //helpers//. Il faut : - créer un fichier dans le répertoire //app/Helpers// - ajouter un test d'existence de la fonction à ajouter : if (! function_exists('nom_de_ma_fonction')) { - définir la fonction - ajouter le chemin vers ce fichier helper dans composer.json à "autoload": { "files": ["app/Helpers/MonFichierHelpers.php",… - exécuter composer dump-autoload pour prendre en compte la modification du //composer.json// ===== Pour le développement et le traçage ===== Équivalent de var_dump: dump($ma_variable); # et aussi dd qui arrête l'execution ! dd($ma_variable); Si c'est dans une vue : {{ dump($ma_variable) }} #ou {{ dd($ma_variable) }} la méthode //->all()//. Les objets //Request//, //Session// … disposent d'une méthode //all// qui n'affiche que ce qui nous intéresse et n'affiche pas le reste. On écrira donc dd($request->all()) et Log: use Illuminate\Support\Facades\Log; $user = User::find(4); Log::info(’Utilisateur chargé !’, $user->toArray()); qui écrit dans **/storage/logs/laravel.log** ===== Les CACHE(s) ===== Si les caches sont un atout pour un site en prod, ils peuvent être la source de comportements qui semblent incompréhensibles. Nettoyer le cache (dont bootstrap/cache/config.php qui contient l'accès à la base de données !) : pha cache:clear((pha -> php artisan créé dans mon .bash_aliases))\\ ou encore ((https://stackoverflow.com/questions/53203254/failed-to-open-stream-no-such-file-or-directory-laravel)) pha config:cache && pha config:clear && composer dump-autoload Le nettoyage du(des) cache(s) peut entraîner un //500 server error//, il peut alors être utile de supprimer le fichier **bootstrap/share/config.php** Le cache des route : S'il est actif, on peut toujours changer, ajouter des routes, la liste est inchangé !\\ La commande pha route:clear s'impose alors !! ===== Variables d'environnement ===== Il y a celles utiles à l'application laravel, celles utiles au conteneur docker… Celles de laravel, on peut voir quelle fichier .env est utilisé en faisant un dd($this->app); (par exemple dans //app/Providers/AppServiceProvider.php//)\\ et on a //#environmentFile: ".env.local"// par exemple. ===== Astuces ===== Il est difficile de savoir ce que modifie l'installation d'un composant.\\ git permet aussi cela, mais il arrive (mise à niveau en repartant d'une ré-installation) que l'on ai beaucoup de fichiers modifiés/supprimés au niveau de git.\\ Voici la commande find qu'on peut exécuter après une installation : find . -type f -not -path '*/storage/*' -not -path '*/.git/*' -iname '*' -mmin -5 on peut évidemment faire varier les //-5// minutes.\\ Et on peut ajouter // -exec git add {} \;// pour ajouter ces fichiers au prochain commit !