Files
geo/api/src/Controllers/FileController.php
pierre 599b9fcda0 feat: Gestion des secteurs et migration v3.0.4+304
- Ajout système complet de gestion des secteurs avec contours géographiques
- Import des contours départementaux depuis GeoJSON
- API REST pour la gestion des secteurs (/api/sectors)
- Service de géolocalisation pour déterminer les secteurs
- Migration base de données avec tables x_departements_contours et sectors_adresses
- Interface Flutter pour visualisation et gestion des secteurs
- Ajout thème sombre dans l'application
- Corrections diverses et optimisations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-07 11:01:45 +02:00

1067 lines
36 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace App\Controllers;
require_once __DIR__ . '/../Services/LogService.php';
require_once __DIR__ . '/../Services/ApiService.php';
use PDO;
use PDOException;
use Database;
use AppConfig;
use Request;
use Response;
use Session;
use LogService;
use ApiService;
use Exception;
class FileController {
private PDO $db;
private AppConfig $appConfig;
// Catégories autorisées par type de support
private const FILE_CATEGORIES = [
'entite' => ['logo', 'document', 'reglement', 'statut'],
'user' => ['avatar', 'photo'],
'operation' => ['planning', 'liste', 'export', 'backup'],
'passage' => ['recu', 'photo', 'justificatif', 'carte']
];
// Extensions autorisées
private const ALLOWED_EXTENSIONS = [
'pdf',
'jpg',
'jpeg',
'png',
'gif',
'webp',
'xlsx',
'xls',
'json',
'csv'
];
public function __construct() {
$this->db = Database::getInstance();
$this->appConfig = AppConfig::getInstance();
}
/**
* Récupère les informations utilisateur (rôle et entité)
*/
private function getUserInfo(int $userId): ?array {
try {
$stmt = $this->db->prepare('SELECT fk_entite, fk_role FROM users WHERE id = ?');
$stmt->execute([$userId]);
return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
} catch (Exception $e) {
LogService::log('Erreur lors de la récupération des infos utilisateur', [
'level' => 'error',
'error' => $e->getMessage(),
'userId' => $userId
]);
return null;
}
}
/**
* Valide qu'un chemin est autorisé pour l'utilisateur
*/
private function validatePath(string $path, int $userRole, int $userEntiteId): bool {
// Empêcher les traversées de répertoire
if (strpos($path, '..') !== false || strpos($path, './') !== false) {
return false;
}
// Normaliser le chemin
$path = trim($path, '/');
// Super admin : accès total
if ($userRole > 2) {
return true;
}
// Admin entité : limité à son entité
if ($userRole == 2) {
return strpos($path, "entites/{$userEntiteId}") === 0 || $path === "entites/{$userEntiteId}";
}
return false;
}
/**
* Vérifie si l'utilisateur peut accéder à un fichier
*/
private function canAccessFile(int $fileId, int $userRole, int $userEntiteId): bool {
try {
$stmt = $this->db->prepare('SELECT fk_entite FROM medias WHERE id = ?');
$stmt->execute([$fileId]);
$file = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$file) {
return false;
}
// Super admin : accès total
if ($userRole > 2) {
return true;
}
// Admin entité : seulement ses fichiers
return (int)$file['fk_entite'] === $userEntiteId;
} catch (Exception $e) {
LogService::log('Erreur lors de la vérification d\'accès au fichier', [
'level' => 'error',
'error' => $e->getMessage(),
'fileId' => $fileId,
'userId' => Session::getUserId()
]);
return false;
}
}
/**
* Extrait et valide les paramètres de filtrage
*/
private function extractFilters(array $params): array {
return [
'page' => max(1, (int)($params['page'] ?? 1)),
'per_page' => min(100, max(1, (int)($params['per_page'] ?? 50))),
'search' => !empty($params['search']) ? trim($params['search']) : null,
'type' => !empty($params['type']) && in_array($params['type'], self::ALLOWED_EXTENSIONS) ? $params['type'] : null,
'category' => !empty($params['category']) ? trim($params['category']) : null,
'sort' => in_array($params['sort'] ?? '', ['name', 'date', 'size', 'type']) ? $params['sort'] : 'date',
'order' => in_array($params['order'] ?? '', ['asc', 'desc']) ? $params['order'] : 'desc'
];
}
/**
* Construit la clause WHERE pour les requêtes de recherche
*/
private function buildWhereClause(array $filters, int $userRole, int $userEntiteId, ?string $path = null): array {
$conditions = [];
$params = [];
// Restriction par entité selon le rôle
if ($userRole == 2) {
$conditions[] = 'm.fk_entite = ?';
$params[] = $userEntiteId;
}
// Filtrage par chemin si spécifié
if ($path !== null) {
$conditions[] = 'm.file_path LIKE ?';
$params[] = "uploads/{$path}%";
}
// Recherche textuelle
if ($filters['search']) {
$searchTerm = '%' . $filters['search'] . '%';
$conditions[] = '(m.fichier LIKE ? OR m.original_name LIKE ? OR m.description LIKE ?)';
$params[] = $searchTerm;
$params[] = $searchTerm;
$params[] = $searchTerm;
}
// Filtrage par type (extension)
if ($filters['type']) {
$conditions[] = 'm.file_type = ?';
$params[] = $filters['type'];
}
// Filtrage par catégorie
if ($filters['category']) {
$conditions[] = 'm.file_category = ?';
$params[] = $filters['category'];
}
$whereClause = !empty($conditions) ? 'WHERE ' . implode(' AND ', $conditions) : '';
return [$whereClause, $params];
}
/**
* Construit la clause ORDER BY
*/
private function buildOrderClause(array $filters): string {
$sortField = match ($filters['sort']) {
'name' => 'm.original_name',
'size' => 'm.file_size',
'type' => 'm.file_type',
default => 'm.created_at'
};
return "ORDER BY {$sortField} {$filters['order']}";
}
/**
* Navigation dans l'arborescence avec recherche et pagination
*/
public function browse(): void {
try {
$userId = Session::getUserId();
if (!$userId) {
Response::json([
'status' => 'error',
'message' => 'Vous devez être connecté pour effectuer cette action'
], 401);
return;
}
$userInfo = $this->getUserInfo($userId);
if (!$userInfo) {
Response::json([
'status' => 'error',
'message' => 'Informations utilisateur non trouvées'
], 404);
return;
}
$userRole = (int)$userInfo['fk_role'];
$userEntiteId = (int)$userInfo['fk_entite'];
$path = $_GET['path'] ?? '';
$filters = $this->extractFilters($_GET);
// Validation du chemin
if (!$this->validatePath($path, $userRole, $userEntiteId)) {
Response::json([
'status' => 'error',
'message' => 'Accès refusé à ce répertoire'
], 403);
return;
}
// Construction de la requête
[$whereClause, $params] = $this->buildWhereClause($filters, $userRole, $userEntiteId, $path);
$orderClause = $this->buildOrderClause($filters);
// Requête pour compter le total
$countSql = "
SELECT COUNT(*) as total
FROM medias m
{$whereClause}
";
$stmt = $this->db->prepare($countSql);
$stmt->execute($params);
$totalItems = (int)$stmt->fetchColumn();
// Calcul de la pagination
$totalPages = ceil($totalItems / $filters['per_page']);
$offset = ($filters['page'] - 1) * $filters['per_page'];
// Requête principale avec pagination
$sql = "
SELECT
m.id, m.fichier, m.original_name, m.file_type, m.file_category,
m.file_size, m.file_path, m.description, m.created_at,
m.fk_user_creat, u.encrypted_name as creator_name
FROM medias m
LEFT JOIN users u ON u.id = m.fk_user_creat
{$whereClause}
{$orderClause}
LIMIT ? OFFSET ?
";
$params[] = $filters['per_page'];
$params[] = $offset;
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
$files = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Déchiffrer les noms des créateurs
foreach ($files as &$file) {
if ($file['creator_name']) {
$file['creator_name'] = ApiService::decryptData($file['creator_name']);
}
unset($file['encrypted_name']);
}
// Statistiques rapides
$statsSql = "
SELECT
COUNT(*) as total_files,
SUM(m.file_size) as total_size,
m.file_category,
COUNT(*) as category_count
FROM medias m
{$whereClause}
GROUP BY m.file_category
";
$stmt = $this->db->prepare($statsSql);
$stmt->execute(array_slice($params, 0, -2)); // Enlever LIMIT et OFFSET
$stats = $stmt->fetchAll(PDO::FETCH_ASSOC);
$summary = [
'total_files' => $totalItems,
'total_size' => array_sum(array_column($stats, 'total_size')),
'by_category' => []
];
foreach ($stats as $stat) {
if ($stat['file_category']) {
$summary['by_category'][$stat['file_category']] = (int)$stat['category_count'];
}
}
Response::json([
'status' => 'success',
'current_path' => $path,
'parent_path' => dirname($path) !== '.' ? dirname($path) : null,
'pagination' => [
'current_page' => $filters['page'],
'per_page' => $filters['per_page'],
'total_items' => $totalItems,
'total_pages' => $totalPages,
'has_next' => $filters['page'] < $totalPages,
'has_prev' => $filters['page'] > 1
],
'filters' => [
'search' => $filters['search'],
'type' => $filters['type'],
'category' => $filters['category'],
'sort' => $filters['sort'],
'order' => $filters['order']
],
'files' => $files,
'summary' => $summary
], 200);
} catch (Exception $e) {
LogService::log('Erreur lors de la navigation des fichiers', [
'level' => 'error',
'error' => $e->getMessage(),
'userId' => $userId ?? null,
'path' => $_GET['path'] ?? null
]);
Response::json([
'status' => 'error',
'message' => 'Erreur lors de la navigation des fichiers'
], 500);
}
}
/**
* Liste des fichiers par support avec recherche et pagination
*/
public function listBySupport(string $support, string $supportId): void {
try {
$userId = Session::getUserId();
if (!$userId) {
Response::json([
'status' => 'error',
'message' => 'Vous devez être connecté pour effectuer cette action'
], 401);
return;
}
$userInfo = $this->getUserInfo($userId);
if (!$userInfo) {
Response::json([
'status' => 'error',
'message' => 'Informations utilisateur non trouvées'
], 404);
return;
}
$userRole = (int)$userInfo['fk_role'];
$userEntiteId = (int)$userInfo['fk_entite'];
$supportIdInt = (int)$supportId;
$filters = $this->extractFilters($_GET);
// Construction de la requête de base
$conditions = ['m.support = ?', 'm.support_id = ?'];
$params = [$support, $supportIdInt];
// Restriction par entité selon le rôle
if ($userRole == 2) {
$conditions[] = 'm.fk_entite = ?';
$params[] = $userEntiteId;
}
// Recherche textuelle
if ($filters['search']) {
$searchTerm = '%' . $filters['search'] . '%';
$conditions[] = '(m.fichier LIKE ? OR m.original_name LIKE ? OR m.description LIKE ?)';
$params[] = $searchTerm;
$params[] = $searchTerm;
$params[] = $searchTerm;
}
// Filtrage par type
if ($filters['type']) {
$conditions[] = 'm.file_type = ?';
$params[] = $filters['type'];
}
// Filtrage par catégorie
if ($filters['category']) {
$conditions[] = 'm.file_category = ?';
$params[] = $filters['category'];
}
$whereClause = 'WHERE ' . implode(' AND ', $conditions);
$orderClause = $this->buildOrderClause($filters);
// Compter le total
$countSql = "SELECT COUNT(*) as total FROM medias m {$whereClause}";
$stmt = $this->db->prepare($countSql);
$stmt->execute($params);
$totalItems = (int)$stmt->fetchColumn();
// Calcul pagination
$totalPages = ceil($totalItems / $filters['per_page']);
$offset = ($filters['page'] - 1) * $filters['per_page'];
// Requête principale
$sql = "
SELECT
m.id, m.fichier, m.original_name, m.file_type, m.file_category,
m.file_size, m.file_path, m.description, m.created_at,
m.fk_user_creat, u.encrypted_name as creator_name
FROM medias m
LEFT JOIN users u ON u.id = m.fk_user_creat
{$whereClause}
{$orderClause}
LIMIT ? OFFSET ?
";
$params[] = $filters['per_page'];
$params[] = $offset;
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
$files = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Déchiffrer les noms
foreach ($files as &$file) {
if ($file['creator_name']) {
$file['creator_name'] = ApiService::decryptData($file['creator_name']);
}
unset($file['encrypted_name']);
}
Response::json([
'status' => 'success',
'support' => $support,
'support_id' => $supportIdInt,
'pagination' => [
'current_page' => $filters['page'],
'per_page' => $filters['per_page'],
'total_items' => $totalItems,
'total_pages' => $totalPages,
'has_next' => $filters['page'] < $totalPages,
'has_prev' => $filters['page'] > 1
],
'filters' => [
'search' => $filters['search'],
'type' => $filters['type'],
'category' => $filters['category']
],
'files' => $files
], 200);
} catch (Exception $e) {
LogService::log('Erreur lors de la liste des fichiers par support', [
'level' => 'error',
'error' => $e->getMessage(),
'support' => $support,
'supportId' => $supportId,
'userId' => $userId ?? null
]);
Response::json([
'status' => 'error',
'message' => 'Erreur lors de la récupération des fichiers'
], 500);
}
}
/**
* Recherche globale de fichiers
*/
public function search(): void {
try {
$userId = Session::getUserId();
if (!$userId) {
Response::json([
'status' => 'error',
'message' => 'Vous devez être connecté pour effectuer cette action'
], 401);
return;
}
$userInfo = $this->getUserInfo($userId);
if (!$userInfo) {
Response::json([
'status' => 'error',
'message' => 'Informations utilisateur non trouvées'
], 404);
return;
}
$userRole = (int)$userInfo['fk_role'];
$userEntiteId = (int)$userInfo['fk_entite'];
$query = $_GET['q'] ?? '';
if (empty(trim($query))) {
Response::json([
'status' => 'error',
'message' => 'Terme de recherche requis'
], 400);
return;
}
$filters = $this->extractFilters($_GET);
$filters['search'] = trim($query);
[$whereClause, $params] = $this->buildWhereClause($filters, $userRole, $userEntiteId);
$orderClause = $this->buildOrderClause($filters);
// Compter le total
$countSql = "SELECT COUNT(*) as total FROM medias m {$whereClause}";
$stmt = $this->db->prepare($countSql);
$stmt->execute($params);
$totalItems = (int)$stmt->fetchColumn();
// Pagination
$totalPages = ceil($totalItems / $filters['per_page']);
$offset = ($filters['page'] - 1) * $filters['per_page'];
// Requête principale
$sql = "
SELECT
m.id, m.fichier, m.original_name, m.file_type, m.file_category,
m.file_size, m.file_path, m.description, m.created_at, m.support,
m.support_id, m.fk_user_creat, u.encrypted_name as creator_name
FROM medias m
LEFT JOIN users u ON u.id = m.fk_user_creat
{$whereClause}
{$orderClause}
LIMIT ? OFFSET ?
";
$params[] = $filters['per_page'];
$params[] = $offset;
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
$files = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Déchiffrer les noms
foreach ($files as &$file) {
if ($file['creator_name']) {
$file['creator_name'] = ApiService::decryptData($file['creator_name']);
}
unset($file['encrypted_name']);
}
Response::json([
'status' => 'success',
'query' => $query,
'pagination' => [
'current_page' => $filters['page'],
'per_page' => $filters['per_page'],
'total_items' => $totalItems,
'total_pages' => $totalPages,
'has_next' => $filters['page'] < $totalPages,
'has_prev' => $filters['page'] > 1
],
'filters' => [
'type' => $filters['type'],
'category' => $filters['category']
],
'files' => $files
], 200);
} catch (Exception $e) {
LogService::log('Erreur lors de la recherche de fichiers', [
'level' => 'error',
'error' => $e->getMessage(),
'query' => $_GET['q'] ?? null,
'userId' => $userId ?? null
]);
Response::json([
'status' => 'error',
'message' => 'Erreur lors de la recherche'
], 500);
}
}
/**
* Statistiques d'utilisation des fichiers
*/
public function getStats(): void {
try {
$userId = Session::getUserId();
if (!$userId) {
Response::json([
'status' => 'error',
'message' => 'Vous devez être connecté pour effectuer cette action'
], 401);
return;
}
$userInfo = $this->getUserInfo($userId);
if (!$userInfo) {
Response::json([
'status' => 'error',
'message' => 'Informations utilisateur non trouvées'
], 404);
return;
}
$userRole = (int)$userInfo['fk_role'];
$userEntiteId = (int)$userInfo['fk_entite'];
if ($userRole == 2) {
// Stats pour admin d'entité
$sql = "
SELECT
COUNT(*) as total_files,
SUM(file_size) as total_size,
support,
file_category,
file_type,
COUNT(*) as count
FROM medias
WHERE fk_entite = ?
GROUP BY support, file_category, file_type
ORDER BY support, file_category
";
$stmt = $this->db->prepare($sql);
$stmt->execute([$userEntiteId]);
$stats = $stmt->fetchAll(PDO::FETCH_ASSOC);
$response = [
'status' => 'success',
'entite_id' => $userEntiteId,
'storage' => [
'total_files' => 0,
'total_size' => 0,
'by_support' => [],
'by_category' => [],
'by_type' => []
]
];
foreach ($stats as $stat) {
$response['storage']['total_files'] += (int)$stat['count'];
$response['storage']['total_size'] += (int)$stat['total_size'];
$support = $stat['support'];
$category = $stat['file_category'] ?: 'non_categorise';
$type = $stat['file_type'] ?: 'inconnu';
if (!isset($response['storage']['by_support'][$support])) {
$response['storage']['by_support'][$support] = ['count' => 0, 'size' => 0];
}
$response['storage']['by_support'][$support]['count'] += (int)$stat['count'];
$response['storage']['by_support'][$support]['size'] += (int)$stat['total_size'];
if (!isset($response['storage']['by_category'][$category])) {
$response['storage']['by_category'][$category] = 0;
}
$response['storage']['by_category'][$category] += (int)$stat['count'];
if (!isset($response['storage']['by_type'][$type])) {
$response['storage']['by_type'][$type] = 0;
}
$response['storage']['by_type'][$type] += (int)$stat['count'];
}
} else {
// Stats globales pour super admin
$sql = "
SELECT
fk_entite,
COUNT(*) as files,
SUM(file_size) as size
FROM medias
GROUP BY fk_entite
ORDER BY size DESC
";
$stmt = $this->db->prepare($sql);
$stmt->execute();
$entiteStats = $stmt->fetchAll(PDO::FETCH_ASSOC);
$totalSql = "
SELECT
COUNT(*) as total_files,
SUM(file_size) as total_size,
COUNT(DISTINCT fk_entite) as entites_count
FROM medias
";
$stmt = $this->db->prepare($totalSql);
$stmt->execute();
$totals = $stmt->fetch(PDO::FETCH_ASSOC);
$response = [
'status' => 'success',
'global_stats' => [
'total_files' => (int)$totals['total_files'],
'total_size' => (int)$totals['total_size'],
'entites_count' => (int)$totals['entites_count'],
'by_entite' => []
]
];
foreach ($entiteStats as $stat) {
$response['global_stats']['by_entite'][] = [
'entite_id' => (int)$stat['fk_entite'],
'files' => (int)$stat['files'],
'size' => (int)$stat['size']
];
}
}
Response::json($response, 200);
} catch (Exception $e) {
LogService::log('Erreur lors de la récupération des statistiques', [
'level' => 'error',
'error' => $e->getMessage(),
'userId' => $userId ?? null
]);
Response::json([
'status' => 'error',
'message' => 'Erreur lors de la récupération des statistiques'
], 500);
}
}
/**
* Téléchargement sécurisé d'un fichier
*/
public function download(string $id): void {
try {
$userId = Session::getUserId();
if (!$userId) {
Response::json([
'status' => 'error',
'message' => 'Vous devez être connecté pour effectuer cette action'
], 401);
return;
}
$userInfo = $this->getUserInfo($userId);
if (!$userInfo) {
Response::json([
'status' => 'error',
'message' => 'Informations utilisateur non trouvées'
], 404);
return;
}
$userRole = (int)$userInfo['fk_role'];
$userEntiteId = (int)$userInfo['fk_entite'];
$fileId = (int)$id;
// Vérifier l'accès au fichier
if (!$this->canAccessFile($fileId, $userRole, $userEntiteId)) {
Response::json([
'status' => 'error',
'message' => 'Accès refusé à ce fichier'
], 403);
return;
}
// Récupérer les informations du fichier
$stmt = $this->db->prepare('
SELECT fichier, file_path, mime_type, original_name, file_size
FROM medias
WHERE id = ?
');
$stmt->execute([$fileId]);
$file = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$file) {
Response::json([
'status' => 'error',
'message' => 'Fichier non trouvé'
], 404);
return;
}
$filepath = getcwd() . '/' . $file['file_path'];
if (!file_exists($filepath)) {
Response::json([
'status' => 'error',
'message' => 'Fichier physique non trouvé'
], 404);
return;
}
// Log du téléchargement
LogService::log('Téléchargement de fichier', [
'level' => 'info',
'userId' => $userId,
'fileId' => $fileId,
'filename' => $file['original_name']
]);
// Envoyer le fichier
header('Content-Type: ' . $file['mime_type']);
header('Content-Disposition: attachment; filename="' . $file['original_name'] . '"');
header('Content-Length: ' . filesize($filepath));
header('Cache-Control: no-cache, must-revalidate');
header('Expires: 0');
readfile($filepath);
exit;
} catch (Exception $e) {
LogService::log('Erreur lors du téléchargement', [
'level' => 'error',
'error' => $e->getMessage(),
'fileId' => $id,
'userId' => $userId ?? null
]);
Response::json([
'status' => 'error',
'message' => 'Erreur lors du téléchargement'
], 500);
}
}
/**
* Suppression sécurisée d'un fichier
*/
public function deleteFile(string $id): void {
try {
$userId = Session::getUserId();
if (!$userId) {
Response::json([
'status' => 'error',
'message' => 'Vous devez être connecté pour effectuer cette action'
], 401);
return;
}
$userInfo = $this->getUserInfo($userId);
if (!$userInfo) {
Response::json([
'status' => 'error',
'message' => 'Informations utilisateur non trouvées'
], 404);
return;
}
$userRole = (int)$userInfo['fk_role'];
$userEntiteId = (int)$userInfo['fk_entite'];
$fileId = (int)$id;
// Vérifier l'accès au fichier
if (!$this->canAccessFile($fileId, $userRole, $userEntiteId)) {
Response::json([
'status' => 'error',
'message' => 'Accès refusé à ce fichier'
], 403);
return;
}
// Récupérer les informations du fichier
$stmt = $this->db->prepare('
SELECT fichier, file_path, original_name, support, support_id
FROM medias
WHERE id = ?
');
$stmt->execute([$fileId]);
$file = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$file) {
Response::json([
'status' => 'error',
'message' => 'Fichier non trouvé'
], 404);
return;
}
// Supprimer le fichier physique
$filepath = getcwd() . '/' . $file['file_path'];
if (file_exists($filepath)) {
unlink($filepath);
}
// Supprimer l'enregistrement en base
$stmt = $this->db->prepare('DELETE FROM medias WHERE id = ?');
$stmt->execute([$fileId]);
LogService::log('Suppression de fichier', [
'level' => 'info',
'userId' => $userId,
'fileId' => $fileId,
'filename' => $file['original_name'],
'support' => $file['support'],
'support_id' => $file['support_id']
]);
Response::json([
'status' => 'success',
'message' => 'Fichier supprimé avec succès'
], 200);
} catch (Exception $e) {
LogService::log('Erreur lors de la suppression de fichier', [
'level' => 'error',
'error' => $e->getMessage(),
'fileId' => $id,
'userId' => $userId ?? null
]);
Response::json([
'status' => 'error',
'message' => 'Erreur lors de la suppression'
], 500);
}
}
/**
* Informations détaillées d'un fichier
*/
public function getFileInfo(string $id): void {
try {
$userId = Session::getUserId();
if (!$userId) {
Response::json([
'status' => 'error',
'message' => 'Vous devez être connecté pour effectuer cette action'
], 401);
return;
}
$userInfo = $this->getUserInfo($userId);
if (!$userInfo) {
Response::json([
'status' => 'error',
'message' => 'Informations utilisateur non trouvées'
], 404);
return;
}
$userRole = (int)$userInfo['fk_role'];
$userEntiteId = (int)$userInfo['fk_entite'];
$fileId = (int)$id;
// Vérifier l'accès au fichier
if (!$this->canAccessFile($fileId, $userRole, $userEntiteId)) {
Response::json([
'status' => 'error',
'message' => 'Accès refusé à ce fichier'
], 403);
return;
}
// Récupérer toutes les informations du fichier
$stmt = $this->db->prepare('
SELECT
m.*,
u_creat.encrypted_name as creator_name,
u_modif.encrypted_name as modifier_name
FROM medias m
LEFT JOIN users u_creat ON u_creat.id = m.fk_user_creat
LEFT JOIN users u_modif ON u_modif.id = m.fk_user_modif
WHERE m.id = ?
');
$stmt->execute([$fileId]);
$file = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$file) {
Response::json([
'status' => 'error',
'message' => 'Fichier non trouvé'
], 404);
return;
}
// Déchiffrer les noms d'utilisateurs
if ($file['creator_name']) {
$file['creator_name'] = ApiService::decryptData($file['creator_name']);
}
if ($file['modifier_name']) {
$file['modifier_name'] = ApiService::decryptData($file['modifier_name']);
}
// Vérifier si le fichier physique existe
$filepath = getcwd() . '/' . $file['file_path'];
$file['file_exists'] = file_exists($filepath);
Response::json([
'status' => 'success',
'file' => $file
], 200);
} catch (Exception $e) {
LogService::log('Erreur lors de la récupération des infos fichier', [
'level' => 'error',
'error' => $e->getMessage(),
'fileId' => $id,
'userId' => $userId ?? null
]);
Response::json([
'status' => 'error',
'message' => 'Erreur lors de la récupération des informations'
], 500);
}
}
/**
* Métadonnées du système de fichiers (catégories, extensions, etc.)
*/
public function getMetadata(): void {
try {
$userId = Session::getUserId();
if (!$userId) {
Response::json([
'status' => 'error',
'message' => 'Vous devez être connecté pour effectuer cette action'
], 401);
return;
}
Response::json([
'status' => 'success',
'categories' => self::FILE_CATEGORIES,
'extensions' => self::ALLOWED_EXTENSIONS,
'mime_types' => [
'pdf' => 'application/pdf',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'webp' => 'image/webp',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xls' => 'application/vnd.ms-excel',
'json' => 'application/json',
'csv' => 'text/csv'
],
'max_file_sizes' => [
'entite' => 20971520, // 20 MB
'user' => 5242880, // 5 MB
'operation' => 20971520, // 20 MB
'passage' => 10485760 // 10 MB
]
], 200);
} catch (Exception $e) {
LogService::log('Erreur lors de la récupération des métadonnées', [
'level' => 'error',
'error' => $e->getMessage(),
'userId' => $userId ?? null
]);
Response::json([
'status' => 'error',
'message' => 'Erreur lors de la récupération des métadonnées'
], 500);
}
}
}