.
/**
* utility class for DTA submission plugin result display
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_submission_utils {
/**
* Broadly used in logic, parametrized for easier change.
*/
const COMPONENT_NAME = "assignsubmission_dta";
/**
* generates a short summary html
*
* @param int $assignmentid assignment
* @param int $submissionid submission to create a report for
* @return string html
*/
public static function generatesummaryhtml(
int $assignmentid,
int $submissionid
): string {
// Fetch data.
$summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
$html = "";
// Calculate success rate, if no unknown result states or compilation errors.
$successrate = "?";
if ($summary->unknownCount() == 0 && $summary->compilationErrorCount() == 0) {
$successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 );
}
// Generate html.
$html .= $summary->successfulCount() . "/";
$html .= ($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0)
? $summary->resultCount() . " (" . $successrate . "%)"
: "?";
$html .= get_string("tests_successful", self::COMPONENT_NAME) . "
";
if ($summary->compilationErrorCount() > 0) {
$html .= $summary->compilationErrorCount() . get_string("compilation_errors", self::COMPONENT_NAME) . "
";
}
if ($summary->unknownCount() > 0) {
$html .= $summary->unknownCount() . get_string("unknown_state", self::COMPONENT_NAME) . "
";
}
$showncompetencies = explode(";", $summary->successfultestcompetencies);
$overallcompetencies = explode(";", $summary->overalltestcompetencies);
$tmp = "";
for ($index = 0, $size = count($showncompetencies); $index < $size; $index++) {
$shown = $showncompetencies[$index];
$comp = $overallcompetencies[$index];
// If the competency was actually assessed by the assignment and tests, add a summary entry.
if ($shown != "0") {
$tmp .= get_string("comp" . $index, self::COMPONENT_NAME) .
" " . 100 * floatval($shown) / floatval($comp) . "% " . "
";
}
}
$html .= get_string("success_competencies", self::COMPONENT_NAME) . "
" . $tmp . "
";
return html_writer::div($html, "dtaSubmissionSummary");
}
/**
* Generiert die detaillierte HTML-Ansicht, einschließlich Zusammenfassung, Kompetenzen, Details und Empfehlungen.
*
* @param int $assignmentid Assignment-ID
* @param int $submissionid Submission-ID, für die der Bericht erstellt wird
* @return string HTML-Code
*/
public static function generatedetailhtml(
int $assignmentid,
int $submissionid
): string {
// HTML-Inhalt initialisieren
$html = "";
// Daten abrufen
$summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
// CSS-Klassen und HTML-Attributarrays definieren
$tableheaderrowattributes = ["class" => "dtaTableHeaderRow"];
$tablerowattributes = ["class" => "dtaTableRow"];
$attributes = ["class" => "dtaTableData"];
$unknownattributes = 'dtaResultUnknown';
$successattributes = 'dtaResultSuccess';
$failureattributes = 'dtaResultFailure';
$compilationerrorattributes = 'dtaResultCompilationError';
// **Zusammenfassungstabelle erstellen**
// (Ihr bisheriger Code bleibt unverändert)
// **Abstand zwischen Tabellen**
$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)) {
// **Sortierparameter abrufen**
$allowed_sort_fields = ['topic', 'exercise_name', 'difficulty', 'score'];
$allowed_sort_dirs = ['asc', 'desc'];
// Sortierparameter aus POST-Daten abrufen
$sortby = isset($_POST['sortby']) ? $_POST['sortby'] : 'score';
$sortdir = isset($_POST['sortdir']) ? $_POST['sortdir'] : 'asc';
// Sortierparameter validieren
if (!in_array($sortby, $allowed_sort_fields)) {
$sortby = 'score';
}
if (!in_array($sortdir, $allowed_sort_dirs)) {
$sortdir = 'asc';
}
// Empfehlungen sortieren
usort($recommendations, function($a, $b) use ($sortby, $sortdir) {
$valueA = $a->{$sortby};
$valueB = $b->{$sortby};
if (is_numeric($valueA) && is_numeric($valueB)) {
$comparison = $valueA - $valueB;
} else {
$comparison = strnatcasecmp($valueA, $valueB);
}
if ($comparison == 0) {
return 0;
}
if ($sortdir == 'asc') {
return ($comparison < 0) ? -1 : 1;
} else {
return ($comparison < 0) ? 1 : -1;
}
});
// Ü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 .= $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 .= $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);
// 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);
$tablebody .= html_writer::tag("tr", $tablerow, $tablerowattributes);
}
$tablebody = html_writer::tag("tbody", $tablebody);
// Empfehlungstabelle zusammenstellen
$html .= html_writer::tag("table", $tableheader . $tablebody, ["class" => "dtaTable"]);
}
// Abschließendes Div für die gesamte HTML-Ausgabe
$html = html_writer::div($html, "dtaSubmissionDetails");
return $html;
}
}