En esta guía, cubriremos:

  1. Instalación y configuración de Cloudinary en Laravel.

  2. Creación de una relación polimórfica para manejar imágenes.

  3. Subida, edición y eliminación de imágenes usando Cloudinary.

  4. Uso del public ID de Cloudinary para gestionar imágenes.


1. Instalación y Configuración de Cloudinary

Paso 1: Instalar el SDK de Cloudinary

Instala el paquete oficial de Cloudinary para Laravel usando Composer:

composer require cloudinary-labs/cloudinary-laravel

Paso 2: Publicar la configuración

Publica el archivo de configuración de Cloudinary:

php artisan vendor:publish --provider="CloudinaryLabs\CloudinaryLaravel\CloudinaryServiceProvider"

Esto creará un archivo de configuración en config/cloudinary.php.

Paso 3: Configurar las credenciales de Cloudinary

Agrega tus credenciales de Cloudinary al archivo .env:

 
CLOUDINARY_CLOUD_NAME=tu_cloud_name
CLOUDINARY_API_KEY=tu_api_key
CLOUDINARY_API_SECRET=tu_api_secret

Puedes obtener estas credenciales desde tu panel de Cloudinary.


2. Creación de una Relación Polimórfica para Imágenes

Paso 1: Crear la migración para la tabla images

Crea una migración para la tabla images:

 
php artisan make:migration create_images_table

En la migración, define la estructura de la tabla:

 
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateImagesTable extends Migration
{
    public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->id();
            $table->string('url'); // URL de la imagen en Cloudinary
            $table->string('public_id'); // Public ID de la imagen en Cloudinary
            $table->unsignedBigInteger('imageable_id'); // ID del modelo relacionado
            $table->string('imageable_type'); // Tipo del modelo relacionado
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('images');
    }
}

Ejecuta la migración:

 
php artisan migrate

Paso 2: Definir las relaciones en los modelos

Modelo Image

El modelo Image será el que pertenezca a otros modelos (como Post o User). Define la relación polimórfica usando el método morphTo:

 
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Image extends Model
{
    protected $fillable = ['url', 'public_id', 'imageable_id', 'imageable_type'];

    public function imageable()
    {
        return $this->morphTo();
    }
}

Modelos Post y User

Los modelos Post y User tendrán una relación polimórfica con Image. Usa el método morphMany para definir la relación:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function images()
    {
        return $this->morphMany(Image::class, 'imageable');
    }
}

class User extends Model
{
    public function images()
    {
        return $this->morphMany(Image::class, 'imageable');
    }
}

3. Subir, Editar y Eliminar Imágenes con Cloudinary

Paso 1: Crear un controlador para manejar imágenes

Crea un controlador para manejar la subida, edición y eliminación de imágenes:

 
php artisan make:controller ImageController

En el controlador, agrega los métodos necesarios:

 
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Image;
use App\Models\Post;
use CloudinaryLabs\CloudinaryLaravel\Facades\Cloudinary;

class ImageController extends Controller
{
    // Subir una imagen y asociarla a un post
    public function store(Request $request, Post $post)
    {
        $request->validate([
            'image' => 'required|image|max:2048', // Validar que sea una imagen
        ]);

        // Subir la imagen a Cloudinary
        $uploadedFile = Cloudinary::upload($request->file('image')->getRealPath());
        $uploadedFileUrl = $uploadedFile->getSecurePath(); // URL de la imagen
        $publicId = $uploadedFile->getPublicId(); // Public ID de la imagen

        // Crear la imagen en la base de datos
        $image = new Image();
        $image->url = $uploadedFileUrl;
        $image->public_id = $publicId;
        $post->images()->save($image);

        return redirect()->back()->with('success', 'Imagen subida correctamente.');
    }

    // Eliminar una imagen
    public function destroy(Image $image)
    {
        // Eliminar la imagen de Cloudinary usando el public ID
        Cloudinary::destroy($image->public_id);

        // Eliminar la imagen de la base de datos
        $image->delete();

        return redirect()->back()->with('success', 'Imagen eliminada correctamente.');
    }

    // Editar una imagen (reemplazarla)
    public function update(Request $request, Image $image)
    {
        $request->validate([
            'image' => 'required|image|max:2048',
        ]);

        // Eliminar la imagen anterior de Cloudinary usando el public ID
        Cloudinary::destroy($image->public_id);

        // Subir la nueva imagen a Cloudinary
        $uploadedFile = Cloudinary::upload($request->file('image')->getRealPath());
        $uploadedFileUrl = $uploadedFile->getSecurePath(); // URL de la nueva imagen
        $publicId = $uploadedFile->getPublicId(); // Public ID de la nueva imagen

        // Actualizar la URL y el public ID de la imagen en la base de datos
        $image->url = $uploadedFileUrl;
        $image->public_id = $publicId;
        $image->save();

        return redirect()->back()->with('success', 'Imagen actualizada correctamente.');
    }
}

Paso 2: Definir las rutas

En routes/web.php, define las rutas para manejar las imágenes:

 
use App\Http\Controllers\ImageController;

Route::post('/posts/{post}/images', [ImageController::class, 'store'])->name('images.store');
Route::delete('/images/{image}', [ImageController::class, 'destroy'])->name('images.destroy');
Route::put('/images/{image}', [ImageController::class, 'update'])->name('images.update');

4. Vistas para Subir, Mostrar y Eliminar Imágenes

Paso 1: Formulario para subir una imagen

En tu vista de creación de posts (create.blade.php), agrega un formulario para subir imágenes:

 
<form action="{{ route('images.store', $post->id) }}" method="POST" enctype="multipart/form-data">
    @csrf
    <input type="file" name="image" required>
    <button type="submit">Subir imagen</button>
</form>

Paso 2: Mostrar y eliminar imágenes

En tu vista de detalles del post (show.blade.php), muestra las imágenes y agrega botones para eliminarlas y reemplazarlas:

 
@foreach ($post->images as $image)
    <div>
        <img src="{{ $image->url }}" alt="Imagen" style="width: 200px;">
        <form action="{{ route('images.destroy', $image->id) }}" method="POST">
            @csrf
            @method('DELETE')
            <button type="submit">Eliminar</button>
        </form>
        <form action="{{ route('images.update', $image->id) }}" method="POST" enctype="multipart/form-data">
            @csrf
            @method('PUT')
            <input type="file" name="image" required>
            <button type="submit">Reemplazar imagen</button>
        </form>
    </div>
@endforeach

Conclusión

Con esta guía completa, has aprendido a:

  1. Integrar Cloudinary en Laravel.

  2. Crear una relación polimórfica para manejar imágenes.

  3. Subir, editar y eliminar imágenes usando Cloudinary.

  4. Usar el public ID de Cloudinary para gestionar imágenes de manera eficiente.