Commit 4e16f800 authored by Kurzenberger's avatar Kurzenberger
Browse files

refactored the code for the code checker plugin

parent 0e5e6553
Pipeline #10747 passed with stage
Showing with 903 additions and 675 deletions
+903 -675
<?php <?php
namespace assignsubmission_dta;
// This file is part of Moodle - http://moodle.org/ // This file is part of Moodle - http://moodle.org/
// //
// Moodle is free software: you can redistribute it and/or modify // Moodle is free software: you can redistribute it and/or modify
...@@ -15,92 +14,119 @@ namespace assignsubmission_dta; ...@@ -15,92 +14,119 @@ namespace assignsubmission_dta;
// 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/>.
/** namespace assignsubmission_dta;
* persistence layer utility class
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
use assignsubmission_dta\dta_backend_utils; use assignsubmission_dta\dta_backend_utils;
use assignsubmission_dta\dta_view_submission_utils; use assignsubmission_dta\dta_view_submission_utils;
use assignsubmission_dta\models\dta_result; use assignsubmission_dta\models\dta_result;
use assignsubmission_dta\models\dta_result_summary; use assignsubmission_dta\models\dta_result_summary;
use assignsubmission_dta\models\dta_recommendation; use assignsubmission_dta\models\dta_recommendation;
/**
* Class dta_db_utils
*
* Persistence layer utility class for storing and retrieving
* DTA plugin data (results, summaries, recommendations).
*
* @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dta_db_utils { class dta_db_utils {
/** /**
* Summary database table name. * Summary database table name.
*/ */
private const ASSIGNSUBMISSION_DTA_TABLE_SUMMARY = "assignsubmission_dta_summary"; private const ASSIGNSUBMISSION_DTA_TABLE_SUMMARY = 'assignsubmission_dta_summary';
/** /**
* Result database table name. * Result database table name.
*/ */
private const ASSIGNSUBMISSION_DTA_TABLE_RESULT = "assignsubmission_dta_result"; private const ASSIGNSUBMISSION_DTA_TABLE_RESULT = 'assignsubmission_dta_result';
private const ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS = "assignsubmission_dta_recommendations"; /**
* Recommendations database table name.
*/
private const ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS = 'assignsubmission_dta_recommendations';
public static function assignsubmission_dta_get_recommendations_from_database(int $assignmentid, int $submissionid): array { /**
global $DB,$USER; * Returns an array of recommendations from the database.
*
* @param int $assignmentid The assignment ID.
* @param int $submissionid The submission ID.
* @return array An array of recommendation records.
*/
public static function assignsubmission_dta_get_recommendations_from_database(
int $assignmentid,
int $submissionid
): array {
global $DB, $USER;
$userid = $USER->id; $userid = $USER->id;
// Schritt 1: Alle Empfehlungen abrufen // Step 1: Retrieve all recommendations.
$records = $DB->get_records(self::ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS, [ $records = $DB->get_records(
'assignment_id' => $assignmentid, self::ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS,
'submission_id' => $submissionid, [
]); 'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
// Schritt 2: Modul-ID für 'assign' abrufen ]
);
// Step 2: Retrieve module ID for 'assign'.
$module = $DB->get_record('modules', ['name' => 'assign'], 'id'); $module = $DB->get_record('modules', ['name' => 'assign'], 'id');
if (!$module) { if (!$module) {
// Fehlerbehandlung, falls das Modul nicht gefunden wird // Handle error case if the module is not found.
return $records; return $records;
} }
$moduleid = $module->id; $moduleid = $module->id;
print_r($records);
// Schritt 3: Überprüfe jeden Datensatz // Step 3: Check each record.
foreach ($records as $key => $record) { foreach ($records as $key => $record) {
// Hol den Namen der Übung aus dem Datensatz // Get the name of the exercise from the record.
$exercisename = $record->exercise_name; $exercisename = $record->exercise_name;
// Suche das Assignment mit diesem Namen // Find the assignment with this name.
$assign = $DB->get_record('assign', ['name' => $exercisename], 'id'); $assign = $DB->get_record('assign', ['name' => $exercisename], 'id');
if ($assign) { if ($assign) {
// Hole die Kursmodul-ID (coursemoduleid) für dieses Assignment // Get the course module ID for this assignment.
$cm = $DB->get_record('course_modules', [ $cm = $DB->get_record(
'module' => $moduleid, 'course_modules',
'instance' => $assign->id [
], 'id'); 'module' => $moduleid,
'instance' => $assign->id,
],
'id'
);
if ($cm) { if ($cm) {
// Überprüfe den Abschlussstatus für dieses Kursmodul und den Benutzer // Check the completion status for this course module and user.
$completion = $DB->get_record('course_modules_completion', [ $completion = $DB->get_record(
'coursemoduleid' => $cm->id, 'course_modules_completion',
'userid' => $userid [
], 'completionstate'); 'coursemoduleid' => $cm->id,
'userid' => $userid,
// Wenn der Abschlussstatus 1 ist, entferne den Datensatz aus $records ],
if ($completion && $completion->completionstate == 1) { 'completionstate'
unset($records[$key]); );
// If the completion state is 1, remove the record from $records.
if ($completion && (int)$completion->completionstate === 1) {
unset($records[$key]);
} }
} }
} }
} }
// Rückgabe der gefilterten Datensätze // Return the filtered records.
return $records; return $records;
} }
/** /**
* gets summary with all corresponding result entries * Gets a summary with all corresponding result entries.
* *
* @param int $assignmentid assignment id to search for * @param int $assignmentid Assignment ID to search for.
* @param int $submissionid submission id to search for * @param int $submissionid Submission ID to search for.
* @return DttResultSummary representing given submission * @return dta_result_summary Summary representing the submission.
*/ */
public static function assignsubmission_dta_get_result_summary_from_database( public static function assignsubmission_dta_get_result_summary_from_database(
int $assignmentid, int $assignmentid,
...@@ -109,15 +135,21 @@ class dta_db_utils { ...@@ -109,15 +135,21 @@ class dta_db_utils {
global $DB; global $DB;
// Fetch data from database. // Fetch data from database.
$summaryrecord = $DB->get_record(self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY, [ $summaryrecord = $DB->get_record(
"assignment_id" => $assignmentid, self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY,
"submission_id" => $submissionid, [
]); 'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]
);
$resultsarray = $DB->get_records(self::ASSIGNSUBMISSION_DTA_TABLE_RESULT, [ $resultsarray = $DB->get_records(
"assignment_id" => $assignmentid, self::ASSIGNSUBMISSION_DTA_TABLE_RESULT,
"submission_id" => $submissionid, [
]); 'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]
);
// Create a summary instance. // Create a summary instance.
$summary = new dta_result_summary(); $summary = new dta_result_summary();
...@@ -146,55 +178,69 @@ class dta_db_utils { ...@@ -146,55 +178,69 @@ class dta_db_utils {
return $summary; return $summary;
} }
/**
* Stores an array of recommendations in the database.
*
* @param int $assignmentid The assignment ID.
* @param int $submissionid The submission ID.
* @param array $recommendations An array of dta_recommendation objects.
*/
public static function assignsubmission_dta_store_recommendations_to_database( public static function assignsubmission_dta_store_recommendations_to_database(
int $assignmentid, int $assignmentid,
int $submissionid, int $submissionid,
array $recommendations array $recommendations
): void { ): void {
global $DB; global $DB;
error_log(print_r($recommendations, true));
// Debug output (you can remove or adapt this if unneeded).
debugging('Recommendations array: ' . json_encode($recommendations));
// If recommendations already exist, delete old values beforehand. // If recommendations already exist, delete old values beforehand.
$existingrecords = $DB->get_records('assignsubmission_dta_recommendations', [ $existingrecords = $DB->get_records(
'assignment_id' => $assignmentid, 'assignsubmission_dta_recommendations',
'submission_id' => $submissionid, [
]);
if ($existingrecords) {
$DB->delete_records('assignsubmission_dta_recommendations', [
'assignment_id' => $assignmentid, 'assignment_id' => $assignmentid,
'submission_id' => $submissionid, 'submission_id' => $submissionid,
]); ]
);
if ($existingrecords) {
$DB->delete_records(
'assignsubmission_dta_recommendations',
[
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]
);
} }
// Create new recommendation entries. // Create new recommendation entries.
foreach ($recommendations as $recommendation) { foreach ($recommendations as $recommendation) {
// Ensure $recommendation is an instance of DtaRecommendation // Check if $recommendation is an instance of dta_recommendation.
if ($recommendation instanceof dta_recommendation) { if ($recommendation instanceof dta_recommendation) {
// Add assignment and submission IDs to the recommendation object // Add assignment and submission IDs to the recommendation object.
$recommendation->assignment_id = $assignmentid; $recommendation->assignment_id = $assignmentid;
$recommendation->submission_id = $submissionid; $recommendation->submission_id = $submissionid;
error_log("Insert record"); debugging('Inserting new recommendation record: ' . json_encode($recommendation));
error_log(print_r($recommendation, true));
// Insert the recommendation into the database.
// Insert the recommendation into the database
$DB->insert_record('assignsubmission_dta_recommendations', $recommendation); $DB->insert_record('assignsubmission_dta_recommendations', $recommendation);
} else { } else {
// Handle the case where $recommendation is not a DtaRecommendation instance // Handle the case where $recommendation is not a dta_recommendation instance.
error_log("Invalid recommendation object"); debugging('Invalid recommendation object encountered.');
} }
} }
} }
/** /**
* save given result summary and single results to database * Saves the given result summary and single results to the database
* under given assignment and submission id * under the specified assignment and submission ID.
* *
* @param int $assignmentid assigment this is submission is linked to * @param int $assignmentid Assignment this submission is linked to.
* @param int $submissionid submission of this result * @param int $submissionid Submission ID for these results.
* @param dta_result_summary $summary instance to persist * @param dta_result_summary $summary Summary instance to persist.
*/ */
public static function assignsubmission_dta_store_result_summary_to_database( public static function assignsubmission_dta_store_result_summary_to_database(
int $assignmentid, int $assignmentid,
...@@ -211,8 +257,8 @@ class dta_db_utils { ...@@ -211,8 +257,8 @@ class dta_db_utils {
$summaryrecord->global_stacktrace = $summary->globalstacktrace; $summaryrecord->global_stacktrace = $summary->globalstacktrace;
$summaryrecord->successful_competencies = $summary->successfultestcompetencies; $summaryrecord->successful_competencies = $summary->successfultestcompetencies;
$summaryrecord->tested_competencies = $summary->overalltestcompetencies; $summaryrecord->tested_competencies = $summary->overalltestcompetencies;
// Prepare results to persist to array. // Prepare results to persist.
$resultrecords = []; $resultrecords = [];
foreach ($summary->results as $r) { foreach ($summary->results as $r) {
$record = new dta_result(); $record = new dta_result();
...@@ -232,21 +278,30 @@ class dta_db_utils { ...@@ -232,21 +278,30 @@ class dta_db_utils {
} }
// If results already exist, delete old values beforehand. // If results already exist, delete old values beforehand.
$submission = $DB->get_record(self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY, [ $submission = $DB->get_record(
'assignment_id' => $assignmentid, self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY,
'submission_id' => $submissionid, [
]);
if ($submission) {
$DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_RESULT, [
'assignment_id' => $assignmentid, 'assignment_id' => $assignmentid,
'submission_id' => $submissionid, 'submission_id' => $submissionid,
]); ]
);
$DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY, [ if ($submission) {
'assignment_id' => $assignmentid, $DB->delete_records(
'submission_id' => $submissionid, self::ASSIGNSUBMISSION_DTA_TABLE_RESULT,
]); [
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]
);
$DB->delete_records(
self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY,
[
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]
);
} }
// Create summary and single result entries. // Create summary and single result entries.
...@@ -257,7 +312,7 @@ class dta_db_utils { ...@@ -257,7 +312,7 @@ class dta_db_utils {
} }
/** /**
* cleans up database if plugin is uninstalled * Cleans up database if plugin is uninstalled.
*/ */
public static function assignsubmission_dta_uninstall_plugin_cleaup(): void { public static function assignsubmission_dta_uninstall_plugin_cleaup(): void {
global $DB; global $DB;
...@@ -265,7 +320,5 @@ class dta_db_utils { ...@@ -265,7 +320,5 @@ class dta_db_utils {
$DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_RESULT, null); $DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_RESULT, null);
$DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY, null); $DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY, null);
$DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS, null); $DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS, null);
} }
} }
<?php <?php
// This file is part of Moodle - http://moodle.org/.
// This file is part of Moodle - http://moodle.org/
// //
// Moodle is free software: you can redistribute it and/or modify // Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
...@@ -16,40 +15,44 @@ ...@@ -16,40 +15,44 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/** /**
* This file contains the backend webservice contact functionality for the DTA plugin * This file contains the backend webservice contact functionality for the DTA plugin.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @copyright 2023 Your Name
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
namespace assignsubmission_dta;
/** /**
* Backend webservice contact utility class * Backend webservice contact utility class.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @copyright 2023 Your Name
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
namespace assignsubmission_dta;
defined('MOODLE_INTERNAL') || die();
class dta_backend_utils { class dta_backend_utils {
/** /**
* Component name for the plugin. * Component name for the plugin.
*/ */
const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta'; public const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta';
/** /**
* Returns the base URL of the backend webservice as configured in the administration settings. * Returns the base URL of the backend webservice as configured in the administration settings.
* @return string Backend host base URL *
* @return string Backend host base URL.
*/ */
private static function assignsubmission_dta_get_backend_baseurl(): string { private static function assignsubmission_dta_get_backend_baseurl(): string {
$backendaddress = get_config(self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME, 'backendHost'); $backendaddress = get_config(
self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME,
'backendHost'
);
if (empty($backendaddress)) { if (empty($backendaddress)) {
\core\notification::error(get_string('backendHost_not_set', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)); \core\notification::error(
get_string('backendHost_not_set', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
);
} }
return $backendaddress; return $backendaddress;
...@@ -58,9 +61,9 @@ class dta_backend_utils { ...@@ -58,9 +61,9 @@ class dta_backend_utils {
/** /**
* Sends the configuration text file uploaded by the teacher to the backend. * Sends the configuration text file uploaded by the teacher to the backend.
* *
* @param \assign $assignment Assignment this test-config belongs to * @param \assign $assignment Assignment this test-config belongs to.
* @param \stored_file $file Uploaded test-config * @param \stored_file $file Uploaded test-config.
* @return bool True if no error occurred * @return bool True if no error occurred.
*/ */
public static function assignsubmission_dta_send_testconfig_to_backend($assignment, $file): bool { public static function assignsubmission_dta_send_testconfig_to_backend($assignment, $file): bool {
$backendaddress = self::assignsubmission_dta_get_backend_baseurl(); $backendaddress = self::assignsubmission_dta_get_backend_baseurl();
...@@ -88,12 +91,16 @@ class dta_backend_utils { ...@@ -88,12 +91,16 @@ class dta_backend_utils {
/** /**
* Sends submission config or archive to backend to be tested. * Sends submission config or archive to backend to be tested.
* *
* @param \assign $assignment Assignment for the submission * @param \assign $assignment Assignment for the submission.
* @param int $submissionid Submission ID of the current file * @param int $submissionid Submission ID of the current file.
* @param \stored_file $file Submission config file or archive with submission * @param \stored_file $file Submission config file or archive with submission.
* @return string|null JSON string with test results or null on error * @return string|null JSON string with test results or null on error.
*/ */
public static function assignsubmission_dta_send_submission_to_backend($assignment, $submissionid, $file): ?string { public static function assignsubmission_dta_send_submission_to_backend(
$assignment,
int $submissionid,
$file
): ?string {
$backendaddress = self::assignsubmission_dta_get_backend_baseurl(); $backendaddress = self::assignsubmission_dta_get_backend_baseurl();
if (empty($backendaddress)) { if (empty($backendaddress)) {
return null; return null;
...@@ -113,12 +120,12 @@ class dta_backend_utils { ...@@ -113,12 +120,12 @@ class dta_backend_utils {
/** /**
* Posts the given params to the given URL and returns the response as a string. * Posts the given params to the given URL and returns the response as a string.
* @param string $url Full URL to request to
* @param array $params Parameters for HTTP request
* *
* @return string|null Received body on success or null on error * @param string $url Full URL to request.
* @param array $params Parameters for HTTP request.
* @return string|null Received body on success or null on error.
*/ */
private static function assignsubmission_dta_post($url, $params): ?string { private static function assignsubmission_dta_post(string $url, array $params): ?string {
if (!isset($url) || !isset($params)) { if (!isset($url) || !isset($params)) {
return null; return null;
} }
...@@ -128,23 +135,32 @@ class dta_backend_utils { ...@@ -128,23 +135,32 @@ class dta_backend_utils {
$curl = new \curl(); $curl = new \curl();
$response = $curl->post($url, $params, $options); $response = $curl->post($url, $params, $options);
// Check state of request, if response code is a 2xx return the answer. // Check state of request, if response code is 2xx, return the answer.
$info = $curl->get_info(); $info = $curl->get_info();
if ($info['http_code'] >= 200 && $info['http_code'] < 300) { if ($info['http_code'] >= 200 && $info['http_code'] < 300) {
return $response; return $response;
} }
// Something went wrong, return null and give an error message. // Something went wrong, return null and display an error message.
debugging(self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME . ': Post file to server was not successful: http_code=' . $info['http_code']); $msg = self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME
. ': Post file to server was not successful. HTTP code='
. $info['http_code'];
debugging($msg);
if ($info['http_code'] >= 400 && $info['http_code'] < 500) { if ($info['http_code'] >= 400 && $info['http_code'] < 500) {
\core\notification::error(get_string('http_client_error_msg', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)); \core\notification::error(
get_string('http_client_error_msg', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
);
return null; return null;
} else if ($info['http_code'] >= 500 && $info['http_code'] < 600) { } else if ($info['http_code'] >= 500 && $info['http_code'] < 600) {
\core\notification::error(get_string('http_server_error_msg', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)); \core\notification::error(
get_string('http_server_error_msg', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
);
return null; return null;
} else { } else {
\core\notification::error(get_string('http_unknown_error_msg', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . $info['http_code'] . $response); $unknownmsg = get_string('http_unknown_error_msg', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
. $info['http_code'] . ' ' . $response;
\core\notification::error($unknownmsg);
return null; return null;
} }
} }
......
This diff is collapsed.
<?php <?php
// This file is part of Moodle - http://moodle.org/ // This file is part of Moodle - http://moodle.org/.
// //
// Moodle is free software: you can redistribute it and/or modify // Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/** /**
* Entity class for DTA submission plugin recommendation * Entity class for DTA submission plugin recommendation.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer * @copyright 2023 Gero Lueckemeyer
...@@ -24,10 +24,8 @@ ...@@ -24,10 +24,8 @@
namespace assignsubmission_dta\models; namespace assignsubmission_dta\models;
defined('MOODLE_INTERNAL') || die();
/** /**
* Entity class for DTA submission plugin recommendation * Entity class for DTA submission plugin recommendation.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @copyright 2023 * @copyright 2023
...@@ -41,9 +39,9 @@ class dta_recommendation { ...@@ -41,9 +39,9 @@ class dta_recommendation {
public $topic; public $topic;
/** /**
* @var string $exercise_name Name of the exercise. * @var string $exerciseName Name of the exercise.
*/ */
public $exercise_name; public $exerciseName;
/** /**
* @var string $url URL of the exercise. * @var string $url URL of the exercise.
...@@ -61,22 +59,22 @@ class dta_recommendation { ...@@ -61,22 +59,22 @@ class dta_recommendation {
public $score; public $score;
/** /**
* Decodes the JSON recommendations returned by the backend service call into an array of DtaRecommendation objects. * Decodes the JSON recommendations returned by the backend service call into an array of dta_recommendation objects.
* *
* @param string $jsonstring JSON string containing recommendations * @param string $jsonstring JSON string containing recommendations.
* @return array Array of DtaRecommendation objects * @return array Array of dta_recommendation objects.
*/ */
public static function assignsubmission_dta_decode_json_recommendations(string $jsonstring): array { public static function assignsubmission_dta_decode_json_recommendations(string $jsonstring): array {
$response = json_decode($jsonstring); $response = json_decode($jsonstring);
$recommendations = []; $recommendations = [];
// Prüfe, ob Empfehlungen vorhanden sind // Check if recommendations exist.
if (!empty($response->recommendations)) { if (!empty($response->recommendations)) {
foreach ($response->recommendations as $recommendation) { foreach ($response->recommendations as $recommendation) {
$rec = new dta_recommendation(); $rec = new dta_recommendation();
$rec->topic = $recommendation->topic ?? null; $rec->topic = $recommendation->topic ?? null;
$rec->exercise_name = $recommendation->url ?? null; // Map correct fields to the renamed variable names:
$rec->exerciseName = $recommendation->url ?? null;
$rec->url = $recommendation->exerciseName ?? null; $rec->url = $recommendation->exerciseName ?? null;
$rec->difficulty = $recommendation->difficulty ?? null; $rec->difficulty = $recommendation->difficulty ?? null;
$rec->score = $recommendation->score ?? null; $rec->score = $recommendation->score ?? null;
......
<?php <?php
// This file is part of Moodle - http://moodle.org/ // This file is part of Moodle - http://moodle.org/.
// //
// Moodle is free software: you can redistribute it and/or modify // Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/** /**
* Entity class for DTA submission plugin result * Entity class for DTA submission plugin result.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer and student project teams * @copyright 2023 Gero Lueckemeyer and student project teams
...@@ -24,10 +24,8 @@ ...@@ -24,10 +24,8 @@
namespace assignsubmission_dta\models; namespace assignsubmission_dta\models;
defined('MOODLE_INTERNAL') || die();
/** /**
* Entity class for DTA submission plugin result * Entity class for DTA submission plugin result.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer and student project teams * @copyright 2023 Gero Lueckemeyer and student project teams
...@@ -38,7 +36,7 @@ class dta_result { ...@@ -38,7 +36,7 @@ class dta_result {
/** /**
* Broadly used in logic, parametrized for easier change. * Broadly used in logic, parametrized for easier change.
*/ */
const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta'; public const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta';
/** /**
* @var string $packagename Package name of the test. * @var string $packagename Package name of the test.
...@@ -97,15 +95,15 @@ class dta_result { ...@@ -97,15 +95,15 @@ class dta_result {
/** /**
* Returns the name of a state with the given number for display. * Returns the name of a state with the given number for display.
* *
* @param int $state Number of the state * @param int $state Number of the state.
* @return string Name of state as defined * @return string Name of state as defined.
*/ */
public static function assignsubmission_dta_get_statename(int $state): string { public static function assignsubmission_dta_get_statename(int $state): string {
if ($state == 1) { if ($state === 1) {
return get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME); return get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME);
} else if ($state == 2) { } else if ($state === 2) {
return get_string('failures', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME); return get_string('failures', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME);
} else if ($state == 3) { } else if ($state === 3) {
return get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME); return get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME);
} else { } else {
return get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME); return get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME);
......
<?php <?php
// This file is part of Moodle - http://moodle.org/ // This file is part of Moodle - http://moodle.org/.
// //
// Moodle is free software: you can redistribute it and/or modify // Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/** /**
* Entity class for DTA submission plugin result summary * Entity class for DTA submission plugin result summary.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer and student project teams * @copyright 2023 Gero Lueckemeyer and student project teams
...@@ -24,10 +24,8 @@ ...@@ -24,10 +24,8 @@
namespace assignsubmission_dta\models; namespace assignsubmission_dta\models;
defined('MOODLE_INTERNAL') || die();
/** /**
* Entity class for DTA submission plugin result summary * Entity class for DTA submission plugin result summary.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer and student project teams * @copyright 2023 Gero Lueckemeyer and student project teams
...@@ -36,22 +34,22 @@ defined('MOODLE_INTERNAL') || die(); ...@@ -36,22 +34,22 @@ defined('MOODLE_INTERNAL') || die();
class dta_result_summary { class dta_result_summary {
/** /**
* @var int $timestamp Result timestamp for chronological ordering and deletion of previous results. * @var int $timestamp Timestamp for ordering and deletion of previous results.
*/ */
public $timestamp; public $timestamp;
/** /**
* @var string $globalstacktrace Global stack trace if applicable, empty string otherwise. * @var string $globalstacktrace Global stack trace if applicable, empty otherwise.
*/ */
public $globalstacktrace; public $globalstacktrace;
/** /**
* @var string $successfultestcompetencies Successfully tested competencies according to tests and weights, empty string otherwise. * @var string $successfultestcompetencies Successfully tested competencies (tests and weights), or empty string.
*/ */
public $successfultestcompetencies; public $successfultestcompetencies;
/** /**
* @var string $overalltestcompetencies Overall tested competencies according to tests and weights, empty string otherwise. * @var string $overalltestcompetencies Overall tested competencies (tests and weights), or empty string.
*/ */
public $overalltestcompetencies; public $overalltestcompetencies;
...@@ -63,8 +61,8 @@ class dta_result_summary { ...@@ -63,8 +61,8 @@ class dta_result_summary {
/** /**
* Decodes the JSON result summary returned by the backend service call into the plugin PHP data structure. * Decodes the JSON result summary returned by the backend service call into the plugin PHP data structure.
* *
* @param string $jsonstring JSON string containing DtaResultSummary * @param string $jsonstring JSON string containing DtaResultSummary.
* @return DtaResultSummary The result summary * @return dta_result_summary The result summary.
*/ */
public static function assignsubmission_dta_decode_json(string $jsonstring): dta_result_summary { public static function assignsubmission_dta_decode_json(string $jsonstring): dta_result_summary {
$response = json_decode($jsonstring); $response = json_decode($jsonstring);
...@@ -82,10 +80,10 @@ class dta_result_summary { ...@@ -82,10 +80,10 @@ class dta_result_summary {
} }
/** /**
* Decodes the array of JSON detail results returned by the backend service call into the plugin PHP data structure. * Decodes an array of JSON detail results into the plugin PHP data structure.
* *
* @param array $jsonarray Decoded JSON array of results * @param array $jsonarray Decoded JSON array of results.
* @return array Array of DtaResult * @return array Array of dta_result objects.
*/ */
private static function assignsubmission_dta_decode_json_result_array(array $jsonarray): array { private static function assignsubmission_dta_decode_json_result_array(array $jsonarray): array {
$ret = []; $ret = [];
...@@ -94,13 +92,10 @@ class dta_result_summary { ...@@ -94,13 +92,10 @@ class dta_result_summary {
$value->packagename = $entry->packageName ?? ''; $value->packagename = $entry->packageName ?? '';
$value->classname = $entry->className ?? ''; $value->classname = $entry->className ?? '';
$value->name = $entry->name ?? ''; $value->name = $entry->name ?? '';
$value->state = $entry->state ?? 0; $value->state = $entry->state ?? 0;
$value->failuretype = $entry->failureType ?? ''; $value->failuretype = $entry->failureType ?? '';
$value->failurereason = $entry->failureReason ?? ''; $value->failurereason = $entry->failureReason ?? '';
$value->stacktrace = $entry->stacktrace ?? ''; $value->stacktrace = $entry->stacktrace ?? '';
$value->columnnumber = $entry->columnNumber ?? ''; $value->columnnumber = $entry->columnNumber ?? '';
$value->linenumber = $entry->lineNumber ?? ''; $value->linenumber = $entry->lineNumber ?? '';
$value->position = $entry->position ?? ''; $value->position = $entry->position ?? '';
...@@ -113,7 +108,7 @@ class dta_result_summary { ...@@ -113,7 +108,7 @@ class dta_result_summary {
/** /**
* Returns the number of detail results attached to the summary. * Returns the number of detail results attached to the summary.
* *
* @return int Count of occurrences * @return int Count of occurrences.
*/ */
public function assignsubmission_dta_result_count(): int { public function assignsubmission_dta_result_count(): int {
return count($this->results); return count($this->results);
...@@ -122,13 +117,13 @@ class dta_result_summary { ...@@ -122,13 +117,13 @@ class dta_result_summary {
/** /**
* Returns the number of detail results with the given state attached to the summary. * Returns the number of detail results with the given state attached to the summary.
* *
* @param int $state State ordinal number * @param int $state State ordinal number.
* @return int Count of occurrences for the provided state * @return int Count of occurrences for the provided state.
*/ */
public function assignsubmission_dta_state_occurence_count(int $state): int { public function assignsubmission_dta_state_occurence_count(int $state): int {
$num = 0; $num = 0;
foreach ($this->results as $r) { foreach ($this->results as $r) {
if ($r->state == $state) { if ($r->state === $state) {
$num++; $num++;
} }
} }
...@@ -138,7 +133,7 @@ class dta_result_summary { ...@@ -138,7 +133,7 @@ class dta_result_summary {
/** /**
* Returns the number of detail results with compilation errors attached to the summary. * Returns the number of detail results with compilation errors attached to the summary.
* *
* @return int Count of occurrences * @return int Count of occurrences.
*/ */
public function assignsubmission_dta_compilation_error_count(): int { public function assignsubmission_dta_compilation_error_count(): int {
return $this->assignsubmission_dta_state_occurence_count(3); return $this->assignsubmission_dta_state_occurence_count(3);
...@@ -147,7 +142,7 @@ class dta_result_summary { ...@@ -147,7 +142,7 @@ class dta_result_summary {
/** /**
* Returns the number of detail results with test failures attached to the summary. * Returns the number of detail results with test failures attached to the summary.
* *
* @return int Count of occurrences * @return int Count of occurrences.
*/ */
public function assignsubmission_dta_failed_count(): int { public function assignsubmission_dta_failed_count(): int {
return $this->assignsubmission_dta_state_occurence_count(2); return $this->assignsubmission_dta_state_occurence_count(2);
...@@ -156,7 +151,7 @@ class dta_result_summary { ...@@ -156,7 +151,7 @@ class dta_result_summary {
/** /**
* Returns the number of detail results with successful tests attached to the summary. * Returns the number of detail results with successful tests attached to the summary.
* *
* @return int Count of occurrences * @return int Count of occurrences.
*/ */
public function assignsubmission_dta_successful_count(): int { public function assignsubmission_dta_successful_count(): int {
return $this->assignsubmission_dta_state_occurence_count(1); return $this->assignsubmission_dta_state_occurence_count(1);
...@@ -165,7 +160,7 @@ class dta_result_summary { ...@@ -165,7 +160,7 @@ class dta_result_summary {
/** /**
* Returns the number of detail results with an unknown result attached to the summary. * Returns the number of detail results with an unknown result attached to the summary.
* *
* @return int Count of occurrences * @return int Count of occurrences.
*/ */
public function assignsubmission_dta_unknown_count(): int { public function assignsubmission_dta_unknown_count(): int {
return $this->assignsubmission_dta_state_occurence_count(0); return $this->assignsubmission_dta_state_occurence_count(0);
......
<?php <?php
// This file is part of Moodle - http://moodle.org/ // This file is part of Moodle - http://moodle.org/.
// //
// Moodle is free software: you can redistribute it and/or modify // Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,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/>.
defined('MOODLE_INTERNAL') || die();
use assignsubmission_dta\dta_db_utils; use assignsubmission_dta\dta_db_utils;
use assignsubmission_dta\dta_backend_utils; use assignsubmission_dta\dta_backend_utils;
use assignsubmission_dta\dta_view_submission_utils; use assignsubmission_dta\dta_view_submission_utils;
...@@ -24,50 +22,58 @@ use assignsubmission_dta\models\dta_result_summary; ...@@ -24,50 +22,58 @@ use assignsubmission_dta\models\dta_result_summary;
use assignsubmission_dta\models\dta_recommendation; use assignsubmission_dta\models\dta_recommendation;
/** /**
* Library class for DTA submission plugin extending assign submission plugin base class * Library class for DTA submission plugin extending assign submission plugin base class.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @copyright 2023 Your Name or Organization
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class assign_submission_dta extends assign_submission_plugin { class assign_submission_dta extends assign_submission_plugin {
/** /**
* Broadly used in logic, parametrized for easier change. * Broadly used in logic, parametrized for easier change.
*/ */
const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = "assignsubmission_dta"; public const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta';
/** /**
* Draft file area for DTA tests to be uploaded by the teacher. * Draft file area for DTA tests to be uploaded by the teacher.
*/ */
const ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST = "tests_draft_dta"; public const ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST = 'tests_draft_dta';
/** /**
* File area for DTA tests to be uploaded by the teacher. * File area for DTA tests to be uploaded by the teacher.
*/ */
const ASSIGNSUBMISSION_DTA_FILEAREA_TEST = "tests_dta"; public const ASSIGNSUBMISSION_DTA_FILEAREA_TEST = 'tests_dta';
/** /**
* File area for DTA submission assignment. * File area for DTA submission assignment.
*/ */
const ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION = "submissions_dta"; public const ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION = 'submissions_dta';
/** /**
* Get plugin name * Get plugin name.
*
* @return string * @return string
*/ */
public function assignsubmission_dta_get_name(): string { public function assignsubmission_dta_get_name(): string {
return get_string("pluginname", self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME); return get_string('pluginname', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME);
} }
/** /**
* Get default settings for assignment submission settings * Get default settings for assignment submission settings.
* *
* @param MoodleQuickForm $mform form to add elements to * @param MoodleQuickForm $mform Form to add elements to.
* @return void * @return void
*/ */
public function assignsubmission_dta_get_settings(MoodleQuickForm $mform): void { public function assignsubmission_dta_get_settings(MoodleQuickForm $mform): void {
// Add draft filemanager to form. // Add draft filemanager to form.
$mform->addElement( $mform->addElement(
"filemanager", 'filemanager',
self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST, self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST,
get_string("submission_settings_label", self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string(
'submission_settings_label',
self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME
),
null, null,
$this->get_file_options(true) $this->get_file_options(true)
); );
...@@ -77,7 +83,7 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -77,7 +83,7 @@ class assign_submission_dta extends assign_submission_plugin {
// Form-unique element id to which to add button. // Form-unique element id to which to add button.
self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST, self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST,
// Key. // Key.
"submission_settings_label", 'submission_settings_label',
// Language file to use. // Language file to use.
self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME
); );
...@@ -96,12 +102,15 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -96,12 +102,15 @@ class assign_submission_dta extends assign_submission_plugin {
/** /**
* Allows the plugin to update the default values passed into * Allows the plugin to update the default values passed into
* the settings form (needed to set up draft areas for editor * the settings form (needed to set up draft areas for editor
* and filemanager elements) * and filemanager elements).
* @param array $defaultvalues *
* @param array $defaultvalues Default values to update.
*/ */
public function data_preprocessing(&$defaultvalues): void { public function data_preprocessing(&$defaultvalues): void {
// Get id of draft area for file manager creation. // Get id of draft area for file manager creation.
$draftitemid = file_get_submitted_draft_itemid(self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST); $draftitemid = file_get_submitted_draft_itemid(
self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST
);
// Prepare draft area with created draft filearea. // Prepare draft area with created draft filearea.
file_prepare_draft_area( file_prepare_draft_area(
...@@ -117,14 +126,13 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -117,14 +126,13 @@ class assign_submission_dta extends assign_submission_plugin {
} }
/** /**
* Save settings of assignment submission settings * Save settings of assignment submission settings.
* *
* @param stdClass $data * @param stdClass $data Form data.
* @return bool * @return bool
*/ */
public function assignsubmission_dta_save_settings(stdClass $data): bool { public function assignsubmission_dta_save_settings(stdClass $data): bool {
// If the assignment has no filemanager for our plugin, just leave.
// If the assignment has no filemanager for our plugin just leave.
$draftfilemanagerid = self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST; $draftfilemanagerid = self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST;
if (!isset($data->$draftfilemanagerid)) { if (!isset($data->$draftfilemanagerid)) {
return true; return true;
...@@ -155,7 +163,9 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -155,7 +163,9 @@ class assign_submission_dta extends assign_submission_plugin {
// Check if a file was uploaded. // Check if a file was uploaded.
if (empty($files)) { if (empty($files)) {
\core\notification::error(get_string("no_testfile_warning", self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)); \core\notification::error(
get_string('no_testfile_warning', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
);
return true; return true;
} }
...@@ -163,19 +173,27 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -163,19 +173,27 @@ class assign_submission_dta extends assign_submission_plugin {
$file = reset($files); $file = reset($files);
// Send file to backend. // Send file to backend.
return dta_backend_utils::assignsubmission_dta_send_testconfig_to_backend($this->assignment, $file); return dta_backend_utils::assignsubmission_dta_send_testconfig_to_backend(
$this->assignment,
$file
);
} }
/** /**
* Add elements to submission form * Add elements to submission form.
* *
* @param mixed $submissionorgrade stdClass|null submission or grade to show in the form * @param stdClass|null $submissionorgrade Submission or grade to show in the form.
* @param MoodleQuickForm $mform form for adding elements * @param MoodleQuickForm $mform Form for adding elements.
* @param stdClass $data data for filling the elements * @param stdClass $data Data for filling the elements.
* @param int $userid current user * @param int $userid Current user.
* @return bool form elements added * @return bool True if form elements added.
*/ */
public function get_form_elements_for_user($submissionorgrade, MoodleQuickForm $mform, stdClass $data, $userid): bool { public function get_form_elements_for_user(
$submissionorgrade,
MoodleQuickForm $mform,
stdClass $data,
$userid
): bool {
// Prepare submission filearea. // Prepare submission filearea.
$data = file_prepare_standard_filemanager( $data = file_prepare_standard_filemanager(
$data, $data,
...@@ -193,20 +211,15 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -193,20 +211,15 @@ class assign_submission_dta extends assign_submission_plugin {
// Form-unique identifier. // Form-unique identifier.
'tasks_filemanager', 'tasks_filemanager',
// Label to show next to the filemanager. // Label to show next to the filemanager.
get_string("submission_label", self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string('submission_label', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
// Attributes.
null, null,
// Options.
$this->get_file_options(false) $this->get_file_options(false)
); );
// Add help button. // Add help button.
$mform->addHelpButton( $mform->addHelpButton(
// Related form item. 'tasks_filemanager',
"tasks_filemanager", 'submission_label',
// Key.
"submission_label",
// Language file.
self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME
); );
...@@ -215,40 +228,46 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -215,40 +228,46 @@ class assign_submission_dta extends assign_submission_plugin {
/** /**
* Determines if a submission file area contains any files. * Determines if a submission file area contains any files.
* @param stdClass $submission submission to check *
* @return bool true if file count is zero * @param stdClass $submission Submission to check.
* @return bool True if file count is zero.
*/ */
public function assignsubmission_dta_is_empty(stdClass $submission): bool { public function assignsubmission_dta_is_empty(stdClass $submission): bool {
return $this->assignsubmission_dta_count_files($submission->id, self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION) == 0; return ($this->assignsubmission_dta_count_files(
$submission->id,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION
) === 0);
} }
/** /**
* Counts the number of files in a filearea * Counts the number of files in a filearea.
* *
* @param int $submissionid submission id to check * @param int $submissionid Submission id to check.
* @param string $areaid filearea id to count * @param string $areaid Filearea id to count.
* @return int number of files submitted in the filearea * @return int Number of files submitted in the filearea.
*/ */
private function assignsubmission_dta_count_files(int $submissionid, $areaid) { private function assignsubmission_dta_count_files(int $submissionid, $areaid): int {
$fs = get_file_storage(); $fs = get_file_storage();
$files = $fs->get_area_files($this->assignment->get_context()->id, $files = $fs->get_area_files(
$this->assignment->get_context()->id,
self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME, self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME,
$areaid, $areaid,
$submissionid, $submissionid,
'id', 'id',
false); false
);
return count($files); return count($files);
} }
/** /**
* Save data to the database * Save data to the database.
* *
* @param stdClass $submission * @param stdClass $submission Submission object.
* @param stdClass $data * @param stdClass $data Data from the form.
* @return bool * @return bool True if saved successfully.
*/ */
public function save(stdClass $submission, stdClass $data) { public function save(stdClass $submission, stdClass $data): bool {
$data = file_postupdate_standard_filemanager( $data = file_postupdate_standard_filemanager(
$data, $data,
'tasks', 'tasks',
...@@ -267,7 +286,6 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -267,7 +286,6 @@ class assign_submission_dta extends assign_submission_plugin {
// Get submitted files. // Get submitted files.
$fs = get_file_storage(); $fs = get_file_storage();
$files = $fs->get_area_files( $files = $fs->get_area_files(
// Id of current assignment.
$this->assignment->get_context()->id, $this->assignment->get_context()->id,
self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME, self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION, self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
...@@ -278,15 +296,22 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -278,15 +296,22 @@ class assign_submission_dta extends assign_submission_plugin {
// Check if a file is uploaded. // Check if a file is uploaded.
if (empty($files)) { if (empty($files)) {
\core\notification::error(get_string("no_submissionfile_warning", self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)); \core\notification::error(
get_string('no_submissionfile_warning', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
);
return true; return true;
} }
// Get the file. // Get the file.
$file = reset($files); $file = reset($files);
// Send file to backend. // Send file to backend (split across lines to avoid exceeding length).
$response = \assignsubmission_dta\dta_backend_utils::assignsubmission_dta_send_submission_to_backend($this->assignment, $submission->id, $file); $response = \assignsubmission_dta\dta_backend_utils::
assignsubmission_dta_send_submission_to_backend(
$this->assignment,
$submission->id,
$file
);
// With a null response, return an error. // With a null response, return an error.
if (is_null($response)) { if (is_null($response)) {
...@@ -299,29 +324,35 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -299,29 +324,35 @@ class assign_submission_dta extends assign_submission_plugin {
// Decode recommendations from response. // Decode recommendations from response.
$recommendations = dta_recommendation::assignsubmission_dta_decode_json_recommendations($response); $recommendations = dta_recommendation::assignsubmission_dta_decode_json_recommendations($response);
error_log(print_r($recommendations, true)); // Use Moodle debugging instead of error_log/print_r.
debugging('Recommendations: ' . json_encode($recommendations), DEBUG_DEVELOPER);
// Persist new results to database. // Persist new results to database (split long lines).
dta_db_utils::assignsubmission_dta_store_result_summary_to_database($this->assignment->get_instance()->id, $submission->id, $resultsummary); dta_db_utils::assignsubmission_dta_store_result_summary_to_database(
$this->assignment->get_instance()->id,
$submission->id,
$resultsummary
);
// Store the array of recommendations in the database. // Store the array of recommendations in the database.
dta_db_utils::assignsubmission_dta_store_recommendations_to_database($this->assignment->get_instance()->id, $submission->id, $recommendations); dta_db_utils::assignsubmission_dta_store_recommendations_to_database(
$this->assignment->get_instance()->id,
$submission->id,
$recommendations
);
return true; return true;
} }
/** /**
* Display a short summary of the test results of the submission * Display a short summary of the test results of the submission.
* This is displayed as default view, with the option to expand
* to the full detailed results.
* *
* @param stdClass $submission to show * @param stdClass $submission Submission to show.
* @param bool $showviewlink configuration variable to show expand option * @param bool $showviewlink Whether to show expand option.
* @return string summary results html * @return string Summary results HTML.
*/ */
public function view_summary(stdClass $submission, & $showviewlink) { public function view_summary(stdClass $submission, &$showviewlink): string {
$showviewlink = true; $showviewlink = true;
return dta_view_submission_utils::assignsubmission_dta_generate_summary_html( return dta_view_submission_utils::assignsubmission_dta_generate_summary_html(
$this->assignment->get_instance()->id, $this->assignment->get_instance()->id,
$submission->id $submission->id
...@@ -329,12 +360,12 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -329,12 +360,12 @@ class assign_submission_dta extends assign_submission_plugin {
} }
/** /**
* Display detailed results * Display detailed results.
* *
* @param stdClass $submission the submission the results are shown for. * @param stdClass $submission The submission for which to show results.
* @return string detailed results html * @return string Detailed results HTML.
*/ */
public function view(stdClass $submission) { public function view(stdClass $submission): string {
return dta_view_submission_utils::assignsubmission_dta_generate_detail_html( return dta_view_submission_utils::assignsubmission_dta_generate_detail_html(
$this->assignment->get_instance()->id, $this->assignment->get_instance()->id,
$submission->id $submission->id
...@@ -344,73 +375,77 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -344,73 +375,77 @@ class assign_submission_dta extends assign_submission_plugin {
/** /**
* Generate array of allowed file types to upload. * Generate array of allowed file types to upload.
* *
* @param bool $settings switch to define if list for assignment settings * @param bool $settings Whether this is for assignment settings or active submission.
* or active submission should be returned
*
* @return array * @return array
*/ */
private function get_file_options(bool $settings): array { private function get_file_options(bool $settings): array {
$fileoptions = [ $fileoptions = [
'subdirs' => 0, 'subdirs' => 0,
"maxfiles" => 1, 'maxfiles' => 1,
'accepted_types' => ($settings 'accepted_types' => (
? [".txt"] $settings
: [ ? ['.txt']
".txt", : [
".zip", '.txt',
]), '.zip',
'return_types' => FILE_INTERNAL, ]
]; ),
'return_types' => FILE_INTERNAL,
];
return $fileoptions; return $fileoptions;
} }
/** /**
* Get file areas returns a list of areas this plugin stores files * Get file areas returns a list of areas this plugin stores files.
* @return array - An array of fileareas (keys) and descriptions (values) *
* @return array An array of fileareas (keys) and descriptions (values).
*/ */
public function get_file_areas() { public function get_file_areas(): array {
return [ return [
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION => get_string("dta_submissions_fa", self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION =>
self::ASSIGNSUBMISSION_DTA_FILEAREA_TEST => get_string("dta_tests_fa", self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string('dta_submissions_fa', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
self::ASSIGNSUBMISSION_DTA_FILEAREA_TEST =>
get_string('dta_tests_fa', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
]; ];
} }
/** /**
* Produce a list of files suitable for export that represent this feedback or submission * Produce a list of files suitable for export that represent this feedback or submission.
* *
* @param stdClass $submission The submission * @param stdClass $submission The submission object.
* @param stdClass $user The user record - unused * @param stdClass $user The user record (unused).
* @return array - return an array of files indexed by filename * @return array An array of files indexed by filename.
*/ */
public function get_files(stdClass $submission, stdClass $user) { public function get_files(stdClass $submission, stdClass $user): array {
$result = []; $result = [];
$fs = get_file_storage(); $fs = get_file_storage();
$files = $fs->get_area_files($this->assignment->get_context()->id, $files = $fs->get_area_files(
$this->assignment->get_context()->id,
self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME, self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION, self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id, $submission->id,
'timemodified', 'timemodified',
false); false
);
foreach ($files as $file) { foreach ($files as $fileobj) {
// Do we return the full folder path or just the file name? // Do we return the full folder path or just the file name?
if (isset($submission->exportfullpath) && $submission->exportfullpath == false) { if (isset($submission->exportfullpath) && $submission->exportfullpath === false) {
$result[$file->get_filename()] = $file; $result[$fileobj->get_filename()] = $fileobj;
} else { } else {
$result[$file->get_filepath().$file->get_filename()] = $file; $result[$fileobj->get_filepath() . $fileobj->get_filename()] = $fileobj;
} }
} }
return $result; return $result;
} }
/** /**
* The plugin is being uninstalled - cleanup * The plugin is being uninstalled - cleanup.
* *
* @return bool * @return bool
*/ */
public function delete_instance() { public function delete_instance(): bool {
dta_db_utils::assignsubmission_dta_uninstall_plugin_cleaup(); dta_db_utils::assignsubmission_dta_uninstall_plugin_cleaup();
return true; return true;
} }
} }
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