<?php
session_start();
require_once 'database/db_config.php';
// Check if token is provided in URL for direct verification
if (isset($_GET['token']) && !empty($_GET['token'])) {
$token = trim($_GET['token']);
processVerificationToken($token, $conn);
exit; // Stop execution after processing the token
}
// Check if admin is logged in for the admin interface
if (!isset($_SESSION['role']) || ($_SESSION['role'] !== 'admin' && $_SESSION['role'] !== 'director')) {
header("Location: login.php");
exit;
}
// Process verification token search
$token_search_result = null;
$verification_success = false;
$verification_error = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['search_token'])) {
$token = trim($_POST['verification_token']);
if (empty($token)) {
$verification_error = "Please enter a verification token.";
} else {
// Search for the token in enrollments
$query = "
SELECT e.*,
u.first_name, u.last_name, u.email,
c.title as course_title, c.price, c.discount_price
FROM enrollments e
JOIN users u ON e.user_id = u.id
JOIN courses c ON e.course_id = c.id
WHERE e.verification_token = ?
";
$stmt = $conn->prepare($query);
$stmt->bind_param("s", $token);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
// If not found in enrollments, check applications
$app_query = "
SELECT ea.*,
u.first_name, u.last_name, u.email,
c.title as course_title, c.price, c.discount_price
FROM enrollment_applications ea
JOIN users u ON ea.user_id = u.id
JOIN courses c ON ea.course_id = c.id
WHERE ea.verification_token = ?
";
$stmt = $conn->prepare($app_query);
$stmt->bind_param("s", $token);
$stmt->execute();
$app_result = $stmt->get_result();
if ($app_result->num_rows === 0) {
$verification_error = "Invalid verification token or enrollment not found.";
} else {
$token_search_result = $app_result->fetch_assoc();
$token_search_result['source'] = 'application';
}
} else {
$token_search_result = $result->fetch_assoc();
$token_search_result['source'] = 'enrollment';
}
}
}
// Process verification action
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['verify_enrollment'])) {
$enrollment_id = intval($_POST['enrollment_id'] ?? 0);
$application_id = intval($_POST['application_id'] ?? 0);
$user_id = intval($_POST['user_id']);
$course_id = intval($_POST['course_id']);
$admin_notes = trim($_POST['admin_notes'] ?? '');
$source = $_POST['source'] ?? '';
// Begin transaction
$conn->begin_transaction();
try {
if ($source === 'application') {
// Update application as verified
$update_query = "
UPDATE enrollment_applications
SET status = 'completed', updated_at = NOW(), admin_notes = ?
WHERE id = ? AND user_id = ? AND course_id = ?
";
$stmt = $conn->prepare($update_query);
$stmt->bind_param("siii", $admin_notes, $application_id, $user_id, $course_id);
$stmt->execute();
// Check if enrollment already exists
$check_query = "SELECT id FROM enrollments WHERE user_id = ? AND course_id = ?";
$stmt = $conn->prepare($check_query);
$stmt->bind_param("ii", $user_id, $course_id);
$stmt->execute();
$check_result = $stmt->get_result();
if ($check_result->num_rows === 0) {
// Create enrollment record
$verification_token = bin2hex(random_bytes(16));
$enroll_query = "
INSERT INTO enrollments (user_id, course_id, enrollment_date, status, verification_token)
VALUES (?, ?, NOW(), 'active', ?)
";
$stmt = $conn->prepare($enroll_query);
$stmt->bind_param("iis", $user_id, $course_id, $verification_token);
$stmt->execute();
} else {
// Update existing enrollment to active
$stmt = $conn->prepare("UPDATE enrollments SET status = 'active' WHERE user_id = ? AND course_id = ?");
$stmt->bind_param("ii", $user_id, $course_id);
$stmt->execute();
}
} else if ($source === 'enrollment') {
// Update enrollment to active
$update_query = "
UPDATE enrollments
SET status = 'active'
WHERE id = ? AND user_id = ? AND course_id = ?
";
$stmt = $conn->prepare($update_query);
$stmt->bind_param("iii", $enrollment_id, $user_id, $course_id);
$stmt->execute();
// Update any associated applications
$stmt = $conn->prepare("UPDATE enrollment_applications SET status = 'completed', updated_at = NOW() WHERE user_id = ? AND course_id = ? AND status IN ('pending', 'payment_pending')");
$stmt->bind_param("ii", $user_id, $course_id);
$stmt->execute();
}
// Log activity
$log_query = "
INSERT INTO activities (user_id, user_type, activity_type, activity_description, created_at)
VALUES (?, 'admin', 'enrollment_verification', ?, NOW())
";
$admin_id = $_SESSION['user_id'];
$activity_description = "Verified enrollment for user #" . $user_id . " in course #" . $course_id;
$stmt = $conn->prepare($log_query);
$stmt->bind_param("is", $admin_id, $activity_description);
if (!$stmt->execute() && $conn->errno != 1146) { // Ignore error if activities table doesn't exist
// Just log to error log
error_log("Failed to log activity: " . $conn->error);
}
// Send confirmation email if email functions are available
if (file_exists('../includes/email_functions.php')) {
require_once '../includes/email_functions.php';
if (function_exists('send_enrollment_verification_email')) {
$email = $_POST['email'] ?? '';
$first_name = $_POST['first_name'] ?? '';
$course_title = $_POST['course_title'] ?? '';
if (!empty($email) && !empty($first_name) && !empty($course_title)) {
send_enrollment_verification_email(
$email,
$first_name,
$course_title
);
}
}
}
// Commit transaction
$conn->commit();
$verification_success = "Enrollment successfully verified. Student has been enrolled in the course.";
$token_search_result = null; // Clear search result
} catch (Exception $e) {
// Rollback transaction on error
$conn->rollback();
$verification_error = "Error verifying enrollment: " . $e->getMessage();
}
}
// Get recent verifications
$recent_verifications_query = "
SELECT e.id, e.verification_token, e.enrollment_date,
CONCAT(u.first_name, ' ', u.last_name) as user_name,
c.title as course_title
FROM enrollments e
JOIN users u ON e.user_id = u.id
JOIN courses c ON e.course_id = c.id
WHERE e.status = 'active'
ORDER BY e.enrollment_date DESC
LIMIT 10
";
$recent_verifications_result = $conn->query($recent_verifications_query);
// Get pending verifications count
$pending_count_query = "
SELECT COUNT(*) as count
FROM enrollments
WHERE status = 'pending'
";
$pending_count_result = $conn->query($pending_count_query);
$pending_count = $pending_count_result->fetch_assoc()['count'] ?? 0;
include 'includes/header.php';
// include 'includes/sidebar.php';
/**
* Function to process a verification token from URL
*/
function processVerificationToken($token, $conn) {
// Check if token exists in database
$query = "SELECT e.*, u.first_name, u.last_name, u.email, c.title as course_title
FROM enrollments e
JOIN users u ON e.user_id = u.id
JOIN courses c ON e.course_id = c.id
WHERE e.verification_token = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("s", $token);
$stmt->execute();
$result = $stmt->get_result();
$success = false;
$message = '';
$enrollment_data = null;
if ($result && $result->num_rows > 0) {
$enrollment_data = $result->fetch_assoc();
// Check if already verified
if ($enrollment_data['status'] === 'active') {
$success = true;
$message = 'This enrollment has already been verified.';
} else {
// Update enrollment status to active
$update_query = "UPDATE enrollments SET status = 'active' WHERE verification_token = ?";
$stmt = $conn->prepare($update_query);
$stmt->bind_param("s", $token);
if ($stmt->execute()) {
$success = true;
$message = 'Enrollment verified successfully!';
// Update any associated applications
$app_update_query = "UPDATE enrollment_applications
SET status = 'completed'
WHERE user_id = ? AND course_id = ? AND status IN ('pending', 'payment_pending')";
$stmt = $conn->prepare($app_update_query);
$stmt->bind_param("ii", $enrollment_data['user_id'], $enrollment_data['course_id']);
$stmt->execute();
// Send confirmation email if email functions are available
if (file_exists('../includes/email_functions.php')) {
require_once '../includes/email_functions.php';
if (function_exists('send_enrollment_verification_email')) {
send_enrollment_verification_email(
$enrollment_data['email'],
$enrollment_data['first_name'],
$enrollment_data['course_title']
);
}
}
} else {
$message = 'Error updating enrollment status. Please try again or contact support.';
}
}
} else {
$message = 'Invalid verification token. Please check the link and try again.';
}
// Set page title based on success
$page_title = $success ? 'Enrollment Verified' : 'Verification Failed';
// Output verification page
echo '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>' . $page_title . '</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="css/styles.css" rel="stylesheet">
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="row justify-content-center mt-5">
<div class="col-md-8">
<div class="card shadow">
<div class="card-header bg-' . ($success ? 'success' : 'danger') . ' text-white">
<h4 class="mb-0">' . $page_title . '</h4>
</div>
<div class="card-body text-center">
<div class="mb-4">
<i class="fas fa-' . ($success ? 'check-circle' : 'exclamation-circle') . ' fa-5x text-' . ($success ? 'success' : 'danger') . '"></i>
</div>
<h5 class="card-title">' . $message . '</h5>';
if ($success && $enrollment_data) {
echo '<div class="alert alert-info mt-4">
<h6>Enrollment Details:</h6>
<p><strong>Student:</strong> ' . htmlspecialchars($enrollment_data['first_name'] . ' ' . $enrollment_data['last_name']) . '</p>
<p><strong>Course:</strong> ' . htmlspecialchars($enrollment_data['course_title']) . '</p>
<p><strong>Enrollment Date:</strong> ' . date('M d, Y', strtotime($enrollment_data['enrollment_date'] ?? 'now')) . '</p>
</div>';
}
echo '<div class="mt-4">
<a href="../index.php" class="btn btn-primary">Go to Homepage</a>';
if (!$success) {
echo '<a href="../contact.php" class="btn btn-outline-secondary ms-2">Contact Support</a>';
}
echo '</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>';
}
?>
<!-- Content Wrapper -->
<div id="content-wrapper" class="d-flex flex-column">
<!-- Main Content -->
<div id="content">
<!-- Begin Page Content -->
<div class="container-fluid">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Verify Student Enrollment</h1>
</div>
<?php if ($verification_success): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="fas fa-check-circle mr-2"></i> <?php echo $verification_success; ?>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<?php endif; ?>
<?php if ($verification_error): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<i class="fas fa-exclamation-circle mr-2"></i> <?php echo $verification_error; ?>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<?php endif; ?>
<div class="row">
<div class="col-xl-4 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
Pending Verifications</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $pending_count; ?></div>
</div>
<div class="col-auto">
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Verification Token Search</h6>
</div>
<div class="card-body">
<form method="post" action="" class="mb-4">
<div class="input-group">
<input type="text" class="form-control" name="verification_token" placeholder="Enter verification token..." aria-label="Verification Token" required>
<div class="input-group-append">
<button class="btn btn-primary" type="submit" name="search_token">
<i class="fas fa-search fa-sm"></i> Search
</button>
</div>
</div>
<small class="form-text text-muted">Enter the verification token provided by the student or from the enrollment email.</small>
</form>
<?php if ($token_search_result): ?>
<div class="verification-result">
<div class="alert alert-info">
<i class="fas fa-info-circle mr-2"></i>
<?php if ($token_search_result['source'] === 'enrollment'): ?>
Enrollment record found! Please review the details below.
<?php else: ?>
Enrollment application found! Please review the details below.
<?php endif; ?>
</div>
<div class="card mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">
<?php echo $token_search_result['source'] === 'enrollment' ? 'Enrollment Details' : 'Application Details'; ?>
</h6>
<span class="badge badge-<?php
if ($token_search_result['source'] === 'enrollment') {
echo $token_search_result['status'] === 'active' ? 'success' : 'warning';
} else {
echo $token_search_result['status'] === 'completed' ? 'success' :
($token_search_result['status'] === 'rejected' ? 'danger' : 'warning');
}
?>">
<?php echo ucfirst($token_search_result['status']); ?>
</span>
</div>
<div class="card-body">
<?php if (
($token_search_result['source'] === 'enrollment' && $token_search_result['status'] === 'active') ||
($token_search_result['source'] === 'application' && $token_search_result['status'] === 'completed')
): ?>
<div class="alert alert-success">
<i class="fas fa-check-circle mr-2"></i> This
<?php echo $token_search_result['source'] === 'enrollment' ? 'enrollment' : 'application'; ?>
has already been verified.
</div>
<?php else: ?>
<form method="post" action="">
<input type="hidden" name="source" value="<?php echo $token_search_result['source']; ?>">
<?php if ($token_search_result['source'] === 'enrollment'): ?>
<input type="hidden" name="enrollment_id" value="<?php echo $token_search_result['id']; ?>">
<?php else: ?>
<input type="hidden" name="application_id" value="<?php echo $token_search_result['id']; ?>">
<?php endif; ?>
<input type="hidden" name="user_id" value="<?php echo $token_search_result['user_id']; ?>">
<input type="hidden" name="course_id" value="<?php echo $token_search_result['course_id']; ?>">
<input type="hidden" name="email" value="<?php echo $token_search_result['email']; ?>">
<input type="hidden" name="first_name" value="<?php echo $token_search_result['first_name']; ?>">
<input type="hidden" name="course_title" value="<?php echo $token_search_result['course_title']; ?>">
<div class="row">
<div class="col-md-6">
<h5 class="mb-3">Student Information</h5>
<table class="table table-borderless">
<tr>
<td><strong>Name:</strong></td>
<td><?php echo htmlspecialchars($token_search_result['first_name'] . ' ' . $token_search_result['last_name']); ?></td>
</tr>
<tr>
<td><strong>Email:</strong></td>
<td><?php echo htmlspecialchars($token_search_result['email']); ?></td>
</tr>
</table>
</div>
<div class="col-md-6">
<h5 class="mb-3">Course Information</h5>
<table class="table table-borderless">
<tr>
<td><strong>Course:</strong></td>
<td><?php echo htmlspecialchars($token_search_result['course_title']); ?></td>
</tr>
<tr>
<td><strong>Price:</strong></td>
<td>
<?php
$price = $token_search_result['discount_price'] > 0 ? $token_search_result['discount_price'] : $token_search_result['price'];
echo '₹' . number_format($price, 2);
?>
</td>
</tr>
</table>
</div>
</div>
<div class="form-group mt-3">
<label for="admin_notes">Admin Notes (Optional):</label>
<textarea class="form-control" id="admin_notes" name="admin_notes" rows="3"></textarea>
</div>
<div class="text-center mt-4">
<button type="submit" name="verify_enrollment" class="btn btn-success">
<i class="fas fa-check-circle mr-2"></i> Verify Enrollment
</button>
</div>
</form>
<?php endif; ?>
</div>
</div>
</div>
<?php endif; ?>
<div class="mt-4">
<h5 class="mb-3">Recent Verifications</h5>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Student</th>
<th>Course</th>
<th>Verification Date</th>
<th>Token</th>
</tr>
</thead>
<tbody>
<?php if ($recent_verifications_result && $recent_verifications_result->num_rows > 0): ?>
<?php while ($verification = $recent_verifications_result->fetch_assoc()): ?>
<tr>
<td><?php echo htmlspecialchars($verification['user_name']); ?></td>
<td><?php echo htmlspecialchars($verification['course_title']); ?></td>
<td>
<?php echo date("M d, Y g:i A", strtotime($verification["enrollment_date"])); ?>
</td>
<td>
<span class="text-monospace"><?php echo substr($verification['verification_token'], 0, 8) . '...'; ?></span>
<button class="btn btn-sm btn-outline-secondary copy-token" data-token="<?php echo $verification['verification_token']; ?>">
<i class="fas fa-copy"></i>
</button>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="4" class="text-center">No recent verifications found.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /.container-fluid -->
</div>
<!-- End of Main Content -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// Copy token to clipboard
document.querySelectorAll('.copy-token').forEach(function(btn) {
btn.addEventListener('click', function() {
const token = this.getAttribute('data-token');
navigator.clipboard.writeText(token).then(function() {
alert('Token copied to clipboard!');
}, function() {
alert('Failed to copy token. Please try again.');
});
});
});
});
</script>
<?php
include 'includes/footer.php';
?>