.
class ViewSubmissionUtils {
// 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");
}
/**
* generates detailed view html
*
* @param int assignmentid assignment
* @param int submissionid submission to create a report for
*/
public static function generatedetailhtml(
int $assignmentid,
int $submissionid
): string {
// Fetch data.
$summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
$html = "";
// Define a few css classes and prepare html attribute arrays to beautify the output.
$tableheaderrowattributes = ["class" => "dtaTableHeaderRow"];
$tablerowattributes = ["class" => "dtaTableRow"];
$resultrowattributes = $tablerowattributes;
$unknownattributes = 'dtaResultUnknown';
$successattributes = 'dtaResultSuccess';
$failureattributes = 'dtaResultFailure';
$compilationerrorattributes = 'dtaResultCompilationError';
// Summary table.
$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);
$body = "";
$tmp = "";
$attributes = ["class" => "dtaTableData"];
$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'] = $resultrowattributes['class'] . " " . $unknownattributes;
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$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'] = $resultrowattributes['class'] . " " . $unknownattributes;
} else {
$successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 );
if ($successrate < 50) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
} else if ($successrate < 75) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $failureattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$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'] = $resultrowattributes['class'] . " " . $failureattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$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'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$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'] = $resultrowattributes['class'] . " " . $unknownattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$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'] = $resultrowattributes['class'] . " " . $unknownattributes;
} else {
if ($successrate < 50) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
} else if ($successrate < 75) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $failureattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$body = html_writer::tag("tbody", $body);
$table = html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);
$html .= $table;
// Add empty div for spacing between summary and compentency table.
$html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);
// Competency assessment table.
$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];
// If the competency was actually assessed by the assignment and tests, add a row in the table.
if($comp!="0") {
// New copy of base attributes array.
$resultrowattributes = $tablerowattributes;
$tmp = "";
$tmp .= html_writer::tag("td", get_string("comp" . $index, self::COMPONENT_NAME), $resultrowattributes);
$tmp .= html_writer::tag("td", 100*floatval($shown)/floatval($comp) . "% " .
"(" . $shown . " / " . $comp . ")", $resultrowattributes);
$tmp .= html_writer::tag("td", get_string("comp_expl" . $index, self::COMPONENT_NAME), $resultrowattributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
}
}
$body = html_writer::tag("tbody", $body);
$html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);
// Add empty div for spacing between competency and details table.
$html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);
// Details table.
$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) {
// Add spacer first if not null.
if (!is_null($spacerrow)) {
$body .= $spacerrow;
}
// New copy of base attributes array.
$resultrowattributes = $tablerowattributes;
// Check which css class to add for the colored left-border according to resuls state.
if ($r->state == 0) {
$resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultUnknown';
} else if ($r->state == 1) {
$resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultSuccess';
} else if ($r->state == 2) {
$resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultFailure';
} else if ($r->state == 3) {
$resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultCompilationError';
}
$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);
$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);
// If state is something different than successful, show additional rows.
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);
// Only show line, column and position if they have useful values.
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_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 (!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);
}
$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);
}
// Set spacerrow value if null for next round separation.
if (is_null($spacerrow)) {
$spacerrow = html_writer::empty_tag("tr", ["class" => "dtaTableSpacer"]);
}
}
$html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);
// Wrap generated html into final div.
$html = html_writer::div($html, "dtaSubmissionDetails");
return $html;
}
}