Laravel: nous analysons les concepts de base. Troisième partie: la finale

Il reste quelques jours avant le début d'un nouveau cours d'OTUS - «Framework Laravel» . En prévision du début du cours, nous partageons la dernière partie de la publication de l'auteur sur les concepts de base de Laravel. Important: cette série de publications n'est pas liée au programme éducatif du cours et est un peu utile pour les débutants . Le programme du cours peut être trouvé ici .




Dans le dernier article, nous avons commencé à écrire une galerie dans laquelle un utilisateur peut se connecter et s'inscrire, créer des albums avec une description, une couverture et un titre. Dans l'application créée, il y a la valeur principale de notre view et maintenant il est nécessaire de l'étendre un peu.
De plus, le code existant mérite une petite amélioration:

Nous avons déjà deux contrôleurs - AlbumController et ImageController . Ajoutez l'importation d'une classe supplémentaire chargée de travailler avec les chaînes:

  use Illuminate\Support\Str; 

Et changez la ligne qui est responsable de générer un nom d'image aléatoire dans notre base de données:

  $random_name = Str::random(8); 

De plus, il vaut maintenant la peine de changer un peu le code de migration pour augmenter la fiabilité de notre application, car l'utilisateur doit avoir le droit de laisser notre champ de description vide (sinon Laravel avec dynamite nous signalera une erreur). Passons à la migration associée à la table d'images, et corrigeons-y la ligne liée à la description de l'image à celle-ci:

  $table->string('description')->nullable(); 

Eh bien, le "refactoring" de l'application est terminé. Ensuite, vous devez terminer l'apparence de notre application. Créez un formulaire dans lequel l'utilisateur pourra créer ses albums:

fichier addimage.blade.php

  @include('includes.header') <body> @include('includes.nav') <div class="container" style="text-align: center;"> <div class="span4" style="display: inline-block; margin-top:100px;"> @if (isset($errors) && $errors->has('')) <div class="alert alert-block alert-error fade in"id="error-block"> <?php $messages = $errors->all('<li>:message</li>'); ?> <button type="button" class="close"data-dismiss="alert">×</button> <h4>Warning!</h4> <ul> @foreach($messages as $message) {{$message}} @endforeach </ul> </div> @endif <form name="createnewalbum" method="POST"action="{{route('create_album')}}" enctype="multipart/form-data"> {{ csrf_field() }} <fieldset> <legend> </legend> <div class="form-group"> <label for="name"> </label> <input name="name" type="text" class="form-control"placeholder=" " value="{{old('name')}}"> </div> <div class="form-group"> <label for="description"> </label> <textarea name="description" type="text"class="form-control" placeholder=" ">{{old('descrption')}}</textarea> </div> <div class="form-group"> <label for="cover_image">   </label> {{Form::file('cover_image')}} </div> <button type="submit" class=«btn btn-default">!</button> </fieldset> </form> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script> </body> </html> 

Permettez-moi de vous rappeler que, dans le haut de la page, nous avons la navigation et les bibliothèques utilisées, qui ont été décrites dans la dernière partie.

De plus, nous devons ajouter le look de album.blade.php

  @include('includes.header') <body> @include('includes.nav') <div class="container"> <div class="starter-template"> <div class="media"> <img class="media-object pull-left"alt="{{$album->name}}" src="/albums/{{$album->cover_image}}" width="350px"> <div class="media-body"> <h2 class="media-heading" style="font-size: 26px;"> :</h2> <p>{{$album->name}}</p> <div class="media"> <h2 class="media-heading" style="font-size: 26px;">  :</h2> <p>{{$album->description}}<p> <a href="{{route('add_image',array('id'=>$album->id))}}"><button type="button"class="btn btn-primary btn-large">    </button></a> <a href="{{route('delete_album',array('id'=>$album->id))}}" onclick="return confirm(' ?')"><button type="button"class="btn btn-danger btn-large"> </button></a> </div> </div> </div> </div> <div class="row"> @foreach($album->Photos as $photo) <div class="col-lg-3"> <div class="thumbnail" style="max-height: 350px;min-height: 350px;"> <img alt="{{$album->name}}" src="/albums/{{$photo->image}}"> <div class="caption"> <p>{{$photo->description}}</p> <p> : {{ date("d FY",strtotime($photo->created_at)) }}at {{ date("g:ha",strtotime($photo->created_at)) }}</p> <a href="{{route('delete_image',array('id'=>$photo->id))}}" onclick="returnconfirm(' ?')"><button type="button"class="btn btn-danger btn-small"> </button></a> <p>     :</p> <form name="movephoto" method="POST"action="{{route('move_image')}}"> {{ csrf_field() }} <select name="new_album"> @foreach($albums as $others) <option value="{{$others->id}}">{{$others->name}}</option> @endforeach </select> <input type="hidden" name="photo"value="{{$photo->id}}" /> <button type="submit" class="btn btn-smallbtn-info" onclick="return confirm(' ?')"> </button> </form> </div> </div> </div> @endforeach </div> </div> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> </body> </html> 

