Que los usuarios puedan agregar su foto de perfil es una funcionalidad que cualquier web tiene. Por eso vamos a agregarla a nuestro proyecto.
Primero de todo generamos una migración, ya que tenemos que agregar un nuevo campo a la base de datos. para generar una migración puedes mirar cómo se hace en otros posts míos. El contenido que deberá tener nuestra nueva migración será:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddAvatarToUserTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function(Blueprint $table) { $table->string('avatar')->default("default_avatar.png"); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function(Blueprint $table) { $table->dropColumn('avatar'); }); } } |
Si te fijas, tiene un valor por defecto, por tanto deberemos poner el nombre de la imagen que queramos que salga por defecto y esta imagen deberá estar en public/uploads/avatars . Ejecutamos la migración.
Ahora vamos a crear las rutas:
1 2 |
Route::get('/profile', 'UserController@profile')->name('user.profile'); Route::patch('/profile', 'UserController@update_profile')->name('user.profile.update'); |
La primera ruta será la que muestre el perfil del usuario y la segunda será la que nos permitirá editarlo.
Creamos el controlador UserController.php :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class UserController extends Controller { public function __construct() { $this->middleware('auth')->only('profile', 'update_profile'); } public function profile() { $user = Auth::user(); return view('profile', ['user' => $user]); } public function update_profile(Request $request) { $this->validate($request, [ 'avatar' => 'required|image|mimes:jpg,png,jpeg,gif,svg|max:2048', ]); $filename = Auth::id().'_'.time().'.'.$request->avatar->getClientOriginalExtension(); $request->avatar->move(public_path('uploads/avatars'), $filename); $user = Auth::user(); $user->avatar = $filename; $user->save(); return redirect()->route('user.profile'); } } |
El método profile envía los datos del usuario logueado a la vista.
El método update_profile valida que sea una imagen lo que enviamos, la sube a la carpeta public/uploads/avatars y después guarda el nombre en la base de datos y volvemos al perfil.
La vista del perfil contiene la imagen y nombre de usuario y un formulario para cambiar la imagen de perfil:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> @include('includes.errors') <img width="100px" height="100px" src="{{ asset('uploads/avatars/'.$user->avatar) }}"> <h2>{{ $user->name }}</h2> <h4>Edit avatar</h4> {{ Form::open(['route' => ['user.profile.update'], 'files' => true, 'method' => 'PATCH']) }} <p>{{ Form::file('avatar') }}</p> <p>{{ Form::submit('Update', ['name' => 'submit']) }}</p> {{ Form::close() }} </div> </div> </div> @endsection |
Y para acabar, añadimos en el header la imagen y en el desplegable un link hacia el perfil del usuario logueado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@if (Auth::guest()) ... @else ... <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> <img width="20px" height="20px" src="{{ asset('uploads/avatars/'.Auth::user()->avatar) }}"> ... </a> <ul class="dropdown-menu" role="menu"> <li> <a href="{{ route('user.profile') }}"> Profile </a> ... </li> </ul> @endif |
Esta entrada era más que nada para ver como subir archivos con Laravel a nuestro servidor y ya hemos visto que es muy simple. Esto también se puede aplicar para otros tipos de ficheros, pero, claro, con diferentes validaciones.
También se podrían añadir más campos (no solo el avatar) para modificar y mejorar la estructura, poniendo el formulario en otra página separada o en una ventana modal. Ésto, a lo mejor, lo hago en otra entrada más adelante.
-
– https://devdojo.com/episode/laravel-user-image
– http://laravel-tricks.com/tricks/laravel-54-upload-image-with-validation-example
Hola!, tengo una duda, hasta este punto todo perfecto en el proyecto, solo que si agrego estas lineas: «avatar) }}»>
Perfil» en el layout sin que haya ningun usuario logueado me marca este error: «ErrorException
Trying to get property of non-object (View: C:\xampp\htdocs\proyectoLaravel\resources\views\layouts\app.blade.php) (View: C:\xampp\htdocs\proyectoLaravel\resources\views\layouts\app.blade.php)», pero si quito las lineas e inicio sesión, y agrego las lineas de nuevo ahora ya con el usuario logueado todo marcha perfecto, mi duda es si asi es como deberia funcionar o que estoy haciendo mal, gracias por tu tiempo y espero puedas apoyarme, muy bueno tu curso 😀
Hey Billy!
Es porque no lo estás poniendo en el lugar correcto. Si te fijas en el header hay este código:
@if (Auth::guest())
// código que ve un usuario no logueado
@else
// código que ve un usuario logueado
@endif
Pues tienes que ponerlo en la parte de usuario loguedo (en el else), porque si no está intentando acceder al usuario y cuando no estás logueado, no existe.
Saludos!
Muchisimas gracias se resolvio el problema 😀
quiero consumir los datos del usuario por medio de un API, pero mandar la imagen como base64 como lo puedo hacer?
Hola Jonathan! Por lo que entiendo, tendrás que transformar la imagen a base64 desde JS (si la llamada la haces desde frontend) o PHP (si la llamada la haces desde backend). Puedes buscar por Google cómo hacerlo. Espero que te sea de ayuda.