diff --git a/public/userarea/api/api_medical_certificates_delete.php b/public/userarea/api/api_medical_certificates_delete.php new file mode 100644 index 0000000..4432cd5 --- /dev/null +++ b/public/userarea/api/api_medical_certificates_delete.php @@ -0,0 +1,56 @@ + false, 'message' => 'Missing certificate id (id or cert_id).']); + exit; + } + + // Get cert and ensure ownership + $stmt = $pdo->prepare(" + SELECT id, stored_path + FROM user_medical_certificates + WHERE id = ? AND user_id = ? + LIMIT 1 + "); + $stmt->execute([$cert_id, $iduserlogin]); + $cert = $stmt->fetch(PDO::FETCH_ASSOC); + + if (!$cert) { + http_response_code(404); + echo json_encode(['success' => false, 'message' => 'Certificate not found.']); + exit; + } + + // stored_path like: userarea/certificate/xxx + $stored = (string)$cert['stored_path']; + $publicRoot = realpath(__DIR__ . '/../../'); // points to /public + $fullPath = $publicRoot . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, ltrim($stored, '/\\')); + + if (is_file($fullPath)) { + @unlink($fullPath); + } + + $del = $pdo->prepare("DELETE FROM user_medical_certificates WHERE id = ? AND user_id = ?"); + $del->execute([$cert_id, $iduserlogin]); + + echo json_encode(['success' => true, 'deleted_id' => $cert_id], JSON_UNESCAPED_UNICODE); +} catch (Throwable $e) { + http_response_code(500); + echo json_encode(['success' => false, 'message' => 'Server error.', 'error' => $e->getMessage()]); +} diff --git a/public/userarea/api/api_medical_certificates_list.php b/public/userarea/api/api_medical_certificates_list.php new file mode 100644 index 0000000..ac11a14 --- /dev/null +++ b/public/userarea/api/api_medical_certificates_list.php @@ -0,0 +1,47 @@ +prepare(" + SELECT id, filename, stored_path, document_name, expiry_date, uploaded_at, notes + FROM user_medical_certificates + WHERE user_id = ? + ORDER BY uploaded_at DESC + "); + $stmt->execute([$iduserlogin]); + $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); + + $now = new DateTimeImmutable('now', new DateTimeZone('Europe/Rome')); + + $certs = array_map(function (array $c) use ($now): array { + $expiry = !empty($c['expiry_date']) ? new DateTimeImmutable($c['expiry_date']) : null; + $isExpired = $expiry ? ($expiry < $now->setTime(0, 0)) : false; + + return [ + 'id' => (int)$c['id'], + 'document_name' => (string)($c['document_name'] ?? ''), + 'filename' => (string)($c['filename'] ?? ''), + 'stored_path' => (string)($c['stored_path'] ?? ''), + 'file_url' => '/' . ltrim((string)($c['stored_path'] ?? ''), '/'), + 'uploaded_at' => $c['uploaded_at'], + 'expiry_date' => $c['expiry_date'], + 'is_expired' => $isExpired, + 'notes' => $c['notes'] ?? null, + ]; + }, $rows); + + echo json_encode([ + 'success' => true, + 'count' => count($certs), + 'certificates' => $certs + ], JSON_UNESCAPED_UNICODE); +} catch (Throwable $e) { + http_response_code(500); + echo json_encode(['success' => false, 'message' => 'Server error.', 'error' => $e->getMessage()]); +} diff --git a/public/userarea/api/api_medical_certificates_upload.php b/public/userarea/api/api_medical_certificates_upload.php new file mode 100644 index 0000000..bbb2cc3 --- /dev/null +++ b/public/userarea/api/api_medical_certificates_upload.php @@ -0,0 +1,102 @@ + false, 'message' => 'Method not allowed. Use POST.']); + exit; + } + + if (!isset($_FILES['certificate']) || ($_FILES['certificate']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) { + http_response_code(422); + echo json_encode(['success' => false, 'message' => 'Missing file field: certificate']); + exit; + } + + $file = $_FILES['certificate']; + + $document_name = trim((string)($_POST['document_name'] ?? 'certificato')); + if ($document_name === '') $document_name = 'certificato'; + + $expiry_date = (string)($_POST['expiry_date'] ?? ''); + if ($expiry_date === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $expiry_date)) { + http_response_code(422); + echo json_encode(['success' => false, 'message' => 'expiry_date is required (YYYY-MM-DD)']); + exit; + } + + $notes = trim((string)($_POST['notes'] ?? '')); + + // Allowed extensions + $allowed_ext = ['jpg', 'jpeg', 'png', 'pdf', 'heic', 'heif']; + $ext = strtolower(pathinfo((string)$file['name'], PATHINFO_EXTENSION)); + + if (!in_array($ext, $allowed_ext, true)) { + http_response_code(422); + echo json_encode(['success' => false, 'message' => 'Unsupported format. Allowed: jpg, jpeg, png, pdf, heic, heif']); + exit; + } + + if ((int)$file['size'] > 10 * 1024 * 1024) { + http_response_code(422); + echo json_encode(['success' => false, 'message' => 'File too large (max 10MB)']); + exit; + } + + // Upload dir: ../certificate relative to /public/userarea/api + $upload_dir = realpath(__DIR__ . '/..') . DIRECTORY_SEPARATOR . 'certificate' . DIRECTORY_SEPARATOR; + if (!is_dir($upload_dir)) { + mkdir($upload_dir, 0755, true); + } + + $safe_name = preg_replace('/[^a-zA-Z0-9\._-]/', '_', basename((string)$file['name'])); + $new_filename = $iduserlogin . '-' . time() . '-' . $safe_name; + + $destination = $upload_dir . $new_filename; + + if (!move_uploaded_file((string)$file['tmp_name'], $destination)) { + http_response_code(500); + echo json_encode(['success' => false, 'message' => 'Error saving the file.']); + exit; + } + + $stored_path = 'userarea/certificate/' . $new_filename; + + // OPTIONAL: if you later add school_id column, include it here too. + $stmt = $pdo->prepare(" + INSERT INTO user_medical_certificates + (user_id, filename, stored_path, document_name, expiry_date, notes, uploaded_at) + VALUES (?, ?, ?, ?, ?, ?, NOW()) + "); + + $stmt->execute([ + $iduserlogin, + (string)$file['name'], + $stored_path, + $document_name, + $expiry_date, + $notes + ]); + + $newId = (int)$pdo->lastInsertId(); + + echo json_encode([ + 'success' => true, + 'certificate' => [ + 'id' => $newId, + 'document_name' => $document_name, + 'filename' => (string)$file['name'], + 'stored_path' => $stored_path, + 'file_url' => '/' . $stored_path, + 'expiry_date' => $expiry_date, + 'notes' => $notes !== '' ? $notes : null + ] + ], JSON_UNESCAPED_UNICODE); +} catch (Throwable $e) { + http_response_code(500); + echo json_encode(['success' => false, 'message' => 'Server error.', 'error' => $e->getMessage()]); +}