Cómo instalar y configurar Spatie Media Library para aplicaciones Laravel. Cómo asociar imágenes a los modelos, realizar transformaciones y recuperar los archivos multimedia que tengamos almacenados.
Spatie Media Library es uno de los packages más populares en el ecosistema Laravel y adecuado para la mayor parte de los proyectos. De hecho, hay pocos proyectos en los que no use Spatie Media Library, ya que nos ofrece muchas ventajas para la gestión de archivos multimedia, que se pueden aprovechar en casi cualquier aplicación.
En este artículo voy a explicar los primeros pasos para poder disponer de Spatie Media Library en un proyecto Laravel.
Instalación de Spatie Media Library
Comenzamos instalando el package vía Composer. Generalmente lo harás con este comando:
composer require "spatie/laravel-medialibrary"
Pero si tu proyecto Laravel usa Sail, recuerda que tendrás que personalizar los comandos así:
sail composer require "spatie/laravel-medialibrary"
Ya no voy a mencionar más la personalización de los comandos por estar usando Sail. Solo para que quede apuntado.
Luego tenemos que instalar las migraciones necesarias para crear las tablas:
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-migrations"
Para acabar instalando las migraciones con el comando:
php artisan migrate
Por último. aunque este paso no sería específicamente necesario, tenemos que publicar la configuración del paquete, de modo que podamos personalizar su funcionamiento a nuestros gustos y necesidades:
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-config"
Este paso creará un archivo llamado media-library.php
en la carpeta config
de nuestro proyecto Laravel. El archivo de configuración es bastante denso y contiene muchas particularidades, aunque está convenientemente comentado para que podamos entender la mayoría de las opciones que permite definir.
Cómo configurar el disco donde se almacenan los archivos
Una vez has instalado el paquete Spatie Media Library es importante configurar los discos donde se van a almacenar los archivos gestionados por la biblioteca de medios.
Si no con figuras nada Spatie Media Library utilizará el disco "
public
", lo que no recomiendo, dado que mezclarás los archivos de tu biblioteca de medios con otros que puedas estar utilizando en tu aplicación.
Los discos con los que trabajas en las aplicaciones Laravel se deben indicar en el archivo de configuración config/filesystems.php
.
En ese archivo de configuración existe una propiedad llamada 'disks
' que es un array donde puedes añadir cualquier número de discos.
Podrías crear un nuevo disco llamado "mediadisk
" usando una configuración como la siguiente.
'disks' => [
// otros discos que ya tienes en tu configuración de Laravel Filesystem
'mediadisk' => [
'driver' => 'local',
'root' => public_path('mediadisck'),
'url' => env('APP_URL').'/mediadisk',
],
],
Si creaste ese disco para almacenar los archivos de Media Library luego tendrás que realizar la correspondiente configuración en el archivo "config/media-library.php
" que publicamos con un comando anterior.
return [
'disk_name' => 'mediadisk',
// otras configuraciones...
];
Cómo usar un disco S3 para almacenar los archivos de medios
Si hay algo que me gusta particularmente configurar en las aplicaciones Laravel es el trabajo con discos S3, ya que nos permite almacenar de manera externa los archivos del sitio, evitando que queden en la estructura de carpetas del servidor donde se haya desplegado la aplicación.
Esto tiene varias ventajas, entre las que se podrían destacar:
- Mantienes el espacio usado del disco de tu servidor más controlado
- Puedes almacenar cualquier cantidad de información, ya que el almacenamiento S3 admite cualquier cantidad de archivos y tamaños
- Si trabajas con grandes cantidades de archivos o mucho tráfico permite descargar de tareas a tu servidor y mantener la transferencia más limitada
- Puedes acceder a los archivos desde cualquier tipo de aplicación, no solo desde tu aplicación Laravel
- No necesitas hacer backup de tus archivos, ya que de ellos se encarga el propio proveedor de cloud
- Cuando migras un servidor no necesitas llevarte los archivos a la nueva máquina, lo que facilita mucho los despliegues
Obviamente, también hay desventajas cuando usamos S3, aunque gracias a la integración de Laravel con este servicio de almacenamiento se reducen bastante.
- Trabajar con discos S3 puede ser más caro que trabajar con el espacio en los discos de almacenamiento del servidor
- Dado que la facturación de S3 se realiza por uso, el coste final que vas a pagar al mes puede ser menos predecible que lo que pagas por un servidor.
Finalmente, cabe decir que no hace falta que utilices Amazon como proveedor de S3. Existen muchos proveedores cloud que permiten usar servicios compatibles con S3 y que ofrecen unas tarifas sensiblemente menores. Dicho esto, vamos a ver cómo configurar S3 en tu proyecto.
Instalar el driver S3 en tu aplicación Laravel
Si queremos usar S3 en una aplicación a la vez tenemos que instalar una dependencia de composer donde se encuentra el driver para el acceso al almacenamiento remoto.
composer require league/flysystem-aws-s3-v3
Definir las variables de entorno en el .env
Para usar S3 comenzamos por definir las variables de entorno de nuestros buckets de S3. Estos valores los tienes que obtener directamente de tu proveedor de cloud. Seguramente al crear los espacios de almacenamiento S3 te hayan entregado los valores que vas a necesitar.
Las variables de entorno relacionadas con S3 son las siguientes:
AWS_ACCESS_KEY_ID=123456789123
AWS_SECRET_ACCESS_KEY=H6GdDD6gh777d888kk999k000
AWS_DEFAULT_REGION=eu-region
AWS_BUCKET=projecto1
AWS_USE_PATH_STYLE_ENDPOINT=false
AWS_ENDPOINT=https://s3-proveedor.com/
Crear un disco S3 basado en esta configuración
Una vez tenemos creadas nuestras variables de entorno,hay que realizar la configuración de los discos del sistema de archivos de nuestra aplicación Laravel. Para ello vamos a editar el archivo config/filesystems.php,Donde colocaremos la siguiente entrada en el array "disks".
'medialibrary' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'visibility' => 'public',
],
Configurar el disco en Media Library
No debemos olvidarnos de configurar este disco que acabamos de crear en el archivo de configuración de Spatie Media Library, en config/media-library.php
.
Simplemente tenemos que ajustar la siguiente entrada del array de configuración:
'disk_name' => env('MEDIA_DISK', 'medialibrary'),
Como puedes ver también puedes ajustarlo mediante la variable de entorno 'MEDIA_DISK' en tu archivo
.env
.
A partir de aquí ya tenemos instalado y listo para funcionar el paquete para la gestión de medios en aplicaciones. Ha sido un paso importante pero la tarea real comienza ahora, configurando los modelos que vamos a utilizar para almacenar archivos multimedia.
Preparar los modelos para almacenar archivos multimedia asociados
Para poder almacenar archivos vamos a asociarlos a los modelos que los necesiten. De este modo, nuestra primera tarea consiste en preparar los modelos de la aplicación Laravel donde queramos guardar archivos.
Para preparar un modelo de Eloquent, de modo que podamos usar Media Library tenemos que implementar una interfaz y usar un trait de PHP.
- La interfaz se llama
HasMedia
- El trait se llama
InteractsWithMedia
Es importante agregar los correctos espacios de nombres, como se puede ver en el siguiente código.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Post extends Model implements HasMedia
{
use InteractsWithMedia;
}
Luego se trata de configurar en los modelos qué colecciones de archivos vamos a disponer. En cada una de las colecciones de archivos podemos configurar un tratamiento específico que se realizará sobre los ficheros asociados. Por ejemplo podremos tener imágenes para los post de un blog y cada una de estas imágenes podría guardarse en varios tamaños.
Existen muchas operaciones de transformación que se pueden configurar en las colecciones, como el redimensionado, recorte, optimización, filtros, la optimización, etc.
Aquí tenemos un ejemplo de configuración de una imagen que estamos añadiendo en una colección que tiene el nombre "card-image
".
use Spatie\MediaLibrary\MediaCollections\Models\Media;
public function registerMediaCollections(): void {
$this
->addMediaCollection('card-image')
->useDisk('medialibrary')
->singleFile()
->registerMediaConversions(function (Media $media) {
$this
->addMediaConversion('small')
->crop('crop-center', 250, 140)
->sharpen(10);
$this
->addMediaConversion('medium')
->crop('crop-center', 480, 270);
});
}
Es una colección donde solo vamos a tener un único archivo por modelo y donde se guardará la imagen con dos transformaciones, una llamada "small
" y otra llamada "medium
". Ambas colecciones tienen algunas configuraciones de recorte y en la transformación "small
" estamos haciendo un filtro para enfocado.
Esas son solo una muestra pequeña de las cosas que puedes configurar como transformaciones en tus archivos multimedia. Incluso si se te quedan cortas el propio spatie tiene un package dedicado al trabajo con imágenes que es fácilmente integrable en Media Library.
Asociar archivos a este modelo
Una vez que hemos configurado las colecciones en nuestro modelo, el siguiente paso es asociar archivos a este modelo. Spatie Media Library facilita esta tarea proporcionando métodos que permiten agregar archivos de diferentes fuentes, como archivos locales, archivos subidos a través de formularios o archivos remotos.
Aquí hay un ejemplo de cómo puedes asociar un archivo subido desde un formulario a la colección card-image
del modelo Post
, donde mostramos todo el flujo de upload del archivo, desde la validación hasta la creación del propio modelo.
use App\Models\Post;
public function store(Request $request)
{
// Validar la solicitud
$request->validate([
'title' => 'required|string|max:255',
'image' => 'required|image|max:2048',
]);
// Crear una nueva instancia del modelo Post
$post = new Post();
$post->title = $request->input('title');
$post->save();
// Asociar la imagen subida a la colección 'card-image'
$post->addMediaFromRequest('image')
->toMediaCollection('card-image');
return redirect()->route('posts.index')->with('success', 'Post creado con éxito y archivo asociado.');
}
En este ejemplo, aparte de la correspondiente validación de la solicitud y la creación de un nuevo Post
, lo que te interesará particularmente es ver cómo utilizamos el método addMediaFromRequest
para asociar la imagen al modelo Post
recién creado en su colección card-image
.
Como alternativa, por si lo necesitas, también puedes agregar archivos desde una ruta local o una URL remota. Aquí hay ejemplos para ambas situaciones:
Agregar archivos desde una ruta local
En este ejemplo añadimos una imagen que estaba previamente en el disco del servidor.
use App\Models\Post;
$post = Post::find(1); // Encuentra el modelo Post existente
$post->addMedia(storage_path('app/public/example.jpg'))
->toMediaCollection('card-image');
Agregar archivos desde una URL remota
Y ahora puedes ver cómo se podría también traerse una imagen que hay en una URL remota, agregando ese archivo al modelo de Post.
use App\Models\Post;
$post = Post::find(1); // Encuentra el modelo Post existente
$post->addMediaFromUrl('https://example.com/image.jpg')
->toMediaCollection('card-image');
Recuperar archivos asociados
Lo último que vamos a ver en este artículo sobre Spatie Media Library es el proceso para usar en tu aplicación los archivos asociados a un modelo. Gracias a los métodos que ofrece la librería puedes obtener el URL del archivo, el path local y otras propiedades útiles.
Para obtener el URL del archivo asociado, puedes usar el siguiente método:
$post = Post::find(1);
$mediaItems = $post->getMedia('card-image');
foreach ($mediaItems as $media) {
echo $media->getUrl(); // Devuelve el URL público del archivo
}
Si has configurado conversiones de medios, también puedes obtener el URL de las versiones convertidas del archivo:
$post = Post::find(1);
$media = $post->getFirstMedia('card-image');
echo $media->getUrl('small'); // URL de la conversión 'small'
echo $media->getUrl('medium'); // URL de la conversión 'medium'
Conclusión
Spatie Media Library es una herramienta poderosa y flexible para gestionar archivos multimedia en aplicaciones Laravel. Desde la instalación y configuración hasta la asociación de archivos y su recuperación, Media Library cubre todas las necesidades básicas y avanzadas para el manejo de archivos multimedia. Hemos visto cómo trabajar con imágenes, pero es posible usar vídeos, PDF y otros ficheros que puedas llegar a manejar.
Este artículo ha cubierto los primeros pasos necesarios para empezar a usar Spatie Media Library, incluyendo la instalación del paquete, la configuración de discos locales y S3, y la preparación de modelos para almacenar archivos multimedia. Con estas bases, estás listo para aprovechar todas las ventajas que Spatie Media Library ofrece en tus proyectos Laravel.
Recuerda revisar la documentación oficial de Spatie Media Library para profundizar en todas las funcionalidades disponibles y obtener ejemplos más detallados sobre cómo usar este paquete en diferentes escenarios.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...