Carga de archivos e imágenes empleando Laravel Livewire en el storage y en el path publico
La carga de archivos no es más que el termino empleado para transferir o subir un archivo desde un dispositivo local como una PC o teléfono inteligente a un servidor; en el caso de Laravel, sería el proyecto en Laravel; esta siempre es una características muy necesaria para realizar todo tipo de operaciones como subir un avatar o imágen del usuario, para subir archivos personales como excels, pdfs u otros…
Ya que este es un proceso rutinario, vamos a hablar de cómo podemos cargar archivos o imágenes, específicamente el avatar del usuario empleando Laravel Livewire; para esto tenemos que tener presentes algunos puntos importantes antes de entrar en detalle sobre el desarrollo que vamos a llevar a cabo.
Livewire y el uso de los componentes
¿Que es Laravel Livewire? no es más que un paquete disponible para nuestro Laravel tal cual mencionamos antes para el desarrollo de aplicaciones basada en componentes que permiten la comunicación FullDuplex mediante websockets entre el frontend y el backend; ademas:
- Recordemos que TODAS las pantallas o al menos la mayoría son en base a componentes, en vez de controladores.
- Tenemos un módulo de usuario con login, registro, recuperación y edición de credenciales existente para Livewire y esto es gracias a JetStream.
Aclarado los puntos anteriores, vamos a comenzar.
Vamos a crear un componente para hacer las operaciones sobre una entidad llamada usuario; con esta entidad queremos que pueda encargarse de realizar el upload o carga de archivos como imágenes o específicamente el avatar, tenemos que emplear la “herencia múltiple” en otras palabras, empleando un trait que nos provee Livewire en nuestro componente:
class SaveUser extends Component
{
use WithFileUploads;
}
Reglas de validación
Ahora, cómo vamos a trabajar con formularios, tenemos que indicar los datos que vamos emplear, y con esto sus reglas de validación:
protected $rules = [
'name' => 'required|min:6',
'email' => 'required|email|unique:users,email',
'password' => 'required',
'avatar' => 'Nullable|image|max:1024',
];
Nada raro en este punto, validaciones normales sobre campos de textos y lo interesante sería el llamado avatar, que como puedes suponer y analizar las validaciones vamos a emplear las mismas para validar la carga de imágenes, es decir el avatar del usuario; en este campo, definimos lo típico, que no sea nulo, que sea una imagen y un tamaño máximo.
Procesar el avatar o imagen del usuario
Al momento de enviar la petición http mediante el formulario, verificamos si tenemos el avatar, ya que el mismo NO es requerido y es completamente opcional, por lo tanto, este paso es opcional y si quieres que sea obligatorio puedes prescindir del condicional y colocar el required en las reglas anteriores:
public function submit()
{
// upload
if($this->avatar){
$imageName = $this->category->slug . '.' . $this->image->getClientOriginalExtension();
$this->avatar->storeAs('images', $imageName,'public_upload');
$this->category->update([
'image'=> $imageName
]);
}
}
El punto clave aquí es que mediante el método de storeAs(), movemos el archivo a la carpeta public, la configuración del disco la mostramos un poco más adelante.
Almacenar en la carpeta public
Por lo demás, simplemente almacenamos el avatar en nuestra aplicación en el disco correspondiente que recuerda tiene que estar definido en /config/filessystems.php
:
'public_upload' => [
'driver' => 'local',
'root' => public_path()
],
De esta manera tan sencilla, ya logramos hacer el upload; como puedes ver, es exatamente igual al que hacemos en Laravel básico; finalmente, desde tu vista, puedes definir en tu formulario, el campo para la carga de archivo:
<x-jet-label for="">Imagen</x-jet-label>
<x-jet-input-error for="image" />
<x-jet-input type="file" wire:model="image" />
Extra: Actualizar el avatar del usuario
Ya por defecto en Livewire tenemos un manejo del avatar, y un disco (disk) para almacenar el mismo; ya en el modelo de usuario tenemos una función que se encarga de realizar TODO este proceso:
$this->user->updateProfilePhoto($this->avatar);
Luce como la siguiente:
trait HasProfilePhoto
{
/**
* Update the user's profile photo.
*
* @param \Illuminate\Http\UploadedFile $photo
* @return void
*/
public function updateProfilePhoto(UploadedFile $photo)
{
tap($this->profile_photo_path, function ($previous) use ($photo) {
$this->forceFill([
'profile_photo_path' => $photo->storePublicly(
'profile-photos', ['disk' => $this->profilePhotoDisk()]
),
])->save();
if ($previous) {
Storage::disk($this->profilePhotoDisk())->delete($previous);
}
});
}
Por lo demás, todo el funcionamiento viene siendo idéntico salvo que ya no tienes que señalar el disco en donde vas a almacenar la foto del usuario.
Recuerda que este material forma parte de mi curso y libro sobre Laravel Livewire.
- Andrés Cruz
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter