<?php
/**
* Enrollment related functions
*/
/**
* Generate a unique enrollment number for a student
*
* Format: YEAR-COURSE_CODE-SEQUENTIAL_NUMBER
* Example: 2023-CS101-0001
*
* @param mysqli $conn Database connection
* @param int $course_id Course ID
* @return string Unique enrollment number
*/
function generate_enrollment_number($conn, $course_id) {
// Get current year
$year = date('Y');
// Get course code
$course_code = 'C';
$course_query = "SELECT course_code FROM courses WHERE id = ?";
$stmt = $conn->prepare($course_query);
if ($stmt) {
$stmt->bind_param("i", $course_id);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
$course_code = !empty($row['course_code']) ? $row['course_code'] : 'C' . sprintf('%03d', $course_id);
} else {
$course_code = 'C' . sprintf('%03d', $course_id);
}
$stmt->close();
}
// Get the highest sequential number for this course in the current year
$sequence = 1;
$query = "SELECT enrollment_number FROM enrollments
WHERE enrollment_number LIKE ?
ORDER BY enrollment_number DESC LIMIT 1";
$pattern = $year . '-' . $course_code . '-%';
$stmt = $conn->prepare($query);
if ($stmt) {
$stmt->bind_param("s", $pattern);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
// Extract the sequential number from the last enrollment number
$parts = explode('-', $row['enrollment_number']);
if (count($parts) == 3) {
$sequence = intval($parts[2]) + 1;
}
}
$stmt->close();
}
// Format the enrollment number: YEAR-COURSE_CODE-SEQUENCE
$enrollment_number = sprintf('%s-%s-%04d', $year, $course_code, $sequence);
return $enrollment_number;
}
/**
* Log enrollment details for diagnostic purposes
*
* @param object $conn Database connection
* @param int $enrollment_id Enrollment ID
* @return void
*/
function log_enrollment_details($conn, $enrollment_id) {
try {
$stmt = $conn->prepare("SELECT e.*, c.title as course_title, u.email, u.first_name, u.last_name
FROM enrollments e
JOIN courses c ON e.course_id = c.id
JOIN users u ON e.user_id = u.id
WHERE e.id = ?");
$stmt->bind_param("i", $enrollment_id);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$enrollment = $result->fetch_assoc();
// Format the log message
$log_message = "ENROLLMENT DETAILS - ID: {$enrollment['id']}, " .
"User: {$enrollment['first_name']} {$enrollment['last_name']} (ID: {$enrollment['user_id']}), " .
"Course: {$enrollment['course_title']} (ID: {$enrollment['course_id']}), " .
"Status: {$enrollment['status']}, " .
"Payment Plan: " . ($enrollment['payment_plan'] ?? 'NULL') . ", " .
"Enrollment Number: {$enrollment['enrollment_number']}, " .
"Enrollment Date: {$enrollment['enrollment_date']}";
error_log($log_message);
} else {
error_log("ENROLLMENT DETAILS - No enrollment found with ID: $enrollment_id");
}
} catch (Exception $e) {
error_log("Error logging enrollment details: " . $e->getMessage());
}
}
/**
* Check if a payment plan is valid
*
* @param string $plan Payment plan to validate
* @return bool Whether the plan is valid
*/
function is_valid_payment_plan($plan) {
$valid_plans = ['monthly', 'half_duration', 'quarterly', 'six_month', 'full'];
return in_array($plan, $valid_plans);
}
/**
* Create a new enrollment record with proper validation
*
* @param object $conn Database connection
* @param int $user_id User ID
* @param int $course_id Course ID
* @param string $payment_plan Payment plan ('monthly', 'half_duration', 'full', etc.)
* @param string $verification_token Verification token
* @return int|bool Enrollment ID if successful, false otherwise
*/
function create_enrollment($conn, $user_id, $course_id, $payment_plan, $verification_token = null) {
try {
// Validate payment plan
if (!is_valid_payment_plan($payment_plan)) {
error_log("Invalid payment plan: $payment_plan - Defaulting to 'full'");
$payment_plan = 'full'; // Default to full payment if invalid
}
// Generate verification token if not provided
if ($verification_token === null) {
$verification_token = bin2hex(random_bytes(16));
}
// Generate a unique enrollment number
$enrollment_number = generate_enrollment_number($conn, $course_id);
// Check if enrollment already exists
$check_stmt = $conn->prepare("SELECT id FROM enrollments WHERE user_id = ? AND course_id = ?");
$check_stmt->bind_param("ii", $user_id, $course_id);
$check_stmt->execute();
$check_result = $check_stmt->get_result();
if ($check_result->num_rows > 0) {
// Enrollment already exists, update it
$enrollment = $check_result->fetch_assoc();
$enrollment_id = $enrollment['id'];
$update_stmt = $conn->prepare("UPDATE enrollments SET status = 'active', payment_plan = ? WHERE id = ?");
$update_stmt->bind_param("si", $payment_plan, $enrollment_id);
if ($update_stmt->execute()) {
error_log("Updated existing enrollment #$enrollment_id with payment plan: $payment_plan");
log_enrollment_details($conn, $enrollment_id);
return $enrollment_id;
} else {
error_log("Failed to update enrollment: " . $update_stmt->error);
return false;
}
} else {
// Create a new enrollment
$insert_stmt = $conn->prepare("INSERT INTO enrollments (user_id, course_id, status, verification_token, payment_plan, enrollment_number)
VALUES (?, ?, 'active', ?, ?, ?)");
$insert_stmt->bind_param("iisss", $user_id, $course_id, $verification_token, $payment_plan, $enrollment_number);
if ($insert_stmt->execute()) {
$enrollment_id = $conn->insert_id;
error_log("Created new enrollment #$enrollment_id with payment plan: $payment_plan");
log_enrollment_details($conn, $enrollment_id);
return $enrollment_id;
} else {
error_log("Failed to create enrollment: " . $insert_stmt->error);
return false;
}
}
} catch (Exception $e) {
error_log("Error in create_enrollment function: " . $e->getMessage());
return false;
}
}