Laravel: analisamos os conceitos básicos. Parte Três: A Final

Restam alguns dias até o início de um novo curso da OTUS - “Framework Laravel” . Antecipando o início do curso, compartilhamos a parte final da publicação do autor sobre os conceitos básicos do Laravel. Importante: esta série de publicações não está relacionada ao programa educacional do curso e é um material pouco útil para iniciantes . O programa do curso pode ser encontrado aqui .




No último artigo, começamos a escrever uma galeria na qual um usuário pode fazer login e se registrar, criar álbuns com uma descrição, capa e título. No aplicativo criado, existe o valor primário de nossa view e agora é necessário expandi-lo um pouco.
Além disso, o código existente merece uma pequena melhoria:

Já temos dois controladores - AlbumController e ImageController . Adicione a importação de uma classe adicional responsável pelo trabalho com cadeias de caracteres:

  use Illuminate\Support\Str; 

E altere a linha responsável por gerar um nome de imagem aleatório em nosso banco de dados:

  $random_name = Str::random(8); 

Além disso, agora vale a pena alterar um pouco o código de migração para aumentar a confiabilidade do nosso aplicativo, porque o usuário deve ter o direito de deixar nosso campo de description branco (caso contrário, o Laravel com dinamite nos notificará sobre um erro). Vamos para a migração associada à tabela de imagens e corrija a linha relacionada à descrição da imagem para esta:

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

Bem, com a "refatoração" do aplicativo está concluída. Em seguida, você precisa finalizar a aparência do nosso aplicativo. Crie um formulário no qual o usuário possa criar seus álbuns:

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

Deixe-me lembrá-lo de que em includes na parte superior da página, temos a navegação e as bibliotecas usadas, descritas na última parte.

Além disso, precisamos adicionar a aparência 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> 

Além disso, podemos atualizar levemente nosso roteamento, por exemplo, em nav.blade.php :

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

Para uma opção mais nova e mais elegante:

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

Por outro lado, a versão anterior funcionou no 6 Laravel. Portanto, já temos uma forma na qual o usuário pode adicionar fotos ao álbum, e existe a view principal view nosso álbum. Em seguida, precisamos adicionar um controlador que será responsável pelo processamento de uma única foto.

Portanto, criamos um controlador responsável por trabalhar com fotos individuais:

  php artisan make:controller ImageController 

Então, o que deve estar dentro de nós:

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



Registro e autorização


No momento, nosso aplicativo está quase pronto. No entanto, ainda precisamos aumentar a capacidade de registrar em nosso aplicativo, sair e fazer login em uma conta existente.

Na última parte, já mostramos como é o nosso includes/nav.blade.php . Porque queremos que os botões Login e apareçam quando o usuário ainda não se registrou e o botão Sair quando ele estiver registrado conosco.

Então, é assim que agora olhamos para a lista em 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> 

Usando o Auth::check construction e elementar, if else , podemos criar alterações em nossa view , dependendo de nosso usuário estar registrado ou não.

No entanto, com as alterações na view antes de criar o modelo e o controlador, corremos um pouco à frente do mecanismo. Para fazer nossa autenticação, usaremos todas as soluções prontas e rápidas que estão no Laravel 6.

Então, sobre o modelo de usuário - usaremos o que vem na caixa. Por um lado, claramente não é suficiente para um aplicativo completo, por outro - não quero me limitar ao escopo de um aplicativo específico. Que tipo de galeria você quer? Onde um usuário pode criar seus próprios álbuns privados que não são acessíveis a ninguém? Ou onde todos compartilham suas fotos? Não teremos limitações em nossa aplicação - acho que o leitor poderá finalizá-las sem problemas ao seu gosto e cor.

Portanto, no Laravel 6, a criação de autenticação se tornou ainda mais fácil. Vamos para a linha de comando do nosso aplicativo:

  composer require laravel/ui —dev 

O que nos dá os pacotes necessários. Agora crie:

  php artisan ui:auth 

O que essa equipe nos dá? Primeiramente, temos uma nova pasta de auth em resources/views , na qual temos todas as views necessárias para autorizar um usuário e registrá-lo: faça login , register e verify . Há também uma subpasta de passwords dedicada à redefinição e recuperação de senhas. Na pasta Http/Controllers , temos o HomeController , necessário para redirecionar para a página inicial após o registro do usuário. Também teremos layouts subpastas, que conterão app.blade.php , que não analisaremos hoje, mas pode ser uma excelente base para um aplicativo criado do zero.

Os modelos de blade gerados já têm um layout inicial personalizado para o Bootstrap . Já o temos conectado em header.blade.php .
Além disso, atualizamos um pouco do roteamento em routes/web.php . As seguintes linhas foram adicionadas:

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

O caminho para home gerado automaticamente e eu fiz o redirecionamento para me logout .

Para que seu layout funcione nos modelos gerados, conectaremos nossa nav e header a eles:

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

Ótimo, agora está tudo pronto. Tente se registrar. A confirmação da senha também deve funcionar:





No futuro, o usuário poderá escolher em qual página do serviço deseja acessar (ou o leitor poderá redirecionar por conta própria, não é complicado o suficiente). Só precisamos corrigir um pequeno detalhe: para que apenas usuários registrados e autorizados possam ver nossos álbuns preciosos.

Para fazer isso, adicionamos uma condição ao nosso roteamento para que o usuário efetue login para acessar os álbuns.

Atualizando nosso 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');; //   

Basicamente, nesta fase, já podemos terminar. Vou deixar para o leitor que aplicativo ele quer fazer: com álbuns particulares ou públicos. Teoricamente, o aplicativo já pode ser usado se você tiver a possibilidade de registrar e criar um usuário separadamente diretamente no banco de dados - por exemplo, se você e seus colegas vão organizar seus álbuns particulares e, por algum motivo, não quiserem usar outros serviços.

Obrigado a todos pela atenção! Como sempre, links úteis:

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


All Articles