Curso Laravel Livewire - Upload o carga de archivos, Componente y Blade
En el modelo de categorías, tenemos una columna para la imagen la cual es una columna opcional ya que, puede ser nula:
Schema::create('categories', function (Blueprint $table) {
***
$table->string('image', 260)->nullable();
});
Vamos a implementar el upload opcional; en este caso, vamos a querer usar el disco local de Laravel, queremos que registre las imágenes en la carpeta public; así que, vamos a crear un nuevo disco:
config/filesystems.php
'public_upload' => [
'driver' => 'local',
'root' => public_path()
],
Y en la clase componente Save.php; vamos a usar la característica que nos permite hacer el upload de archivos:
app/Livewire/Dashboard/Category/Save.php
use Livewire\WithFileUploads;
class Save extends Component
{
use WithFileUploads;
***
Con ella, creamos la propiedad para la imagen e indicamos las validaciones para la imagen; lo típico, que sea de tipo imagen, un tamaño máximo y que es opcional:
app/Livewire/Dashboard/Category/Save.php
public $title;
public $text;
public $image;
public $category;
protected $rules = [
'title' => "required|min:2|max:255",
'text' => "nullable",
'image' => "nullable|image|max:1024",
];
***
En el método de submit(), verificamos si el usuario seleccione una imagen (para eso el condicional):
- Damos un nombre a la imagen.
- Movemos la imagen al disco que creamos anteriormente.
- Actualizamos en la base de datos.
app/Livewire/Dashboard/Category/Save.php
function submit()
{
$this->validate();
if ($this->category) {
$this->category->update(
[
'title' => $this->title,
'text' => $this->text,
'slug' => str($this->title)->slug(),
]
);
$this->dispatch('updated');
} else {
$this->category = Category::create(
[
'title' => $this->title,
'text' => $this->text,
'slug' => str($this->title)->slug(),
]
);
$this->dispatch('created');
}
// upload
if($this->image){
$imageName = $this->category->slug . '.'.$this->image->getClientOriginalExtension();
$this->image->storeAs('images/category',$imageName,'public_upload');
$this->category->update([
'image' => $imageName
]);
}
}
Para poder referenciar fácilmente la imagen, vamos a crear un método que nos devuelve la ruta absoluta a la imagen:
App/Models
use Illuminate\Support\Facades\URL;
***
class Category extends Model
{
***
public function getImageUrl()
{
return URL::asset("images/category/".$this->image);
}
}
Y en la vista, colocamos al final de todo, el campo para la imagen:
***
<x-label for="">Imagen</x-label>
<x-input-error for="image" />
<x-input type="file" wire:model="image" />
<x-button type="submit">Enviar</x-button>
Y un condicional que pregunta si tenemos una imagen registrada para la categoría, entonces la mostramos:
resources/views/livewire/dashboard/category/save.blade.php
@if ($category && $category->image)
<img class="w-40 my-3" src="{{ $category->getImageUrl() }}" />
@endif
Transcipción del vídeo
Vamos a comenzar la parte que te decía que faltaba es la de la categoría que es la que estamos manipulando luego por aquí abajo que es donde hacemos aquí elat en la implementación pudistes apreciar de que yo estoy utilizando el slot para colocarlo como nombre de la imagen por tal motivo Me parece buena idea por aquí recargar el la categoría aquí en update no debería hacer falta porque automático aquí en crear si haría falta asignárseles pero era para colocarte en contexto y aquí trabajamos con la categoría Entonces vamos a ya que estamos acá crear el nuevo campo aquí lo coloco como image Según definimos image y por aquí las reglas coloco una coma coloco image puede ser de tipo nulo y aquí todas las consideraciones las validaciones que quieras colocar coloco una validación que indica que es un image y una longitud máxima algo interesante con la longitud máxima este es 1024 que es un mega 1024 kb Recuerda que es un mega si publicaste el archivo de livewire por aquí también Tenemos uno para la fase de carga en este caso los temporales Fíjate que por aquí tenemos un tamaño máximo que son de 12 megas.
Cambiar tamaño máximo de archivos en Livewire
Entonces en caso de que quieras trabajar con imágenes bueno recursos en general más grandes tuvieras que definir esta regla por acá y aquí le colocas el valor que tú quieras por ejemplo en este caso sería como 120 megas no es exactamente porque le coloco un cero más pero por ahí va esto para que lo tengas presente y aquí Bueno las extensiones y y demás Eh bueno esto era importante Recuerda que está en este archivo que lo podemos publicar mediante el comando de vendor publish.
Carga de archivos
Bien regresamos acá Aquí tenemos la imagen ya Aquí más o menos lo tenemos todo falta es crear el disco y todo lo demás para poder seguir aquí la implementación Recuerda que el disco estaría en Field System aquí en confit aquí Recuerda que puedes ver la ruta vamos a crear un disco partiendo de uno existente voy a partir de este que dice local aquí el nombre le puedes colocar cualquiera Ya esto es lar el básico ya esto también lo hicimos en el Larabel básico y voy a colocarle public una a contra vez depende de ti el Driver es local aquí Recuerda que colocaría si es de Amazon que sería el S3 o creo que era el S3 de Amazon server o cualquier otro pero en este caso es local a nuestro proyecto:
config/filesystems.php
'public_upload' => [
'driver' => 'local',
'root' => public_path()
],
Colocamos local aquí sería la ubicación podemos colocar el public_path mediante este esta función que Recuerda que hace referencia la carpeta public que es la única que puede acceder mediante el bueno el navegador o en general para consumir la aplicación lo que tenemos acá Esa es la ruta que nos da y esto no haría falta por lo demás ya aquí tenemos listo el Driver listo para utilizar entonces podemos cerrar esto recuerda aquí traerte el nombre regresamos acá y hacemos lo que es el proceso upload, Comencemos generando el nombre de la imagen coloco image name va a ser igual atis aquí depende de ti puedes también colocar directamente la función de Time para un nombre único yo voy a utilizar aquí el tis es loot como te comentaba antes category es loot aquí como esto es solamente un texto le tenemos que indicar la extensión de la imagen aquí le colocamos el punto para que sea nombre imagen punto lo que sería el image que es el campo get client original Dios mío no sé que estoy escribiendo client original extension con el cual obtenemos la extensión original del recurso:
$imageName = $this->category->slug . '.'.$this->image->getClientOriginalExtension();
Aquí tenemos el nombre entonces faltaría ya es almacenarla colocamos ts image Recuerda que esto no es un campo ordinario luego lo podemos imprimir por pantalla esto es una clase de tipo load con todo lo que esto trae y lo que implica y por aquí tenemos un método llamado Store as que es para almacenarlo en alguna ubicación que en este caso es en la carpeta public Entonces esto nos pide varias cositas esto otra vez es la r básico aquí nos pide el nombre del recurso aquí ya lo generamos y aquí nos pide Cuál es el nombre del disco que Recuerda que es public_upload:
$this->image->storeAs('images/category',$imageName,'public_upload');
Al menos en mi caso y por aquí le podemos colocar carpetas adicionales que se van que se van anexar a raíz o a o a partir de esta es decir a partir de la carpeta public que es la ruta que indicamos acá se va a anexar la carpeta llamada image category para que lo podamos tener más organizado ya que cuando queramos también almacenar la de las publicaciones no estén todos en la misma carpeta y esto sería todo ya con esto estuviéramos almacenando el archivo Así que falta hacer la actualización de la imagen que ya la tenemos ya sea bueno de la categoría Mejor dicho de la categoría que ya tenemos ya sea por que ya existía o ya sea porque la estamos creando por acá entonces aquí colocamos category update porque ya existe por lo comentado antes ya se creó o ya existía y simplemente la estábamos editando colocamos image Y recuerda que aquí solamente referenciamos su nombre ya que la ubicación ya la tenemos ahí fija y es la que definimos anteriormente:
$this->category->update([
'image' => $imageName
]);
Y esto sería todo aquí en el controlador falta ir ahora aquí al cliente en el cual voy a partir de esto coloco aquí image aquí va a ser image que es el nombre de la propiedad de tipo Field y aquí preguntamos si tenemos algún problema con la imagen y esto sería ya todo por acá faltan el resto de las cositas pero ya son opcionales por aquí lo tenemos voy a darle aquí a seleccionar Bueno me fue para mis cursos vengo aquí a descargas aquí ya tengo algunas imágenes y nos da un bonito error que nos indica Ah Me faltó el Trade Disculpa que son tantas cositas bueno en cuanto al Trade vamos a importarlo colocamos aquí useLivewireWith Aquí está lo importamos y lo utilizamos acá colocamos use Livewire\WithFileUploads; guardamos voy a recargar que me gusta recargar selecciono Y ahora fíjate que ya no da la sección y damos aquí un y ahora si nos da una sección qu bonito aquí nos indica illuminate validate image no existe Puede que haya escrito algo aquí mal vamos a ver máxima es image en singular eso fue lo que nos dijo que esa validación no existe damos un s y dice que se actualizó correctamente vamos a ver si hizo la carga Bueno aquí está en verde luce bien image y aquí la tenemos con el nombre que generamos aquí que es categoría 11 que es lo que tenemos por acá Bueno el lo no lo editamos pero ahí tienes el nombre entonces pues nada es eso déjame probarla de crear porque H no quiero dejar un código incorrecto ahí create vo a colocar aquí 15 text Aunque siempre yo coloco este proceso cuando estamos ahí ya lista la categoría cuando ya existe pero categoría Okay creada exitosamente Okay aquí sí la tenemos funciona perfectamente no recordaba si el método de create devolve el ID o directamente el objeto Entonces se devuelve el objeto y ya lo podemos ahí manipular lo que pasó es que la creamos acá se la asignamos a la categoría bueno da igual los eventos aquí ya teníamos la categoría y podemos Acceder al slot cualquier otra vez puedes colocar aquí el Time si es lo que tú quieres ya creo que esto se alargó un poco así que vamos a dejarla hasta acá y en la siguiente clase terminamos la implementación con los restos de los de las operaciones opcionales que nos quedan Así que vamos allá.
- Andrés Cruz
Este material forma parte de mi curso y libro completo; puedes adquirirlos desde el apartado de libros y/o cursos Curso y Libro Laravel 11 con Tailwind Vue 3, introducción a Jetstream Livewire e Inerta desde cero - 2024.
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter