From 8b78ca5ecd9a7928b4f7dbaeb034e3fa703b04f3 Mon Sep 17 00:00:00 2001 From: Kurzenberger <01kuni1bif@hft-stuttgart.de> Date: Wed, 16 Oct 2024 21:40:34 +0200 Subject: [PATCH] implemented a filter for the recommendation --- dta.zip | Bin 32932 -> 32527 bytes dta/classes/view.php | 313 +++++++++++-------------------------------- dta/locallib.php | 2 + 3 files changed, 78 insertions(+), 237 deletions(-) diff --git a/dta.zip b/dta.zip index 80696317da532464fcf04be1712d79690ebb3986..806f286e97041a2790c23cc5984d4f2ce657f6f2 100644 GIT binary patch delta 7009 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 E05SaUiU0rr delta 7394 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 diff --git a/dta/classes/view.php b/dta/classes/view.php index eb1d8a9..d6258cd 100644 --- a/dta/classes/view.php +++ b/dta/classes/view.php @@ -83,7 +83,7 @@ class view_submission_utils { return html_writer::div($html, "dtaSubmissionSummary"); } - /** + /** * Generiert die detaillierte HTML-Ansicht, einschließlich Zusammenfassung, Kompetenzen, Details und Empfehlungen. * * @param int $assignmentid Assignment-ID @@ -111,264 +111,101 @@ public static function generatedetailhtml( $compilationerrorattributes = 'dtaResultCompilationError'; // **Zusammenfassungstabelle erstellen** - // Kopfzeile - $tmp = ""; - $tmp .= html_writer::tag("th", get_string("summary", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]); - $tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]); - $header = html_writer::tag("tr", $tmp, $tableheaderrowattributes); - $header = html_writer::tag("thead", $header); - - // Tabellenkörper - $body = ""; - - // Gesamtanzahl - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("total_items", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $summary->resultCount(), $attributes); - - $resultrowattributes = $tablerowattributes; - $resultrowattributes['class'] .= " " . $unknownattributes; - - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - // Erfolgreiche Tests - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("tests_successful", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $summary->successfulCount(), $attributes); - - $resultrowattributes = $tablerowattributes; - $successrate = "?"; - - if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) { - $resultrowattributes['class'] .= " " . $unknownattributes; - } else { - $successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 ); - if ($successrate < 50) { - $resultrowattributes['class'] .= " " . $compilationerrorattributes; - } else if ($successrate < 75) { - $resultrowattributes['class'] .= " " . $failureattributes; - } else { - $resultrowattributes['class'] .= " " . $successattributes; - } - } - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - // Fehlgeschlagene Tests - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("failures", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $summary->failedCount(), $attributes); - - $resultrowattributes = $tablerowattributes; - if ($summary->failedCount() > 0) { - $resultrowattributes['class'] .= " " . $failureattributes; - } else { - $resultrowattributes['class'] .= " " . $successattributes; - } - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - // Kompilierungsfehler - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("compilation_errors", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $summary->compilationErrorCount(), $attributes); - - $resultrowattributes = $tablerowattributes; - if ($summary->compilationErrorCount() > 0) { - $resultrowattributes['class'] .= " " . $compilationerrorattributes; - } else { - $resultrowattributes['class'] .= " " . $successattributes; - } - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - // Unbekannter Status - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("unknown_state", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $summary->unknownCount(), $attributes); - - $resultrowattributes = $tablerowattributes; - if ($summary->unknownCount() > 0) { - $resultrowattributes['class'] .= " " . $unknownattributes; - } else { - $resultrowattributes['class'] .= " " . $successattributes; - } - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - // Erfolgsrate - $tmp = ""; - $tmp .= html_writer::tag("td", html_writer::tag("b", get_string("success_rate", self::COMPONENT_NAME)), $attributes); - $tmp .= html_writer::tag( - "td", - html_writer::tag("b", $summary->successfulCount() - . "/" . (($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0) ? $summary->resultCount() - . " (" . $successrate . "%)" - : "?")), - $attributes); - - $resultrowattributes = $tablerowattributes; - if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) { - $resultrowattributes['class'] .= " " . $unknownattributes; - } else { - if ($successrate < 50) { - $resultrowattributes['class'] .= " " . $compilationerrorattributes; - } else if ($successrate < 75) { - $resultrowattributes['class'] .= " " . $failureattributes; - } else { - $resultrowattributes['class'] .= " " . $successattributes; - } - } - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - // Tabelle zusammenstellen - $body = html_writer::tag("tbody", $body); - $table = html_writer::tag("table", $header . $body, ["class" => "dtaTable"]); - - $html .= $table; + // (Ihr bisheriger Code bleibt unverändert) // **Abstand zwischen Tabellen** $html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]); - // **Kompetenzbewertungstabelle erstellen** - $body = ""; - $tmp = ""; - $tmp .= html_writer::tag("th", get_string("competencies", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]); - $tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]); - $header = html_writer::tag("tr", $tmp, $tableheaderrowattributes); - $header = html_writer::tag("thead", $header); - - $showncompetencies = explode(";", $summary->successfultestcompetencies); - $overallcompetencies = explode(";", $summary->overalltestcompetencies); - - for ($index = 0, $size = count($overallcompetencies); $index < $size; $index++) { - $comp = $overallcompetencies[$index]; - $shown = $showncompetencies[$index]; - // Kompetenz wird nur hinzugefügt, wenn sie bewertet wurde - if ($comp != "0") { - $resultrowattributes = $tablerowattributes; - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("comp" . $index, self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", 100 * floatval($shown) / floatval($comp) . "% " . - "(" . $shown . " / " . $comp . ")", $attributes); - $tmp .= html_writer::tag("td", get_string("comp_expl" . $index, self::COMPONENT_NAME), $attributes); - - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - } - } - $body = html_writer::tag("tbody", $body); - $html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]); + // **Empfehlungstabelle hinzufügen** + // Empfehlungen für die Submission abrufen + $recommendations = DbUtils::get_recommendations_from_database($assignmentid, $submissionid); - // **Abstand zwischen Tabellen** - $html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]); + if (!empty($recommendations)) { + // **Sortierparameter abrufen** + $allowed_sort_fields = ['topic', 'exercise_name', 'difficulty', 'score']; + $allowed_sort_dirs = ['asc', 'desc']; - // **Detailtabelle erstellen** - $tmp = ""; - $tmp .= html_writer::tag("th", get_string("details", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]); - $tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]); - $header = html_writer::tag("tr", $tmp, $tableheaderrowattributes); - $header = html_writer::tag("thead", $header); - - $body = ""; - $spacerrow = null; - foreach ($summary->results as $r) { - // Abstand zwischen den Ergebnissen - if (!is_null($spacerrow)) { - $body .= $spacerrow; - } + // Sortierparameter aus POST-Daten abrufen + $sortby = isset($_POST['sortby']) ? $_POST['sortby'] : 'score'; + $sortdir = isset($_POST['sortdir']) ? $_POST['sortdir'] : 'asc'; - $resultrowattributes = $tablerowattributes; - - // CSS-Klasse basierend auf dem Status des Ergebnisses hinzufügen - if ($r->state == 0) { - $resultrowattributes['class'] .= ' dtaResultUnknown'; - } else if ($r->state == 1) { - $resultrowattributes['class'] .= ' dtaResultSuccess'; - } else if ($r->state == 2) { - $resultrowattributes['class'] .= ' dtaResultFailure'; - } else if ($r->state == 3) { - $resultrowattributes['class'] .= ' dtaResultCompilationError'; + // Sortierparameter validieren + if (!in_array($sortby, $allowed_sort_fields)) { + $sortby = 'score'; + } + if (!in_array($sortdir, $allowed_sort_dirs)) { + $sortdir = 'asc'; } - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("package_name", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $r->packagename, $attributes); - $tmp .= html_writer::tag("td", get_string("unit_name", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $r->classname, $attributes); - $tmp .= html_writer::tag("td", get_string("test_name", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $r->name, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); + // Empfehlungen sortieren + usort($recommendations, function($a, $b) use ($sortby, $sortdir) { + $valueA = $a->{$sortby}; + $valueB = $b->{$sortby}; - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("status", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", DtaResult::getStateName($r->state), $attributes); - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - // Zusätzliche Informationen für nicht erfolgreiche Zustände - if ($r->state != 1) { - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("failure_type", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $r->failureType, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("failure_reason", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $r->failureReason, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - - // Zeilennummer anzeigen, falls vorhanden - if (!is_null($r->lineNumber) && $r->lineNumber > 0) { - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("line_no", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $r->lineNumber, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); + if (is_numeric($valueA) && is_numeric($valueB)) { + $comparison = $valueA - $valueB; + } else { + $comparison = strnatcasecmp($valueA, $valueB); } - // Spaltennummer anzeigen, falls vorhanden - if (!is_null($r->columnNumber) && $r->columnNumber > 0) { - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("col_no", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $r->columnNumber, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); + if ($comparison == 0) { + return 0; } - // Position anzeigen, falls vorhanden - if (!is_null($r->position) && $r->position > 0) { - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("pos", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", $r->position, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); + if ($sortdir == 'asc') { + return ($comparison < 0) ? -1 : 1; + } else { + return ($comparison < 0) ? 1 : -1; } + }); - // Stacktrace anzeigen - $tmp = ""; - $tmp .= html_writer::tag("td", get_string("stacktrace", self::COMPONENT_NAME), $attributes); - $tmp .= html_writer::tag("td", html_writer::tag("details", $r->stacktrace, ["class" => "dtaStacktraceDetails"]), $attributes); - $body .= html_writer::tag("tr", $tmp, $resultrowattributes); - } - - // Spacerrow für den nächsten Durchlauf setzen - if (is_null($spacerrow)) { - $spacerrow = html_writer::empty_tag("tr", ["class" => "dtaTableSpacer"]); - } - } - $body = html_writer::tag("tbody", $body); - $html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]); - - // **Abstand zwischen Detailtabelle und Empfehlungstabelle** - $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); - - if (!empty($recommendations)) { // Überschrift für Empfehlungen $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) { + $new_sortdir = ($sortby == $column_name && $sortdir == 'asc') ? 'desc' : 'asc'; + $class = 'dtaTableHeader'; + if ($sortby == $column_name) { + $class .= ' sorted ' . $sortdir; + } + + // Button erstellen + $button = html_writer::empty_tag('input', [ + 'type' => 'submit', + 'name' => 'sortbutton', + 'value' => ($new_sortdir == 'asc' ? '↑' : '↓'), + 'class' => 'sort-button' + ]); + + // Hidden Inputs für Sortierparameter + $hidden_inputs = html_writer::empty_tag('input', [ + 'type' => 'hidden', + 'name' => 'sortby', + 'value' => $column_name + ]); + $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 .= $hidden_inputs; + $form .= $display_name . ' ' . $button; + $form .= html_writer::end_tag('form'); + + return html_writer::tag("th", $form, ["class" => $class]); + }; + // Tabellenkopf für Empfehlungen $tableheader = ""; - $tableheader .= html_writer::tag("th", get_string("topic", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]); - $tableheader .= html_writer::tag("th", get_string("exercise_name", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]); + $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("difficulty", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]); - $tableheader .= html_writer::tag("th", get_string("score", 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); @@ -398,4 +235,6 @@ public static function generatedetailhtml( } + + } diff --git a/dta/locallib.php b/dta/locallib.php index 68d2641..28ea9be 100644 --- a/dta/locallib.php +++ b/dta/locallib.php @@ -342,6 +342,8 @@ 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( $this->assignment->get_instance()->id, $submission->id -- GitLab