Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Media Bundle Laravel Package

dahovitech/media-bundle

View on GitHub
Deep Wiki
Context7

API REST - Documentation complète

Le DahoviTech Media Bundle expose une API REST complète basée sur API Platform, permettant la gestion programmatique de vos médias.

Base URL et Authentication

URL de base

https://your-domain.com/api/media

Authentication

L'API utilise l'authentication Symfony. Selon votre configuration :

# Token Bearer (recommandé)
Authorization: Bearer <your-token>

# Session-based
Cookie: PHPSESSID=<session-id>

Endpoints disponibles

Vue d'ensemble

Méthode Endpoint Description
GET /api/media Liste tous les médias
GET /api/media/{id} Récupère un média spécifique
POST /api/media/upload Upload un fichier unique
POST /api/media/upload/multiple Upload multiple de fichiers
PUT /api/media/{id} Met à jour un média
DELETE /api/media/{id} Supprime un média
GET /api/media/search Recherche dans les médias
GET /api/media/{id}/download Télécharge un fichier
POST /api/media/{id}/duplicate Duplique un média
GET /api/media/statistics Statistiques (admin)
GET /api/media/types Types de médias supportés
GET /api/media/config Configuration API

Détail des endpoints

1. Lister les médias

GET /api/media

Paramètres de requête

Paramètre Type Description
page integer Numéro de page (défaut: 1)
limit integer Nombre d'éléments par page (défaut: 20, max: 100)
type string Filtrer par type (image, document, pdf, other)
search string Recherche dans nom, description, nom de fichier
isPublic boolean Filtrer par statut public/privé
mimeType string Filtrer par type MIME

Exemple de requête

curl -X GET "https://your-domain.com/api/media?page=1&limit=10&type=image" \
  -H "Accept: application/json"

Réponse

{
  "data": [
    {
      "id": 1,
      "name": "Mon image",
      "description": "Description de l'image",
      "filename": "abc123.jpg",
      "originalFilename": "mon-image.jpg",
      "mimeType": "image/jpeg",
      "size": 256000,
      "type": "image",
      "width": 1920,
      "height": 1080,
      "isPublic": true,
      "createdAt": "2024-01-15T10:30:00+00:00",
      "updatedAt": "2024-01-15T10:30:00+00:00",
      "url": "/uploads/media/abc123.jpg",
      "thumbnailUrl": "/media/cache/thumbnail/abc123.jpg"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 25,
    "totalPages": 3
  }
}

2. Récupérer un média

GET /api/media/{id}

Exemple de requête

curl -X GET "https://your-domain.com/api/media/1" \
  -H "Accept: application/json"

Réponse

{
  "id": 1,
  "name": "Mon image",
  "description": "Description détaillée",
  "filename": "abc123.jpg",
  "originalFilename": "mon-image.jpg",
  "mimeType": "image/jpeg",
  "size": 256000,
  "type": "image",
  "width": 1920,
  "height": 1080,
  "altText": "Texte alternatif",
  "isPublic": true,
  "hash": "def456",
  "metadata": {
    "camera": "Canon EOS R5",
    "iso": 400,
    "focal_length": "85mm"
  },
  "createdAt": "2024-01-15T10:30:00+00:00",
  "updatedAt": "2024-01-15T10:30:00+00:00",
  "expiresAt": null,
  "url": "/uploads/media/abc123.jpg",
  "thumbnailUrl": "/media/cache/thumbnail/abc123.jpg"
}

3. Upload d'un fichier unique

POST /api/media/upload

Headers requis

Content-Type: multipart/form-data

Paramètres

Paramètre Type Requis Description
file file Oui Le fichier à uploader
name string Non Nom du média (généré auto si omis)
description string Non Description du média
isPublic boolean Non Statut public (défaut: true)

Exemple de requête

curl -X POST "https://your-domain.com/api/media/upload" \
  -H "Authorization: Bearer <token>" \
  -F "file=@/path/to/image.jpg" \
  -F "name=Mon image" \
  -F "description=Description de mon image" \
  -F "isPublic=true"

Exemple JavaScript

const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'Mon image');
formData.append('description', 'Description');
formData.append('isPublic', 'true');

fetch('/api/media/upload', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer ' + token
    },
    body: formData
})
.then(response => response.json())
.then(media => console.log('Média créé:', media));

Réponse (201 Created)

{
  "id": 2,
  "name": "Mon image",
  "description": "Description de mon image",
  "filename": "xyz789.jpg",
  "originalFilename": "image.jpg",
  "mimeType": "image/jpeg",
  "size": 512000,
  "type": "image",
  "width": 2048,
  "height": 1536,
  "isPublic": true,
  "createdAt": "2024-01-15T11:00:00+00:00",
  "updatedAt": "2024-01-15T11:00:00+00:00",
  "url": "/uploads/media/xyz789.jpg",
  "thumbnailUrl": "/media/cache/thumbnail/xyz789.jpg"
}

