Commit 64cc51fa authored by Kurzenberger's avatar Kurzenberger
Browse files

fixed version with enhanced provider.php and checked with codeChecker

parent 4e16f800
Pipeline #10777 passed with stage
Showing with 206 additions and 238 deletions
+206 -238
...@@ -81,7 +81,7 @@ class dta_backend_utils { ...@@ -81,7 +81,7 @@ class dta_backend_utils {
]; ];
// If request returned null, return false to indicate failure. // If request returned null, return false to indicate failure.
if (is_null(self::dta_post($url, $params))) { if (is_null(self::assignsubmission_dta_post($url, $params))) {
return false; return false;
} else { } else {
return true; return true;
......
File moved
...@@ -26,7 +26,6 @@ use assignsubmission_dta\models\dta_recommendation; ...@@ -26,7 +26,6 @@ use assignsubmission_dta\models\dta_recommendation;
* Utility class for DTA submission plugin result display. * Utility class for DTA submission plugin result display.
* *
* @package assignsubmission_dta * @package assignsubmission_dta
* @copyright 2023 Your Name <you@example.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class dta_view_submission_utils { class dta_view_submission_utils {
...@@ -37,69 +36,96 @@ class dta_view_submission_utils { ...@@ -37,69 +36,96 @@ class dta_view_submission_utils {
public const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta'; public const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta';
/** /**
* Generates a short summary HTML. * Generates a short summary HTML (like your old plugin).
* *
* @param int $assignmentid The assignment ID. * @param int $assignmentid The assignment ID.
* @param int $submissionid The submission ID to create a report for. * @param int $submissionid The submission ID to create a report for.
* @return string HTML summary. * @return string The HTML summary.
*/ */
public static function assignsubmission_dta_generate_summary_html( public static function assignsubmission_dta_generate_summary_html(
int $assignmentid, int $assignmentid,
int $submissionid int $submissionid
): string { ): string {
// Fetch data.
$summary = dta_db_utils::assignsubmission_dta_get_result_summary_from_database( // 1) Retrieve the summary data from the DB (adjust your DB-utils class as needed).
$assignmentid, $summary = dta_db_utils::assignsubmission_dta_get_result_summary_from_database($assignmentid, $submissionid);
$submissionid
); // 2) Prepare an HTML buffer.
$html = ''; $html = '';
// Calculate success rate, if no unknown result states or compilation errors. // 3) Extract counts from your new method names:
$successrate = '?'; $unknowncount = $summary->assignsubmission_dta_unknown_count();
if ($summary->unknown_count() === 0 && $summary->compilation_error_count() === 0) { $compilecount = $summary->assignsubmission_dta_compilation_error_count();
$successrate = round(($summary->successful_count() / $summary->result_count()) * 100, 2); $successcount = $summary->assignsubmission_dta_successful_count();
} $failcount = $summary->assignsubmission_dta_failed_count();
$totalcount = $summary->assignsubmission_dta_result_count();
// Generate HTML. // 4) Compute success rate if no unknown/compile errors and total>0.
$html .= $summary->successful_count() . '/'; $successrate = '?';
if ($summary->compilation_error_count() === 0 && $summary->unknown_count() === 0) { if ($unknowncount === 0 && $compilecount === 0 && $totalcount > 0) {
$html .= $summary->result_count() . ' (' . $successrate . '%)'; $successrate = round(($successcount / $totalcount) * 100, 2);
}
// 5) “X/Y (Z%) tests successful” line:
// If either compile errors or unknown exist -> we show "?"
// else X/Y (rate%).
$html .= $successcount . '/';
if ($compilecount === 0 && $unknowncount === 0) {
$html .= ($totalcount > 0)
? ($totalcount . ' (' . $successrate . '%)')
: ('0 (' . $successrate . ')');
} else { } else {
$html .= '?'; $html .= '?';
} }
$html .= get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . '<br />'; $html .= get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . "<br />";
if ($summary->compilation_error_count() > 0) { // 6) If there are compilation errors, show them:
$html .= $summary->compilation_error_count() if ($compilecount > 0) {
$html .= $compilecount
. get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
. '<br />'; . "<br />";
} }
if ($summary->unknown_count() > 0) { // 7) If there are unknown results, show them:
$html .= $summary->unknown_count() if ($unknowncount > 0) {
$html .= $unknowncount
. get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
. '<br />'; . "<br />";
} }
// 8) Competencies (like your old snippet):
$showncompetencies = explode(';', $summary->successfultestcompetencies); $showncompetencies = explode(';', $summary->successfultestcompetencies);
$overallcompetencies = explode(';', $summary->overalltestcompetencies); $overallcompetencies = explode(';', $summary->overalltestcompetencies);
$tmp = ''; $tmp = '';
for ($index = 0, $size = count($showncompetencies); $index < $size; $index++) { $size = count($showncompetencies);
$shown = $showncompetencies[$index]; for ($i = 0; $i < $size; $i++) {
$comp = $overallcompetencies[$index]; $shown = $showncompetencies[$i];
// If the competency was actually assessed, add a summary entry. $comp = $overallcompetencies[$i];
// If the competency was actually used (non-zero?), show a row.
if ($shown !== '0') { if ($shown !== '0') {
$tmp .= get_string('comp' . $index, self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) $shownval = floatval($shown);
. ' ' . (100 * floatval($shown) / floatval($comp)) . '% ' . '<br />'; $compval = floatval($comp);
// Guard division by zero:
$pct = 0;
if ($compval > 0) {
$pct = 100.0 * $shownval / $compval;
}
// “compX XX%<br />”
$tmp .= get_string('comp' . $i, self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
. ' ' . round($pct, 2) . '%<br />';
} }
} }
$html .= get_string('success_competencies', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) $html .= get_string('success_competencies', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
. '<br />' . $tmp . '<br />'; . "<br />" . $tmp . "<br />";
return \html_writer::div($html, 'dtaSubmissionSummary'); // 9) Wrap it in a DIV for styling, and return.
} return \html_writer::div($html, "dtaSubmissionSummary");
}
/** /**
* Generates detailed view HTML. * Generates detailed view HTML.
...@@ -134,7 +160,7 @@ class dta_view_submission_utils { ...@@ -134,7 +160,7 @@ class dta_view_submission_utils {
$compilationerrorattributes = 'dtaResultCompilationError'; $compilationerrorattributes = 'dtaResultCompilationError';
$attributes = ['class' => 'dtaTableData']; $attributes = ['class' => 'dtaTableData'];
// Building summary table. // Build the summary table header.
$tmp = \html_writer::tag( $tmp = \html_writer::tag(
'th', 'th',
get_string('summary', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string('summary', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
...@@ -146,6 +172,13 @@ class dta_view_submission_utils { ...@@ -146,6 +172,13 @@ class dta_view_submission_utils {
$body = ''; $body = '';
// Pull the counters from the summary object.
$resultcount = $summary->assignsubmission_dta_result_count();
$successfulcount = $summary->assignsubmission_dta_successful_count();
$failedcount = $summary->assignsubmission_dta_failed_count();
$compilationcount = $summary->assignsubmission_dta_compilation_error_count();
$unknowncount = $summary->assignsubmission_dta_unknown_count();
// Total items. // Total items.
$tmp = ''; $tmp = '';
$tmp .= \html_writer::tag( $tmp .= \html_writer::tag(
...@@ -153,8 +186,9 @@ class dta_view_submission_utils { ...@@ -153,8 +186,9 @@ class dta_view_submission_utils {
get_string('total_items', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string('total_items', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
$attributes $attributes
); );
$tmp .= \html_writer::tag('td', $summary->result_count(), $attributes); $tmp .= \html_writer::tag('td', $resultcount, $attributes);
$resultrowattributes = $tablerowattributes; $resultrowattributes = $tablerowattributes;
// Original code colors this row as unknown by default:
$resultrowattributes['class'] .= ' ' . $unknownattributes; $resultrowattributes['class'] .= ' ' . $unknownattributes;
$body .= \html_writer::tag('tr', $tmp, $resultrowattributes); $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
...@@ -165,16 +199,13 @@ class dta_view_submission_utils { ...@@ -165,16 +199,13 @@ class dta_view_submission_utils {
get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
$attributes $attributes
); );
$tmp .= \html_writer::tag('td', $summary->successful_count(), $attributes); $tmp .= \html_writer::tag('td', $successfulcount, $attributes);
$resultrowattributes = $tablerowattributes; $resultrowattributes = $tablerowattributes;
// Compute success rate if no unknown or compilation errors, and resultcount > 0.
$successrate = '?'; $successrate = '?';
if ($summary->unknown_count() > 0 || $summary->compilation_error_count() > 0) { if ($unknowncount == 0 && $compilationcount == 0 && $resultcount > 0) {
$resultrowattributes['class'] .= ' ' . $unknownattributes; $successrate = round(($successfulcount / $resultcount) * 100, 2);
} else {
$successrate = round(
($summary->successful_count() / $summary->result_count()) * 100,
2
);
if ($successrate < 50) { if ($successrate < 50) {
$resultrowattributes['class'] .= ' ' . $compilationerrorattributes; $resultrowattributes['class'] .= ' ' . $compilationerrorattributes;
} else if ($successrate < 75) { } else if ($successrate < 75) {
...@@ -182,6 +213,9 @@ class dta_view_submission_utils { ...@@ -182,6 +213,9 @@ class dta_view_submission_utils {
} else { } else {
$resultrowattributes['class'] .= ' ' . $successattributes; $resultrowattributes['class'] .= ' ' . $successattributes;
} }
} else {
// If unknown or compilation errors => highlight as unknown.
$resultrowattributes['class'] .= ' ' . $unknownattributes;
} }
$body .= \html_writer::tag('tr', $tmp, $resultrowattributes); $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
...@@ -192,9 +226,9 @@ class dta_view_submission_utils { ...@@ -192,9 +226,9 @@ class dta_view_submission_utils {
get_string('failures', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string('failures', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
$attributes $attributes
); );
$tmp .= \html_writer::tag('td', $summary->failed_count(), $attributes); $tmp .= \html_writer::tag('td', $failedcount, $attributes);
$resultrowattributes = $tablerowattributes; $resultrowattributes = $tablerowattributes;
if ($summary->failed_count() > 0) { if ($failedcount > 0) {
$resultrowattributes['class'] .= ' ' . $failureattributes; $resultrowattributes['class'] .= ' ' . $failureattributes;
} else { } else {
$resultrowattributes['class'] .= ' ' . $successattributes; $resultrowattributes['class'] .= ' ' . $successattributes;
...@@ -208,9 +242,9 @@ class dta_view_submission_utils { ...@@ -208,9 +242,9 @@ class dta_view_submission_utils {
get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
$attributes $attributes
); );
$tmp .= \html_writer::tag('td', $summary->compilation_error_count(), $attributes); $tmp .= \html_writer::tag('td', $compilationcount, $attributes);
$resultrowattributes = $tablerowattributes; $resultrowattributes = $tablerowattributes;
if ($summary->compilation_error_count() > 0) { if ($compilationcount > 0) {
$resultrowattributes['class'] .= ' ' . $compilationerrorattributes; $resultrowattributes['class'] .= ' ' . $compilationerrorattributes;
} else { } else {
$resultrowattributes['class'] .= ' ' . $successattributes; $resultrowattributes['class'] .= ' ' . $successattributes;
...@@ -224,68 +258,61 @@ class dta_view_submission_utils { ...@@ -224,68 +258,61 @@ class dta_view_submission_utils {
get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME),
$attributes $attributes
); );
$tmp .= \html_writer::tag('td', $summary->unknown_count(), $attributes); $tmp .= \html_writer::tag('td', $unknowncount, $attributes);
$resultrowattributes = $tablerowattributes; $resultrowattributes = $tablerowattributes;
if ($summary->unknown_count() > 0) { if ($unknowncount > 0) {
$resultrowattributes['class'] .= ' ' . $unknownattributes; $resultrowattributes['class'] .= ' ' . $unknownattributes;
} else { } else {
$resultrowattributes['class'] .= ' ' . $successattributes; $resultrowattributes['class'] .= ' ' . $successattributes;
} }
$body .= \html_writer::tag('tr', $tmp, $resultrowattributes); $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
// Success rate. // Success rate row.
$tmp = ''; $tmp = '';
$tmp .= \html_writer::tag( $tmp .= \html_writer::tag(
'td', 'td',
\html_writer::tag( \html_writer::tag('b', get_string('success_rate', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)),
'b',
get_string('success_rate', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)
),
$attributes $attributes
); );
$suffix = '?'; // If no compilation errors or unknown => show successrate, else "?".
if ($summary->compilation_error_count() === 0 && $summary->unknown_count() === 0) { $suffix = ($compilationcount == 0 && $unknowncount == 0 && $resultcount > 0)
$suffix = $summary->result_count() . ' (' . $successrate . '%)'; ? ($resultcount . ' (' . $successrate . '%)')
} : '?';
$tmp .= \html_writer::tag( $tmp .= \html_writer::tag(
'td', 'td',
\html_writer::tag( \html_writer::tag('b', $successfulcount . '/' . $suffix),
'b',
$summary->successful_count() . '/' . $suffix
),
$attributes $attributes
); );
$resultrowattributes = $tablerowattributes; $resultrowattributes = $tablerowattributes;
if ($summary->unknown_count() > 0 || $summary->compilation_error_count() > 0) { if ($compilationcount == 0 && $unknowncount == 0 && $resultcount > 0) {
$resultrowattributes['class'] .= ' ' . $unknownattributes;
} else {
if ($successrate !== '?' && $successrate < 50) { if ($successrate !== '?' && $successrate < 50) {
$resultrowattributes['class'] .= ' ' . $compilationerrorattributes; $resultrowattributes['class'] .= ' ' . $compilationerrorattributes;
} else if ($successrate !== '?' && $successrate < 75) { } else if ($successrate !== '?' && $successrate < 75) {
$resultrowattributes['class'] .= ' ' . $failureattributes; $resultrowattributes['class'] .= ' ' . $failureattributes;
} else if ($successrate !== '?') { } else {
$resultrowattributes['class'] .= ' ' . $successattributes; $resultrowattributes['class'] .= ' ' . $successattributes;
} }
} else {
$resultrowattributes['class'] .= ' ' . $unknownattributes;
} }
$body .= \html_writer::tag('tr', $tmp, $resultrowattributes); $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
// Finalize the summary table.
$body = \html_writer::tag('tbody', $body); $body = \html_writer::tag('tbody', $body);
$table = \html_writer::tag('table', $header . $body, ['class' => 'dtaTable']); $table = \html_writer::tag('table', $header . $body, ['class' => 'dtaTable']);
$html .= $table; $html .= $table;
// Add empty div for spacing after summary. // Spacing after the summary table.
$html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']); $html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']);
// *** Recommendations Table *** // *** Recommendations Table ***
if (!empty($recommendations)) { if (!empty($recommendations)) {
// Sorting logic.
$allowedsortfields = ['topic', 'exercise_name', 'difficulty', 'score']; $allowedsortfields = ['topic', 'exercise_name', 'difficulty', 'score'];
$allowedsortdirs = ['asc', 'desc']; $allowedsortdirs = ['asc', 'desc'];
$sortby = isset($_POST['sortby']) ? $_POST['sortby'] : 'score'; $sortby = $_POST['sortby'] ?? 'score';
$sortdir = isset($_POST['sortdir']) ? $_POST['sortdir'] : 'asc'; $sortdir = $_POST['sortdir'] ?? 'asc';
if (!in_array($sortby, $allowedsortfields)) { if (!in_array($sortby, $allowedsortfields)) {
$sortby = 'score'; $sortby = 'score';
...@@ -307,7 +334,6 @@ class dta_view_submission_utils { ...@@ -307,7 +334,6 @@ class dta_view_submission_utils {
if ($comparison === 0) { if ($comparison === 0) {
return 0; return 0;
} }
if ($sortdir === 'asc') { if ($sortdir === 'asc') {
return ($comparison < 0) ? -1 : 1; return ($comparison < 0) ? -1 : 1;
} else { } else {
...@@ -358,7 +384,7 @@ class dta_view_submission_utils { ...@@ -358,7 +384,7 @@ class dta_view_submission_utils {
return \html_writer::tag('th', $form, ['class' => $class]); return \html_writer::tag('th', $form, ['class' => $class]);
}; };
// Table header for recommendations. // Build the recommendations table header.
$tableheader = ''; $tableheader = '';
$tableheader .= $generatesortableheader( $tableheader .= $generatesortableheader(
'topic', 'topic',
...@@ -405,7 +431,7 @@ class dta_view_submission_utils { ...@@ -405,7 +431,7 @@ class dta_view_submission_utils {
$html .= \html_writer::tag('table', $tableheader . $tablebody, ['class' => 'dtaTable']); $html .= \html_writer::tag('table', $tableheader . $tablebody, ['class' => 'dtaTable']);
// Add empty div for spacing after recommendations. // Spacing after recommendations.
$html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']); $html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']);
} }
...@@ -427,8 +453,18 @@ class dta_view_submission_utils { ...@@ -427,8 +453,18 @@ class dta_view_submission_utils {
for ($index = 0, $size = count($overallcompetencies); $index < $size; $index++) { for ($index = 0, $size = count($overallcompetencies); $index < $size; $index++) {
$comp = $overallcompetencies[$index]; $comp = $overallcompetencies[$index];
$shown = $showncompetencies[$index]; $shown = $showncompetencies[$index];
// If the competency was assessed, add a row in the table.
// If the competency was actually assessed, add a row in the table.
if ($comp !== '0') { if ($comp !== '0') {
$compval = floatval($comp);
$shownval = floatval($shown);
// Guard division by zero:
$pct = 0;
if ($compval > 0) {
$pct = (100.0 * $shownval / $compval);
}
$resultrowattributes = $tablerowattributes; $resultrowattributes = $tablerowattributes;
$tmp = ''; $tmp = '';
$tmp .= \html_writer::tag( $tmp .= \html_writer::tag(
...@@ -438,7 +474,7 @@ class dta_view_submission_utils { ...@@ -438,7 +474,7 @@ class dta_view_submission_utils {
); );
$tmp .= \html_writer::tag( $tmp .= \html_writer::tag(
'td', 'td',
(100 * floatval($shown) / floatval($comp)) . '% (' . $shown . ' / ' . $comp . ')', round($pct, 2) . '% (' . $shown . ' / ' . $comp . ')',
$resultrowattributes $resultrowattributes
); );
$tmp .= \html_writer::tag( $tmp .= \html_writer::tag(
...@@ -521,7 +557,7 @@ class dta_view_submission_utils { ...@@ -521,7 +557,7 @@ class dta_view_submission_utils {
); );
$body .= \html_writer::tag('tr', $tmp, $resultrowattributes); $body .= \html_writer::tag('tr', $tmp, $resultrowattributes);
// If state is different than successful, show additional info. // If state != 1, show additional info.
if ($r->state !== 1) { if ($r->state !== 1) {
$tmp = ''; $tmp = '';
$tmp .= \html_writer::tag( $tmp .= \html_writer::tag(
......
<?php <?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 summary.
*
* @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; namespace assignsubmission_dta\models;
/** /**
* Entity class for DTA submission plugin result summary. * Entity class for DTA submission plugin result summary.
*
* @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_summary { class dta_result_summary {
/**
* @var int $timestamp Timestamp for ordering and deletion of previous results.
*/
public $timestamp; public $timestamp;
/**
* @var string $globalstacktrace Global stack trace if applicable, empty otherwise.
*/
public $globalstacktrace; public $globalstacktrace;
/**
* @var string $successfultestcompetencies Successfully tested competencies (tests and weights), or empty string.
*/
public $successfultestcompetencies; public $successfultestcompetencies;
/**
* @var string $overalltestcompetencies Overall tested competencies (tests and weights), or empty string.
*/
public $overalltestcompetencies; public $overalltestcompetencies;
/**
* @var array $results List of detail results.
*/
public $results; public $results;
/**
* Decodes the JSON result summary returned by the backend service call into the plugin PHP data structure.
*
* @param string $jsonstring JSON string containing DtaResultSummary.
* @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);
$summary = new dta_result_summary(); $summary = new dta_result_summary();
$summary->timestamp = $response->timestamp; $summary->timestamp = $response->timestamp ?? 0;
$summary->globalstacktrace = $response->globalstacktrace; $summary->globalstacktrace = $response->globalstacktrace ?? '';
$summary->successfultestcompetencies = $response->successfulTestCompetencyProfile ?? ''; $summary->successfultestcompetencies = $response->successfulTestCompetencyProfile ?? '';
$summary->overalltestcompetencies = $response->overallTestCompetencyProfile ?? ''; $summary->overalltestcompetencies = $response->overallTestCompetencyProfile ?? '';
if (!empty($response->results) && is_array($response->results)) {
$summary->results = self::assignsubmission_dta_decode_json_result_array($response->results); $summary->results = self::assignsubmission_dta_decode_json_result_array($response->results);
} else {
$summary->results = [];
}
return $summary; return $summary;
} }
/**
* Decodes an array of JSON detail results into the plugin PHP data structure.
*
* @param array $jsonarray Decoded JSON array of results.
* @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 = [];
foreach ($jsonarray as $entry) { foreach ($jsonarray as $entry) {
...@@ -96,30 +42,19 @@ class dta_result_summary { ...@@ -96,30 +42,19 @@ class dta_result_summary {
$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 ?? 0;
$value->linenumber = $entry->lineNumber ?? ''; $value->linenumber = $entry->lineNumber ?? 0;
$value->position = $entry->position ?? ''; $value->position = $entry->position ?? 0;
$ret[] = $value; $ret[] = $value;
} }
return $ret; return $ret;
} }
/**
* Returns the number of detail results attached to the summary.
*
* @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);
} }
/**
* Returns the number of detail results with the given state attached to the summary.
*
* @param int $state State ordinal number.
* @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) {
...@@ -130,39 +65,29 @@ class dta_result_summary { ...@@ -130,39 +65,29 @@ class dta_result_summary {
return $num; return $num;
} }
/**
* Returns the number of detail results with compilation errors attached to the summary.
*
* @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); // State=3 => compile error
} }
/**
* Returns the number of detail results with test failures attached to the summary.
*
* @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); // State=2 => fail
} }
/**
* Returns the number of detail results with successful tests attached to the summary.
*
* @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); // State=1 => success
} }
/**
* Returns the number of detail results with an unknown result attached to the summary.
*
* @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); // State=0 => unknown
}
// OPTIONAL: A helper to safely get success rate 0..100
public function assignsubmission_dta_success_rate(): float {
$count = $this->assignsubmission_dta_result_count();
if ($count === 0) {
return 0.0;
}
$successful = $this->assignsubmission_dta_successful_count();
return ($successful / $count) * 100.0;
} }
} }
...@@ -190,6 +190,8 @@ class provider implements \core_privacy\local\metadata\provider, ...@@ -190,6 +190,8 @@ class provider implements \core_privacy\local\metadata\provider,
// Delete records from assignsubmission_dta tables. // Delete records from assignsubmission_dta tables.
$DB->delete_records('assignsubmission_dta_result', ['assignmentid' => $assignmentid]); $DB->delete_records('assignsubmission_dta_result', ['assignmentid' => $assignmentid]);
$DB->delete_records('assignsubmission_dta_summary', ['assignmentid' => $assignmentid]); $DB->delete_records('assignsubmission_dta_summary', ['assignmentid' => $assignmentid]);
$DB->delete_records('assignsubmission_dta_recommendations', ['assignmentid' => $assignmentid]);
} }
/** /**
...@@ -218,6 +220,10 @@ class provider implements \core_privacy\local\metadata\provider, ...@@ -218,6 +220,10 @@ class provider implements \core_privacy\local\metadata\provider,
'assignmentid' => $assignmentid, 'assignmentid' => $assignmentid,
'submissionid' => $submissionid, 'submissionid' => $submissionid,
]); ]);
$DB->delete_records('assignsubmission_dta_recommendations', [
'assignmentid' => $assignmentid,
'submissionid' => $submissionid,
]);
} }
/** /**
...@@ -245,6 +251,7 @@ class provider implements \core_privacy\local\metadata\provider, ...@@ -245,6 +251,7 @@ class provider implements \core_privacy\local\metadata\provider,
$params['assignid'] = $deletedata->get_assignid(); $params['assignid'] = $deletedata->get_assignid();
$DB->delete_records_select('assignsubmission_dta_result', "assignmentid = :assignid AND submissionid $sql", $params); $DB->delete_records_select('assignsubmission_dta_result', "assignmentid = :assignid AND submissionid $sql", $params);
$DB->delete_records_select('assignsubmission_dta_summary', "assignmentid = :assignid AND submissionid $sql", $params); $DB->delete_records_select('assignsubmission_dta_summary', "assignmentid = :assignid AND submissionid $sql", $params);
$DB->delete_records_select('assignsubmission_dta_recommendations', "assignmentid = :assignid AND submissionid $sql", $params);
} }
/** /**
......
...@@ -55,7 +55,7 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -55,7 +55,7 @@ class assign_submission_dta extends assign_submission_plugin {
* *
* @return string * @return string
*/ */
public function assignsubmission_dta_get_name(): string { public function get_name(): string {
return get_string('pluginname', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME); return get_string('pluginname', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME);
} }
...@@ -65,7 +65,7 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -65,7 +65,7 @@ class assign_submission_dta extends assign_submission_plugin {
* @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 get_settings(MoodleQuickForm $mform): void {
// Add draft filemanager to form. // Add draft filemanager to form.
$mform->addElement( $mform->addElement(
'filemanager', 'filemanager',
...@@ -131,7 +131,7 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -131,7 +131,7 @@ class assign_submission_dta extends assign_submission_plugin {
* @param stdClass $data Form data. * @param stdClass $data Form data.
* @return bool * @return bool
*/ */
public function assignsubmission_dta_save_settings(stdClass $data): bool { public function 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)) {
...@@ -232,8 +232,8 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -232,8 +232,8 @@ class assign_submission_dta extends assign_submission_plugin {
* @param stdClass $submission Submission to check. * @param stdClass $submission Submission to check.
* @return bool True if file count is zero. * @return bool True if file count is zero.
*/ */
public function assignsubmission_dta_is_empty(stdClass $submission): bool { public function is_empty(stdClass $submission): bool {
return ($this->assignsubmission_dta_count_files( return ($this->count_files(
$submission->id, $submission->id,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION
) === 0); ) === 0);
...@@ -246,7 +246,7 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -246,7 +246,7 @@ class assign_submission_dta extends assign_submission_plugin {
* @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): int { private function count_files(int $submissionid, $areaid): int {
$fs = get_file_storage(); $fs = get_file_storage();
$files = $fs->get_area_files( $files = $fs->get_area_files(
$this->assignment->get_context()->id, $this->assignment->get_context()->id,
...@@ -279,7 +279,7 @@ class assign_submission_dta extends assign_submission_plugin { ...@@ -279,7 +279,7 @@ class assign_submission_dta extends assign_submission_plugin {
); );
// If submission is empty, leave directly. // If submission is empty, leave directly.
if ($this->assignsubmission_dta_is_empty($submission)) { if ($this->is_empty($submission)) {
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