Laravel: Wir analysieren die Grundkonzepte. Dritter Teil: Das Finale

Bis zum Start eines neuen Kurses von OTUS - „Framework Laravel“ - verbleiben noch einige Tage. Im Vorgriff auf den Beginn des Kurses teilen wir den letzten Teil der Veröffentlichung des Autors zu den Grundkonzepten in Laravel. Wichtig: Diese Reihe von Veröffentlichungen bezieht sich nicht auf das Bildungsprogramm des Kurses und ist ein wenig nützliches Material für Anfänger . Das Kursprogramm finden Sie hier .




Im letzten Artikel haben wir begonnen, eine Galerie zu schreiben, in der sich ein Benutzer anmelden und registrieren sowie Alben mit Beschreibung, Cover und Titel erstellen kann. In der erstellten Anwendung gibt es den Hauptwert unserer view und jetzt ist es notwendig, sie ein wenig zu erweitern.
Auch der vorhandene Code ist eine kleine Verbesserung wert:

Wir haben bereits zwei Controller - AlbumController und ImageController . Fügen Sie den Import einer zusätzlichen Klasse hinzu, die für die Arbeit mit Zeichenfolgen verantwortlich ist:

  use Illuminate\Support\Str; 

Und ändern Sie die Zeile, die für die Generierung eines zufälligen Bildnamens in unserer Datenbank verantwortlich ist:

  $random_name = Str::random(8); 

Außerdem lohnt es sich jetzt, den Migrationscode ein wenig zu ändern, um die Zuverlässigkeit unserer Anwendung zu erhöhen, da der Benutzer das Recht haben muss, unser description leer zu lassen (andernfalls benachrichtigt uns Laravel mit Dynamit über einen Fehler). Gehen wir zur Migration, die der Bildtabelle zugeordnet ist, und korrigieren dort die Zeile, die sich auf die Bildbeschreibung bezieht, auf diese:

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

Nun, mit dem "Refactoring" der Anwendung ist fertig. Als nächstes müssen Sie das Aussehen unserer Anwendung beenden. Erstellen Sie ein Formular, in dem der Benutzer seine Alben erstellen kann:

addimage.blade.php Datei

  @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> 

Ich möchte Sie daran erinnern, dass in den includes oben auf der Seite die Navigation und die Bibliotheken verwendet werden, die im letzten Teil beschrieben wurden.

Außerdem müssen wir das Aussehen von 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> 

Außerdem können wir unser Routing leicht aktualisieren, beispielsweise in nav.blade.php :

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

Zu einer neueren und modischeren Option:

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

Andererseits funktionierte die vorherige Version auf 6 Laravel. Wir haben also bereits eine Form, in der der Benutzer Fotos zum Album hinzufügen kann, und es gibt die Hauptansicht unseres Albums. Als nächstes müssen wir einen Controller hinzufügen, der für die Verarbeitung eines einzelnen Fotos verantwortlich ist.

Also erstellen wir einen Controller, der für die Arbeit mit einzelnen Fotos verantwortlich ist:

  php artisan make:controller ImageController 

Also, was sollte in uns sein:

  <?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')]); } } 



Registrierung und Autorisierung


Im Moment ist unsere Bewerbung fast fertig. Wir müssen jedoch noch die Möglichkeit verbessern, uns in unserer Anwendung zu registrieren, sich abzumelden und sich bei einem vorhandenen Konto anzumelden.

Im letzten Teil haben wir bereits gezeigt, wie unsere includes/nav.blade.php aussieht. Weil Wir möchten, dass die Schaltflächen Anmelden und angezeigt werden, wenn sich der Benutzer noch nicht registriert hat, und die Schaltfläche Abmelden, wenn er bei uns registriert ist.

So sehen wir uns nun die Liste in 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> 

Mit der Auth::check Konstruktion und der Elementar-Funktion if else wir Änderungen in unserer view vornehmen, je nachdem, ob unser Benutzer registriert ist oder nicht.