4. Upload multiple

POST /api/media/upload/multiple

Paramètres

Paramètre Type Requis Description
files[] file[] Oui Tableau de fichiers à uploader

Exemple de requête

curl -X POST "https://your-domain.com/api/media/upload/multiple" \
  -H "Authorization: Bearer <token>" \
  -F "files[]=@/path/to/image1.jpg" \
  -F "files[]=@/path/to/image2.jpg" \
  -F "files[]=@/path/to/document.pdf"

Exemple JavaScript

const formData = new FormData();
for (let i = 0; i < fileInput.files.length; i++) {
    formData.append('files[]', fileInput.files[i]);
}

fetch('/api/media/upload/multiple', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer ' + token
    },
    body: formData
})
.then(response => response.json())
.then(result => console.log('Résultat:', result));

Réponse

{
  "uploaded": {
    "0": {
      "id": 3,
      "name": "Image1",
      "filename": "abc123.jpg",
      "type": "image"
    },
    "1": {
      "id": 4,
      "name": "Image2", 
      "filename": "def456.jpg",
      "type": "image"
    }
  },
  "errors": {
    "2": "Type de fichier non autorisé"
  },
  "summary": {
    "total": 3,
    "success": 2,
    "failed": 1
  }
}

5. Mettre à jour un média

PUT /api/media/{id}

Headers

Content-Type: application/json

Paramètres

{
  "name": "Nouveau nom",
  "description": "Nouvelle description",
  "altText": "Nouveau texte alternatif",
  "isPublic": false,
  "expiresAt": "2024-12-31T23:59:59+00:00"
}

Exemple de requête

curl -X PUT "https://your-domain.com/api/media/1" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "Nom mis à jour",
    "description": "Description mise à jour",
    "isPublic": false
  }'

6. Supprimer un média

DELETE /api/media/{id}

Exemple de requête

curl -X DELETE "https://your-domain.com/api/media/1" \
  -H "Authorization: Bearer <token>"

Réponse (200 OK)

{
  "message": "Média supprimé avec succès"
}

7. Rechercher des médias

GET /api/media/search

Paramètres de requête

Paramètre Type Requis Description
q string Oui Terme de recherche (min 2 caractères)
page integer Non Numéro de page
limit integer Non Limite par page
type string Non Filtrer par type
isPublic boolean Non Filtrer par statut

Exemple de requête

curl -X GET "https://your-domain.com/api/media/search?q=photo&type=image" \
  -H "Accept: application/json"

Réponse

