Commit 2a7c45cc authored by Kurzenberger's avatar Kurzenberger
Browse files

changed to match namespace conventions

1 merge request!1Coding style and recommendations
Pipeline #10523 passed with stage
Showing with 675 additions and 146 deletions
+675 -146
No preview for this file type
<?php
namespace assignsubmission_dta;
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
......@@ -21,7 +22,13 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
class DbUtils {
use assignsubmission_dta\dta_backend_utils;
use assignsubmission_dta\view_submission_utils;
use assignsubmission_dta\models\dta_result;
use assignsubmission_dta\models\dta_result_summary;
use assignsubmission_dta\models\dta_recommendation;
class db_utils {
/**
* Summary database table name.
......@@ -77,6 +84,7 @@ class DbUtils {
// Wenn der Abschlussstatus 1 ist, entferne den Datensatz aus $records
if ($completion && $completion->completionstate == 1) {
unset($records[$key]);
}
}
}
......@@ -94,10 +102,10 @@ class DbUtils {
* @param int $submissionid submission id to search for
* @return DttResultSummary representing given submission
*/
public static function getresultsummaryfromdatabase(
public static function get_result_summary_from_database(
int $assignmentid,
int $submissionid
): DtaResultSummary {
): dta_result_summary {
global $DB;
// Fetch data from database.
......@@ -112,7 +120,7 @@ class DbUtils {
]);
// Create a summary instance.
$summary = new DtaResultSummary();
$summary = new dta_result_summary();
$summary->timestamp = $summaryrecord->timestamp;
$summary->globalstacktrace = $summaryrecord->global_stacktrace;
$summary->successfultestcompetencies = $summaryrecord->successful_competencies;
......@@ -121,7 +129,7 @@ class DbUtils {
// Create result instances and add to array of summary instance.
foreach ($resultsarray as $rr) {
$result = new DtaResult();
$result = new dta_result();
$result->packagename = $rr->package_name;
$result->classname = $rr->class_name;
$result->name = $rr->name;
......@@ -138,33 +146,16 @@ class DbUtils {
return $summary;
}
public static function storeRecommendationstoDatabase(
public static function store_recommendations_to_database(
int $assignmentid,
int $submissionid,
array $recommendations
): void {
global $DB;
error_log(print_r($recommendations,true));
// Prepare recommendations to persist to array.
$recommendationrecords = [];
foreach ($recommendations as $recommendation) {
$record = new stdClass();
$record->assignment_id = $assignmentid;
$record->submission_id = $submissionid;
$record->topic = $recommendation['topic'];
$record->url = $recommendation['url'];
$record->exercise_name = $recommendation['exercise_name'];
$record->difficulty = $recommendation['difficulty'];
$record->score = $recommendation['score'];
$recommendationrecords[] = $record;
}
error_log("Das sind die Recommendationrecords.");
error_log(print_r($recommendationrecords,true));
error_log(print_r($recommendations, true));
// If recommendations already exist, delete old values beforehand.
$existingrecords = $DB->get_record('assignsubmission_dta_recommendations', [
$existingrecords = $DB->get_records('assignsubmission_dta_recommendations', [
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]);
......@@ -177,10 +168,22 @@ class DbUtils {
}
// Create new recommendation entries.
foreach ($recommendationrecords as $rec) {
error_log("Insert record");
error_log(print_r($rec,true));
$DB->insert_record('assignsubmission_dta_recommendations', $rec);
foreach ($recommendations as $recommendation) {
// Ensure $recommendation is an instance of DtaRecommendation
if ($recommendation instanceof dta_recommendation) {
// Add assignment and submission IDs to the recommendation object
$recommendation->assignment_id = $assignmentid;
$recommendation->submission_id = $submissionid;
error_log("Insert record");
error_log(print_r($recommendation, true));
// Insert the recommendation into the database
$DB->insert_record('assignsubmission_dta_recommendations', $recommendation);
} else {
// Handle the case where $recommendation is not a DtaRecommendation instance
error_log("Invalid recommendation object");
}
}
}
......@@ -191,17 +194,17 @@ class DbUtils {
*
* @param int $assignmentid assigment this is submission is linked to
* @param int $submissionid submission of this result
* @param DtaResultSummary $summary instance to persist
* @param dta_result_summary $summary instance to persist
*/
public static function storeresultsummarytodatabase(
public static function store_result_summary_to_database(
int $assignmentid,
int $submissionid,
DtaResultSummary $summary
dta_result_summary $summary
): void {
global $DB;
// Prepare new database entries.
$summaryrecord = new stdClass();
$summaryrecord = new dta_result_summary();
$summaryrecord->assignment_id = $assignmentid;
$summaryrecord->submission_id = $submissionid;
$summaryrecord->timestamp = $summary->timestamp;
......@@ -212,7 +215,7 @@ class DbUtils {
// Prepare results to persist to array.
$resultrecords = [];
foreach ($summary->results as $r) {
$record = new stdClass();
$record = new dta_result();
$record->assignment_id = $assignmentid;
$record->submission_id = $submissionid;
$record->package_name = $r->packagename;
......@@ -256,7 +259,7 @@ class DbUtils {
/**
* cleans up database if plugin is uninstalled
*/
public static function uninstallplugincleaup(): void {
public static function uninstall_plugin_cleaup(): void {
global $DB;
$DB->delete_records(self::TABLE_RESULT, null);
......
<?php
// This file is part of Moodle - http://moodle.org/
//
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
......@@ -19,52 +20,61 @@
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
/**
* backend webservice contact utility class
* Backend webservice contact 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
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class DtaBackendUtils {
namespace assignsubmission_dta;
defined('MOODLE_INTERNAL') || die();
class dta_backend_utils {
/**
* Component name for the plugin.
*/
const COMPONENT_NAME = 'assignsubmission_dta';
/**
* Returns the base url of the backend webservice as configured in the administration settings.
* @return string backend host base url
* Returns the base URL of the backend webservice as configured in the administration settings.
* @return string Backend host base URL
*/
private static function getbackendbaseurl(): string {
$backendaddress = get_config(assign_submission_dta::COMPONENT_NAME, "backendHost");
private static function get_backend_baseurl(): string {
$backendaddress = get_config(self::COMPONENT_NAME, 'backendHost');
if (empty($backendaddress)) {
\core\notification::error(get_string("backendHost_not_set", assign_submission_dta::COMPONENT_NAME));
\core\notification::error(get_string('backendHost_not_set', self::COMPONENT_NAME));
}
return $backendaddress;
}
/**
* Sends the configuration textfile uploaded by prof to the backend.
* Sends the configuration text file uploaded by the teacher to the backend.
*
* @param stdClass $assignment assignment this test-config belongs to
* @param stdClass $file uploaded test-config
* @return bool true if no error occurred
* @param \assign $assignment Assignment this test-config belongs to
* @param \stored_file $file Uploaded test-config
* @return bool True if no error occurred
*/
public static function sendtestconfigtobackend($assignment, $file): bool {
$backendaddress = self::getbackendbaseurl();
public static function send_testconfig_to_backend($assignment, $file): bool {
$backendaddress = self::get_backend_baseurl();
if (empty($backendaddress)) {
return true;
}
// Set endpoint for test upload.
$url = $backendaddress . "/v1/unittest";
$url = $backendaddress . '/v1/unittest';
// Prepare params.
$params = [
"unitTestFile" => $file,
"assignmentId" => $assignment->get_instance()->id,
'unitTestFile' => $file,
'assignmentId' => $assignment->get_instance()->id,
];
// If request returned null, return false to indicate failure.
......@@ -78,67 +88,64 @@ class DtaBackendUtils {
/**
* Sends submission config or archive to backend to be tested.
*
* @param stdClass $assignment assignment for the submission
* @param int $submissionid submissionid of the current file
* @param stdClass $file submission config file or archive with submission
* @return string json string with testresults or null on error
* @param \assign $assignment Assignment for the submission
* @param int $submissionid Submission ID of the current file
* @param \stored_file $file Submission config file or archive with submission
* @return string|null JSON string with test results or null on error
*/
public static function send_submission_to_backend($assignment, $submissionid, $file): ?string {
$backendaddress = self::getbackendbaseurl();
$backendaddress = self::get_backend_baseurl();
if (empty($backendaddress)) {
return true;
return null;
}
// Set endpoint for test upload.
$url = $backendaddress . "/v1/task/" . $submissionid;
// Set endpoint for submission upload.
$url = $backendaddress . '/v1/task/' . $submissionid;
// Prepare params.
$params = [
"taskFile" => $file,
"assignmentId" => $assignment->get_instance()->id,
'taskFile' => $file,
'assignmentId' => $assignment->get_instance()->id,
];
return self::post($url, $params);
}
/**
* 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
* 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 received body on success or null on error
* @return string|null Received body on success or null on error
*/
private static function post($url, $params): ?string {
if (!isset($url) || !isset($params)) {
return false;
return null;
}
$options = ["CURLOPT_RETURNTRANSFER" => true];
$options = ['CURLOPT_RETURNTRANSFER' => true];
$curl = new curl();
$curl = new \curl();
$response = $curl->post($url, $params, $options);
// Check state of request, if response code is a 2xx return the answer.
$info = $curl->get_info();
if ($info["http_code"] >= 200 && $info["http_code"] < 300) {
if ($info['http_code'] >= 200 && $info['http_code'] < 300) {
return $response;
}
// Something went wrong, return null and give an error message.
debugging(assign_submission_dta::COMPONENT_NAME . ": Post file to server was not successful: http_code=" .
$info["http_code"]);
debugging(self::COMPONENT_NAME . ': Post file to server was not successful: http_code=' . $info['http_code']);
if ($info['http_code'] >= 400 && $info['http_code'] < 500) {
\core\notification::error(get_string("http_client_error_msg", assign_submission_dta::COMPONENT_NAME));
\core\notification::error(get_string('http_client_error_msg', self::COMPONENT_NAME));
return null;
} else if ($info['http_code'] >= 500 && $info['http_code'] < 600) {
\core\notification::error(get_string("http_server_error_msg", assign_submission_dta::COMPONENT_NAME));
\core\notification::error(get_string('http_server_error_msg', self::COMPONENT_NAME));
return null;
} else {
\core\notification::error(get_string("http_unknown_error_msg", assign_submission_dta::COMPONENT_NAME) .
$info["http_code"] . $response);
\core\notification::error(get_string('http_unknown_error_msg', self::COMPONENT_NAME) . $info['http_code'] . $response);
return null;
}
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Entity class for DTA submission plugin recommendation
*
* @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignsubmission_dta\models;
defined('MOODLE_INTERNAL') || die();
/**
* Entity class for DTA submission plugin recommendation
*
* @package assignsubmission_dta
* @copyright 2023
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dta_recommendation {
/**
* @var string $topic Topic of the recommendation.
*/
public $topic;
/**
* @var string $exercise_name Name of the exercise.
*/
public $exercise_name;
/**
* @var string $url URL of the exercise.
*/
public $url;
/**
* @var int $difficulty Difficulty level of the exercise.
*/
public $difficulty;
/**
* @var int $score Score associated with the recommendation.
*/
public $score;
/**
* Decodes the JSON recommendations returned by the backend service call into an array of DtaRecommendation objects.
*
* @param string $jsonstring JSON string containing recommendations
* @return array Array of DtaRecommendation objects
*/
public static function decode_json_recommendations(string $jsonstring): array {
$response = json_decode($jsonstring);
$recommendations = [];
// Prüfe, ob Empfehlungen vorhanden sind
if (!empty($response->recommendations)) {
foreach ($response->recommendations as $recommendation) {
$rec = new dta_recommendation();
$rec->topic = $recommendation->topic ?? null;
$rec->exercise_name = $recommendation->url ?? null;
$rec->url = $recommendation->exerciseName ?? null;
$rec->difficulty = $recommendation->difficulty ?? null;
$rec->score = $recommendation->score ?? null;
$recommendations[] = $rec;
}
}
return $recommendations;
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Entity class for DTA submission plugin result
*
* @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer and student project teams
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace assignsubmission_dta\models;
defined('MOODLE_INTERNAL') || die();
/**
* Entity class for DTA submission plugin result
*
* @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer and student project teams
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dta_result {
/**
* Broadly used in logic, parametrized for easier change.
*/
const COMPONENT_NAME = 'assignsubmission_dta';
/**
* @var string $packagename Package name of the test.
*/
public $packagename;
/**
* @var string $classname Unit name of the test.
*/
public $classname;
/**
* @var string $name Name of the test.
*/
public $name;
/**
* @var int $state State is defined as:
* 0 UNKNOWN
* 1 SUCCESS
* 2 FAILURE
* 3 COMPILATIONERROR
*/
public $state;
/**
* @var string $failuretype Type of test failure if applicable, empty string otherwise.
*/
public $failuretype;
/**
* @var string $failurereason Reason of test failure if applicable, empty string otherwise.
*/
public $failurereason;
/**
* @var string $stacktrace Stack trace of test failure if applicable, empty string otherwise.
*/
public $stacktrace;
/**
* @var int|string $columnnumber Column number of compile failure if applicable, empty string otherwise.
*/
public $columnnumber;
/**
* @var int|string $linenumber Line number of compile failure if applicable, empty string otherwise.
*/
public $linenumber;
/**
* @var int|string $position Position of compile failure if applicable, empty string otherwise.
*/
public $position;
/**
* Returns the name of a state with the given number for display.
*
* @param int $state Number of the state
* @return string Name of state as defined
*/
public static function getstatename(int $state): string {
if ($state == 1) {
return get_string('tests_successful', self::COMPONENT_NAME);
} else if ($state == 2) {
return get_string('failures', self::COMPONENT_NAME);
} else if ($state == 3) {
return get_string('compilation_errors', self::COMPONENT_NAME);
} else {
return get_string('unknown_state', self::COMPONENT_NAME);
}
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* entity classes for DTA submission plugin result summary and test results
* Entity class for DTA submission plugin result summary
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
* @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer and student project teams
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* entity class for DTA submission plugin result
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
class DtaResult {
/**
* Broadly used in logic, parametrized for easier change.
*/
const COMPONENT_NAME = "assignsubmission_dta";
/**
* @var $packagename Package name of the test.
*/
public $packagename;
/**
* @var $classname Unit name of the test.
*/
public $classname;
/**
* @var $name Name of the test.
*/
public $name;
/**
* @var $state State is defined like below
*
* 0 UNKNOWN
* 1 SUCCESS
* 2 FAILURE
* 3 COMPILATIONERROR
*/
public $state;
/**
* @var $failuretype Type of test failure if applicable, "" otherwise.
*/
public $failuretype;
/**
* @var $failurereason Reason of test failure if applicable, "" otherwise.
*/
public $failurereason;
/**
* @var $stacktrace Stack trace of test failure if applicable, "" otherwise.
*/
public $stacktrace;
/**
* @var $columnnumber Column number of compile failure if applicable, "" otherwise.
*/
public $columnnumber;
/**
* @var $linenumber Line number of compile failure if applicable, "" otherwise.
*/
public $linenumber;
/**
* @var $position Position of compile failure if applicable, "" otherwise.
*/
public $position;
namespace assignsubmission_dta\models;
/**
* Returns the name of a state with the given number of display.
* @param int $state number of the state
* @return string name of state as defined
*/
public static function getstatename(int $state): string {
if ($state == 1) {
return get_string("tests_successful", self::COMPONENT_NAME);
} else if ($state == 2) {
return get_string("failures", self::COMPONENT_NAME);
} else if ($state == 3) {
return get_string("compilation_errors", self::COMPONENT_NAME);
} else {
return get_string("unknown_state", self::COMPONENT_NAME);
}
}
}
defined('MOODLE_INTERNAL') || die();
/**
* entity class for DTA submission plugin result
* Entity class for DTA submission plugin result summary
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
* @package assignsubmission_dta
* @copyright 2023 Gero Lueckemeyer and student project teams
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class DtaResultSummary {
class dta_result_summary {
/**
* @var $timestamp Result timestamp for chronological ordering and deletion of previous results.
* @var int $timestamp Result timestamp for chronological ordering and deletion of previous results.
*/
public $timestamp;
/**
* @var $globalstacktrace Global stack trace if applicable, "" otherwise.
* @var string $globalstacktrace Global stack trace if applicable, empty string otherwise.
*/
public $globalstacktrace;
/**
* @var $successfultestcompetencies Successfully tested competencies according to tests and weights, "" otherwise.
* @var string $successfultestcompetencies Successfully tested competencies according to tests and weights, empty string otherwise.
*/
public $successfultestcompetencies;
/**
* @var overalltestcompetencies Overall tested competencies according to tests and weights, "" otherwise.
* @var string $overalltestcompetencies Overall tested competencies according to tests and weights, empty string otherwise.
*/
public $overalltestcompetencies;
/**
* @var results List of detail results.
* @var array $results List of detail results.
*/
public $results;
/**
* Decodes the JSON result summary returned by the backend service call into the plugin PHP data structure.
* @param string $jsonstring jsonString containing DtaResultSummary
* @return DtaResultSummary the result summary
*
* @param string $jsonstring JSON string containing DtaResultSummary
* @return DtaResultSummary The result summary
*/
public static function decodejson(string $jsonstring): DtaResultSummary {
public static function decode_json(string $jsonstring): dta_result_summary {
$response = json_decode($jsonstring);
$summary = new DtaResultSummary();
$summary = new dta_result_summary();
$summary->timestamp = $response->timestamp;
$summary->globalstacktrace = $response->globalstacktrace;
$summary->successfultestcompetencies = $response->successfulTestCompetencyProfile;
$summary->overalltestcompetencies = $response->overallTestCompetencyProfile;
$summary->successfultestcompetencies = $response->successfulTestCompetencyProfile ?? '';
$summary->overalltestcompetencies = $response->overallTestCompetencyProfile ?? '';
$summary->results = self::decodejsonresultarray($response->results);
$summary->results = self::decode_json_result_array($response->results);
return $summary;
}
public static function decodeJsonRecommendation(string $jsonstring): array {
// Decode the JSON string into a PHP object
$response = json_decode($jsonstring);
error_log("decodeJsonRecommendation");
error_log(print_r($response, true));
// Initialize an empty array to store recommendations
$recommendations = [];
// Loop through the recommendations in the response
if (!empty($response->recommendations)) {
foreach ($response->recommendations as $recommendation) {
// For each recommendation, create an associative array with the properties
$recommendations[] = [
'topic' => $recommendation->topic ?? null,
'url' => $recommendation->exerciseName ?? null,
'exercise_name' => $recommendation->url ?? null,
'difficulty' => $recommendation->difficulty ?? null,
'score' => $recommendation->score ?? null
];
}
}
error_log(print_r($recommendations,true));
// Return the array of recommendations
return $recommendations;
}
/**
* Decodes the array of JSON detail results returned by the backend service call into the plugin PHP data structure.
* @param array $jsonarray decoded json array of results array
* @return array of DtaResult
*
* @param array $jsonarray Decoded JSON array of results
* @return array Array of DtaResult
*/
private static function decodejsonresultarray($jsonarray): array {
private static function decode_json_result_array(array $jsonarray): array {
$ret = [];
foreach ($jsonarray as $entry) {
$value = new DtaResult();
$value->packagename = $entry->packageName;
$value->classname = $entry->className;
$value->name = $entry->name;
$value = new dta_result();
$value->packagename = $entry->packageName ?? '';
$value->classname = $entry->className ?? '';
$value->name = $entry->name ?? '';
$value->state = $entry->state;
$value->state = $entry->state ?? 0;
$value->failuretype = $entry->failureType;
$value->failurereason = $entry->failureReason;
$value->stacktrace = $entry->stacktrace;
$value->failuretype = $entry->failureType ?? '';
$value->failurereason = $entry->failureReason ?? '';
$value->stacktrace = $entry->stacktrace ?? '';
$value->columnnumber = $entry->columnNumber;
$value->linenumber = $entry->lineNumber;
$value->position = $entry->position;
$value->columnnumber = $entry->columnNumber ?? '';
$value->linenumber = $entry->lineNumber ?? '';
$value->position = $entry->position ?? '';
$ret[] = $value;
}
return $ret;
}
/**
* Returns the number of detail results attached to the summary.
* @return int count of occurences
*
* @return int Count of occurrences
*/
public function resultcount(): int {
public function result_count(): int {
return count($this->results);
}
/**
* Returns the number of detail results with the given state attached to the summary.
* @param int $state state ordinal number
* @return int count of occurences provided state has
*
* @param int $state State ordinal number
* @return int Count of occurrences for the provided state
*/
public function stateoccurencecount(int $state): int {
public function state_occurence_count(int $state): int {
$num = 0;
foreach ($this->results as $r) {
if ($r->state == $state) {
......@@ -244,34 +137,37 @@ class DtaResultSummary {
/**
* Returns the number of detail results with compilation errors attached to the summary.
* @return int count of occurences
*
* @return int Count of occurrences
*/
public function compilationerrorcount(): int {
return $this->stateoccurencecount(3);
return $this->state_occurence_count(3);
}
/**
* Returns the number of detail results with test failures attached to the summary.
* @return int count of occurences
*
* @return int Count of occurrences
*/
public function failedcount(): int {
return $this->stateoccurencecount(2);
return $this->state_occurence_count(2);
}
/**
* Returns the number of detail results with successful tests attached to the summary.
* @return int count of occurences
*
* @return int Count of occurrences
*/
public function successfulcount(): int {
return $this->stateoccurencecount(1);
return $this->state_occurence_count(1);
}
/**
* Returns the number of detail results with an unknown result - mostly due to compile errors - attached to the summary.
* @return int count of occurences
* Returns the number of detail results with an unknown result attached to the summary.
*
* @return int Count of occurrences
*/
public function unknowncount(): int {
return $this->stateoccurencecount(0);
return $this->state_occurence_count(0);
}
}
<?php
namespace assignsubmission_dta;
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
......@@ -20,6 +21,12 @@
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use assignsubmission_dta\db_utils;
use assignsubmission_dta\dta_backend_utils;
use assignsubmission_dta\models\dta_result;
use assignsubmission_dta\models\dta_result_summary;
use assignsubmission_dta\models\dta_recommendation;
class view_submission_utils {
/**
......@@ -34,13 +41,13 @@ class view_submission_utils {
* @param int $submissionid submission to create a report for
* @return string html
*/
public static function generatesummaryhtml(
public static function generate_summary_html(
int $assignmentid,
int $submissionid
): string {
// Fetch data.
$summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
$summary = db_utils::get_Result_Summary_From_Database($assignmentid, $submissionid);
$html = "";
// Calculate success rate, if no unknown result states or compilation errors.
......@@ -52,7 +59,7 @@ class view_submission_utils {
// Generate html.
$html .= $summary->successfulCount() . "/";
$html .= ($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0)
? $summary->resultCount() . " (" . $successrate . "%)"
? $summary->result_Count() . " (" . $successrate . "%)"
: "?";
$html .= get_string("tests_successful", self::COMPONENT_NAME) . "<br />";
......@@ -80,7 +87,7 @@ class view_submission_utils {
$html .= get_string("success_competencies", self::COMPONENT_NAME) . "<br />" . $tmp . "<br />";
return html_writer::div($html, "dtaSubmissionSummary");
return \html_writer::div($html, "dtaSubmissionSummary");
}
/**
......@@ -90,7 +97,7 @@ class view_submission_utils {
* @param int $submissionid Submission-ID, für die der Bericht erstellt wird
* @return string HTML-Code
*/
public static function generatedetailhtml(
public static function generate_detail_html(
int $assignmentid,
int $submissionid
): string {
......@@ -99,7 +106,7 @@ public static function generatedetailhtml(
$html = "";
// Daten abrufen
$summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
$summary = db_utils::get_Result_Summary_From_Database($assignmentid, $submissionid);
// CSS-Klassen und HTML-Attributarrays definieren
$tableheaderrowattributes = ["class" => "dtaTableHeaderRow"];
......@@ -114,11 +121,11 @@ public static function generatedetailhtml(
// (Ihr bisheriger Code bleibt unverändert)
// **Abstand zwischen Tabellen**
$html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);
$html .= \html_writer::empty_tag("div", ["class" => "dtaSpacer"]);
// **Empfehlungstabelle hinzufügen**
// Empfehlungen für die Submission abrufen
$recommendations = DbUtils::get_recommendations_from_database($assignmentid, $submissionid);
$recommendations = db_utils::get_recommendations_from_database($assignmentid, $submissionid);
if (!empty($recommendations)) {
// **Sortierparameter abrufen**
......@@ -160,7 +167,7 @@ public static function generatedetailhtml(
});
// Überschrift für Empfehlungen
$html .= html_writer::tag('h3', get_string('recommendations', self::COMPONENT_NAME));
$html .= \html_writer::tag('h3', get_string('recommendations', self::COMPONENT_NAME));
// Helper-Funktion zum Generieren von sortierbaren Headern
$generate_sortable_header = function($column_name, $display_name) use ($sortby, $sortdir) {
......@@ -171,7 +178,7 @@ public static function generatedetailhtml(
}
// Button erstellen
$button = html_writer::empty_tag('input', [
$button = \html_writer::empty_tag('input', [
'type' => 'submit',
'name' => 'sortbutton',
'value' => ($new_sortdir == 'asc' ? '↑' : '↓'),
......@@ -179,57 +186,57 @@ public static function generatedetailhtml(
]);
// Hidden Inputs für Sortierparameter
$hidden_inputs = html_writer::empty_tag('input', [
$hidden_inputs = \html_writer::empty_tag('input', [
'type' => 'hidden',
'name' => 'sortby',
'value' => $column_name
]);
$hidden_inputs .= html_writer::empty_tag('input', [
$hidden_inputs .= \html_writer::empty_tag('input', [
'type' => 'hidden',
'name' => 'sortdir',
'value' => $new_sortdir
]);
// Formular für den Button erstellen
$form = html_writer::start_tag('form', ['method' => 'post', 'style' => 'display:inline']);
$form = \html_writer::start_tag('form', ['method' => 'post', 'style' => 'display:inline']);
$form .= $hidden_inputs;
$form .= $display_name . ' ' . $button;
$form .= html_writer::end_tag('form');
$form .= \html_writer::end_tag('form');
return html_writer::tag("th", $form, ["class" => $class]);
return \html_writer::tag("th", $form, ["class" => $class]);
};
// Tabellenkopf für Empfehlungen
$tableheader = "";
$tableheader .= $generate_sortable_header('topic', get_string("topic", self::COMPONENT_NAME));
$tableheader .= $generate_sortable_header('exercise_name', get_string("exercise_name", self::COMPONENT_NAME));
$tableheader .= html_writer::tag("th", get_string("url", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
$tableheader .= \html_writer::tag("th", get_string("url", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
$tableheader .= $generate_sortable_header('difficulty', get_string("difficulty", self::COMPONENT_NAME));
$tableheader .= $generate_sortable_header('score', get_string("score", self::COMPONENT_NAME));
$tableheader = html_writer::tag("tr", $tableheader, ["class" => "dtaTableHeaderRow"]);
$tableheader = html_writer::tag("thead", $tableheader);
$tableheader = \html_writer::tag("tr", $tableheader, ["class" => "dtaTableHeaderRow"]);
$tableheader = \html_writer::tag("thead", $tableheader);
// Tabellenkörper für Empfehlungen
$tablebody = "";
foreach ($recommendations as $recommendation) {
$tablerow = "";
$tablerow .= html_writer::tag("td", $recommendation->topic, $attributes);
$tablerow .= html_writer::tag("td", $recommendation->exercise_name, $attributes);
$tablerow .= html_writer::tag("td", html_writer::link($recommendation->url, $recommendation->url), $attributes);
$tablerow .= html_writer::tag("td", $recommendation->difficulty, $attributes);
$tablerow .= html_writer::tag("td", $recommendation->score, $attributes);
$tablerow .= \html_writer::tag("td", $recommendation->topic, $attributes);
$tablerow .= \html_writer::tag("td", $recommendation->exercise_name, $attributes);
$tablerow .= \html_writer::tag("td", \html_writer::link($recommendation->url, $recommendation->url), $attributes);
$tablerow .= \html_writer::tag("td", $recommendation->difficulty, $attributes);
$tablerow .= \html_writer::tag("td", $recommendation->score, $attributes);
$tablebody .= html_writer::tag("tr", $tablerow, $tablerowattributes);
$tablebody .= \html_writer::tag("tr", $tablerow, $tablerowattributes);
}
$tablebody = html_writer::tag("tbody", $tablebody);
$tablebody = \html_writer::tag("tbody", $tablebody);
// Empfehlungstabelle zusammenstellen
$html .= html_writer::tag("table", $tableheader . $tablebody, ["class" => "dtaTable"]);
$html .= \html_writer::tag("table", $tableheader . $tablebody, ["class" => "dtaTable"]);
}
// Abschließendes Div für die gesamte HTML-Ausgabe
$html = html_writer::div($html, "dtaSubmissionDetails");
$html = \html_writer::div($html, "dtaSubmissionDetails");
return $html;
}
......
......@@ -16,14 +16,15 @@
defined('MOODLE_INTERNAL') || die();
// Import various entity and application logic files.
require_once($CFG->dirroot . '/mod/assign/submission/dta/models/DtaResult.php');
require_once($CFG->dirroot . '/mod/assign/submission/dta/classes/database.php');
require_once($CFG->dirroot . '/mod/assign/submission/dta/classes/backend.php');
require_once($CFG->dirroot . '/mod/assign/submission/dta/classes/view.php');
use assignsubmission_dta\db_utils;
use assignsubmission_dta\dta_backend_utils;
use assignsubmission_dta\view_submission_utils;
use assignsubmission_dta\models\dta_result;
use assignsubmission_dta\models\dta_result_summary;
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
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
......@@ -35,20 +36,20 @@ class assign_submission_dta extends assign_submission_plugin {
*/
const 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";
/**
* 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";
/**
* File area for dta submission assignment.
* File area for DTA submission assignment.
*/
const ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION = "submissions_dta";
/**
* get plugin name
* Get plugin name
* @return string
*/
public function get_name(): string {
......@@ -93,7 +94,7 @@ class assign_submission_dta extends assign_submission_plugin {
}
/**
* Allows the plugin to update the defaultvalues passed in to
* Allows the plugin to update the default values passed into
* the settings form (needed to set up draft areas for editor
* and filemanager elements)
* @param array $defaultvalues
......@@ -162,7 +163,7 @@ class assign_submission_dta extends assign_submission_plugin {
$file = reset($files);
// Send file to backend.
return DtaBackendUtils::sendtestconfigtobackend($this->assignment, $file);
return dta_backend_utils::send_testconfig_to_backend($this->assignment, $file);
}
/**
......@@ -240,86 +241,78 @@ class assign_submission_dta extends assign_submission_plugin {
return count($files);
}
/**
* Save data to the database
*
* @param stdClass $submission
* @param stdClass $data
* @return bool
*/
public function save(stdClass $submission, stdClass $data) {
$data = file_postupdate_standard_filemanager(
$data,
'tasks',
$this->get_file_options(false),
$this->assignment->get_context(),
self::COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id
);
// If submission is empty leave directly.
if ($this->is_empty($submission)) {
return true;
}
// Get submitted files.
$fs = get_file_storage();
$files = $fs->get_area_files(
// Id of current assignment.
$this->assignment->get_context()->id,
self::COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id,
'id',
false
);
// Check if a file is uploaded.
if (empty($files)) {
\core\notification::error(get_string("no_submissionfile_warning", self::COMPONENT_NAME));
return true;
}
// Get the file.
$file = reset($files);
/**
* Save data to the database
*
* @param stdClass $submission
* @param stdClass $data
* @return bool
*/
public function save(stdClass $submission, stdClass $data) {
$data = file_postupdate_standard_filemanager(
$data,
'tasks',
$this->get_file_options(false),
$this->assignment->get_context(),
self::COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id
);
// Send file to backend.
$response = DtaBackendUtils::send_submission_to_backend($this->assignment, $submission->id, $file);
// If submission is empty, leave directly.
if ($this->is_empty($submission)) {
return true;
}
// With a null response, return an error.
if (is_null($response)) {
return false;
}
// Get submitted files.
$fs = get_file_storage();
$files = $fs->get_area_files(
// Id of current assignment.
$this->assignment->get_context()->id,
self::COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id,
'id',
false
);
// Convert received json to valid class instances.
$resultsummary = DtaResultSummary::decodejson($response);
// Log an error message.
$recommendations = DtaResultSummary::decodeJsonRecommendation($response);
// Check if a file is uploaded.
if (empty($files)) {
\core\notification::error(get_string("no_submissionfile_warning", self::COMPONENT_NAME));
return true;
}
error_log(print_r($recommendations,true));
// Get the file.
$file = reset($files);
// Send file to backend.
$response = \assignsubmission_dta\dta_backend_utils::send_submission_to_backend($this->assignment, $submission->id, $file);
// With a null response, return an error.
if (is_null($response)) {
return false;
}
// Persist new results to database.
DbUtils::storeresultsummarytodatabase($this->assignment->get_instance()->id, $submission->id, $resultsummary);
// Convert received JSON to valid class instances.
$resultsummary = dta_result_summary::decode_json($response);
// Decode recommendations from response.
$recommendations = dta_recommendation::decode_json_recommendations($response);
error_log(print_r($recommendations, true));
// Store the array of records in the database.
DbUtils::storeRecommendationstoDatabase($this->assignment->get_instance()->id, $submission->id, $recommendations);
// Persist new results to database.
db_utils::store_result_summary_to_database($this->assignment->get_instance()->id, $submission->id, $resultsummary);
return true;
}
// Store the array of recommendations in the database.
db_utils::store_recommendations_to_database($this->assignment->get_instance()->id, $submission->id, $recommendations);
return true;
}
/**
* Display a short summary of the test results of the submission
* This is diplayed as default view, with the option to expand
* This is displayed as default view, with the option to expand
* to the full detailed results.
*
* @param stdClass $submission to show
......@@ -329,7 +322,7 @@ public function save(stdClass $submission, stdClass $data) {
public function view_summary(stdClass $submission, & $showviewlink) {
$showviewlink = true;
return view_submission_utils::generatesummaryhtml(
return view_submission_utils::generate_summary_html(
$this->assignment->get_instance()->id,
$submission->id
);
......@@ -342,16 +335,14 @@ public function save(stdClass $submission, stdClass $data) {
* @return string detailed results html
*/
public function view(stdClass $submission) {
// Sicherstellen, dass $cmid verfügbar ist
return view_submission_utils::generatedetailhtml(
return view_submission_utils::generate_detail_html(
$this->assignment->get_instance()->id,
$submission->id
);
}
/**
* generate array of allowed filetypes to upload.
* Generate array of allowed file types to upload.
*
* @param bool $settings switch to define if list for assignment settings
* or active submission should be returned
......@@ -413,12 +404,12 @@ public function save(stdClass $submission, stdClass $data) {
}
/**
* The plugin is beeing uninstalled - cleanup
* The plugin is being uninstalled - cleanup
*
* @return bool
*/
public function delete_instance() {
DbUtils::uninstallplugincleanup();
db_utils::uninstall_plugin_cleanup();
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