getConnection(); /* |-------------------------------------------------------------------------- | Upload configuration |-------------------------------------------------------------------------- | The page is expected to be inside /public. | Files will be stored in /public/uploads/ppe. | The database stores the relative browser path, for example: | uploads/ppe/ppe_20260604_123456_abcd.jpg |-------------------------------------------------------------------------- */ const PPE_UPLOAD_RELATIVE_DIR = 'uploads/ppe'; const PPE_UPLOAD_MAX_SIZE = 5242880; // 5 MB $ppeUploadAbsoluteDir = __DIR__ . '/' . PPE_UPLOAD_RELATIVE_DIR; if (!is_dir($ppeUploadAbsoluteDir)) { mkdir($ppeUploadAbsoluteDir, 0755, true); } function jsonResponse(bool $success, string $message = '', array $extra = []): void { header('Content-Type: application/json; charset=utf-8'); echo json_encode(array_merge([ 'success' => $success, 'message' => $message, ], $extra)); exit; } function cleanString(?string $value): string { return trim((string)$value); } function cleanNullableString(?string $value): ?string { $value = trim((string)$value); return $value === '' ? null : $value; } function toActiveValue($value): int { return ((string)$value === '1') ? 1 : 0; } function normalizePathForDb(string $path): string { return str_replace('\\', '/', $path); } function deletePpePhotoIfExists(?string $relativePath): void { if (!$relativePath) { return; } $relativePath = normalizePathForDb($relativePath); if (strpos($relativePath, PPE_UPLOAD_RELATIVE_DIR . '/') !== 0) { return; } $absolutePath = __DIR__ . '/' . $relativePath; if (is_file($absolutePath)) { unlink($absolutePath); } } function uploadPpePhoto(array $file): ?string { if (!isset($file['error']) || $file['error'] === UPLOAD_ERR_NO_FILE) { return null; } if ($file['error'] !== UPLOAD_ERR_OK) { throw new RuntimeException('Errore durante il caricamento della foto.'); } if (($file['size'] ?? 0) > PPE_UPLOAD_MAX_SIZE) { throw new RuntimeException('La foto supera la dimensione massima consentita di 5 MB.'); } $tmpPath = $file['tmp_name'] ?? ''; if (!is_uploaded_file($tmpPath)) { throw new RuntimeException('File caricato non valido.'); } $finfo = new finfo(FILEINFO_MIME_TYPE); $mimeType = $finfo->file($tmpPath); $allowedMimeTypes = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp', ]; if (!isset($allowedMimeTypes[$mimeType])) { throw new RuntimeException('Formato foto non consentito. Sono ammessi JPG, PNG e WEBP.'); } $extension = $allowedMimeTypes[$mimeType]; $randomName = bin2hex(random_bytes(6)); $fileName = 'ppe_' . date('Ymd_His') . '_' . $randomName . '.' . $extension; $absoluteDestination = __DIR__ . '/' . PPE_UPLOAD_RELATIVE_DIR . '/' . $fileName; $relativeDestination = PPE_UPLOAD_RELATIVE_DIR . '/' . $fileName; if (!move_uploaded_file($tmpPath, $absoluteDestination)) { throw new RuntimeException('Impossibile salvare la foto nella cartella DPI.'); } return normalizePathForDb($relativeDestination); } /* |-------------------------------------------------------------------------- | AJAX actions |-------------------------------------------------------------------------- */ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { try { $action = $_POST['action']; /* |-------------------------------------------------------------------------- | Save PPE |-------------------------------------------------------------------------- */ if ($action === 'save_ppe') { $id = isset($_POST['id']) && $_POST['id'] !== '' ? (int)$_POST['id'] : null; $name = cleanString($_POST['name'] ?? ''); $description = cleanNullableString($_POST['description'] ?? null); $category = cleanNullableString($_POST['category'] ?? null); $standardReference = cleanNullableString($_POST['standard_reference'] ?? null); $validityMonths = isset($_POST['validity_months']) && $_POST['validity_months'] !== '' ? (int)$_POST['validity_months'] : null; $sortOrder = isset($_POST['sort_order']) && $_POST['sort_order'] !== '' ? (int)$_POST['sort_order'] : 999; $isActive = toActiveValue($_POST['is_active'] ?? 1); $removePhoto = (int)($_POST['remove_photo'] ?? 0) === 1; if ($name === '') { jsonResponse(false, 'Il nome del DPI è obbligatorio.'); } $uploadedPhotoPath = null; if (isset($_FILES['photo'])) { $uploadedPhotoPath = uploadPpePhoto($_FILES['photo']); } if ($id) { $stmt = $pdo->prepare(" SELECT photo FROM ppe_items WHERE id = ? LIMIT 1 "); $stmt->execute([$id]); $existingPhoto = $stmt->fetchColumn(); if ($existingPhoto === false) { jsonResponse(false, 'DPI non trovato.'); } $finalPhoto = $existingPhoto; if ($removePhoto) { deletePpePhotoIfExists($existingPhoto); $finalPhoto = null; } if ($uploadedPhotoPath) { deletePpePhotoIfExists($existingPhoto); $finalPhoto = $uploadedPhotoPath; } $stmt = $pdo->prepare(" UPDATE ppe_items SET name = :name, description = :description, category = :category, photo = :photo, standard_reference = :standard_reference, validity_months = :validity_months, sort_order = :sort_order, is_active = :is_active, updated_at = CURRENT_TIMESTAMP WHERE id = :id "); $stmt->execute([ ':name' => $name, ':description' => $description, ':category' => $category, ':photo' => $finalPhoto, ':standard_reference' => $standardReference, ':validity_months' => $validityMonths, ':sort_order' => $sortOrder, ':is_active' => $isActive, ':id' => $id, ]); jsonResponse(true, 'DPI aggiornato correttamente.'); } $stmt = $pdo->prepare(" INSERT INTO ppe_items ( name, description, category, photo, standard_reference, validity_months, sort_order, is_active, created_at, updated_at ) VALUES ( :name, :description, :category, :photo, :standard_reference, :validity_months, :sort_order, :is_active, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP ) "); $stmt->execute([ ':name' => $name, ':description' => $description, ':category' => $category, ':photo' => $uploadedPhotoPath, ':standard_reference' => $standardReference, ':validity_months' => $validityMonths, ':sort_order' => $sortOrder, ':is_active' => $isActive, ]); jsonResponse(true, 'DPI creato correttamente.'); } /* |-------------------------------------------------------------------------- | Get PPE |-------------------------------------------------------------------------- */ if ($action === 'get_ppe') { $id = (int)($_POST['id'] ?? 0); if ($id <= 0) { jsonResponse(false, 'ID DPI non valido.'); } $stmt = $pdo->prepare(" SELECT id, name, description, category, photo, standard_reference, validity_months, sort_order, is_active FROM ppe_items WHERE id = ? LIMIT 1 "); $stmt->execute([$id]); $ppe = $stmt->fetch(PDO::FETCH_ASSOC); if (!$ppe) { jsonResponse(false, 'DPI non trovato.'); } jsonResponse(true, '', [ 'ppe' => $ppe, ]); } /* |-------------------------------------------------------------------------- | Delete PPE |-------------------------------------------------------------------------- */ if ($action === 'delete_ppe') { $id = (int)($_POST['id'] ?? 0); if ($id <= 0) { jsonResponse(false, 'ID DPI non valido.'); } $stmt = $pdo->prepare(" SELECT photo FROM ppe_items WHERE id = ? LIMIT 1 "); $stmt->execute([$id]); $photo = $stmt->fetchColumn(); if ($photo === false) { jsonResponse(false, 'DPI non trovato.'); } $pdo->beginTransaction(); $stmt = $pdo->prepare(" DELETE FROM ppe_items WHERE id = ? "); $stmt->execute([$id]); $pdo->commit(); deletePpePhotoIfExists($photo ?: null); jsonResponse(true, 'DPI eliminato correttamente.'); } jsonResponse(false, 'Azione non riconosciuta.'); } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } jsonResponse(false, 'Errore: ' . $e->getMessage()); } } /* |-------------------------------------------------------------------------- | Page data |-------------------------------------------------------------------------- */ $stmt = $pdo->prepare(" SELECT id, name, description, category, photo, standard_reference, validity_months, sort_order, is_active, created_at, updated_at FROM ppe_items ORDER BY sort_order ASC, name ASC "); $stmt->execute(); $ppeItems = $stmt->fetchAll(PDO::FETCH_ASSOC); $totalPpe = count($ppeItems); $totalActivePpe = 0; $totalWithPhoto = 0; $categories = []; foreach ($ppeItems as $ppe) { if ((int)$ppe['is_active'] === 1) { $totalActivePpe++; } if (!empty($ppe['photo'])) { $totalWithPhoto++; } if (!empty($ppe['category'])) { $categories[$ppe['category']] = true; } } $totalCategories = count($categories); ?> Gestione DPI - <?= htmlspecialchars($titlewebsite ?? '', ENT_QUOTES, 'UTF-8'); ?>

Gestione DPI

Anagrafica dei Dispositivi di Protezione Individuale, con foto, categorie, validità e standard di riferimento.

DPI totali
DPI attivi
Categorie
Con foto
Elenco DPI
ID Foto DPI Categoria Standard Validità Stato Azioni
<?= htmlspecialchars($ppe['name'], ENT_QUOTES, 'UTF-8'); ?>
No foto
Nessuna descrizione
Ordine:
- -'; ?> mesi Nessuna Attivo Inattivo
Le foto vengono salvate nella cartella . Nel database viene salvato solo il percorso relativo.