{
  "query": "photo",
  "data": [
    {
      "id": 1,
      "name": "Photo de vacances",
      "type": "image"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 1,
    "totalPages": 1
  }
}

8. Télécharger un fichier

GET /api/media/{id}/download

Exemple de requête

curl -X GET "https://your-domain.com/api/media/1/download" \
  -H "Authorization: Bearer <token>" \
  -o "downloaded-file.jpg"

Headers de réponse

Content-Type: image/jpeg
Content-Disposition: attachment; filename="original-filename.jpg"
Content-Length: 256000

9. Dupliquer un média

POST /api/media/{id}/duplicate

Exemple de requête

curl -X POST "https://your-domain.com/api/media/1/duplicate" \
  -H "Authorization: Bearer <token>"

Réponse (201 Created)

{
  "id": 5,
  "name": "Mon image (Copie)",
  "filename": "ghi789.jpg",
  "originalFilename": "original.jpg",
  "type": "image"
}

10. Statistiques (Admin seulement)

GET /api/media/statistics

Exemple de requête

curl -X GET "https://your-domain.com/api/media/statistics" \
  -H "Authorization: Bearer <admin-token>"

Réponse

{
  "total": 150,
  "by_type": [
    {"type": "image", "count": 100},
    {"type": "document", "count": 30},
    {"type": "pdf", "count": 20}
  ],
  "total_size": 52428800,
  "average_size": 349525
}

11. Types supportés

GET /api/media/types

Réponse

{
  "types": ["image", "document", "pdf", "other"],
  "image_formats": ["jpg", "jpeg", "png", "gif", "webp"],
  "document_formats": ["txt", "doc", "docx"],
  "other_formats": ["pdf"]
}

12. Configuration API

GET /api/media/config

Réponse

{
  "maxFileSize": 10485760,
  "allowedExtensions": ["jpg", "jpeg", "png", "gif", "webp", "pdf", "txt", "doc", "docx"],
  "allowedMimeTypes": [
    "image/jpeg",
    "image/png", 
    "image/gif",
    "image/webp",
    "application/pdf",
    "text/plain"
  ]
}

Gestion des erreurs

Codes de statut HTTP

Code Description
200 Succès
201 Créé avec succès
400 Requête invalide
401 Non authentifié
403 Accès interdit
404 Ressource non trouvée
413 Fichier trop volumineux
415 Type de média non supporté
422 Entité non traitable
500 Erreur serveur

Format des erreurs

{
  "error": "Message d'erreur descriptif",
  "code": "ERROR_CODE",
  "details": {
    "field": "description de l'erreur"
  }
}

Exemples d'erreurs courantes

Fichier trop volumineux

{
  "error": "Le fichier est trop volumineux. Taille maximale autorisée : 10 Mo",
  "code": "FILE_TOO_LARGE"
}

Type de fichier non autorisé

{
  "error": "Type de fichier non autorisé : application/zip. Types autorisés : image/jpeg, image/png...",
  "code": "INVALID_FILE_TYPE"
}

Validation échouée

{
  "error": "Validation échouée",
  "code": "VALIDATION_ERROR",
  "details": {
    "name": "Le nom est requis",
    "file": "Le fichier est requis"
  }
}

Exemples d'intégration

JavaScript (Fetch API)

class MediaAPI {
    constructor(baseURL, token) {
        this.baseURL = baseURL;
        this.token = token;
    }

    async getMedias(filters = {}) {
        const params = new URLSearchParams(filters);
        const response = await fetch(`${this.baseURL}/api/media?${params}`, {
            headers: {
                'Authorization': `Bearer ${this.token}`,
                'Accept': 'application/json'
            }
        });
        return response.json();
    }

    async uploadFile(file, metadata = {}) {
        const formData = new FormData();
        formData.append('file', file);
        
        Object.keys(metadata).forEach(key => {
            formData.append(key, metadata[key]);
        });

        const response = await fetch(`${this.baseURL}/api/media/upload`, {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${this.token}`
            },
            body: formData
        });
        
        return response.json();
    }

    async deleteMedia(id) {
        const response = await fetch(`${this.baseURL}/api/media/${id}`, {
            method: 'DELETE',
            headers: {
                'Authorization': `Bearer ${this.token}`
            }
        });
        
        return response.json();
    }
}

// Utilisation
const api = new MediaAPI('https://your-domain.com', 'your-token');

// Lister les médias
const medias = await api.getMedias({ type: 'image', page: 1 });

// Uploader un fichier
const fileInput = document.getElementById('file');
const media = await api.uploadFile(fileInput.files[0], {
    name: 'Mon image',
    description: 'Description'
});

PHP (avec Guzzle)

<?php

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Utils;

class MediaAPI 
{
    private Client $client;
    private string $token;

    public function __construct(string $baseURL, string $token)
    {
        $this->client = new Client(['base_uri' => $baseURL]);
        $this->token = $token;
    }

    public function getMedias(array $filters = []): array
    {
        $response = $this->client->get('/api/media', [
            'query' => $filters,
            'headers' => [
                'Authorization' => 'Bearer ' . $this->token,
                'Accept' => 'application/json'
            ]
        ]);

        return json_decode($response->getBody(), true);
    }

    public function uploadFile(string $filePath, array $metadata = []): array
    {
        $multipart = [
            [
                'name' => 'file',
                'contents' => Utils::tryFopen($filePath, 'r'),
                'filename' => basename($filePath)
            ]
        ];

        foreach ($metadata as $key => $value) {
            $multipart[] = [
                'name' => $key,
                'contents' => $value
            ];
        }

        $response = $this->client->post('/api/media/upload', [
            'headers' => [
                'Authorization' => 'Bearer ' . $this->token
            ],
            'multipart' => $multipart
        ]);

        return json_decode($response->getBody(), true);
    }
}

// Utilisation
$api = new MediaAPI('https://your-domain.com', 'your-token');

// Lister les médias
$medias = $api->getMedias(['type' => 'image']);

// Uploader un fichier
$media = $api->uploadFile('/path/to/file.jpg', [
    'name' => 'Mon image',
    'description' => 'Description'
]);

CORS (Cross-Origin Resource Sharing)

Pour utiliser l'API depuis un navigateur avec un domaine différent, configurez CORS :

# config/packages/dahovi_tech_media.yaml
dahovi_tech_media:
    api:
        cors:
            allowed_origins: 
                - 'https://monsite.com'
                - 'https://admin.monsite.com'
            allowed_methods: ['GET', 'POST', 'PUT', 'DELETE']
            allowed_headers: ['Content-Type', 'Authorization']

Rate Limiting

Pour limiter les requêtes API, vous pouvez utiliser des bundles comme noxlogic/ratelimit-bundle :

# config/packages/noxlogic_rate_limit.yaml
noxlogic_rate_limit:
    path_limits:
        - { path: ^/api/media/upload, limit: 10, period: 60 }
        - { path: ^/api/media, limit: 100, period: 60 }

Prochaines étapes

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime