feat: Add XLSX export for user grades report
Introduces XLSX export functionality to the user grades report. Adds a checkbox for selecting XLSX export in the form interface. Uses PhpSpreadsheet to generate and download detailed Excel files containing user grades and quiz attempts. Enhancement enables convenient data export for offline analysis and sharing.
This commit is contained in:
parent
7252b729b2
commit
80ac83db92
4 changed files with 147 additions and 54 deletions
|
@ -15,6 +15,9 @@ class usergrades_form extends moodleform
|
||||||
|
|
||||||
$mform->addElement('select', 'userid', get_string('selectuser', 'report_usergrades'), $users[get_string('users')]);
|
$mform->addElement('select', 'userid', get_string('selectuser', 'report_usergrades'), $users[get_string('users')]);
|
||||||
|
|
||||||
|
// XLSX Export checkbox
|
||||||
|
$mform->addElement('checkbox', 'exportxls', get_string('exportxls', 'report_usergrades'));
|
||||||
|
|
||||||
// Add form action buttons
|
// Add form action buttons
|
||||||
$this->add_action_buttons(false, get_string('showgrades', 'report_usergrades'));
|
$this->add_action_buttons(false, get_string('showgrades', 'report_usergrades'));
|
||||||
}
|
}
|
||||||
|
|
115
details.php
115
details.php
|
@ -8,34 +8,119 @@ require_once($CFG->dirroot . '/user/selector/lib.php');
|
||||||
require_once('classes/user_selector.php');
|
require_once('classes/user_selector.php');
|
||||||
require_once('classes/usergrades_form.php');
|
require_once('classes/usergrades_form.php');
|
||||||
|
|
||||||
// Set up the page context and other configurations
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
|
||||||
admin_externalpage_setup('report_usergrades_details', '', null, '', array('capability' => 'report/usergrades:view'));
|
admin_externalpage_setup('report_usergrades_details', '', null, '', array('capability' => 'report/usergrades:view'));
|
||||||
|
|
||||||
// Instantiate the form
|
// Instantiate the form
|
||||||
$mform = new usergrades_form();
|
$mform = new usergrades_form();
|
||||||
echo $OUTPUT->header();
|
|
||||||
echo $OUTPUT->heading(get_string('usergradesreport', 'report_usergrades'));
|
|
||||||
|
|
||||||
// Form processing and displaying is done here
|
// Check if form data is submitted
|
||||||
if ($mform->is_cancelled()) {
|
if ($data = $mform->get_data()) {
|
||||||
// Handle form cancellation, if necessary
|
|
||||||
redirect(new moodle_url('/admin/report.php'));
|
|
||||||
} else if ($data = $mform->get_data()) {
|
|
||||||
$userid = $data->userid;
|
$userid = $data->userid;
|
||||||
|
|
||||||
// Fetch and display user grades if a user is selected
|
|
||||||
if (!empty($userid)) {
|
if (!empty($userid)) {
|
||||||
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
|
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
|
||||||
$courses = enrol_get_users_courses($user->id, true);
|
$courses = enrol_get_users_courses($user->id, true);
|
||||||
$questions = $DB->get_records('question');
|
$questions = $DB->get_records('question');
|
||||||
|
|
||||||
// User details
|
if (isset($data->exportxls)) { // Assume a form field named 'exportxls' for Excel export action
|
||||||
|
// Create a new Spreadsheet object
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
$row = 1;
|
||||||
|
|
||||||
|
// Add the user details
|
||||||
|
$sheet->setCellValue('A' . $row, get_string('username', 'report_usergrades'));
|
||||||
|
$sheet->setCellValue('B' . $row, $user->username);
|
||||||
|
$row++;
|
||||||
|
$sheet->setCellValue('A' . $row, get_string('firstname', 'report_usergrades'));
|
||||||
|
$sheet->setCellValue('B' . $row, $user->firstname);
|
||||||
|
$row++;
|
||||||
|
$sheet->setCellValue('A' . $row, get_string('lastname', 'report_usergrades'));
|
||||||
|
$sheet->setCellValue('B' . $row, $user->lastname);
|
||||||
|
$row++;
|
||||||
|
$sheet->setCellValue('A' . $row, get_string('email', 'report_usergrades'));
|
||||||
|
$sheet->setCellValue('B' . $row, $user->email);
|
||||||
|
$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);
|
||||||
|
$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);
|
||||||
|
$row++;
|
||||||
|
|
||||||
|
foreach ($quiz_attempts as $attempt) {
|
||||||
|
$sheet->setCellValue('A' . $row, get_string('attempt', 'report_usergrades') . ' ' . $attempt->attempt);
|
||||||
|
$row++;
|
||||||
|
|
||||||
|
$sheet->setCellValue('A' . $row, get_string('question', 'report_usergrades'));
|
||||||
|
$sheet->setCellValue('B' . $row, get_string('response', 'report_usergrades'));
|
||||||
|
$sheet->setCellValue('C' . $row, get_string('grade', 'report_usergrades'));
|
||||||
|
$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) {
|
||||||
|
$sheet->setCellValue('A' . $row, $question->name . ': ' . $question->questiontext);
|
||||||
|
$sheet->setCellValue('B' . $row, $response);
|
||||||
|
$sheet->setCellValue('C' . $row, $question_grade->fraction);
|
||||||
|
$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);
|
||||||
|
$row += 2; // Extra space before next attempt or quiz
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$row += 2; // Extra space between courses
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
echo $OUTPUT->heading(get_string('userdetails', 'report_usergrades'), 3);
|
||||||
|
|
||||||
$user_table = new html_table();
|
$user_table = new html_table();
|
||||||
$user_table->head = array(get_string('field', 'report_usergrades'), get_string('value', 'report_usergrades'));
|
$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('username', 'report_usergrades'), $user->username);
|
||||||
$user_table->data[] = array(get_string('firstname', 'report_usergrades'), $user->firstname);
|
$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('lastname', 'report_usergrades'), $user->lastname);
|
||||||
|
@ -93,12 +178,14 @@ if ($mform->is_cancelled()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
echo $OUTPUT->footer();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
echo $OUTPUT->notification(get_string('nouserselected', 'report_usergrades'), 'notifyproblem');
|
echo $OUTPUT->notification(get_string('nouserselected', 'report_usergrades'), 'notifyproblem');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Display form if no data is submitted
|
// Show the form
|
||||||
|
echo $OUTPUT->header();
|
||||||
$mform->display();
|
$mform->display();
|
||||||
}
|
|
||||||
|
|
||||||
echo $OUTPUT->footer();
|
echo $OUTPUT->footer();
|
||||||
|
}
|
||||||
|
|
|
@ -19,3 +19,6 @@ $string['lastname'] = 'Last Name';
|
||||||
$string['email'] = 'Email';
|
$string['email'] = 'Email';
|
||||||
$string['field'] = 'Field';
|
$string['field'] = 'Field';
|
||||||
$string['value'] = 'Value';
|
$string['value'] = 'Value';
|
||||||
|
$string['exportxls'] = 'Export to XLSX';
|
||||||
|
$string['course'] = 'Course';
|
||||||
|
$string['quiz'] = 'Quiz';
|
|
@ -2,7 +2,7 @@
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
$plugin->component = 'report_usergrades';
|
$plugin->component = 'report_usergrades';
|
||||||
$plugin->version = 2024112101;
|
$plugin->version = 2024112500;
|
||||||
$plugin->requires = 2022041900;
|
$plugin->requires = 2022041900;
|
||||||
$plugin->maturity = MATURITY_ALPHA;
|
$plugin->maturity = MATURITY_ALPHA;
|
||||||
$plugin->release = 'v1.0';
|
$plugin->release = 'v1.0';
|
||||||
|
|
Loading…
Reference in a new issue