diff --git a/asystgrade/api.php b/asystgrade/api.php new file mode 100644 index 0000000000000000000000000000000000000000..5fff84e4e4b1aecf059b87ef2b8957cb6cb8641b --- /dev/null +++ b/asystgrade/api.php @@ -0,0 +1,39 @@ +<?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 diff --git a/asystgrade/js/grade.js b/asystgrade/js/grade.js new file mode 100644 index 0000000000000000000000000000000000000000..3295616a9c7168e1a59c2b9df9fc6d1d8977d4e0 --- /dev/null +++ b/asystgrade/js/grade.js @@ -0,0 +1,40 @@ +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 diff --git a/asystgrade/lib.php b/asystgrade/lib.php index 625ae406d9dcde888b171ba5de2af0862f19bc28..299712fdbdb9b3de8449e5a8eeb80493175f5133 100755 --- a/asystgrade/lib.php +++ b/asystgrade/lib.php @@ -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\api\client; -use local_asystgrade\api\http_client; use local_asystgrade\db\quizquery; defined('MOODLE_INTERNAL') || die(); @@ -62,54 +60,21 @@ function local_asystgrade_before_footer() $studentData = $data['studentData']; $inputNames = array_column($studentData, 'inputName'); - error_log('Data prepared: ' . print_r($data, true)); - - $apiendpoint = get_config('local_asystgrade', 'apiendpoint'); - if (!$apiendpoint) { - $apiendpoint = 'http://flask:5000/api/autograde'; // Default setting, flask is the name of flask container - } - - error_log('APIendpoint: ' . $apiendpoint); - - try { - $httpClient = new http_client(); - $apiClient = client::getInstance($apiendpoint, $httpClient); - 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'); + $js_data = [ + 'apiendpoint' => 'http://flask:5000/api/autograde', + 'formNames' => $inputNames, + 'maxmark' => $maxmark, + 'request' => [ + 'referenceAnswer' => $data['referenceAnswer'], + 'studentAnswers' => array_column($studentData, 'studentAnswer') + ] + ]; + + $PAGE->requires->js(new moodle_url('/local/asystgrade/js/grade.js', ['v' => time()])); + $PAGE->requires->js_init_call('M.local_asystgrade.init', [$js_data]); } } -/** - * 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 * @@ -150,55 +115,4 @@ function prepare_api_data(quizquery $database, $question_attempts, $referenceAns 'referenceAnswer' => $referenceAnswer, 'studentData' => $studentData ]; -} - -/** - * 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); -// } -// } -//}); +} \ No newline at end of file