Mit Änderungen an der view vor dem Erstellen des Modells und der Steuerung laufen wir jedoch der Engine ein wenig voraus. Um unsere Authentifizierung vorzunehmen, werden wir alle vorgefertigten und schnellen Lösungen verwenden, die in Laravel 6 enthalten sind.

Also, über das Benutzermodell - wir werden das im Lieferumfang enthaltene verwenden. Einerseits reicht es für eine vollwertige Bewerbung eindeutig nicht aus, andererseits möchte ich mich nicht auf den Umfang einer bestimmten Bewerbung beschränken. Was für eine Galerie willst du? Wo kann ein Benutzer seine eigenen privaten Alben erstellen, auf die niemand zugreifen kann? Oder wo teilen alle ihre Fotos? Wir werden keine Einschränkungen in unserer Anwendung haben - ich denke, der Leser wird sie ohne Probleme für seinen Geschmack und seine Farbe fertigstellen können.

In Laravel 6 ist das Erstellen der Authentifizierung noch einfacher geworden. Wir gehen zur Kommandozeile unserer Anwendung:

  composer require laravel/ui —dev 

Welches gibt uns die notwendigen Pakete. Jetzt erstellen:

  php artisan ui:auth 

Was gibt uns dieses Team? Erstens haben wir einen neuen auth Ordner in resources/views , in dem wir alle views , die erforderlich sind, um den Benutzer zu autorisieren und zu registrieren: login , register und verify . Es gibt auch einen Unterordner für passwords , in dem Kennwörter zurückgesetzt und wiederhergestellt werden. Im Ordner " HomeController Http/Controllers " befindet sich der HomeController , der benötigt wird, um nach der Benutzerregistrierung zur Startseite umzuleiten. Wir werden auch ein Unterordner- app.blade.php , das app.blade.php enthält, das wir heute nicht analysieren werden, aber es kann eine hervorragende Basis für eine von Grund auf neu erstellte Anwendung sein.

Generierte Blade-Vorlagen haben bereits ein anfängliches Layout, das auf Bootstrap zugeschnitten ist. Wir haben es bereits in header.blade.php .
Außerdem haben wir ein bisschen Routing in routes/web.php . Die folgenden Zeilen wurden hinzugefügt:

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

Der Pfad nach home automatisch generiert, und ich habe die Umleitung durchgeführt, um mich logout .

Damit Ihr Layout an den generierten Vorlagen arbeiten kann, verbinden wir unser nav und unseren header mit diesen:

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

Großartig, jetzt ist alles fertig. Versuchen Sie sich zu registrieren. Die Passwortbestätigung sollte auch funktionieren:





In Zukunft kann der Benutzer auswählen, zu welcher Seite des Dienstes er gehen möchte (oder der Leser kann selbst eine Weiterleitung vornehmen, dies ist nicht kompliziert genug). Wir müssen nur ein kleines Detail korrigieren: Damit nur registrierte und autorisierte Benutzer unsere wertvollen Alben sehen können.

Zu diesem Zweck fügen wir unserem Routing eine Bedingung hinzu, damit sich der Benutzer anmeldet, um auf die Alben zuzugreifen.

Aktualisierung unserer 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');; //   

Grundsätzlich können wir zu diesem Zeitpunkt bereits fertig sein. Ich überlasse es dem Leser, welchen Antrag er stellen möchte: mit privaten oder mit öffentlichen Alben. Rein theoretisch kann die Anwendung bereits verwendet werden, wenn Sie die Möglichkeit der Registrierung ausgeschlossen und einen Benutzer separat direkt in der Datenbank erstellt haben - beispielsweise, wenn Sie und Ihre Kollegen Ihre privaten Alben organisieren und aus irgendeinem Grund keine anderen Dienste nutzen möchten.

Vielen Dank für Ihre Aufmerksamkeit! Wie immer nützliche Links:

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


All Articles