Linux cesa-www-main 6.1.0-49-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
Apache/2.4.68 (Debian)
Server IP : 10.218.0.2 & Your IP : 216.73.216.28
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
var /
www /
cesa.co.za /
php /
includes /
Delete
Unzip
Name
Size
Permission
Date
Action
error_handling
[ DIR ]
drwxr-sr-x
2025-07-07 15:54
mail
[ DIR ]
drwxr-sr-x
2025-06-14 11:17
ADQAnswers.php
3.16
KB
-rw-r--r--
2026-06-03 05:55
ADQAudit.php
6.51
KB
-rw-r--r--
2026-06-03 05:55
ADQAuditAnswers.php
1.21
KB
-rw-r--r--
2026-06-03 05:55
ADQFirms.php
18.41
KB
-rw-r--r--
2025-12-31 10:56
ADQuestionnairesAnswers.php
1.05
KB
-rw-r--r--
2026-06-03 05:55
ADQuestionnairesAudit.php
2.01
KB
-rw-r--r--
2026-06-03 05:55
ADecQuestionnaires.php
3.31
KB
-rw-r--r--
2026-06-03 05:55
ADecQuestions.php
541
B
-rw-r--r--
2026-06-03 05:55
ADec_Contacts.php
1.61
KB
-rw-r--r--
2026-06-03 05:55
ADec_OfficeContacts.php
7.43
KB
-rw-r--r--
2026-06-03 05:55
ADec_PIUnderwriters.php
742
B
-rw-r--r--
2026-06-03 05:55
ADec_Transformation.php
817
B
-rw-r--r--
2026-06-03 05:55
ADec_tblMemberFirmOffices.php
1.49
KB
-rw-r--r--
2026-06-03 05:55
ADec_tblMemberFirmSkills.php
2.38
KB
-rw-r--r--
2026-06-03 05:55
ADec_tblMemberFirms.php
19.37
KB
-rw-r--r--
2026-06-03 05:55
AnonRespondees.php
4.25
KB
-rw-r--r--
2026-06-05 11:41
AwardsEntries.php
2.4
KB
-rw-r--r--
2026-06-06 10:48
BaseTableClass.php
950
B
-rw-r--r--
2026-04-26 08:24
BatchJob.php
4.46
KB
-rw-r--r--
2026-06-03 05:55
BceAssignmentFeedbackFormsReportService.php
6.77
KB
-rw-r--r--
2026-05-25 13:06
CCEAssignment.php
12.44
KB
-rw-r--r--
2026-05-26 14:26
CCEAssignmentMarking.php
26.26
KB
-rw-r--r--
2026-08-14 12:06
CCEBooks.php
524
B
-rw-r--r--
2026-06-03 05:55
CCEConvenorAuth.php
3.06
KB
-rw-r--r--
2026-08-19 11:18
CCECourseSchedules.php
579
B
-rw-r--r--
2026-06-03 05:55
CCEDocCategories.php
529
B
-rw-r--r--
2026-06-03 05:55
CCEDocuments.php
8.15
KB
-rw-r--r--
2026-08-20 12:16
CCEExam.php
15.87
KB
-rw-r--r--
2026-06-03 06:35
CCEExamQuestion.php
1.76
KB
-rw-r--r--
2026-06-03 05:55
CCEFacilitatorUser.php
931
B
-rw-r--r--
2026-06-03 05:55
CCEMessageLog.php
951
B
-rw-r--r--
2026-06-03 05:55
CCEMessages.php
8.88
KB
-rw-r--r--
2026-07-01 13:20
CCEModuleMarksService.php
7.16
KB
-rw-r--r--
2026-05-26 10:30
CCEModules.php
1.16
KB
-rw-r--r--
2026-06-03 05:55
CCEResourceGroups.php
591
B
-rw-r--r--
2026-06-03 05:55
CCEResources.php
896
B
-rw-r--r--
2026-06-03 05:55
CCESetup.php
256
B
-rw-r--r--
2026-02-09 16:20
CCEStAssigExtension.php
2.07
KB
-rw-r--r--
2026-06-03 05:55
CCEStAssigExtensionRequest.php
6.65
KB
-rw-r--r--
2026-06-03 05:55
CCEStudentAssignment.php
16.61
KB
-rw-r--r--
2026-07-15 14:44
CCEStudentCourses.php
611
B
-rw-r--r--
2026-06-03 05:55
CCEStudentDisplayOrder.php
4.96
KB
-rw-r--r--
2026-05-26 09:32
CCEStudents.php
8.4
KB
-rw-r--r--
2026-08-19 11:18
CCETemplates.php
896
B
-rw-r--r--
2026-06-03 05:55
CCEWeeklySessions.php
2.27
KB
-rw-r--r--
2026-02-09 16:25
CPDSPReview.php
624
B
-rw-r--r--
2026-06-03 05:55
CPDServiceProvider.php
4.57
KB
-rw-r--r--
2026-06-12 11:48
CPDTrainingMaterial.php
3.96
KB
-rw-r--r--
2026-06-12 11:48
CceUploadedFileService.php
34.9
KB
-rw-r--r--
2026-06-24 12:03
Certificates.php
8.93
KB
-rw-r--r--
2026-08-18 15:42
Contact.php
690
B
-rw-r--r--
2026-06-03 05:55
ErrorLog.php
1.22
KB
-rw-r--r--
2026-08-24 10:12
EventSchedules.php
5.39
KB
-rw-r--r--
2025-12-20 10:03
FileUploads.php
2.1
KB
-rw-r--r--
2026-06-03 05:55
HTMLHelper.php
17.2
KB
-rw-r--r--
2026-06-03 05:55
KeyValue.php
4.9
KB
-rw-r--r--
2026-04-25 09:34
Mailer.php
12.78
KB
-rw-r--r--
2026-07-15 09:50
MarketingAttendees.php
36.87
KB
-rw-r--r--
2026-08-14 12:06
MarketingPayments.php
2.52
KB
-rw-r--r--
2026-06-03 05:55
MemberContact.php
1.04
KB
-rw-r--r--
2026-06-03 05:55
MemberFirm.php
17.71
KB
-rw-r--r--
2026-06-03 05:55
MemberFirmOffices.php
752
B
-rw-r--r--
2026-06-03 05:55
MemberFirmSkill.php
18.04
KB
-rw-r--r--
2026-06-03 05:55
MemberPortalTransformationProxy.php
4.44
KB
-rw-r--r--
2026-05-20 09:08
MemberPortalUrls.php
1.82
KB
-rw-r--r--
2026-05-20 09:53
MsgAttachFileService.php
4.92
KB
-rw-r--r--
2026-06-22 08:37
OfficeContact.php
1.01
KB
-rw-r--r--
2026-06-03 05:55
Picklists.php
539
B
-rw-r--r--
2026-06-03 05:55
Questionnaires.php
849
B
-rw-r--r--
2026-01-23 12:39
SchoolAttendeeBulkMailerService.php
34.26
KB
-rw-r--r--
2026-08-11 10:45
SchoolAttendees.php
73.21
KB
-rw-r--r--
2026-08-11 10:45
SchoolCourses.php
7.98
KB
-rw-r--r--
2026-08-19 11:59
SchoolEvents.php
45.54
KB
-rw-r--r--
2026-08-18 15:42
SchoolPayments.php
4.48
KB
-rw-r--r--
2026-04-13 09:33
SchoolPresenters.php
1.86
KB
-rw-r--r--
2026-01-23 12:43
SchoolWeeksCoursesDashboardProxy.php
10.69
KB
-rw-r--r--
2026-08-14 12:32
TrainingProvider.php
8.06
KB
-rw-r--r--
2026-01-23 12:43
TrainingProviderDoc.php
554
B
-rw-r--r--
2026-06-03 05:55
Transformation.php
10.87
KB
-rw-r--r--
2026-05-13 09:36
UnempPractitioners.php
1.43
KB
-rw-r--r--
2026-06-03 05:55
Utils.php
13.72
KB
-rw-r--r--
2026-07-23 07:28
WeeklySessionsParser.php
7.87
KB
-rw-r--r--
2026-02-09 16:20
cceMessageAttachmentUpload.inc.php
5.12
KB
-rw-r--r--
2026-06-03 05:55
cceMessageEditor.inc.php
9.26
KB
-rw-r--r--
2026-07-01 13:20
cce_file_download_endpoint.php
1.75
KB
-rw-r--r--
2026-06-24 08:38
cstUnreadMessages.php
2.1
KB
-rw-r--r--
2026-07-01 13:20
cstWeeksCourses.php
1.84
KB
-rw-r--r--
2026-08-14 12:06
load_phpmailer.php
742
B
-rw-r--r--
2026-07-17 14:57
maill.php
19.45
KB
-rw-r--r--
2026-08-19 12:23
require_ewmysql.php
1.2
KB
-rw-r--r--
2026-08-24 10:12
sqlFunctions.php
10.48
KB
-rw-r--r--
2026-08-24 10:12
Save
Rename
<?php class CCEExam extends BaseTableClass { /** Number of modules used for exam marks (M1–M4 in convenors report) */ const NUM_EXAM_MODULES = 5; const EXAM_TIMEZONE = 'Africa/Johannesburg'; /** * Whether the given student's exam has been marked. * True when the student has at least one CCEExamMarks row for an exam timing with CCEExamTiming.IsMarked = 1. * Used to show/hide the Exam Results menu item and to allow access to the exam results page. * * @param int $studentId CCEStudentID * @return bool */ public function hasExamBeenMarked($studentId) { global $conni; $studentId = (int) $studentId; if ($studentId <= 0) { return false; } $sql = "SELECT 1 FROM CCEExamMarks INNER JOIN CCEExamTiming ON (CCEExamMarks.ExamTimingID = CCEExamTiming.CCEExamTimingID) WHERE CCEExamMarks.CCEStudentID = " . $studentId . " AND (CCEExamTiming.IsMarked = 1 OR CCEExamTiming.IsMarked = TRUE) LIMIT 1"; // echo $sql . '<br />'; $rec = mysqli_query($conni, $sql); $hasMarked = $rec && mysqli_fetch_assoc($rec); if ($rec) { mysqli_free_result($rec); } return (bool) $hasMarked; } /** * Get human-readable label for ResultStatus code. * * @param string $code P, S, F or empty * @return string */ public function getResultStatusLabel($code) { $labels = [ 'P' => 'Passed', 'S' => 'Supplementary Exam/s Required', 'F' => 'Failed', ]; return isset($labels[$code]) ? $labels[$code] : ''; } /** * Get the logged-in student's exam result for the current schedule (same data as one row of convenors report). * Returns null if student has no result or exam not marked; otherwise array with keys: * ResultStatus, ResultComments, Achieved, ModuleMarks (1..4), ExamAvg, AssignmentAverage, CourseYear. * * @param int $studentId CCEStudentID * @return array|null */ public function getStudentExamResult($studentId) { global $conni; $studentId = (int) $studentId; if ($studentId <= 0) { return null; } $sql = "SELECT CCEStudents.CCEStudentID, CCEStudents.Surname, CCEStudents.FirstName, CCEStudents.KnownAs, CCEStudents.ResultComments, CCEStudents.ResultStatus, CCEStudents.Achieved, CCEStudentCourses.CCECourseScheduleID AS CurrentScheduleID, YEAR(CCECourseSchedules.StartDate) AS CourseYear FROM CCEStudents INNER JOIN CCEStudentCourses USING (CCEStudentID) INNER JOIN CCECourseSchedules ON (CCEStudentCourses.CCECourseScheduleID = CCECourseSchedules.CCECourseScheduleID) WHERE CCEStudents.CCEStudentID = " . $studentId; // echo $sql . '<br />'; $rec = mysqli_query($conni, $sql); if (!$rec || !($rowStudent = mysqli_fetch_assoc($rec))) { if ($rec) { mysqli_free_result($rec); } return null; } mysqli_free_result($rec); $result = [ 'CCEStudentID' => (int) $rowStudent['CCEStudentID'], 'KnownAs' => $rowStudent['KnownAs'], 'Surname' => $rowStudent['Surname'], 'ResultStatus' => $rowStudent['ResultStatus'], 'ResultComments' => $rowStudent['ResultComments'], 'Achieved' => (int) $rowStudent['Achieved'], 'CourseYear' => $rowStudent['CourseYear'], 'ModuleMarks' => [1 => null, 2 => null, 3 => null, 4 => null], 'ExamAvg' => null, 'AssignmentAverage' => null, ]; $numModules = self::NUM_EXAM_MODULES; $someMarks = false; for ($i = 1; $i <= $numModules; $i++) { $sql = "SELECT CCEExamMarks.Questionnaire_ID, MAX(CCEExamMarks.DateMarked) AS DateMarked, SUM(CCEExamMarks.Question_Score)/CCEExams.Score*100 AS TotalScore, CCEExamMarks.ExamTimingID AS OneExamTimingID FROM CCEExams JOIN CCEExamMarks USING (Questionnaire_ID) JOIN CCEExamTiming ON (CCEExamMarks.ExamTimingID = CCEExamTiming.CCEExamTimingID) JOIN CCEModules ON (CCEExams.CCEModuleID = CCEModules.CCEModuleID) WHERE CCEExamMarks.CCEStudentID = " . $studentId . " AND (CCEExamTiming.IsMarked = 1 OR CCEExamTiming.IsMarked = TRUE) AND CCEModules.ModuleNum = " . $i . " GROUP BY CCEExamMarks.ExamTimingId ORDER BY CCEExamMarks.DateMarked ASC"; // echo $sql . '<br />'; $rec = mysqli_query($conni, $sql); $firstScore = null; while ($row = mysqli_fetch_assoc($rec)) { if ($row['TotalScore'] !== '' && $row['TotalScore'] !== null) { if ($firstScore === null) { $firstScore = (float) $row['TotalScore']; $result['ModuleMarks'][$i] = $firstScore; $someMarks = true; } } } mysqli_free_result($rec); } if (!$someMarks) { return $result; } $arrMarks = array_filter($result['ModuleMarks'], function ($v) { return $v !== null; }); $result['ExamAvg'] = count($arrMarks) > 0 ? round(array_sum($arrMarks) / count($arrMarks)) : null; if (function_exists('GetAverageAssigScore')) { $result['AssignmentAverage'] = GetAverageAssigScore($studentId, false, 0, $rowStudent['CourseYear']) / 10 * 100; } return $result; } /** * Return exam list with visibility and availability flags for a student. * Rules: * - Upcoming exams show with timezone-correct date/time. * - If start date is more than 24 hours away, only test student IDs can see it. * * @param int $studentId * @param array $testStudentIDs * @param string $timeZone * @return array */ public function getExamListForStudent($studentId, $testStudentIDs = array(54, 3920), $timeZone = self::EXAM_TIMEZONE) { global $conni; $studentId = (int) $studentId; if ($studentId <= 0) { return array(); } $isTestStudent = in_array($studentId, $testStudentIDs); $examTimezone = new DateTimeZone($timeZone); $nowDateTime = new DateTime("now", $examTimezone); $sql = "SELECT Questionnaire_ID, Questionnaire_Name, StartDate, CloseDate, CONCAT(Questionnaire_Name, ' Exam ', DATE_FORMAT(StartDate, '%M %Y')) AS ExamDisplayTitle, DATE_FORMAT(StartDate, '%M %Y') AS StartMonthYear, DATE_FORMAT(StartDate, '%Y-%m-%d %H:%i') AS StartTimeDisplay, DATE_FORMAT(CloseDate, '%Y-%m-%d %H:%i') AS EndTimeDisplay FROM CCEExams WHERE StartDate IS NOT NULL AND CloseDate IS NOT NULL AND YEAR(StartDate) >= YEAR(CURDATE()) - 1 ORDER BY StartDate ASC"; $rec = mysqli_query($conni, $sql); if (!$rec) { return array(); } $exams = array(); while ($row = mysqli_fetch_assoc($rec)) { if (empty($row['StartDate']) || empty($row['CloseDate'])) { continue; } $startDateTime = new DateTime($row['StartDate'], $examTimezone); $closeDateTime = new DateTime($row['CloseDate'], $examTimezone); $secondsUntilStart = $startDateTime->getTimestamp() - $nowDateTime->getTimestamp(); $isMoreThan24HoursAway = $secondsUntilStart > (24 * 60 * 60); $isVisibleToStudent = !$isMoreThan24HoursAway || $isTestStudent; $isPastExam = $closeDateTime < $nowDateTime; if (!$isVisibleToStudent) { continue; } $exams[] = array( 'Questionnaire_ID' => (int) $row['Questionnaire_ID'], 'Questionnaire_Name' => $row['Questionnaire_Name'], 'ExamDisplayTitle' => $row['ExamDisplayTitle'], 'StartMonthYear' => $row['StartMonthYear'], 'StartTimeDisplay' => $row['StartTimeDisplay'], 'EndTimeDisplay' => $row['EndTimeDisplay'], 'StartDate' => $startDateTime->format('Y-m-d H:i:s'), 'CloseDate' => $closeDateTime->format('Y-m-d H:i:s'), 'StartDateDisplay' => $startDateTime->format('Y-m-d H:i'), 'CloseDateDisplay' => $closeDateTime->format('Y-m-d H:i'), 'IsMoreThan24HoursAway' => $isMoreThan24HoursAway, 'IsPastExam' => $isPastExam, 'IsAvailableNow' => ($nowDateTime >= $startDateTime && $nowDateTime <= $closeDateTime), 'SecondsUntilStart' => $secondsUntilStart, ); } mysqli_free_result($rec); return $exams; } /** * Return only upcoming exams (not yet ended) visible to a student. * * @param int $studentId * @param array $testStudentIDs * @param string $timeZone * @return array */ public function getUpcomingExamListForStudent($studentId, $testStudentIDs = array(54, 3920), $timeZone = self::EXAM_TIMEZONE) { $examTimezone = new DateTimeZone($timeZone); $nowDateTime = new DateTime("now", $examTimezone); $allExams = $this->getExamListForStudent($studentId, $testStudentIDs, $timeZone); return array_values(array_filter($allExams, function ($exam) use ($nowDateTime, $examTimezone) { if (empty($exam['CloseDate'])) { return false; } $closeDateTime = new DateTime($exam['CloseDate'], $examTimezone); return $closeDateTime >= $nowDateTime; })); } /** * Return past exams for "Marked Exams" display. * * @param int $studentId * @param array $testStudentIDs * @param string $timeZone * @return array */ public function getMarkedExamListForStudent($studentId, $testStudentIDs = array(54, 3920), $timeZone = self::EXAM_TIMEZONE) { $examTimezone = new DateTimeZone($timeZone); $nowDateTime = new DateTime("now", $examTimezone); $allExams = $this->getExamListForStudent($studentId, $testStudentIDs, $timeZone); return array_values(array_filter($allExams, function ($exam) use ($nowDateTime, $examTimezone) { if (empty($exam['CloseDate'])) { return false; } $closeDateTime = new DateTime($exam['CloseDate'], $examTimezone); return $closeDateTime < $nowDateTime; })); } /** * True when the student should see the "Exam" menu link. * * @param int $studentId * @param array $testStudentIDs * @param string $timeZone * @return bool */ public function hasVisibleExamForStudent($studentId, $testStudentIDs = array(54, 3920), $timeZone = self::EXAM_TIMEZONE) { $exams = $this->getExamListForStudent($studentId, $testStudentIDs, $timeZone); return count($exams) > 0; } /** * True when the student has an upcoming visible exam. * * @param int $studentId * @param array $testStudentIDs * @param string $timeZone * @return bool */ public function hasUpcomingVisibleExamForStudent($studentId, $testStudentIDs = array(54, 3920), $timeZone = self::EXAM_TIMEZONE) { $exams = $this->getUpcomingExamListForStudent($studentId, $testStudentIDs, $timeZone); return count($exams) > 0; } /** * Whether exam navigation should jump to the first unanswered question (legacy). * * @return bool */ public function shouldRedirectToFirstUnansweredQuestion() { return defined('EXAM_REDIRECT_TO_FIRST_UNANSWERED') && EXAM_REDIRECT_TO_FIRST_UNANSWERED; } /** * Question to open when exam.php loads without ?q= (after save or implicit entry). * * @param array<int,int> $arrAllQuestions question_id => sort key * @param array<int,int> $arrNotStarted * @param array<int,int> $arrInProgress * @param array<int,int> $arrIncomplete * @param int $savedQuestionId question just saved (0 if none) * @return int 0 = no redirect (e.g. show instructions) */ public function resolveExamRedirectQuestionId(array $arrAllQuestions, array $arrNotStarted, array $arrInProgress, array $arrIncomplete, $savedQuestionId = 0) { if ($this->shouldRedirectToFirstUnansweredQuestion()) { return $this->resolveFirstUnansweredExamQuestionId($arrNotStarted, $arrInProgress, $arrIncomplete, $savedQuestionId); } return $this->resolveNextSequentialExamQuestionId($arrAllQuestions, $savedQuestionId); } /** * Legacy: first not started, else first in progress, else next incomplete after saved. * * @param array<int,int> $arrNotStarted * @param array<int,int> $arrInProgress * @param array<int,int> $arrIncomplete * @param int $savedQuestionId * @return int */ private function resolveFirstUnansweredExamQuestionId(array $arrNotStarted, array $arrInProgress, array $arrIncomplete, $savedQuestionId) { if (!empty($arrNotStarted)) { asort($arrNotStarted); return (int) array_key_first($arrNotStarted); } if (!empty($arrInProgress)) { asort($arrInProgress); return (int) array_key_first($arrInProgress); } if (empty($arrIncomplete)) { return 0; } asort($arrIncomplete); $savedQuestionId = intval($savedQuestionId); $prevOrderBy = 0; if ($savedQuestionId > 0) { foreach ($arrIncomplete as $questionId => $sortOrder) { if ((int) $questionId === $savedQuestionId) { $prevOrderBy = $sortOrder; break; } } } foreach ($arrIncomplete as $questionId => $sortOrder) { if ($sortOrder > $prevOrderBy) { return (int) $questionId; } } return (int) array_key_first($arrIncomplete); } /** * Next question in section/display order after the one just saved; first question if none saved. * * @param array<int,int> $arrAllQuestions * @param int $savedQuestionId * @return int */ private function resolveNextSequentialExamQuestionId(array $arrAllQuestions, $savedQuestionId) { if (empty($arrAllQuestions)) { return 0; } asort($arrAllQuestions); $savedQuestionId = intval($savedQuestionId); if ($savedQuestionId > 0 && isset($arrAllQuestions[$savedQuestionId])) { $prevOrder = $arrAllQuestions[$savedQuestionId]; foreach ($arrAllQuestions as $questionId => $sortOrder) { if ($sortOrder > $prevOrder) { return (int) $questionId; } } return 0; } return (int) array_key_first($arrAllQuestions); } } /** * Backwards-compatible plural alias. */ class CCEExams extends CCEExam { } function cceQuestionListPageLoad() { if (!isset($_REQUEST['Questionnaire_ID']) || intval($_REQUEST['Questionnaire_ID']) <= 0) { return ''; } return '<a href="/php/templates/bce/memorandum.php?exam_id=' . $_REQUEST['Questionnaire_ID'] . '" target="_blank">Download Exam Memorandum</a>'; } function getExamResultCssClass($score) { if ($score >= 90) return 'excel'; if ($score >= 70) return 'pass'; if ($score >= 60) return 'warn'; return 'fail'; }