De plus, nous pouvons légèrement mettre à jour notre routage, par exemple dans nav.blade.php :

  <li><a href="{{URL::route('create_album_form')}}">  </a></li> 

Vers une option plus récente et plus à la mode:

  <li><a href="{{route('create_album_form')}}">  </a></li> 

En revanche, la version précédente fonctionnait sur 6 Laravel. Donc, nous avons déjà un formulaire dans lequel l'utilisateur peut ajouter des photos à l'album, et il y a la view principale view notre album. Ensuite, nous devons ajouter un contrôleur qui sera responsable du traitement d'une seule photo.

Nous créons donc un contrôleur chargé de travailler avec les photos individuelles:

  php artisan make:controller ImageController 

Alors, ce qui devrait être en nous:

  <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\MessageBag; use Validator; //       use App\Album; use App\Image; use Illuminate\Support\Str; class ImageController extends Controller { public function getForm($id) { $album = Album::find($id); return view('addimage') ->with('album',$album); //  ,          } public function postAdd(Request $request) { //    ,       $rules = [ 'album_id' => 'required|numeric|exists:albums,id', 'image'=>'required|image' ]; $input = ['album_id' => null]; $validator = Validator::make($request->all(), $rules); if($validator->fails()){ return redirect()->route('add_image', ['id' => $request->get('album_id')])->withErrors($validator)->withInput(); } $file = $request->file('image'); //   $random_name = Str::random(8); //  $destinationPath = 'albums/'; $extension = $file->getClientOriginalExtension(); $filename=$random_name.'_album_image.'.$extension; $uploadSuccess = $request->file('image')->move($destinationPath, $filename); Image::create(array( 'description' => $request->get('description'), //   'image' => $filename, //   'album_id'=> $request->get('album_id') //         )); return redirect()->route('show_album',['id'=>$request->get('album_id')]); } public function getDelete($id) //       { $image = Image::find($id); $image->delete(); return redirect()->route('show_album',['id'=>$image->album_id]); } //       public function postMove(Request $request) { $rules = array( 'new_album' => 'required|numeric|exists:albums,id', 'photo'=>'required|numeric|exists:images,id' ); //    $validator = Validator::make($request->all(), $rules); if($validator->fails()){ return redirect()->route('index'); } $image = Image::find($request->get('photo')); $image->album_id = $request->get('new_album'); $image->save(); return redirect()->route('show_album', ['id'=>$request->get('new_album')]); } } 



Enregistrement et autorisation


Pour le moment, notre application est presque prête. Cependant, nous devons encore resserrer la possibilité de s'inscrire dans notre application, de se déconnecter et de se connecter à un compte existant.

Dans la dernière partie, nous avons déjà montré à quoi ressemble notre includes/nav.blade.php . Parce que nous voulons que les boutons de connexion et d' apparaissent lorsque l'utilisateur ne s'est pas encore inscrit, et le bouton de déconnexion lorsqu'il est enregistré avec nous.

Donc, includes/nav.blade.php comment nous regardons maintenant la liste dans includes/nav.blade.php :

  <ul class="nav navbar-nav"> @if (Auth::check()) <li> <button type="button" class="btn btn-primary"> <!--   ,  ->   --> {{{ Auth::user()->name}}} </button> </li> <li><a href="{{route('create_album_form')}}">  </a></li> @else <!--    --> <li><a href="{{route('register')}}"></a></li> <li><a href="{{route('login')}}"></a></li> @endif @if (Auth::check()) <!--  ,       --> <!--      --> <li> <a href="{{url('/logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">  </a> <form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;"> {{ csrf_field() }} </form> </li> @endif </ul> 

En utilisant la construction Auth::check et élémentaire if else , nous pouvons construire des changements dans notre view , selon que notre utilisateur est enregistré ou non.

