Creando instagram (versión web) con laravel #5: Foto de perfil.
En esta oportunidad añadiremos la funcionalidad de subir una foto de perfil pero antes de comenzar debemos modificar algunas cosas:
El repositorio para seguir el código esta en: https://github.com/Brandonxy/imagegram.
En el controlador HomeController cambiamos el index
para que apunte al home y no al user.profile
, entonces queda asi:
public function index()
{
return view('home');
}
En el Controller ProfileController modificamos el método index para que apunte a la vista correcta, antes apuntaba a view('profile.index')
y lo cambiamos a view('user.profile’)
.
Base de datos
1.- Creamos una migración para la foto de perfil:
php artisan migration add_profile_picture_field
Luego correr esta migración con php artisan migrate y agregará una columna para el nombre del archivo de la foto de perfil.
Modelo
En el modelo User creamos 2 nuevos métodos:
El método hasProfilePicture()
es saber si el usuario tiene una foto de perfil asignada, en caso de no tener simplemente retorna false y ponemos una imagen por defecto, en este caso la obtenemos desde https://via.placeholder.com/150x150.
Por otro lado el método getProfilePictureAttribute()
es para obtener la ruta completa de la imagen, que es una combinación de “nombre de la carpeta + el nombre de la columna en la base de datos” utilizando el helper url() de laravel. Finalemente debes crear una carpeta profile_pictures dentro de /public para almacenar las imágenes.
La vista
La vista profile.blade.php
dentro de resources/user
debería quedar de la siguiente manera:
Aquí utilizamos los métodos creados anteriormente y notarás que estoy utilizando Auth::user()->profile_picture
y no getProfilePictureAttribute
, es simplemente porque este método es un “accessor”, que es para darle otra forma al atributo al momento de obtenerlo, en este caso en vez de solo obtener el nombre del archivo (foto de perfil) retornamos una ruta mas elaborada desde el método para simplificar la vista.
Si vamos al perfil del usuario después de este código veremos algo asi:
En mi caso aparecen datos generados por el faker y abajo la sección de las fotos. Como ves cargo la foto desde placeholder.it porque en la base de datos no se asigno una imagen al momento de registrarse ni tampoco tenemos una forma de subir una. Por ahora pondremos una foto arbitraria:
En el seeder UsersTableSeeder agregamos:
Esto solo agrega el nombre al archivo y finalmente debemos crear una carpeta en public/profile_pictures
y guardar una imagen cualquiera dentro (preferentemente de 150x150) y listo:
Agregando funcionalidad para subir foto de perfil.
Esto lo haremos de la manera mas simple posible, justo debajo de la foto de perfil agregaremos un input para subir un archivo y al lado un botón para actualizar la misma. Justo debajo de la comprobación de la foto de perfil (el método hasProfilePicture
), insertamos un formulario con el siguiente código:
Le asignamos la ruta profile.update.picture
y le aplicamos un poco de css (mas adelante separaremos el css donde debe ir en su propio archivo) y también el input y el botón para enviar el formulario. Lo siguiente es la ruta del formulario:
Esta ruta la agregas al final de las existentes en el archivo routes/web.php
.
Finalmente en el controlador debemos tener un método updateProfilePicture
que hará el trabajo de obtener la foto, asignarle un nombre aleatorio y subirla al servidor.
ProfileController@updateProfilePicture
Lo primero que hacemos es definir una propiedad que contiene el nombre de la carpeta donde se subirán las fotos (profile_pictures) y luego en el método realizamos lo siguiente:
- Obtenemos el archivo con
$request->file('profile-picture')
- Creamos una variable
$filename
compuesta de: valor aleatorio con el helperstr_random(cantidad de caracteres)
+el punto entre el nombre y la extensión
+la extensión original del archivo
. - Movemos el archivo a la carpeta con el valor de
$filename
. - Al usuario “logueado” actual le actualizamos la columna
profile_picture
con el valor de$filename
. - Finalmente re-dirigimos al mismo usuario al mismo lugar con la foto actualizada.
La validación
En el método realizamos la validación mediante una Form Request que verifica que cuando le den al botón actualizar haya algún archivo subido por el usuario y que sea una imagen, a continuación el Form Request:
- En el método
authorized()
retornamos true porque siempre actualizaremos la foto de perfil del usuario autentificado, utilizandoAuth::user().
- En el método
rules()
indicamos que necesitamos que sea obligatorio subir un archivo y que sea una imagen. La reglaimage
permite estos tipos:jpeg, png, bmp, gif o svg
. - El método
messages()
es para indicar los mensajes de la validación.
Conclusión
Como ves parece un post muy largo pero si ven el código completo notarás que es todo es muy simple hasta ahora. En los siguientes posts agregaremos la funcionalidad para actualizar la bio, subir fotos, cambiar el nombre, nombre de usuario etc.
El repositorio para seguir el código esta en: https://github.com/Brandonxy/imagegram.