['table' => 'inv_equipment_files', 'owner' => 'equipment_id', 'parent' => 'inv_equipment'], 'maintenance' => ['table' => 'maint_maintenance_files', 'owner' => 'maintenance_id', 'parent' => 'maint_maintenances'], 'intervention' => ['table' => 'maint_intervention_files', 'owner' => 'intervention_id', 'parent' => 'maint_interventions'], ]; if (!isset($config[$scope])) { mnt_json_fail('Scope non valido.'); } if ($ownerId <= 0) { mnt_json_fail('ID non valido.'); } if (empty($_FILES['files']['name'][0])) { mnt_json_fail('Nessun file selezionato.'); } $target = $config[$scope]; $stmt = $pdo->prepare("SELECT id FROM {$target['parent']} WHERE id = ?"); $stmt->execute([$ownerId]); if (!$stmt->fetchColumn()) { mnt_json_fail('Record collegato non trovato.'); } $columns = $scope === 'equipment' ? "({$target['owner']}, kind, original_name, stored_name, mime_type, size, uploaded_by)" : "({$target['owner']}, original_name, stored_name, mime_type, size, uploaded_by)"; $placeholders = $scope === 'equipment' ? '(?, ?, ?, ?, ?, ?, ?)' : '(?, ?, ?, ?, ?, ?)'; $insert = $pdo->prepare("INSERT INTO {$target['table']} $columns VALUES $placeholders"); $uploaded = []; $errors = []; $fileCount = count($_FILES['files']['name']); for ($i = 0; $i < $fileCount; $i++) { $file = [ 'name' => $_FILES['files']['name'][$i], 'type' => $_FILES['files']['type'][$i], 'tmp_name' => $_FILES['files']['tmp_name'][$i], 'error' => $_FILES['files']['error'][$i], 'size' => $_FILES['files']['size'][$i], ]; try { $stored = mnt_store_upload($file, $scope); } catch (RuntimeException $e) { $errors[] = $file['name'] . ': ' . $e->getMessage(); continue; } // A file uploaded as a photo but not actually an image is kept as a file $rowKind = ($kind === 'photo' && $stored['is_image']) ? 'photo' : 'file'; $values = $scope === 'equipment' ? [$ownerId, $rowKind, $stored['original_name'], $stored['stored_name'], $stored['mime_type'], $stored['size'], $currentUserId] : [$ownerId, $stored['original_name'], $stored['stored_name'], $stored['mime_type'], $stored['size'], $currentUserId]; $insert->execute($values); $uploaded[] = ['id' => (int)$pdo->lastInsertId(), 'name' => $stored['original_name']]; } if (!$uploaded) { mnt_json_fail($errors ? implode('; ', $errors) : 'Nessun file caricato.'); } // The first photo of an item becomes its cover automatically if ($scope === 'equipment' && $kind === 'photo') { $stmt = $pdo->prepare("SELECT cover_file_id FROM inv_equipment WHERE id = ?"); $stmt->execute([$ownerId]); if (!$stmt->fetchColumn()) { $pdo->prepare("UPDATE inv_equipment SET cover_file_id = ? WHERE id = ?") ->execute([$uploaded[0]['id'], $ownerId]); } } $equipmentId = $scope === 'equipment' ? $ownerId : null; $maintenanceId = $scope === 'maintenance' ? $ownerId : null; $interventionId = $scope === 'intervention' ? $ownerId : null; mnt_log($pdo, 'file_added', $equipmentId, $maintenanceId, $interventionId, $currentUserId, null, implode(', ', array_column($uploaded, 'name'))); mnt_json_ok(['uploaded' => $uploaded, 'errors' => $errors]); } catch (Throwable $e) { mnt_json_fail('Errore: ' . $e->getMessage()); }