Mini Shell
<?php
session_start();
$rootPath = realpath(dirname(__FILE__) . '/..');
require_once $rootPath . '/Portal/config/config.php';
require_once $rootPath . '/Portal/include/auth_validate.php';
// Memory and execution time limits
ini_set('memory_limit', '128M');
ini_set('max_execution_time', 300);
set_time_limit(300);
// Error reporting
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Check if user is authenticated
if (!isset($_SESSION['id'])) {
header('Location: login.php');
exit();
}
$User = $_SESSION['id'];
// Fetch user data
$stmt = mysqli_prepare($conn, "SELECT Access_Level, Full_Name FROM admin_accounts WHERE id = ?");
mysqli_stmt_bind_param($stmt, "i", $User);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
if (mysqli_num_rows($result) > 0) {
$rows = mysqli_fetch_assoc($result);
$UserAccessName = $rows['Access_Level'];
$FullName = isset($rows['Full_Name']) ? $rows['Full_Name'] : '';
}
mysqli_stmt_close($stmt);
// File upload configuration
$maxFileSize = 5 * 1024 * 1024; // 5MB
$allowedTypes = ['text/csv', 'application/vnd.ms-excel', 'text/plain'];
$maxRecords = 1000;
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Debug: Check what's being posted
error_log("POST data: " . print_r($_POST, true));
error_log("FILES data: " . print_r($_FILES, true));
// Validate inputs
$errors = [];
if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
$errors[] = "File upload failed. Error code: " . ($_FILES['file']['error'] ?? 'Unknown');
error_log("File upload error: " . ($_FILES['file']['error'] ?? 'Unknown'));
}
// Validate form fields (removed Exam_Type since it's not in the form)
$requiredFields = ['Term', 'Year', 'Out_OF'];
foreach ($requiredFields as $field) {
if (empty($_POST[$field])) {
$errors[] = ucfirst(str_replace('_', ' ', $field)) . " is required";
error_log("Missing field: $field");
}
}
if (empty($errors)) {
// Sanitize inputs
$Term = mysqli_real_escape_string($conn, $_POST['Term']);
$Year = mysqli_real_escape_string($conn, $_POST['Year']);
$Out_OF = mysqli_real_escape_string($conn, $_POST['Out_OF']);
// Validate file
$fileSize = $_FILES['file']['size'];
$fileType = $_FILES['file']['type'];
$tmpName = $_FILES['file']['tmp_name'];
$fileName = $_FILES['file']['name'];
// Check file size
if ($fileSize > $maxFileSize) {
$errors[] = "File size exceeds maximum limit of 5MB";
}
// Check file type by extension as well
$fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
if (!in_array($fileExt, ['csv']) && !in_array($fileType, $allowedTypes)) {
$errors[] = "Only CSV files are allowed";
}
if (empty($errors)) {
// Process CSV file from temporary location without saving
$processedCount = 0;
$failedCount = 0;
$duplicateCount = 0;
$successfulRecords = [];
$isFirstRow = true; // Flag to skip header row
error_log("Starting CSV processing...");
// Start transaction
mysqli_begin_transaction($conn);
try {
// Open CSV file
$file = fopen($tmpName, 'r');
if ($file !== FALSE) {
echo '<html>';
include_once 'include/AdminHeader.php';
echo '<div id="page-wrapper">';
echo '<div class="row">';
echo '<br><br><br><hr>';
echo '</div>';
// Display debug info (you can remove this later)
echo '<div class="alert alert-info">';
echo '<h4>Debug Info</h4>';
echo '<p>File: ' . htmlspecialchars($fileName) . '</p>';
echo '<p>Term: ' . htmlspecialchars($Term) . '</p>';
echo '<p>Year: ' . htmlspecialchars($Year) . '</p>';
echo '<p>Out Of: ' . htmlspecialchars($Out_OF) . '</p>';
echo '</div>';
$rowNumber = 0;
while (($data = fgetcsv($file, 1000, ",")) !== FALSE) {
$rowNumber++;
error_log("Processing row $rowNumber: " . print_r($data, true));
// Skip header row (first row)
if ($isFirstRow) {
$isFirstRow = false;
error_log("Skipping header row");
continue;
}
// Stop if max records reached
if ($processedCount >= $maxRecords) {
$_SESSION['warning'] = "Upload limited to first {$maxRecords} records.";
break;
}
// Validate CSV row has minimum required columns
if (count($data) >= 5) {
// Check if array indexes exist before accessing them
$Student_No = isset($data[0]) ? mysqli_real_escape_string($conn, trim($data[0])) : '';
$Full_Name = isset($data[1]) ? mysqli_real_escape_string($conn, trim($data[1])) : '';
$Level = isset($data[2]) ? mysqli_real_escape_string($conn, trim($data[2])) : '';
$Score = isset($data[3]) ? mysqli_real_escape_string($conn, trim($data[3])) : '';
$Remarks = isset($data[4]) ? mysqli_real_escape_string($conn, trim($data[4])) : '';
error_log("Parsed data - Student_No: $Student_No, Full_Name: $Full_Name, Level: $Level, Score: $Score");
// Basic validation - Check if Score is numeric
if (empty($Student_No) || empty($Full_Name) || empty($Level) || !is_numeric(trim($Score))) {
error_log("Validation failed for row $rowNumber");
$failedCount++;
} else {
// FIXED: Corrected table name and column names to match database
$checkDuplicateSql = "SELECT COUNT(*) as count FROM position
WHERE STudent_No = ?
AND Score = ? -- Changed from Position to Score
AND Term = ?
AND Year = ?";
$stmt = mysqli_prepare($conn, $checkDuplicateSql);
mysqli_stmt_bind_param($stmt, "siss", $Student_No, $Score, $Term, $Year);
mysqli_stmt_execute($stmt);
$duplicateResult = mysqli_stmt_get_result($stmt);
$duplicateRow = mysqli_fetch_assoc($duplicateResult);
mysqli_stmt_close($stmt);
if ($duplicateRow['count'] > 0) {
error_log("Duplicate found for Student_No: $Student_No, Score: $Score");
$duplicateCount++;
} else {
// Insert the record using prepared statement
// FIXED: Corrected column names to match database exactly
$insertSql = "INSERT INTO position (STudent_No, Full_Name, Score, Out_Of, Term, Year, Level, Remarks, Created_By)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = mysqli_prepare($conn, $insertSql);
mysqli_stmt_bind_param($stmt, "ssisssssi",
$Student_No,
$Full_Name,
$Score,
$Out_OF,
$Term,
$Year,
$Level,
$Remarks,
$User
);
if (mysqli_stmt_execute($stmt)) {
$processedCount++;
error_log("Successfully inserted record for Student_No: $Student_No");
// Store successful record for display
$successfulRecords[] = [
'Student_No' => $Student_No,
'Full_Name' => $Full_Name,
'Level' => $Level,
'Score' => $Score,
'Remarks' => $Remarks
];
} else {
error_log("Insert failed: " . mysqli_error($conn));
$failedCount++;
}
mysqli_stmt_close($stmt);
}
}
} else {
error_log("Row $rowNumber has insufficient columns: " . count($data));
$failedCount++;
}
}
fclose($file);
// Commit transaction
mysqli_commit($conn);
error_log("Transaction committed. Processed: $processedCount, Failed: $failedCount, Duplicates: $duplicateCount");
// Display summary
echo '<div class="row">';
echo '<div class="col-md-12">';
// Show flash messages
include('include/flash_messages.php');
echo '<div class="alert alert-info">';
echo '<h4>Upload Summary</h4>';
echo '<p>Total Rows Processed: ' . $rowNumber . '</p>';
echo '<p>Successfully Inserted: ' . $processedCount . '</p>';
echo '<p>Duplicates Skipped: ' . $duplicateCount . '</p>';
echo '<p>Failed: ' . $failedCount . '</p>';
// Show detailed error if all failed
if ($processedCount == 0 && $rowNumber > 1) {
echo '<hr>';
echo '<p><strong>Possible issues:</strong></p>';
echo '<ul>';
echo '<li>Check if CSV file has correct format (5 columns: Student_No, Full_Name, Level, Score, Remarks)</li>';
echo '<li>Check if Score column contains only numbers</li>';
echo '<li>Check if database table "position" exists with correct columns</li>';
echo '<li>Check if you have INSERT permissions on the table</li>';
echo '</ul>';
// Show sample CSV format
echo '<p><strong>Sample CSV format (first row is header):</strong></p>';
echo '<pre>';
echo "Student_No,Full_Name,Level,Score,Remarks\n";
echo "STU001,John Doe,Form 1,5,Excellent\n";
echo "STU002,Jane Smith,Form 2,12,Good\n";
echo '</pre>';
}
echo '</div>';
// Display successful records if any
if (!empty($successfulRecords)) {
echo '<h4>Successfully Uploaded Records:</h4>';
echo '<div class="table-responsive">';
echo '<table class="table table-bordered table-hover">';
echo '<thead><tr>';
echo '<th>#</th>';
echo '<th>Student No</th>';
echo '<th>Full Name</th>';
echo '<th>Level</th>';
echo '<th>Score (Position)</th>';
echo '<th>Term</th>';
echo '<th>Year</th>';
echo '<th>Remarks</th>';
echo '</tr></thead>';
echo '<tbody>';
$counter = 1;
foreach ($successfulRecords as $record) {
echo '<tr>';
echo '<td>' . $counter++ . '</td>';
echo '<td>' . htmlspecialchars($record['Student_No'] ?? '') . '</td>';
echo '<td>' . htmlspecialchars($record['Full_Name'] ?? '') . '</td>';
echo '<td>' . htmlspecialchars($record['Level'] ?? '') . '</td>';
echo '<td>' . htmlspecialchars($record['Score'] ?? '') . '</td>';
echo '<td>' . htmlspecialchars($Term ?? '') . '</td>';
echo '<td>' . htmlspecialchars($Year ?? '') . '</td>';
echo '<td>' . htmlspecialchars($record['Remarks'] ?? '') . '</td>';
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
echo '</div>';
// Add a back button
echo '<div class="text-center">';
echo '<a href="AdminPortal.php" class="btn btn-primary">Back to Admin Portal</a>';
echo '</div>';
} else {
echo '<div class="alert alert-warning">';
echo '<h4>No Records Uploaded</h4>';
echo '<p>No records were successfully uploaded. This could be due to:</p>';
echo '<ul>';
echo '<li>Empty CSV file</li>';
echo '<li>Incorrect CSV format</li>';
echo '<li>All records were duplicates</li>';
echo '<li>Database connection or permission issues</li>';
echo '</ul>';
echo '<p>Please check the CSV file format and try again.</p>';
echo '</div>';
// Add a back button
echo '<div class="text-center">';
echo '<a href="AdminPortal.php" class="btn btn-primary">Back to Admin Portal</a>';
echo '</div>';
}
echo '</div>';
echo '</div>';
echo '</div>';
echo '</html>';
// Set session messages
if ($processedCount > 0) {
$_SESSION['success'] = "Positions uploaded successfully! Inserted: {$processedCount}, Duplicates: {$duplicateCount}, Failed: {$failedCount}";
} else {
$_SESSION['failure'] = "No records were uploaded. Total rows processed: {$rowNumber}. Please check your CSV file format.";
}
} else {
throw new Exception("Failed to open uploaded file");
}
} catch (Exception $e) {
// Rollback transaction on error
mysqli_rollback($conn);
error_log("Error in upload: " . $e->getMessage());
$_SESSION['failure'] = "Upload failed: " . $e->getMessage();
header('Location: AdminPortal.php');
exit();
}
}
}
// If there were errors, redirect back
if (!empty($errors)) {
$_SESSION['errors'] = $errors;
header('Location: AdminPortal.php');
exit();
}
} else {
// Not a POST request, redirect
header('Location: AdminPortal.php');
exit();
}
?>