Project 'ulrike.pado/asyst-moodle-plugin' was moved to 'knight/asyst-moodle-plugin'. Please update any links and bookmarks that may still have the old path.
Commit 0b8d71f6 authored by Artem Baranovskyi's avatar Artem Baranovskyi
Browse files

Added AJAX request with the endpoint using YUI.

parent d1e1acc0
Showing with 92 additions and 99 deletions
+92 -99
<?php
// local/asystgrade/api.php
require_once('../../config.php');
require_once('lib.php');
use local_asystgrade\api\client;
use local_asystgrade\api\http_client;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
if ($data) {
// Preparing Flask API
$apiendpoint = get_config('local_asystgrade', 'apiendpoint') ?: 'http://flask:5000/api/autograde';
$httpClient = new http_client();
$apiClient = client::getInstance($apiendpoint, $httpClient);
try {
// Sending data on Flask and obtaining an answer
$response = $apiClient->send_data($data);
$grades = json_decode($response, true);
// Check JSON validity
if (json_last_error() === JSON_ERROR_NONE) {
echo json_encode(['success' => true, 'grades' => $grades]);
} else {
echo json_encode(['error' => 'Invalid JSON from Flask API']);
}
} catch (Exception $e) {
echo json_encode(['error' => $e->getMessage()]);
}
} else {
echo json_encode(['error' => 'No data received']);
}
} else {
echo json_encode(['error' => 'Invalid request method']);
}
\ No newline at end of file
M.local_asystgrade = {
init: function(Y, js_data) { // YUI Module entry point
window.gradeData = js_data;
document.addEventListener('DOMContentLoaded', function() {
const apiEndpoint = M.cfg.wwwroot + '/local/asystgrade/api.php';
const gradesDataRequest = window.gradeData.request;
if (gradesDataRequest) {
fetch(apiEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(gradesDataRequest)
})
.then(response => response.json())
.then(data => {
updateMarks(data.grades);
})
.catch(error => console.error('Error:', error));
}
function updateMarks(grades) {
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}"]`);
if (gradeInput) {
gradeInput.value = predictedGrade;
} else {
console.error(`Input field not found for name: ${inputName}`);
}
});
}
});
}
};
\ No newline at end of file
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
use local_asystgrade\api\client;
use local_asystgrade\api\http_client;
use local_asystgrade\db\quizquery; use local_asystgrade\db\quizquery;
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
...@@ -62,54 +60,21 @@ function local_asystgrade_before_footer() ...@@ -62,54 +60,21 @@ function local_asystgrade_before_footer()
$studentData = $data['studentData']; $studentData = $data['studentData'];
$inputNames = array_column($studentData, 'inputName'); $inputNames = array_column($studentData, 'inputName');
error_log('Data prepared: ' . print_r($data, true)); $js_data = [
'apiendpoint' => 'http://flask:5000/api/autograde',
$apiendpoint = get_config('local_asystgrade', 'apiendpoint'); 'formNames' => $inputNames,
if (!$apiendpoint) { 'maxmark' => $maxmark,
$apiendpoint = 'http://flask:5000/api/autograde'; // Default setting, flask is the name of flask container 'request' => [
} 'referenceAnswer' => $data['referenceAnswer'],
'studentAnswers' => array_column($studentData, 'studentAnswer')
error_log('APIendpoint: ' . $apiendpoint); ]
];
try {
$httpClient = new http_client(); $PAGE->requires->js(new moodle_url('/local/asystgrade/js/grade.js', ['v' => time()]));
$apiClient = client::getInstance($apiendpoint, $httpClient); $PAGE->requires->js_init_call('M.local_asystgrade.init', [$js_data]);
error_log('ApiClient initiated.');
error_log('Sending data to API and getting grade');
$response = $apiClient->send_data([
'referenceAnswer' => $data['referenceAnswer'],
'studentAnswers' => array_column($studentData, 'studentAnswer')
]);
$grades = json_decode($response, true);
error_log('Grade obtained: ' . print_r($grades, true));
} catch (Exception $e) {
error_log('Error sending data to API: ' . $e->getMessage());
return;
}
error_log('After API call');
pasteGradedMarks($grades, $inputNames, $maxmark);
error_log('URL matches /mod/quiz/report.php in page_init');
} }
} }
/**
* Adds JavasScript scrypt to update marks
* @param array $grades
* @param array $inputNames
* @param float $maxmark
* @return void
*/
function pasteGradedMarks(array $grades, array $inputNames, float $maxmark): void
{
echo generate_script($grades, $inputNames, $maxmark);
}
/** /**
* Processes question attempts and answers to prepare for API a data to estimate answers * Processes question attempts and answers to prepare for API a data to estimate answers
* *
...@@ -150,55 +115,4 @@ function prepare_api_data(quizquery $database, $question_attempts, $referenceAns ...@@ -150,55 +115,4 @@ function prepare_api_data(quizquery $database, $question_attempts, $referenceAns
'referenceAnswer' => $referenceAnswer, 'referenceAnswer' => $referenceAnswer,
'studentData' => $studentData 'studentData' => $studentData
]; ];
} }
\ No newline at end of file
/**
* Builds JavasScript scrypt to update marks using DOM manipulations
*
* @param array $grades
* @param array $inputNames
* @param float $maxmark
* @return string
*/
function generate_script(array $grades, array $inputNames, float $maxmark) {
$script = "<script type='text/javascript'>
document.addEventListener('DOMContentLoaded', function() {";
foreach ($grades as $index => $grade) {
if (isset($grade['predicted_grade'])) {
$predicted_grade = $grade['predicted_grade'] == 'correct' ? $maxmark : 0;
$input_name = $inputNames[$index];
$script .= "
console.log('Trying to update input: {$input_name} with grade: {$predicted_grade}');
var gradeInput = document.querySelector('input[name=\"{$input_name}\"]');
if (gradeInput) {
console.log('Found input: {$input_name}');
gradeInput.value = '{$predicted_grade}';
} else {
console.log('Input not found: {$input_name}');
}";
}
}
$script .= "});
</script>";
return $script;
}
/**
* Autoloader registration
*/
//spl_autoload_register(function ($classname) {
// // Check if the class name starts with our plugin's namespace
// if (strpos($classname, 'local_asystgrade\\') === 0) {
// // Transforming the Namespace into the Path
// $classname = str_replace('local_asystgrade\\', '', $classname);
// $classname = str_replace('\\', DIRECTORY_SEPARATOR, $classname);
// $filepath = __DIR__ . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $classname . '.php';
//
// if (file_exists($filepath)) {
// require_once($filepath);
// }
// }
//});
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