Kumi
504fb793ff
Cleans up unused imports in the spreadsheet styling part, eliminating unnecessary dependencies. This improves code maintainability by reducing clutter.
228 lines
12 KiB
PHP
228 lines
12 KiB
PHP
<?php
|
||
require_once('../../config.php');
|
||
require_once($CFG->libdir . '/adminlib.php');
|
||
require_once($CFG->libdir . '/gradelib.php');
|
||
require_once($CFG->libdir . '/tablelib.php');
|
||
require_once($CFG->libdir . '/formslib.php');
|
||
require_once($CFG->dirroot . '/user/selector/lib.php');
|
||
require_once('classes/user_selector.php');
|
||
require_once('classes/usergrades_form.php');
|
||
require_once('vendor/autoload.php');
|
||
|
||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||
use Soundasleep\Html2Text;
|
||
|
||
admin_externalpage_setup('report_usergrades_details', '', null, '', array('capability' => 'report/usergrades:view'));
|
||
|
||
// Instantiate the form
|
||
$mform = new usergrades_form();
|
||
|
||
// Check if form data is submitted
|
||
if ($data = $mform->get_data()) {
|
||
$userid = $data->userid;
|
||
|
||
if (!empty($userid)) {
|
||
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
|
||
$courses = enrol_get_users_courses($user->id, true);
|
||
$questions = $DB->get_records('question');
|
||
|
||
if (isset($data->exportxls)) { //
|
||
// Create a new Spreadsheet object
|
||
$spreadsheet = new Spreadsheet();
|
||
$sheet = $spreadsheet->getActiveSheet();
|
||
|
||
// Set default font and size
|
||
$spreadsheet->getDefaultStyle()->getFont()->setName('Arial')->setSize(10);
|
||
|
||
$row = 1;
|
||
|
||
// Add the user details
|
||
$headers = [
|
||
get_string('field', 'report_usergrades'),
|
||
get_string('value', 'report_usergrades'),
|
||
];
|
||
|
||
$details = [
|
||
[get_string('username', 'report_usergrades'), $user->username],
|
||
[get_string('firstname', 'report_usergrades'), $user->firstname],
|
||
[get_string('lastname', 'report_usergrades'), $user->lastname],
|
||
[get_string('email', 'report_usergrades'), $user->email]
|
||
];
|
||
|
||
// Apply header styling
|
||
$sheet->fromArray($headers, NULL, 'A' . $row);
|
||
$sheet->getStyle('A' . $row . ':B' . $row)->getFont()->setBold(true);
|
||
$sheet->getStyle('A' . $row . ':B' . $row)->getFill()->setFillType(Fill::FILL_SOLID)->getStartColor()->setARGB("ff808080");
|
||
$row++;
|
||
|
||
// Fill in the user details
|
||
foreach ($details as $detail) {
|
||
$sheet->fromArray($detail, NULL, 'A' . $row);
|
||
$row++;
|
||
}
|
||
$row += 2; // Extra space before courses
|
||
|
||
// Start iterating the courses
|
||
foreach ($courses as $course) {
|
||
$sheet->setCellValue('A' . $row, get_string('course', 'report_usergrades') . ': ' . $course->fullname);
|
||
$sheet->getStyle('A' . $row)->getFont()->setBold(true);
|
||
$row++;
|
||
|
||
$quizzes = $DB->get_records('quiz', array('course' => $course->id));
|
||
|
||
if ($quizzes) {
|
||
foreach ($quizzes as $quiz) {
|
||
$quiz_attempts = $DB->get_records('quiz_attempts', array('quiz' => $quiz->id, 'userid' => $user->id));
|
||
|
||
if ($quiz_attempts) {
|
||
$sheet->setCellValue('A' . $row, get_string('quiz', 'report_usergrades') . ': ' . $quiz->name);
|
||
$sheet->getStyle('A' . $row)->getFont()->setBold(true);
|
||
$row++;
|
||
|
||
foreach ($quiz_attempts as $attempt) {
|
||
$sheet->setCellValue('A' . $row, get_string('attempt', 'report_usergrades') . ' ' . $attempt->attempt);
|
||
$sheet->getStyle('A' . $row)->getFont()->setItalic(true);
|
||
$row++;
|
||
|
||
$attempt_header = [
|
||
get_string('question', 'report_usergrades'),
|
||
get_string('response', 'report_usergrades'),
|
||
get_string('grade', 'report_usergrades')
|
||
];
|
||
$sheet->fromArray($attempt_header, NULL, 'A' . $row);
|
||
$sheet->getStyle('A' . $row . ':C' . $row)->getFont()->setBold(true)->getColor()->setARGB(Color::COLOR_WHITE);
|
||
$sheet->getStyle('A' . $row . ':C' . $row)->getFill()->setFillType(Fill::FILL_SOLID)->getStartColor()->setARGB(Color::COLOR_DARKBLUE);
|
||
$row++;
|
||
|
||
$question_usages = $DB->get_records('question_usages', array('id' => $attempt->uniqueid));
|
||
|
||
foreach ($question_usages as $question_usage) {
|
||
$question_attempts = $DB->get_records('question_attempts', array('questionusageid' => $question_usage->id));
|
||
|
||
foreach ($question_attempts as $question_attempt) {
|
||
$question = $questions[$question_attempt->questionid];
|
||
$response = $question_attempt->responsesummary;
|
||
|
||
$question_grades = $DB->get_records('question_attempt_steps', array('questionattemptid' => $question_attempt->id));
|
||
|
||
foreach ($question_grades as $question_grade) {
|
||
if ($question_grade->fraction) {
|
||
$data = [
|
||
$question->name . ': ' . Html2Text::convert($question->questiontext),
|
||
$response,
|
||
$question_grade->fraction
|
||
];
|
||
$sheet->fromArray($data, NULL, 'A' . $row);
|
||
$sheet->getStyle('A' . $row . ':C' . $row)->getAlignment()->setWrapText(true);
|
||
$row++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$total_grade = $DB->get_record('quiz_grades', array('quiz' => $quiz->id, 'userid' => $user->id));
|
||
$sheet->setCellValue('A' . $row, get_string('totalgrade', 'report_usergrades') . ': ' . $total_grade->grade . ' / ' . $quiz->grade);
|
||
$sheet->getStyle('A' . $row . ':C' . $row)->getFont()->setBold(true);
|
||
$row += 2; // Extra space before next attempt or quiz
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$row += 2; // Extra space between courses
|
||
}
|
||
|
||
$sheet->getColumnDimension('A')->setWidth(50);
|
||
$sheet->getColumnDimension('B')->setWidth(50);
|
||
$sheet->getColumnDimension('C')->setWidth(10);
|
||
|
||
// Create writer and output the file
|
||
$writer = new Xlsx($spreadsheet);
|
||
$filename = 'user_grades_' . $user->id . '.xlsx';
|
||
|
||
// Redirect output to a client’s web browser (Excel2007)
|
||
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||
header('Content-Disposition: attachment;filename="' . $filename . '"');
|
||
header('Cache-Control: max-age=0');
|
||
|
||
$writer->save('php://output');
|
||
exit();
|
||
} else {
|
||
// HTML output if not exporting
|
||
echo $OUTPUT->header();
|
||
echo $OUTPUT->heading(get_string('usergradesreport', 'report_usergrades'));
|
||
|
||
echo $OUTPUT->heading(get_string('userdetails', 'report_usergrades'), 3);
|
||
|
||
$user_table = new html_table();
|
||
$user_table->head = array(get_string('field', 'report_usergrades'), get_string('value', 'report_usergrades'));
|
||
$user_table->data[] = array(get_string('username', 'report_usergrades'), $user->username);
|
||
$user_table->data[] = array(get_string('firstname', 'report_usergrades'), $user->firstname);
|
||
$user_table->data[] = array(get_string('lastname', 'report_usergrades'), $user->lastname);
|
||
$user_table->data[] = array(get_string('email', 'report_usergrades'), $user->email);
|
||
|
||
echo html_writer::table($user_table);
|
||
|
||
foreach ($courses as $course) {
|
||
echo $OUTPUT->heading($course->fullname, 3);
|
||
|
||
$quizzes = $DB->get_records('quiz', array('course' => $course->id));
|
||
|
||
if ($quizzes) {
|
||
echo $OUTPUT->heading(get_string('quizzes', 'report_usergrades'), 4);
|
||
|
||
foreach ($quizzes as $quiz) {
|
||
$quiz_questions = $DB->get_records('quiz_slots', array('quizid' => $quiz->id));
|
||
$quiz_attempts = $DB->get_records('quiz_attempts', array('quiz' => $quiz->id, 'userid' => $user->id));
|
||
|
||
if ($quiz_attempts) {
|
||
echo $OUTPUT->heading($quiz->name, 5);
|
||
|
||
foreach ($quiz_attempts as $attempt) {
|
||
echo $OUTPUT->heading(get_string('attempt', 'report_usergrades') . ' ' . $attempt->attempt, 6);
|
||
|
||
$attempt_table = new html_table();
|
||
$attempt_table->head = array(get_string('question', 'report_usergrades'), get_string('response', 'report_usergrades'), get_string('grade', 'report_usergrades'));
|
||
|
||
$question_usages = $DB->get_records('question_usages', array('id' => $attempt->uniqueid));
|
||
|
||
foreach ($question_usages as $question_usage) {
|
||
$question_attempts = $DB->get_records('question_attempts', array('questionusageid' => $question_usage->id));
|
||
|
||
foreach ($question_attempts as $question_attempt) {
|
||
$question = $questions[$question_attempt->questionid];
|
||
$response = $question_attempt->responsesummary;
|
||
|
||
$question_grades = $DB->get_records('question_attempt_steps', array('questionattemptid' => $question_attempt->id));
|
||
|
||
foreach ($question_grades as $question_grade) {
|
||
if ($question_grade->fraction) {
|
||
$attempt_table->data[] = array($question->name . ': ' . $question->questiontext, $response, $question_grade->fraction);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
echo html_writer::table($attempt_table);
|
||
|
||
$total_grade = $DB->get_record('quiz_grades', array('quiz' => $quiz->id, 'userid' => $user->id));
|
||
|
||
echo $OUTPUT->heading(get_string('totalgrade', 'report_usergrades') . ': ' . $total_grade->grade . ' / ' . $quiz->grade, 6);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
echo $OUTPUT->footer();
|
||
}
|
||
} else {
|
||
echo $OUTPUT->notification(get_string('nouserselected', 'report_usergrades'), 'notifyproblem');
|
||
}
|
||
} else {
|
||
// Show the form
|
||
echo $OUTPUT->header();
|
||
$mform->display();
|
||
echo $OUTPUT->footer();
|
||
}
|