Commit 9a9d06d3 authored by Artem Baranovskyi's avatar Artem Baranovskyi
Browse files

Changed the source of request payload generation from DB to existing Manual Grading frontend page.

parent 0b8d71f6
Showing with 35 additions and 192 deletions
+35 -192
<?php
// local/asystgrade/api.php
require_once('../../config.php');
require_once('lib.php');
......@@ -30,7 +29,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} catch (Exception $e) {
echo json_encode(['error' => $e->getMessage()]);
}
} else {
echo json_encode(['error' => 'No data received']);
}
......
<?php
namespace local_asystgrade\db;
class quizquery implements quizquery_interface
{
private $db;
public function __construct() {
global $DB;
$this->db = $DB;
}
/**
* @param $qid
* @param $slot
* @return mixed
*/
public function get_question_attempts($qid, $slot) {
return $this->db->get_recordset(
'question_attempts',
[
'questionid' => $qid,
'slot' => $slot
],
'',
'*'
);
}
/**
* @param $qid
* @return mixed
*/
public function get_reference_answer($qid) {
return $this->db->get_record(
'qtype_essay_options',
[
'questionid' => $qid
],
'*',
MUST_EXIST
)->graderinfo;
}
/**
* @param $question_attempt_id
* @return mixed
*/
public function get_attempt_steps($question_attempt_id) {
return $this->db->get_recordset(
'question_attempt_steps',
[
'questionattemptid' => $question_attempt_id
],
'',
'*'
);
}
/**
* @param $attemptstepid
* @return mixed
*/
public function get_student_answer($attemptstepid) {
return $this->db->get_record(
'question_attempt_step_data',
[
'attemptstepid' => $attemptstepid,
'name' => 'answer'
],
'*',
MUST_EXIST
)->value;
}
/**
* Checks if scores exist for a given quizid and userid.
* *
* * @param int $quizid quiz ID.
* * @param int $userid user ID.
* * @return bool Returns true if scores exist for a given quizid and userid, otherwise false.
*/
public function gradesExist(int $quizid, int $userid): bool {
global $DB;
// Check for the presence of an entry in the mdl_quiz_grades table for this quizid and userid
return $DB->record_exists(
'quiz_grades',
[
'quiz' => $quizid,
'userid' => $userid
]
);
}
}
M.local_asystgrade = {
init: function(Y, js_data) { // YUI Module entry point
init: function(Y, js_data) {
window.gradeData = js_data;
document.addEventListener('DOMContentLoaded', function() {
const apiEndpoint = M.cfg.wwwroot + '/local/asystgrade/api.php';
const gradesDataRequest = window.gradeData.request;
const maxmark = document.querySelectorAll("input[name$='-maxmark']")[0].value;
const answerDivs = document.querySelectorAll(".qtype_essay_response");
const studentAnswers = Array.from(answerDivs).map(element => element.innerText || element.value);
const gradesDataRequest = {
referenceAnswer: document.querySelectorAll(".essay .qtext p")[0].innerHTML,
studentAnswers: studentAnswers
};
if (gradesDataRequest) {
fetch(apiEndpoint, {
method: 'POST',
headers: {
......@@ -16,22 +21,25 @@ M.local_asystgrade = {
})
.then(response => response.json())
.then(data => {
if (data.success && data.grades) {
console.log(data.grades);
updateMarks(data.grades);
} else {
console.error('Error in grade response:', data.error);
}
})
.catch(error => console.error('Error:', error));
}
function updateMarks(grades) {
const inputs = document.querySelectorAll("input[name$='_-mark']");
grades.forEach((grade, index) => {
console.log(grade, index)
const predictedGrade = grade.predicted_grade === 'correct' ? window.gradeData.maxmark : 0;
const inputName = window.gradeData.formNames[index];
const gradeInput = document.querySelector(`input[name="${inputName}"]`);
const predictedGrade = grade.predicted_grade === 'correct' ? maxmark : 0;
if (gradeInput) {
gradeInput.value = predictedGrade;
if (inputs[index]) {
inputs[index].value = predictedGrade;
} else {
console.error(`Input field not found for name: ${inputName}`);
console.error(`No grade input found for index: ${index}`);
}
});
}
......
......@@ -20,8 +20,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
use local_asystgrade\db\quizquery;
defined('MOODLE_INTERNAL') || die();
/**
......@@ -34,85 +32,19 @@ defined('MOODLE_INTERNAL') || die();
function local_asystgrade_before_footer()
{
global $PAGE;
// Obtaining parameters from URL
$qid = optional_param('qid', null, PARAM_INT);
$slot = optional_param('slot', false, PARAM_INT);
if ($PAGE->url->compare(new moodle_url('/mod/quiz/report.php'), URL_MATCH_BASE) && $slot) {
$quizQuery = new quizquery();
if ($quizQuery->gradesExist($qid, $slot)) {
error_log('Grades already exist in the database.');
return;
}
$question_attempts = $quizQuery->get_question_attempts($qid, $slot);
$referenceAnswer = $quizQuery->get_reference_answer($qid);
$maxmark = (float)$question_attempts->current()->maxmark;
$data = prepare_api_data($quizQuery, $question_attempts, $referenceAnswer);
foreach (array_keys($data['studentData']) as $studentId) {
if ($quizQuery->gradesExist($qid, $studentId)) {
return;
}
}
$studentData = $data['studentData'];
$inputNames = array_column($studentData, 'inputName');
$js_data = [
'apiendpoint' => 'http://flask:5000/api/autograde',
'formNames' => $inputNames,
'maxmark' => $maxmark,
'request' => [
'referenceAnswer' => $data['referenceAnswer'],
'studentAnswers' => array_column($studentData, 'studentAnswer')
]
'qid' => $qid,
'slot' => $slot
];
$PAGE->requires->js(new moodle_url('/local/asystgrade/js/grade.js', ['v' => time()]));
$PAGE->requires->js_init_call('M.local_asystgrade.init', [$js_data]);
}
}
\ No newline at end of file
/**
* Processes question attempts and answers to prepare for API a data to estimate answers
*
* @param quizquery $database
* @param $question_attempts
* @param $referenceAnswer
* @return array
*/
function prepare_api_data(quizquery $database, $question_attempts, $referenceAnswer): array
{
$studentData = [];
foreach ($question_attempts as $question_attempt) {
$quizattempt_steps = $database->get_attempt_steps($question_attempt->id);
foreach ($quizattempt_steps as $quizattempt_step) {
if ($quizattempt_step->state === 'complete') {
$studentAnswer = $database->get_student_answer($quizattempt_step->id);
$studentId = $quizattempt_step->userid;
$inputName = "q" . $question_attempt->questionusageid . ":" . $question_attempt->slot . "_-mark";
// Adding data to an associative array
$studentData[$studentId] = [
'studentAnswer' => $studentAnswer,
'inputName' => $inputName // identifying name for mark input field updating
];
error_log("Student ID: $studentId, Student Answer: $studentAnswer, Input Name: $inputName");
}
}
$quizattempt_steps->close();
}
$question_attempts->close();
return [
'referenceAnswer' => $referenceAnswer,
'studentData' => $studentData
];
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment