Quedan unos días hasta el comienzo de un nuevo curso de OTUS: "Framework Laravel" . En previsión del comienzo del curso, compartimos la parte final de la publicación del autor sobre los conceptos básicos en Laravel. Importante: esta serie de publicaciones no está relacionada con el programa educativo del curso y es un material poco útil para principiantes . El programa del curso se puede encontrar aquí .
En el último 
artículo, comenzamos a escribir una galería en la que un usuario puede iniciar sesión y registrarse, crear álbumes con una descripción, portada y título. En la aplicación creada existe el valor principal de nuestra 
view y ahora es necesario expandirlo un poco. 
Además, el código existente merece una pequeña mejora:
Ya tenemos dos controladores: 
AlbumController e 
ImageController . Agregue la importación de una clase adicional que se encarga de trabajar con cadenas:
  use Illuminate\Support\Str; 
Y cambie la línea responsable de generar un nombre de imagen aleatorio en nuestra base de datos:
  $random_name = Str::random(8); 
Además, ahora vale la pena cambiar un poco el código de migración para aumentar la confiabilidad de nuestra aplicación, porque el usuario debe tener el derecho de dejar nuestro campo de 
description vacío (de lo contrario, Laravel con dinamita nos notificará un error). Pasemos a la migración asociada con la tabla de imágenes y corrijamos allí la línea relacionada con la descripción de la imagen para esta:
  $table->string('description')->nullable(); 
Bueno, con la "refactorización" de la aplicación está terminada. A continuación, debe finalizar el aspecto de nuestra aplicación. Cree un formulario en el que el usuario podrá crear sus álbumes:
archivo 
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> 
Permítame recordarle que en 
includes en la parte superior de la página tenemos la navegación y las bibliotecas utilizadas, que se describieron en la última parte.
Además, necesitamos agregar el aspecto 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> 
Además, podemos actualizar ligeramente nuestro enrutamiento, por ejemplo, en 
nav.blade.php :
  <li><a href="{{URL::route('create_album_form')}}">  </a></li> 
A una opción más nueva y más de moda:
  <li><a href="{{route('create_album_form')}}">  </a></li> 
Por otro lado, la versión anterior funcionó en 6 Laravel. Entonces, ya tenemos un formulario en el que el usuario puede agregar fotos al álbum, y allí está la 
view principal 
view nuestro álbum. A continuación, debemos agregar un controlador que será responsable del procesamiento de una sola foto.
Entonces, creamos un controlador responsable de trabajar con fotos individuales:
  php artisan make:controller ImageController 
Entonces, qué debería estar dentro de nosotros:
  <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\MessageBag; use Validator;  

Registro y autorización
Por el momento, nuestra aplicación está casi lista. Sin embargo, aún debemos reforzar la capacidad de registrarnos en nuestra aplicación, cerrar sesión e iniciar sesión en una cuenta existente.
En la última parte, ya hemos mostrado cómo se ve nuestro 
includes/nav.blade.php . Porque queremos que los botones 
Iniciar sesión y 
aparezcan cuando el usuario aún no se haya registrado, y el botón 
Cerrar sesión cuando esté registrado con nosotros.
Entonces, así es como vemos ahora la lista en 
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 
Auth::check construction y elemental, de 
if else , podemos generar cambios en nuestra 
view , dependiendo de si nuestro usuario está registrado o no.
Sin embargo, con los cambios en la 
view antes de crear el modelo y el controlador, corremos un poco por delante del motor. Para realizar nuestra autenticación, utilizaremos todas las soluciones rápidas y listas para usar que se encuentran en Laravel 6.
Entonces, sobre el modelo de 
Usuario , usaremos el que viene en la caja. Por un lado, claramente no es suficiente para una aplicación completa, por el otro, no quiero limitarme al alcance de una aplicación específica. ¿Qué tipo de galería quieres? ¿Dónde puede un usuario crear sus propios álbumes privados que no sean accesibles para nadie? ¿O dónde comparten todos sus fotos? No tendremos limitaciones en nuestra aplicación: creo que el lector podrá terminarlas sin ningún problema para su gusto y color.
Entonces, en Laravel 6, crear autenticación se ha vuelto aún más fácil. Vamos a la línea de comando de nuestra aplicación:
  composer require laravel/ui —dev 
Lo que nos da los paquetes necesarios. Ahora crea:
  php artisan ui:auth 
¿Qué nos da este equipo? En primer lugar, tenemos una nueva carpeta de 
auth en 
resources/views , en la que tenemos todas las 
views que pueden ser necesarias para autorizar a un usuario y registrarlas: 
login , 
register y 
verify . También hay una subcarpeta de 
passwords dedicada a restablecer y recuperar contraseñas. En la carpeta 
Http/Controllers , tenemos 
HomeController , que es necesario para redirigir a la página de inicio después del registro del usuario. También tendremos un 
layouts subcarpeta, que contendrá 
app.blade.php , que no analizaremos hoy, pero puede ser una base excelente para una aplicación creada desde cero.
Las plantillas de hoja generadas ya tienen un diseño inicial personalizado para 
Bootstrap . Ya lo tenemos conectado en 
header.blade.php .
Además, hemos actualizado un poco de enrutamiento en 
routes/web.php . Se agregaron las siguientes líneas:
  Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); Route::post('/logout', 'Auth\LoginController@logout')->name('logout'); 
La ruta de acceso a 
home genera automáticamente y realicé el redireccionamiento para 
logout .
Para que su diseño funcione en las plantillas generadas, conectaremos nuestro 
nav y 
header a ellas:
  @include('includes.header') <body> @include('includes.nav') @extends('layouts.app') 
Genial, ahora todo está listo. Intenta registrarte. La confirmación de contraseña también debería funcionar:


En el futuro, el usuario puede elegir a qué página del servicio quiere ir (o el lector puede hacer una redirección por su cuenta, no es lo suficientemente complicado). Solo tenemos que arreglar un pequeño detalle: para que solo los usuarios registrados y autorizados puedan ver nuestros preciosos álbumes.
Para hacer esto, agregamos una condición a nuestra ruta para que el usuario inicie sesión para acceder a los álbumes.
Actualizando nuestro 
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');; //   
Básicamente, en esta etapa ya podemos terminar. Dejaré al lector qué aplicación quiere hacer: con álbumes privados o públicos. Teóricamente, la aplicación ya se puede usar si desactivó la posibilidad de registrarse y crear un usuario por separado directamente en la base de datos, por ejemplo, si usted y sus colegas van a organizar sus álbumes privados y, por alguna razón, no desean utilizar otros servicios.
¡Gracias a todos por su atención! Como siempre, enlaces útiles: