# Médias — Gestion et conventions

## Concept

La médiathèque centralise tous les fichiers uploadés (images, documents).
Les blocs référencent les médias via leur chemin storage (`/storage/media/...`).

---

## Modèle de données

```sql
media
  id, filename, path, disk, mime_type,
  size (bytes), alt, width, height,
  created_at, updated_at
```

---

## MediaService

```php
// app/Services/MediaService.php

class MediaService
{
    public function upload(UploadedFile $file, string $alt = ''): Media
    {
        // 1. Générer un nom unique
        $filename = Str::uuid() . '.' . $file->getClientOriginalExtension();

        // 2. Stocker le fichier
        $path = $file->storeAs('media', $filename, 'public');

        // 3. Extraire les dimensions si image
        $dimensions = $this->getDimensions($file);

        // 4. Créer l'entrée BDD
        return Media::create([
            'filename'  => $filename,
            'path'      => $path,
            'disk'      => 'public',
            'mime_type' => $file->getMimeType(),
            'size'      => $file->getSize(),
            'alt'       => $alt,
            'width'     => $dimensions['width'] ?? null,
            'height'    => $dimensions['height'] ?? null,
        ]);
    }

    public function delete(Media $media): void
    {
        Storage::disk($media->disk)->delete($media->path);
        $media->delete();
    }

    private function getDimensions(UploadedFile $file): array
    {
        if (!str_starts_with($file->getMimeType(), 'image/')) {
            return [];
        }
        [$width, $height] = getimagesize($file->getRealPath());
        return compact('width', 'height');
    }
}
```

---

## Accessor sur le modèle Media

```php
// app/Models/Media.php

protected $appends = ['url'];

public function getUrlAttribute(): string
{
    return Storage::disk($this->disk)->url($this->path);
}
```

---

## Composant MediaPicker (back-office)

Utilisé dans `PropsEditor.vue` pour les props de type `media` et `media[]`.

```
MediaPicker.vue
 ├── Bouton "Choisir un média"
 │    └── Ouvre MediaLibraryModal.vue
 │         ├── Grille des médias existants
 │         ├── Zone d'upload drag & drop
 │         ├── Champ de recherche/filtre
 │         └── Bouton "Sélectionner"
 └── Aperçu du média sélectionné + bouton supprimer
```

---

## Types de fichiers acceptés

| Catégorie | Extensions |
|---|---|
| Images | jpg, jpeg, png, gif, webp, svg |
| Documents | pdf |

Taille max : **10 Mo** par fichier (configurable dans `config/media.php`).

---

## Conventions

- Ne jamais stocker le chemin absolu — stocker le chemin relatif au disk (`media/uuid.jpg`)
- Toujours utiliser l'accessor `$media->url` pour afficher l'URL publique
- Dans les props JSON d'un bloc, stocker l'URL publique complète au moment de la sauvegarde
- Ne jamais supprimer un fichier média sans vérifier qu'aucun bloc ne le référence