Cependant, avec des modifications apportées à la view avant de créer le modèle et le contrôleur, nous avons un peu d'avance sur le moteur. Afin de faire notre authentification, nous utiliserons toutes les solutions prêtes à l'emploi et rapides qui se trouvent dans Laravel 6.

Donc, à propos du modèle utilisateur - nous utiliserons celui qui vient dans la boîte. D'une part, ce n'est clairement pas suffisant pour une application à part entière, d'autre part - je ne veux pas me limiter à la portée d'une application spécifique. Quel genre de galerie voulez-vous? Où un utilisateur peut-il créer ses propres albums privés qui ne sont accessibles à personne? Ou où tout le monde partage ses photos? Nous n'aurons pas de limites dans notre application - je pense que le lecteur pourra les finir sans aucun problème à son goût et sa couleur.

Ainsi, dans Laravel 6, la création de l'authentification est devenue encore plus facile. Nous allons sur la ligne de commande de notre application:

  composer require laravel/ui —dev 

Ce qui nous donne les packages nécessaires. Créez maintenant:

  php artisan ui:auth 

Que nous apporte cette équipe? Premièrement, nous avons un nouveau dossier d' auth dans les resources/views , dans lequel nous avons toutes les views qui peuvent être nécessaires pour autoriser un utilisateur et l'enregistrer: login , register et verify . Il existe également un sous-dossier de passwords dédié à la réinitialisation et à la récupération des mots de passe. Dans le dossier Http/Controllers , nous avons HomeController , qui est nécessaire pour rediriger vers la page d'accueil après l'enregistrement de l'utilisateur. Nous aurons également une layouts sous-dossiers, qui contiendra app.blade.php , que nous app.blade.php pas aujourd'hui, mais cela peut être une excellente base pour une application créée à partir de zéro.

Les modèles de lame générés ont déjà une disposition initiale adaptée à Bootstrap . Nous l'avons déjà connecté dans header.blade.php .
De plus, nous avons mis à jour un peu de routage dans routes/web.php . Les lignes suivantes ont été ajoutées:

  Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); Route::post('/logout', 'Auth\LoginController@logout')->name('logout'); 

Le chemin vers la home généré automatiquement et j'ai fait la redirection pour me logout moi-même.

Pour que votre mise en page fonctionne sur les modèles générés, nous allons leur connecter notre nav et notre en- header :

  @include('includes.header') <body> @include('includes.nav') @extends('layouts.app') 

Génial, maintenant tout est prêt. Essayez de vous inscrire. La confirmation du mot de passe devrait également fonctionner:





À l'avenir, l'utilisateur peut choisir vers quelle page du service il veut aller (ou le lecteur peut faire lui-même une redirection, ce n'est pas très difficile) Il suffit de fixer un petit détail: faire en sorte que seuls les utilisateurs enregistrés et autorisés puissent voir nos précieux albums.

Pour ce faire, nous ajoutons une condition à notre routage afin que l'utilisateur se connecte pour accéder aux albums.

Mise à jour de notre web.php :

  Route::get('/', array('as' => 'index','uses' => 'AlbumsController@getList')) ->middleware('auth');; //middleware     http    Route::get('/createalbum', array('as' => 'create_album_form','uses' => 'AlbumsController@getForm')) ->middleware('auth');; //    Route::post('/createalbum', array('as' => 'create_album','uses' => 'AlbumsController@postCreate')) ->middleware('auth');; //   Route::get('/deletealbum/{id}', array('as' => 'delete_album','uses' => 'AlbumsController@getDelete')) ->middleware('auth');; //   Route::get('/album/{id}', array('as' => 'show_album','uses' => 'AlbumsController@getAlbum')) ->middleware('auth');; //   

Fondamentalement, à ce stade, nous pouvons déjà terminer. Je laisse au lecteur le choix de l'application qu'il souhaite faire: avec des albums privés ou avec des albums publics. En théorie, l'application peut déjà être utilisée si vous avez vu la possibilité de vous inscrire et de créer un utilisateur séparément directement dans la base de données - par exemple, si vous et vos collègues allez organiser vos albums privés et que pour une raison quelconque vous ne souhaitez pas utiliser d'autres services.

Merci à tous pour votre attention! Comme toujours, des liens utiles:

Source: https://habr.com/ru/post/fr473114/


All Articles