From 64cc51fa606056dbdd9803d842f6faa78dce1aef Mon Sep 17 00:00:00 2001 From: Kurzenberger <01kuni1bif@hft-stuttgart.de> Date: Fri, 10 Jan 2025 14:29:02 +0100 Subject: [PATCH] fixed version with enhanced provider.php and checked with codeChecker --- dta/classes/dta_backend_utils.php | 2 +- .../{db_utils.php => dta_db_utils.php} | 0 dta/classes/dta_view_submission_utils.php | 282 ++++++++++-------- dta/classes/models/dta_result_summary.php | 139 ++------- dta/classes/privacy/provider.php | 7 + dta/locallib.php | 14 +- 6 files changed, 206 insertions(+), 238 deletions(-) rename dta/classes/{db_utils.php => dta_db_utils.php} (100%) diff --git a/dta/classes/dta_backend_utils.php b/dta/classes/dta_backend_utils.php index 369b733..1c7aa8d 100644 --- a/dta/classes/dta_backend_utils.php +++ b/dta/classes/dta_backend_utils.php @@ -81,7 +81,7 @@ class dta_backend_utils { ]; // 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; } else { return true; diff --git a/dta/classes/db_utils.php b/dta/classes/dta_db_utils.php similarity index 100% rename from dta/classes/db_utils.php rename to dta/classes/dta_db_utils.php diff --git a/dta/classes/dta_view_submission_utils.php b/dta/classes/dta_view_submission_utils.php index a85b551..aec50aa 100644 --- a/dta/classes/dta_view_submission_utils.php +++ b/dta/classes/dta_view_submission_utils.php @@ -1,6 +1,6 @@ <?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 @@ -26,7 +26,6 @@ use assignsubmission_dta\models\dta_recommendation; * Utility class for DTA submission plugin result display. * * @package assignsubmission_dta - * @copyright 2023 Your Name <you@example.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class dta_view_submission_utils { @@ -36,70 +35,97 @@ class dta_view_submission_utils { */ public const ASSIGNSUBMISSION_DTA_COMPONENT_NAME = 'assignsubmission_dta'; - /** - * Generates a short summary HTML. - * - * @param int $assignmentid The assignment ID. - * @param int $submissionid The submission ID to create a report for. - * @return string HTML summary. - */ - public static function assignsubmission_dta_generate_summary_html( - int $assignmentid, - int $submissionid - ): string { - // Fetch data. - $summary = dta_db_utils::assignsubmission_dta_get_result_summary_from_database( - $assignmentid, - $submissionid - ); - $html = ''; - - // Calculate success rate, if no unknown result states or compilation errors. - $successrate = '?'; - if ($summary->unknown_count() === 0 && $summary->compilation_error_count() === 0) { - $successrate = round(($summary->successful_count() / $summary->result_count()) * 100, 2); - } - - // Generate HTML. - $html .= $summary->successful_count() . '/'; - if ($summary->compilation_error_count() === 0 && $summary->unknown_count() === 0) { - $html .= $summary->result_count() . ' (' . $successrate . '%)'; - } else { - $html .= '?'; - } - $html .= get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . '<br />'; + /** + * Generates a short summary HTML (like your old plugin). + * + * @param int $assignmentid The assignment ID. + * @param int $submissionid The submission ID to create a report for. + * @return string The HTML summary. + */ +public static function assignsubmission_dta_generate_summary_html( + int $assignmentid, + int $submissionid +): string { + + // 1) Retrieve the summary data from the DB (adjust your DB-utils class as needed). + $summary = dta_db_utils::assignsubmission_dta_get_result_summary_from_database($assignmentid, $submissionid); + + // 2) Prepare an HTML buffer. + $html = ''; + + // 3) Extract counts from your new method names: + $unknowncount = $summary->assignsubmission_dta_unknown_count(); + $compilecount = $summary->assignsubmission_dta_compilation_error_count(); + $successcount = $summary->assignsubmission_dta_successful_count(); + $failcount = $summary->assignsubmission_dta_failed_count(); + $totalcount = $summary->assignsubmission_dta_result_count(); + + // 4) Compute success rate if no unknown/compile errors and total>0. + $successrate = '?'; + if ($unknowncount === 0 && $compilecount === 0 && $totalcount > 0) { + $successrate = round(($successcount / $totalcount) * 100, 2); + } - if ($summary->compilation_error_count() > 0) { - $html .= $summary->compilation_error_count() - . get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) - . '<br />'; - } + // 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 { + $html .= '?'; + } + $html .= get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) . "<br />"; - if ($summary->unknown_count() > 0) { - $html .= $summary->unknown_count() - . get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) - . '<br />'; - } + // 6) If there are compilation errors, show them: + if ($compilecount > 0) { + $html .= $compilecount + . get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) + . "<br />"; + } - $showncompetencies = explode(';', $summary->successfultestcompetencies); - $overallcompetencies = explode(';', $summary->overalltestcompetencies); + // 7) If there are unknown results, show them: + if ($unknowncount > 0) { + $html .= $unknowncount + . get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) + . "<br />"; + } - $tmp = ''; - for ($index = 0, $size = count($showncompetencies); $index < $size; $index++) { - $shown = $showncompetencies[$index]; - $comp = $overallcompetencies[$index]; - // If the competency was actually assessed, add a summary entry. - if ($shown !== '0') { - $tmp .= get_string('comp' . $index, self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) - . ' ' . (100 * floatval($shown) / floatval($comp)) . '% ' . '<br />'; + // 8) Competencies (like your old snippet): + $showncompetencies = explode(';', $summary->successfultestcompetencies); + $overallcompetencies = explode(';', $summary->overalltestcompetencies); + + $tmp = ''; + $size = count($showncompetencies); + for ($i = 0; $i < $size; $i++) { + $shown = $showncompetencies[$i]; + $comp = $overallcompetencies[$i]; + + // If the competency was actually used (non-zero?), show a row. + if ($shown !== '0') { + $shownval = floatval($shown); + $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) - . '<br />' . $tmp . '<br />'; + $html .= get_string('success_competencies', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) + . "<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. @@ -126,15 +152,15 @@ class dta_view_submission_utils { // *** Summary Table *** $tableheaderrowattributes = ['class' => 'dtaTableHeaderRow']; - $tablerowattributes = ['class' => 'dtaTableRow']; - $resultrowattributes = $tablerowattributes; - $unknownattributes = 'dtaResultUnknown'; - $successattributes = 'dtaResultSuccess'; - $failureattributes = 'dtaResultFailure'; + $tablerowattributes = ['class' => 'dtaTableRow']; + $resultrowattributes = $tablerowattributes; + $unknownattributes = 'dtaResultUnknown'; + $successattributes = 'dtaResultSuccess'; + $failureattributes = 'dtaResultFailure'; $compilationerrorattributes = 'dtaResultCompilationError'; - $attributes = ['class' => 'dtaTableData']; + $attributes = ['class' => 'dtaTableData']; - // Building summary table. + // Build the summary table header. $tmp = \html_writer::tag( 'th', get_string('summary', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), @@ -146,6 +172,13 @@ class dta_view_submission_utils { $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. $tmp = ''; $tmp .= \html_writer::tag( @@ -153,8 +186,9 @@ class dta_view_submission_utils { get_string('total_items', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), $attributes ); - $tmp .= \html_writer::tag('td', $summary->result_count(), $attributes); + $tmp .= \html_writer::tag('td', $resultcount, $attributes); $resultrowattributes = $tablerowattributes; + // Original code colors this row as unknown by default: $resultrowattributes['class'] .= ' ' . $unknownattributes; $body .= \html_writer::tag('tr', $tmp, $resultrowattributes); @@ -165,16 +199,13 @@ class dta_view_submission_utils { get_string('tests_successful', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), $attributes ); - $tmp .= \html_writer::tag('td', $summary->successful_count(), $attributes); + $tmp .= \html_writer::tag('td', $successfulcount, $attributes); $resultrowattributes = $tablerowattributes; + + // Compute success rate if no unknown or compilation errors, and resultcount > 0. $successrate = '?'; - if ($summary->unknown_count() > 0 || $summary->compilation_error_count() > 0) { - $resultrowattributes['class'] .= ' ' . $unknownattributes; - } else { - $successrate = round( - ($summary->successful_count() / $summary->result_count()) * 100, - 2 - ); + if ($unknowncount == 0 && $compilationcount == 0 && $resultcount > 0) { + $successrate = round(($successfulcount / $resultcount) * 100, 2); if ($successrate < 50) { $resultrowattributes['class'] .= ' ' . $compilationerrorattributes; } else if ($successrate < 75) { @@ -182,6 +213,9 @@ class dta_view_submission_utils { } else { $resultrowattributes['class'] .= ' ' . $successattributes; } + } else { + // If unknown or compilation errors => highlight as unknown. + $resultrowattributes['class'] .= ' ' . $unknownattributes; } $body .= \html_writer::tag('tr', $tmp, $resultrowattributes); @@ -192,9 +226,9 @@ class dta_view_submission_utils { get_string('failures', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), $attributes ); - $tmp .= \html_writer::tag('td', $summary->failed_count(), $attributes); + $tmp .= \html_writer::tag('td', $failedcount, $attributes); $resultrowattributes = $tablerowattributes; - if ($summary->failed_count() > 0) { + if ($failedcount > 0) { $resultrowattributes['class'] .= ' ' . $failureattributes; } else { $resultrowattributes['class'] .= ' ' . $successattributes; @@ -208,9 +242,9 @@ class dta_view_submission_utils { get_string('compilation_errors', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), $attributes ); - $tmp .= \html_writer::tag('td', $summary->compilation_error_count(), $attributes); + $tmp .= \html_writer::tag('td', $compilationcount, $attributes); $resultrowattributes = $tablerowattributes; - if ($summary->compilation_error_count() > 0) { + if ($compilationcount > 0) { $resultrowattributes['class'] .= ' ' . $compilationerrorattributes; } else { $resultrowattributes['class'] .= ' ' . $successattributes; @@ -224,68 +258,61 @@ class dta_view_submission_utils { get_string('unknown_state', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), $attributes ); - $tmp .= \html_writer::tag('td', $summary->unknown_count(), $attributes); + $tmp .= \html_writer::tag('td', $unknowncount, $attributes); $resultrowattributes = $tablerowattributes; - if ($summary->unknown_count() > 0) { + if ($unknowncount > 0) { $resultrowattributes['class'] .= ' ' . $unknownattributes; } else { $resultrowattributes['class'] .= ' ' . $successattributes; } $body .= \html_writer::tag('tr', $tmp, $resultrowattributes); - // Success rate. + // Success rate row. $tmp = ''; $tmp .= \html_writer::tag( 'td', - \html_writer::tag( - 'b', - get_string('success_rate', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME) - ), + \html_writer::tag('b', get_string('success_rate', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME)), $attributes ); - $suffix = '?'; - if ($summary->compilation_error_count() === 0 && $summary->unknown_count() === 0) { - $suffix = $summary->result_count() . ' (' . $successrate . '%)'; - } + // If no compilation errors or unknown => show successrate, else "?". + $suffix = ($compilationcount == 0 && $unknowncount == 0 && $resultcount > 0) + ? ($resultcount . ' (' . $successrate . '%)') + : '?'; $tmp .= \html_writer::tag( 'td', - \html_writer::tag( - 'b', - $summary->successful_count() . '/' . $suffix - ), + \html_writer::tag('b', $successfulcount . '/' . $suffix), $attributes ); $resultrowattributes = $tablerowattributes; - if ($summary->unknown_count() > 0 || $summary->compilation_error_count() > 0) { - $resultrowattributes['class'] .= ' ' . $unknownattributes; - } else { + if ($compilationcount == 0 && $unknowncount == 0 && $resultcount > 0) { if ($successrate !== '?' && $successrate < 50) { $resultrowattributes['class'] .= ' ' . $compilationerrorattributes; } else if ($successrate !== '?' && $successrate < 75) { $resultrowattributes['class'] .= ' ' . $failureattributes; - } else if ($successrate !== '?') { + } else { $resultrowattributes['class'] .= ' ' . $successattributes; } + } else { + $resultrowattributes['class'] .= ' ' . $unknownattributes; } $body .= \html_writer::tag('tr', $tmp, $resultrowattributes); - $body = \html_writer::tag('tbody', $body); + // Finalize the summary table. + $body = \html_writer::tag('tbody', $body); $table = \html_writer::tag('table', $header . $body, ['class' => 'dtaTable']); - $html .= $table; - // Add empty div for spacing after summary. + // Spacing after the summary table. $html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']); // *** Recommendations Table *** if (!empty($recommendations)) { - // Sorting logic. $allowedsortfields = ['topic', 'exercise_name', 'difficulty', 'score']; - $allowedsortdirs = ['asc', 'desc']; + $allowedsortdirs = ['asc', 'desc']; - $sortby = isset($_POST['sortby']) ? $_POST['sortby'] : 'score'; - $sortdir = isset($_POST['sortdir']) ? $_POST['sortdir'] : 'asc'; + $sortby = $_POST['sortby'] ?? 'score'; + $sortdir = $_POST['sortdir'] ?? 'asc'; if (!in_array($sortby, $allowedsortfields)) { $sortby = 'score'; @@ -307,7 +334,6 @@ class dta_view_submission_utils { if ($comparison === 0) { return 0; } - if ($sortdir === 'asc') { return ($comparison < 0) ? -1 : 1; } else { @@ -329,27 +355,27 @@ class dta_view_submission_utils { // Sort button. $button = \html_writer::empty_tag('input', [ - 'type' => 'submit', - 'name' => 'sortbutton', + 'type' => 'submit', + 'name' => 'sortbutton', 'value' => ($newsortdir === 'asc' ? '↑' : '↓'), 'class' => 'sort-button', ]); // Hidden inputs. $hiddeninputs = \html_writer::empty_tag('input', [ - 'type' => 'hidden', - 'name' => 'sortby', + 'type' => 'hidden', + 'name' => 'sortby', 'value' => $columnname, ]); $hiddeninputs .= \html_writer::empty_tag('input', [ - 'type' => 'hidden', - 'name' => 'sortdir', + 'type' => 'hidden', + 'name' => 'sortdir', 'value' => $newsortdir, ]); $form = \html_writer::start_tag('form', [ 'method' => 'post', - 'style' => 'display:inline', + 'style' => 'display:inline', ]); $form .= $hiddeninputs; $form .= $displayname . ' ' . $button; @@ -358,7 +384,7 @@ class dta_view_submission_utils { return \html_writer::tag('th', $form, ['class' => $class]); }; - // Table header for recommendations. + // Build the recommendations table header. $tableheader = ''; $tableheader .= $generatesortableheader( 'topic', @@ -405,13 +431,13 @@ class dta_view_submission_utils { $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']); } // *** Competency Assessment Table *** $body = ''; - $tmp = ''; + $tmp = ''; $tmp .= \html_writer::tag( 'th', get_string('competencies', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME), @@ -421,14 +447,24 @@ class dta_view_submission_utils { $header = \html_writer::tag('tr', $tmp, $tableheaderrowattributes); $header = \html_writer::tag('thead', $header); - $showncompetencies = explode(';', $summary->successfultestcompetencies); + $showncompetencies = explode(';', $summary->successfultestcompetencies); $overallcompetencies = explode(';', $summary->overalltestcompetencies); for ($index = 0, $size = count($overallcompetencies); $index < $size; $index++) { - $comp = $overallcompetencies[$index]; + $comp = $overallcompetencies[$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') { + $compval = floatval($comp); + $shownval = floatval($shown); + + // Guard division by zero: + $pct = 0; + if ($compval > 0) { + $pct = (100.0 * $shownval / $compval); + } + $resultrowattributes = $tablerowattributes; $tmp = ''; $tmp .= \html_writer::tag( @@ -438,7 +474,7 @@ class dta_view_submission_utils { ); $tmp .= \html_writer::tag( 'td', - (100 * floatval($shown) / floatval($comp)) . '% (' . $shown . ' / ' . $comp . ')', + round($pct, 2) . '% (' . $shown . ' / ' . $comp . ')', $resultrowattributes ); $tmp .= \html_writer::tag( @@ -449,8 +485,8 @@ class dta_view_submission_utils { $body .= \html_writer::tag('tr', $tmp, $resultrowattributes); } } - $body = \html_writer::tag('tbody', $body); - $html .= \html_writer::tag('table', $header . $body, ['class' => 'dtaTable']); + $body = \html_writer::tag('tbody', $body); + $html .= \html_writer::tag('table', $header . $body, ['class' => 'dtaTable']); // Add empty div for spacing. $html .= \html_writer::empty_tag('div', ['class' => 'dtaSpacer']); @@ -466,7 +502,7 @@ class dta_view_submission_utils { $header = \html_writer::tag('tr', $tmp, $tableheaderrowattributes); $header = \html_writer::tag('thead', $header); - $body = ''; + $body = ''; $spacerrow = null; foreach ($summary->results as $r) { // Add spacer first if not null. @@ -521,7 +557,7 @@ class dta_view_submission_utils { ); $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) { $tmp = ''; $tmp .= \html_writer::tag( diff --git a/dta/classes/models/dta_result_summary.php b/dta/classes/models/dta_result_summary.php index 7659d47..541b02f 100644 --- a/dta/classes/models/dta_result_summary.php +++ b/dta/classes/models/dta_result_summary.php @@ -1,125 +1,60 @@ <?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; /** * 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 { - /** - * @var int $timestamp Timestamp for ordering and deletion of previous results. - */ public $timestamp; - - /** - * @var string $globalstacktrace Global stack trace if applicable, empty otherwise. - */ public $globalstacktrace; - - /** - * @var string $successfultestcompetencies Successfully tested competencies (tests and weights), or empty string. - */ public $successfultestcompetencies; - - /** - * @var string $overalltestcompetencies Overall tested competencies (tests and weights), or empty string. - */ public $overalltestcompetencies; - - /** - * @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 JSON string containing DtaResultSummary. - * @return dta_result_summary The result summary. - */ public static function assignsubmission_dta_decode_json(string $jsonstring): dta_result_summary { $response = json_decode($jsonstring); $summary = new dta_result_summary(); - $summary->timestamp = $response->timestamp; - $summary->globalstacktrace = $response->globalstacktrace; + $summary->timestamp = $response->timestamp ?? 0; + $summary->globalstacktrace = $response->globalstacktrace ?? ''; $summary->successfultestcompetencies = $response->successfulTestCompetencyProfile ?? ''; - $summary->overalltestcompetencies = $response->overallTestCompetencyProfile ?? ''; + $summary->overalltestcompetencies = $response->overallTestCompetencyProfile ?? ''; - $summary->results = self::assignsubmission_dta_decode_json_result_array($response->results); + if (!empty($response->results) && is_array($response->results)) { + $summary->results = self::assignsubmission_dta_decode_json_result_array($response->results); + } else { + $summary->results = []; + } 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 { $ret = []; foreach ($jsonarray as $entry) { $value = new dta_result(); - $value->packagename = $entry->packageName ?? ''; - $value->classname = $entry->className ?? ''; - $value->name = $entry->name ?? ''; - $value->state = $entry->state ?? 0; - $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->packagename = $entry->packageName ?? ''; + $value->classname = $entry->className ?? ''; + $value->name = $entry->name ?? ''; + $value->state = $entry->state ?? 0; + $value->failuretype = $entry->failureType ?? ''; + $value->failurereason = $entry->failureReason ?? ''; + $value->stacktrace = $entry->stacktrace ?? ''; + $value->columnnumber = $entry->columnNumber ?? 0; + $value->linenumber = $entry->lineNumber ?? 0; + $value->position = $entry->position ?? 0; $ret[] = $value; } return $ret; } - /** - * Returns the number of detail results attached to the summary. - * - * @return int Count of occurrences. - */ public function assignsubmission_dta_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 occurrences for the provided state. - */ public function assignsubmission_dta_state_occurence_count(int $state): int { $num = 0; foreach ($this->results as $r) { @@ -130,39 +65,29 @@ class dta_result_summary { 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 { - 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 { - 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 { - 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 { - 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; } } diff --git a/dta/classes/privacy/provider.php b/dta/classes/privacy/provider.php index f310b37..acadff8 100644 --- a/dta/classes/privacy/provider.php +++ b/dta/classes/privacy/provider.php @@ -190,6 +190,8 @@ class provider implements \core_privacy\local\metadata\provider, // Delete records from assignsubmission_dta tables. $DB->delete_records('assignsubmission_dta_result', ['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, 'assignmentid' => $assignmentid, 'submissionid' => $submissionid, ]); + $DB->delete_records('assignsubmission_dta_recommendations', [ + 'assignmentid' => $assignmentid, + 'submissionid' => $submissionid, + ]); } /** @@ -245,6 +251,7 @@ class provider implements \core_privacy\local\metadata\provider, $params['assignid'] = $deletedata->get_assignid(); $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_recommendations', "assignmentid = :assignid AND submissionid $sql", $params); } /** diff --git a/dta/locallib.php b/dta/locallib.php index b0e9ba9..546919d 100644 --- a/dta/locallib.php +++ b/dta/locallib.php @@ -55,7 +55,7 @@ class assign_submission_dta extends assign_submission_plugin { * * @return string */ - public function assignsubmission_dta_get_name(): string { + public function get_name(): string { return get_string('pluginname', self::ASSIGNSUBMISSION_DTA_COMPONENT_NAME); } @@ -65,7 +65,7 @@ class assign_submission_dta extends assign_submission_plugin { * @param MoodleQuickForm $mform Form to add elements to. * @return void */ - public function assignsubmission_dta_get_settings(MoodleQuickForm $mform): void { + public function get_settings(MoodleQuickForm $mform): void { // Add draft filemanager to form. $mform->addElement( 'filemanager', @@ -131,7 +131,7 @@ class assign_submission_dta extends assign_submission_plugin { * @param stdClass $data Form data. * @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. $draftfilemanagerid = self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST; if (!isset($data->$draftfilemanagerid)) { @@ -232,8 +232,8 @@ class assign_submission_dta extends assign_submission_plugin { * @param stdClass $submission Submission to check. * @return bool True if file count is zero. */ - public function assignsubmission_dta_is_empty(stdClass $submission): bool { - return ($this->assignsubmission_dta_count_files( + public function is_empty(stdClass $submission): bool { + return ($this->count_files( $submission->id, self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION ) === 0); @@ -246,7 +246,7 @@ class assign_submission_dta extends assign_submission_plugin { * @param string $areaid Filearea id to count. * @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(); $files = $fs->get_area_files( $this->assignment->get_context()->id, @@ -279,7 +279,7 @@ class assign_submission_dta extends assign_submission_plugin { ); // If submission is empty, leave directly. - if ($this->assignsubmission_dta_is_empty($submission)) { + if ($this->is_empty($submission)) { return true; } -- GitLab