<?php
// Start output buffering to prevent headers already sent error
ob_start();
$pageTitle = "My Certificates";
include_once('includes/header.php');
require_once('../includes/certificate_lib.php');
// Check if session is already started before starting a new one
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Check if student is logged in
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'student') {
header("Location: ../login.php");
exit();
}
$userId = $_SESSION['user_id'];
$success_message = '';
$error_message = '';
// Initialize the certificate generator
$certificateGenerator = new CertificateGenerator();
// Handle flash messages
if (isset($_SESSION['success_message'])) {
$success_message = $_SESSION['success_message'];
unset($_SESSION['success_message']);
}
if (isset($_SESSION['error_message'])) {
$error_message = $_SESSION['error_message'];
unset($_SESSION['error_message']);
}
// Function to get institute settings
function getInstituteSettings($conn) {
$settings = [
'institute_name' => "Popular Computer Institute",
'institute_logo' => "../assets/img/logo.png",
'institute_address' => "Bhimpura No.1,Ballia,UP",
'institute_website' => "www.example.com",
'director_name' => "John Smith",
];
$query = "SELECT setting_key, setting_value FROM site_settings
WHERE setting_key IN ('site_name', 'site_logo', 'site_address',
'site_url', 'director_name')";
$result = $conn->query($query);
if ($result && $result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$settings[$row['setting_key']] = $row['setting_value'];
}
}
return $settings;
}
// Function to get certificates
function getStudentCertificates($conn, $userId) {
$certificates = [];
$query = "SELECT e.id as enrollment_id, e.completion_date, e.certificate_number,
e.certificate_issue_date, e.status as enrollment_status, e.verification_code,
e.certificate_data, e.certificate_meta,
c.id as course_id, c.title as course_title, c.image as course_image,
c.duration, c.level, c.status as course_status,
CASE
WHEN e.status = 'completed' THEN 1
WHEN c.status = 'completed' THEN 1
ELSE 0
END as is_completed
FROM enrollments e
INNER JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ? AND (e.status = 'completed' OR c.status = 'completed')
ORDER BY e.completion_date DESC";
$stmt = $conn->prepare($query);
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$certificates[] = $row;
}
return $certificates;
}
// Function to get student details
function getStudentDetails($conn, $userId) {
$student = null;
$query = "SELECT first_name, last_name, email FROM users WHERE id = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
if ($result && $result->num_rows > 0) {
$student = $result->fetch_assoc();
}
return $student;
}
// Generate a verification code
function generateVerificationCode() {
global $certificateGenerator;
// Use the certificate generator if available
if (isset($certificateGenerator) && $certificateGenerator !== null) {
return $certificateGenerator->generateVerificationCode();
}
// Fallback to a simple verification code generator
return strtoupper(substr(md5(uniqid(rand(), true)), 0, 8));
}
// Update the getStudentCertificates function to check for completed courses without certificates
function getCompletedCoursesWithoutCertificates($conn, $userId) {
$courses = [];
$query = "SELECT e.id as enrollment_id, e.completion_date, e.status as enrollment_status,
c.id as course_id, c.title as course_title, c.image as course_image,
c.duration, c.level, c.status as course_status,
CASE
WHEN e.status = 'completed' THEN 1
WHEN c.status = 'completed' THEN 1
ELSE 0
END as is_completed
FROM enrollments e
INNER JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ?
AND (e.status = 'completed' OR c.status = 'completed')
AND e.certificate_number IS NULL
ORDER BY e.completion_date DESC";
$stmt = $conn->prepare($query);
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$courses[] = $row;
}
return $courses;
}
// Function to get exam certificates
function getStudentExamCertificates($conn, $userId) {
$certificates = [];
try {
$query = "SELECT ec.*, se.percentage, se.status as exam_status,
es.title as exam_title, c.title as course_title, c.image as course_image,
CONCAT(u.first_name, ' ', u.last_name) as student_name
FROM exam_certificates ec
JOIN student_exams se ON ec.student_exam_id = se.id
JOIN exam_schedules es ON se.exam_id = es.id
JOIN courses c ON es.course_id = c.id
JOIN users u ON se.user_id = u.id
WHERE se.user_id = ?
ORDER BY ec.issue_date DESC";
$stmt = $conn->prepare($query);
if ($stmt === false) {
error_log("Prepare failed: " . $conn->error);
return $certificates;
}
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$row['certificate_type'] = 'exam';
$certificates[] = $row;
}
} catch (Exception $e) {
error_log("Error fetching exam certificates: " . $e->getMessage());
}
return $certificates;
}
// Function to get passed exams without certificates
function getPassedExamsWithoutCertificates($conn, $userId) {
$exams = [];
try {
$query = "SELECT se.id as student_exam_id, se.exam_id, se.percentage, se.status,
es.title as exam_title, c.id as course_id, c.title as course_title, c.image as course_image
FROM student_exams se
JOIN exam_schedules es ON se.exam_id = es.id
JOIN courses c ON es.course_id = c.id
WHERE se.user_id = ? AND se.status = 'passed'
AND NOT EXISTS (SELECT 1 FROM exam_certificates ec WHERE ec.student_exam_id = se.id)
ORDER BY se.completion_date DESC";
$stmt = $conn->prepare($query);
if ($stmt === false) {
error_log("Prepare failed: " . $conn->error);
return $exams;
}
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$exams[] = $row;
}
} catch (Exception $e) {
error_log("Error fetching passed exams: " . $e->getMessage());
}
return $exams;
}
// Function to determine grade based on percentage
function calculateGrade($percentage) {
if ($percentage >= 90) {
return ['grade' => 'A+', 'description' => 'Outstanding', 'color' => '#28a745'];
} elseif ($percentage >= 80) {
return ['grade' => 'A', 'description' => 'Excellent', 'color' => '#28a745'];
} elseif ($percentage >= 70) {
return ['grade' => 'B+', 'description' => 'Very Good', 'color' => '#17a2b8'];
} elseif ($percentage >= 60) {
return ['grade' => 'B', 'description' => 'Good', 'color' => '#17a2b8'];
} elseif ($percentage >= 50) {
return ['grade' => 'C', 'description' => 'Average', 'color' => '#6c757d'];
} elseif ($percentage >= 40) {
return ['grade' => 'D', 'description' => 'Pass', 'color' => '#ffc107'];
} else {
return ['grade' => 'F', 'description' => 'Fail', 'color' => '#dc3545'];
}
}
// Get institute settings
$institute_settings = getInstituteSettings($conn);
$institute_name = $institute_settings['site_name'] ?? 'Popular Computer Institute';
$institute_logo = '../'. $institute_settings['site_logo'] ?? '/assets/img/logo.png';
$institute_address = $institute_settings['site_address'] ?? 'Institute Address';
$director_name = $institute_settings['director_name'] ?? 'Institute Director';
// Get certificates data
$course_certificates = getStudentCertificates($conn, $userId);
$exam_certificates = getStudentExamCertificates($conn, $userId);
$student = getStudentDetails($conn, $userId);
// Get completed courses and passed exams without certificates
$pending_course_certificates = getCompletedCoursesWithoutCertificates($conn, $userId);
$pending_exam_certificates = getPassedExamsWithoutCertificates($conn, $userId);
// Combine all certificates for display
$all_certificates = array_merge($course_certificates, $exam_certificates);
usort($all_certificates, function($a, $b) {
$a_date = $a['certificate_issue_date'] ?? $a['completion_date'] ?? date('Y-m-d');
$b_date = $b['certificate_issue_date'] ?? $b['completion_date'] ?? date('Y-m-d');
return strtotime($b_date) - strtotime($a_date); // Sort by date descending
});
// Calculate statistics
$total_certificates = count($all_certificates);
$course_certified_count = 0;
$exam_certified_count = 0;
$pending_course_count = count($pending_course_certificates);
$pending_exam_count = count($pending_exam_certificates);
$recent_count = 0;
foreach ($course_certificates as $cert) {
if (!empty($cert['certificate_number'])) {
$course_certified_count++;
// Count certificates issued in the last 30 days
if (!empty($cert['certificate_issue_date']) && (strtotime($cert['certificate_issue_date']) > strtotime('-30 days'))) {
$recent_count++;
}
}
}
foreach ($exam_certificates as $cert) {
$exam_certified_count++;
// Count certificates issued in the last 30 days
if (!empty($cert['issue_date']) && (strtotime($cert['issue_date']) > strtotime('-30 days'))) {
$recent_count++;
}
}
// Request certificate generation for course
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['generate_certificate'])) {
$enrollment_id = $_POST['enrollment_id'] ?? 0;
if ($enrollment_id > 0) {
// Validate the enrollment ID belongs to the current user
$validate_query = "SELECT e.id, e.status, e.course_id, c.title AS course_title,
CONCAT(u.first_name, ' ', u.last_name) AS student_name,
u.email AS student_email
FROM enrollments e
INNER JOIN courses c ON e.course_id = c.id
INNER JOIN users u ON e.user_id = u.id
WHERE e.id = ? AND e.user_id = ? AND (e.status = 'completed' OR c.status = 'completed')";
$stmt = $conn->prepare($validate_query);
$stmt->bind_param("ii", $enrollment_id, $userId);
$stmt->execute();
$result = $stmt->get_result();
if ($result && $result->num_rows > 0) {
$enrollment = $result->fetch_assoc();
// Generate a unique certificate number
$certificate_number = 'PCIB-' . date('Ymd') . '-' . sprintf('%04d', $enrollment_id);
// Generate a verification code
$verification_code = generateVerificationCode();
// Generate certificate meta data (JSON)
$certificate_meta = json_encode([
'student_name' => $enrollment['student_name'],
'student_email' => $enrollment['student_email'],
'course_title' => $enrollment['course_title'],
'certificate_number' => $certificate_number,
'verification_code' => $verification_code,
'issue_date' => date('Y-m-d H:i:s'),
'institute_name' => $institute_name,
'director_name' => $director_name
]);
// Generate certificate HTML
$certificate_html = '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Certificate of Achievement - ' . htmlspecialchars($enrollment['student_name']) . '</title>
<style>
@import url(\'https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Montserrat:wght@300;400;600;700&display=swap\');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: \'Montserrat\', sans-serif;
background-color: #f8f9fa;
color: #212529;
line-height: 1.6;
}
.certificate-container {
width: 100%;
height: 100%;
position: relative;
margin: 0 auto;
background: #fff;
box-shadow: 0 0 25px rgba(0,0,0,0.1);
overflow: hidden;
}
.background-pattern {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(#f0f4f8 20%, transparent 20%),
radial-gradient(#f0f4f8 20%, transparent 20%);
background-position: 0 0, 10px 10px;
background-size: 20px 20px;
opacity: 0.4;
z-index: 0;
}
.border-frame {
position: absolute;
top: 20px;
left: 20px;
right: 20px;
bottom: 20px;
border: 2px solid #1a5276;
z-index: 1;
}
.inner-frame {
position: absolute;
top: 25px;
left: 25px;
right: 25px;
bottom: 25px;
border: 1px solid #d4af37;
z-index: 1;
}
.content {
position: relative;
z-index: 2;
height: 100%;
padding: 40px;
display: flex;
flex-direction: column;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20px;
border-bottom: 1px solid #d4af37;
margin-bottom: 40px;
}
.institution-logo {
max-width: 120px;
}
.govt-logos {
display: flex;
justify-content: flex-end;
gap: 15px;
}
.govt-logo {
height: 40px;
width: auto;
}
.certificate-title {
text-align: center;
margin-bottom: 30px;
}
.certificate-title h1 {
font-family: \'Playfair Display\', serif;
font-size: 48px;
color: #1a5276;
margin-bottom: 10px;
letter-spacing: 2px;
}
.certificate-title p {
font-size: 18px;
color: #7d6608;
text-transform: uppercase;
letter-spacing: 3px;
}
.recipient-section {
text-align: center;
margin-bottom: 40px;
}
.recipient-intro {
font-size: 16px;
font-style: italic;
margin-bottom: 15px;
}
.recipient-name {
font-family: \'Playfair Display\', serif;
font-size: 42px;
color: #d4af37;
margin-bottom: 20px;
}
.achievement-text {
font-size: 18px;
margin-bottom: 10px;
}
.course-name {
font-family: \'Playfair Display\', serif;
font-size: 28px;
color: #1a5276;
font-weight: bold;
max-width: 80%;
margin: 0 auto 40px;
line-height: 1.3;
}
.certificate-footer {
margin-top: auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
}
.left-footer {
display: flex;
flex-direction: column;
}
.right-footer {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.signature-area {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 30px;
}
.signature-line {
width: 200px;
border-bottom: 1px solid #000;
margin-bottom: 10px;
}
.signatory-name {
font-weight: bold;
font-size: 16px;
}
.signatory-title {
font-size: 14px;
color: #555;
}
.certificate-date {
font-size: 16px;
margin-top: 10px;
}
.certificate-details {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.detail-item {
font-size: 14px;
color: #555;
margin-bottom: 5px;
}
.qr-verification {
display: flex;
flex-direction: column;
align-items: center;
}
.qr-code {
width: 80px;
height: 80px;
margin-bottom: 5px;
}
.verification-text {
font-size: 12px;
color: #555;
text-align: center;
}
.decorative-corner {
position: absolute;
width: 70px;
height: 70px;
z-index: 2;
}
.top-left {
top: 30px;
left: 30px;
border-top: 3px solid #d4af37;
border-left: 3px solid #d4af37;
}
.top-right {
top: 30px;
right: 30px;
border-top: 3px solid #d4af37;
border-right: 3px solid #d4af37;
}
.bottom-left {
bottom: 30px;
left: 30px;
border-bottom: 3px solid #d4af37;
border-left: 3px solid #d4af37;
}
.bottom-right {
bottom: 30px;
right: 30px;
border-bottom: 3px solid #d4af37;
border-right: 3px solid #d4af37;
}
.watermark {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0.03;
z-index: 1;
width: 80%;
}
@media print {
body {
background-color: #fff;
}
.certificate-container {
box-shadow: none;
margin: 0;
width: 100%;
height: 100%;
page-break-inside: avoid;
}
.print-actions {
display: none;
}
}
@media screen {
.print-actions {
display: flex;
justify-content: center;
gap: 10px;
margin: 20px 0;
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 100;
}
.print-btn {
background-color: #1a5276;
color: white;
border: none;
padding: 12px 24px;
border-radius: 4px;
cursor: pointer;
font-family: \'Montserrat\', sans-serif;
font-weight: 600;
transition: background-color 0.3s;
display: flex;
align-items: center;
gap: 8px;
}
.print-btn:hover {
background-color: #154360;
}
.download-btn {
background-color: #d4af37;
color: white;
border: none;
padding: 12px 24px;
border-radius: 4px;
cursor: pointer;
font-family: \'Montserrat\', sans-serif;
font-weight: 600;
transition: background-color 0.3s;
display: flex;
align-items: center;
gap: 8px;
}
.download-btn:hover {
background-color: #b7950b;
}
}
</style>
</head>
<body>
<div class="certificate-container">
<div class="background-pattern"></div>
<div class="border-frame"></div>
<div class="inner-frame"></div>
<div class="decorative-corner top-left"></div>
<div class="decorative-corner top-right"></div>
<div class="decorative-corner bottom-left"></div>
<div class="decorative-corner bottom-right"></div>
<img src="' . $institute_logo . '" alt="Watermark" class="watermark">
<div class="content">
<div class="header">
<img src="' . $institute_logo . '" alt="' . htmlspecialchars($institute_name) . '" class="institution-logo">
<div class="govt-logos">
<img src="../assets/img/nielit-logo.png" alt="NIELIT" class="govt-logo">
<img src="../assets/img/skill-india-logo.png" alt="Skill India" class="govt-logo">
<img src="../assets/img/digital-india-logo.png" alt="Digital India" class="govt-logo">
</div>
</div>
<div class="certificate-title">
<h1>Certificate of Achievement</h1>
<p>Recognition of Excellence</p>
</div>
<div class="recipient-section">
<div class="recipient-intro">This is to certify that</div>
<div class="recipient-name">' . htmlspecialchars($enrollment['student_name']) . '</div>
<div class="achievement-text">has successfully completed the course</div>
<div class="course-name">' . htmlspecialchars($enrollment['course_title']) . '</div>
</div>
<div class="certificate-footer">
<div class="left-footer">
<div class="signature-area">
<div class="signature-line"></div>
<div class="signatory-name">' . htmlspecialchars($director_name) . '</div>
<div class="signatory-title">Director, ' . htmlspecialchars($institute_name) . '</div>
</div>
<div class="certificate-date">Issued on: ' . date('F d, Y') . '</div>
</div>
<div class="right-footer">
<div class="certificate-details">
<div class="detail-item"><strong>Certificate ID:</strong> ' . $certificate_number . '</div>
<div class="detail-item"><strong>Verification Code:</strong> ' . $verification_code . '</div>
<div class="detail-item"><strong>Valid Until:</strong> Lifetime</div>
</div>
<div class="qr-verification">
<img src="https://api.qrserver.com/v1/create-qr-code/?size=80x80&data=' . urlencode('https://' . $_SERVER['HTTP_HOST'] . '/verify.php?code=' . $verification_code) . '" alt="Verify" class="qr-code">
<div class="verification-text">Scan to verify authenticity</div>
</div>
</div>
</div>
</div>
</div>
<div class="print-actions">
<button class="print-btn" onclick="window.print()">
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M5 1a2 2 0 0 0-2 2v1h10V3a2 2 0 0 0-2-2H5zm6 8H5a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1z"/>
<path d="M0 7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-1v-2a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v2H2a2 2 0 0 1-2-2V7zm2.5 1a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1z"/>
</svg>
Print Certificate
</button>
<button class="download-btn" onclick="downloadPDF()">
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
<path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
</svg>
Download PDF
</button>
</div>
<script>
function downloadPDF() {
// Create a form and submit it to the PDF generation endpoint
var form = document.createElement("form");
form.method = "POST";
form.action = "ajax/download_certificate_pdf.php";
form.target = "_blank";
var input = document.createElement("input");
input.type = "hidden";
input.name = "certificate_number";
input.value = "' . $certificate_number . '";
form.appendChild(input);
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
</script>
</body>
</html>';
// Update the enrollment record
$update_query = "UPDATE enrollments SET
certificate_number = ?,
certificate_data = ?,
certificate_meta = ?,
certificate_issue_date = NOW(),
verification_code = ?
WHERE id = ?";
$stmt = $conn->prepare($update_query);
$stmt->bind_param("ssssi", $certificate_number, $certificate_html, $certificate_meta, $verification_code, $enrollment_id);
if ($stmt->execute()) {
$success_message = "Certificate generated successfully!";
// Set a session variable to track the certificate
$_SESSION['last_certificate'] = $certificate_number;
// Redirect to view certificate
header("Location: view_certificate.php?number=" . $certificate_number);
exit();
} else {
$error_message = "Error updating certificate information: " . $conn->error;
}
} else {
$error_message = "Invalid enrollment or course not completed.";
}
} else {
$error_message = "Invalid enrollment ID.";
}
}
// Handle exam certificate generation
if (($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['generate_exam_certificate'])) ||
(isset($_GET['exam_id']) && is_numeric($_GET['exam_id']))) {
$exam_id = isset($_POST['exam_id']) ? intval($_POST['exam_id']) : intval($_GET['exam_id']);
// Check if the exam exists and the student has passed it
$exam_query = "SELECT se.*, e.title AS exam_title, c.title AS course_title, c.id AS course_id,
e.passing_percentage, c.duration AS course_duration, c.level AS course_level
FROM student_exams se
JOIN exam_schedules e ON se.exam_id = e.id
JOIN courses c ON e.course_id = c.id
WHERE se.exam_id = ? AND se.user_id = ? AND se.status = 'passed'";
$stmt = $conn->prepare($exam_query);
$stmt->bind_param("ii", $exam_id, $userId);
$stmt->execute();
$exam_result = $stmt->get_result();
if ($exam_result->num_rows > 0) {
$exam_data = $exam_result->fetch_assoc();
// Check for course completion
$course_query = "SELECT * FROM enrollments WHERE user_id = ? AND course_id = ? AND status = 'completed'";
$course_stmt = $conn->prepare($course_query);
$course_stmt->bind_param("ii", $userId, $exam_data['course_id']);
$course_stmt->execute();
$course_result = $course_stmt->get_result();
// If course is not completed yet, update it to completed
if ($course_result->num_rows == 0) {
$update_course = "UPDATE enrollments SET status = 'completed', completion_date = NOW()
WHERE user_id = ? AND course_id = ?";
$update_stmt = $conn->prepare($update_course);
$update_stmt->bind_param("ii", $userId, $exam_data['course_id']);
$update_stmt->execute();
// Re-fetch the course data
$course_stmt->execute();
$course_result = $course_stmt->get_result();
}
$course_data = $course_result->fetch_assoc();
// Check if a certificate already exists for this exam
$cert_check_query = "SELECT * FROM exam_certificates WHERE student_exam_id = ?";
$cert_stmt = $conn->prepare($cert_check_query);
$cert_stmt->bind_param("i", $exam_data['id']);
$cert_stmt->execute();
$cert_result = $cert_stmt->get_result();
if ($cert_result->num_rows == 0) {
// No certificate exists, create one
// Get student details
$student = getStudentDetails($conn, $userId);
$student_name = $student['first_name'] . ' ' . $student['last_name'];
// Generate a unique certificate number (unified for both course and exam)
$certificate_number = 'CERT-' . date('Ymd') . '-' . sprintf('%04d', $exam_data['id']);
// Generate a verification code
$verification_code = generateVerificationCode();
// Calculate grade
$grade = calculateGrade($exam_data['percentage']);
// Create certificate data for the unified certificate
$certificate_data = json_encode([
'exam_title' => $exam_data['exam_title'],
'course_title' => $exam_data['course_title'],
'course_id' => $exam_data['course_id'],
'course_duration' => $exam_data['course_duration'],
'course_level' => $exam_data['course_level'],
'student_name' => $student_name,
'student_email' => $student['email'],
'percentage' => $exam_data['percentage'],
'grade' => $grade['grade'],
'grade_description' => $grade['description'],
'grade_color' => $grade['color'],
'passing_score' => $exam_data['passing_percentage'],
'passing_percentage' => $exam_data['passing_percentage'],
'issue_date' => date('Y-m-d'),
'institute_name' => $institute_name,
'course_completion_date' => $course_data['completion_date'],
'unified_certificate' => true
]);
// Insert certificate record for exam
$insert_query = "INSERT INTO exam_certificates
(student_exam_id, certificate_number, issue_date, verification_code, certificate_data)
VALUES (?, ?, NOW(), ?, ?)";
$insert_stmt = $conn->prepare($insert_query);
$insert_stmt->bind_param("isss", $exam_data['id'], $certificate_number, $verification_code, $certificate_data);
if ($insert_stmt->execute()) {
$certificate_id = $conn->insert_id;
// Update the enrollment record to link to the same certificate
$update_enrollment = "UPDATE enrollments
SET certificate_number = ?,
certificate_issue_date = NOW(),
verification_code = ?,
status = 'completed',
completion_date = COALESCE(completion_date, NOW())
WHERE user_id = ? AND course_id = ?";
$update_stmt = $conn->prepare($update_enrollment);
$update_stmt->bind_param("ssii", $certificate_number, $verification_code, $userId, $exam_data['course_id']);
$update_stmt->execute();
$_SESSION['success_message'] = "Unified certificate generated successfully! This certificate includes both your course completion and exam results.";
// Redirect to view the certificate
header("Location: view_certificate.php?id=" . $certificate_id);
exit();
} else {
$_SESSION['error_message'] = "Failed to generate certificate. Please try again.";
}
} else {
// Certificate already exists
$certificate = $cert_result->fetch_assoc();
$_SESSION['success_message'] = "You already have a certificate for this exam and course.";
// Redirect to view the certificate
header("Location: view_certificate.php?id=" . $certificate['id']);
exit();
}
} else {
$_SESSION['error_message'] = "You have not passed this exam or it does not exist.";
}
}
?>
<!-- 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">My Certificates</h1>
</div>
<?php if (!empty($success_message)): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<?php echo $success_message; ?>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<?php endif; ?>
<?php if (!empty($error_message)): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<?php echo $error_message; ?>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<?php endif; ?>
<!-- Content Row - Statistics -->
<div class="row">
<div class="col-xl-3 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">
Total Certificates</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $total_certificates; ?></div>
</div>
<div class="col-auto">
<i class="fas fa-certificate fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-success 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-success text-uppercase mb-1">
Issued Certificates</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $course_certified_count + $exam_certified_count; ?></div>
</div>
<div class="col-auto">
<i class="fas fa-check-circle fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-info 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-info text-uppercase mb-1">
Pending Certificates</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $pending_course_count + $pending_exam_count; ?></div>
</div>
<div class="col-auto">
<i class="fas fa-hourglass-half fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-warning 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-warning text-uppercase mb-1">
Recent (30 days)</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $recent_count; ?></div>
</div>
<div class="col-auto">
<i class="fas fa-calendar-alt fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<?php if (!empty($pending_course_certificates)): ?>
<!-- Available Courses for Certificate Card -->
<div class="card shadow 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">Available Courses for Certificate</h6>
<span class="badge bg-info text-white"><?php echo count($pending_course_certificates); ?> course(s)</span>
</div>
<div class="card-body">
<div class="row">
<?php foreach ($pending_course_certificates as $course): ?>
<div class="col-md-6 col-lg-4 mb-4">
<div class="card h-100 shadow-sm border-warning">
<div class="card-header bg-light p-3">
<div class="d-flex justify-content-between align-items-center">
<h6 class="mb-0 text-primary"><?php echo htmlspecialchars($course['course_title']); ?></h6>
<span class="badge bg-success">Completed</span>
</div>
</div>
<div class="card-body">
<p class="text-muted mb-3">
<i class="fas fa-calendar-check me-2"></i> Completed:
<?php echo !empty($course['completion_date']) ?
date('M d, Y', strtotime($course['completion_date'])) :
'Date not recorded'; ?>
</p>
<div class="text-center mb-3">
<img src="../assets/img/certificate-icon.png" class="img-fluid" alt="Certificate" style="max-height: 100px;">
</div>
<form method="post" action="">
<input type="hidden" name="enrollment_id" value="<?php echo $course['enrollment_id']; ?>">
<button type="submit" name="generate_certificate" class="btn btn-warning w-100">
<i class="fas fa-certificate me-2"></i> Generate Certificate
</button>
</form>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if (!empty($pending_exam_certificates)): ?>
<!-- Available Exam Certificates Card -->
<div class="card shadow 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">Available Unified Certificates</h6>
<span class="badge bg-info text-white"><?php echo count($pending_exam_certificates); ?> exam(s)</span>
</div>
<div class="card-body">
<?php if (!empty($pending_exam_certificates)): ?>
<div class="alert alert-info mb-4">
<i class="fas fa-info-circle mr-2"></i>
When you generate a certificate, it will include both your course completion and exam results in a unified certificate.
</div>
<div class="row">
<?php foreach ($pending_exam_certificates as $exam): ?>
<div class="col-md-6 col-lg-4 mb-4">
<div class="card h-100 shadow-sm border-success">
<div class="card-header bg-light p-3">
<div class="d-flex justify-content-between align-items-center">
<h6 class="mb-0 text-primary"><?php echo htmlspecialchars($exam['exam_title']); ?></h6>
<span class="badge bg-success">Passed</span>
</div>
</div>
<div class="card-body">
<p class="text-muted mb-2">
<i class="fas fa-book me-2"></i> Course:
<?php echo htmlspecialchars($exam['course_title']); ?>
</p>
<div class="mb-3 text-center">
<div class="display-4 font-weight-bold text-success">
<?php echo number_format($exam['percentage'], 1); ?>%
</div>
<div class="text-muted">Your Score</div>
<?php $grade = calculateGrade($exam['percentage']); ?>
<div class="mt-2">
<span class="badge badge-pill badge-primary p-2">Grade: <?php echo $grade['grade']; ?></span>
<span class="text-muted d-block mt-1"><?php echo $grade['description']; ?></span>
</div>
<div class="progress mt-2" style="height: 8px;">
<div class="progress-bar" style="width: <?php echo $exam['percentage']; ?>%; background-color: <?php echo $grade['color']; ?>"
role="progressbar" aria-valuenow="<?php echo $exam['percentage']; ?>"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="text-center mb-3">
<img src="../assets/img/certificate-icon.png" class="img-fluid" alt="Certificate" style="max-height: 80px;">
</div>
<form method="post" action="">
<input type="hidden" name="exam_id" value="<?php echo $exam['exam_id']; ?>">
<button type="submit" name="generate_exam_certificate" class="btn btn-success w-100">
<i class="fas fa-certificate me-2"></i> Generate Unified Certificate
</button>
</form>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i> You don't have any passed exams available for certificate generation.
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<!-- Certificate List -->
<div class="card shadow 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">My Certificates</h6>
<?php if (!empty($all_certificates)): ?>
<span class="badge bg-primary text-white"><?php echo count($all_certificates); ?> certificate(s)</span>
<?php endif; ?>
</div>
<div class="card-body">
<?php if (empty($all_certificates)): ?>
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i> You don't have any certificates yet. Complete a course to get your certificate.
</div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-bordered" id="certificatesTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Title</th>
<th>Type</th>
<th>Certificate No</th>
<th>Issue Date</th>
<th>Grade/Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($all_certificates as $certificate): ?>
<?php
$certificate_type = isset($certificate['certificate_type']) && $certificate['certificate_type'] == 'exam' ? 'Exam' : 'Course';
$title = isset($certificate['exam_title']) ? $certificate['exam_title'] : $certificate['course_title'];
$certificate_number = isset($certificate['certificate_number']) ? $certificate['certificate_number'] : '';
$issue_date = isset($certificate['issue_date']) ? $certificate['issue_date'] :
(isset($certificate['certificate_issue_date']) ? $certificate['certificate_issue_date'] : '');
$percentage = isset($certificate['percentage']) ? $certificate['percentage'] : null;
// Calculate grade for exam certificates
$grade = $percentage !== null ? calculateGrade($percentage) : null;
?>
<tr>
<td>
<div class="d-flex align-items-center">
<img src="<?php echo !empty($certificate['course_image']) ? '../' . $certificate['course_image'] : '../assets/img/certificate-bg.jpg'; ?>"
class="img-thumbnail mr-2" alt="Certificate" style="width: 50px; height: 50px; object-fit: cover;">
<div>
<?php echo htmlspecialchars($title); ?>
</div>
</div>
</td>
<td>
<span class="badge badge-<?php echo $certificate_type == 'Exam' ? 'success' : 'primary'; ?> badge-pill">
<?php echo $certificate_type; ?>
</span>
</td>
<td><?php echo !empty($certificate_number) ? $certificate_number : 'Not issued'; ?></td>
<td><?php echo !empty($issue_date) ? date('M d, Y', strtotime($issue_date)) : 'Not available'; ?></td>
<td>
<?php if ($certificate_type == 'Exam' && $grade): ?>
<span class="badge badge-pill badge-info p-2">Grade: <?php echo $grade['grade']; ?></span>
<small class="d-block text-muted mt-1"><?php echo $grade['description']; ?></small>
<?php else: ?>
<span class="badge badge-pill badge-success">Completed</span>
<?php endif; ?>
</td>
<td>
<?php if ($certificate_type == 'Exam'): ?>
<a href="view_certificate.php?id=<?php echo $certificate['id']; ?>" target="_blank" class="btn btn-sm btn-primary">
<i class="fas fa-eye"></i> View Unified Certificate
</a>
<?php if (isset($certificate['verification_code'])): ?>
<a href="../verify.php?code=<?php echo $certificate['verification_code']; ?>" target="_blank" class="btn btn-sm btn-info">
<i class="fas fa-check-circle"></i> Verify
</a>
<?php endif; ?>
<?php elseif (!empty($certificate_number)): ?>
<a href="view_certificate.php?number=<?php echo $certificate_number; ?>" target="_blank" class="btn btn-sm btn-primary">
<i class="fas fa-eye"></i> View Certificate
</a>
<a href="download_certificate.php?number=<?php echo $certificate_number; ?>&format=pdf" class="btn btn-sm btn-info">
<i class="fas fa-download"></i> Download
</a>
<?php else: ?>
<form method="post" action="">
<input type="hidden" name="enrollment_id" value="<?php echo $certificate['enrollment_id']; ?>">
<button type="submit" name="generate_certificate" class="btn btn-sm btn-warning">
<i class="fas fa-certificate"></i> Generate
</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$('#certificatesTable').DataTable({
"order": [[ 3, "desc" ]], // Sort by issue date
"pageLength": 10
});
// Show a message if coming from exam results page
<?php if(isset($_GET['from_results']) && $_GET['from_results'] == '1' && isset($_GET['exam_id'])): ?>
Swal.fire({
title: 'Exam Passed!',
text: 'Congratulations! You can now generate your certificate.',
icon: 'success',
confirmButtonText: 'Generate Certificate'
}).then((result) => {
if (result.isConfirmed) {
// Create a form and submit it programmatically
var form = document.createElement('form');
form.method = 'POST';
form.action = '';
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'exam_id';
input.value = '<?php echo $_GET["exam_id"]; ?>';
var submit = document.createElement('input');
submit.type = 'hidden';
submit.name = 'generate_exam_certificate';
submit.value = '1';
form.appendChild(input);
form.appendChild(submit);
document.body.appendChild(form);
form.submit();
}
});
<?php endif; ?>
});
</script>
<?php include_once 'includes/footer.php'; ?>