view.php 17.3 KB
Newer Older
1
<?php
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 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/>.
16
17
18

class ViewSubmissionUtils {

19
20
21
    // Broadly used in logic, parametrized for easier change.
    const COMPONENT_NAME = "assignsubmission_dta";

22
23
24
    /**
     * generates a short summary html
     *
25
26
     * @param int assignmentid assignment
     * @param int submissionid submission to create a report for
27
28
     * @return string html
     */
29
    public static function generatesummaryhtml(
30
31
        int $assignmentid,
        int $submissionid
32
33
    ): string {

34
        // Fetch data.
35
        $summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
36
37
        $html = "";

38
        // Calculate success rate, if no unknown result states or compilation errors.
39
        $successrate = "?";
40
        if ($summary->unknownCount() == 0 && $summary->compilationErrorCount() == 0) {
41
            $successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 );
42
43
        }

44
        // Generate html.
45
46
        $html .= $summary->successfulCount() . "/";
        $html .= ($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0)
47
            ? $summary->resultCount() . " (" . $successrate . "%)"
48
                : "?";
Lückemeyer's avatar
Lückemeyer committed
49
        $html .= get_string("tests_successful", self::COMPONENT_NAME) . "<br />";
50
51

        if ($summary->compilationErrorCount() > 0) {
Lückemeyer's avatar
Lückemeyer committed
52
            $html .= $summary->compilationErrorCount() . get_string("compilation_errors", self::COMPONENT_NAME) . "<br />";
53
54
55
        }

        if ($summary->unknownCount() > 0) {
Lückemeyer's avatar
Lückemeyer committed
56
            $html .= $summary->unknownCount() . get_string("unknown_state", self::COMPONENT_NAME) . "<br />";
57
        }
58

Lückemeyer's avatar
Lückemeyer committed
59
60
61
62
63
64
65
66
67
68
69
70
71
72
        $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) . "% " . "<br />";
            }
        }
        
        $html .= get_string("success_competencies", self::COMPONENT_NAME) . $tmp . "<br />";
73
74
75
76
77
78
79

        return html_writer::div($html, "dtaSubmissionSummary");
    }

    /**
     * generates detailed view html
     *
80
81
     * @param int assignmentid assignment
     * @param int submissionid submission to create a report for
82
     */
83
    public static function generatedetailhtml(
84
85
        int $assignmentid,
        int $submissionid
86
87
    ): string {

88
        // Fetch data.
89
        $summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
90
91
        $html = "";

92
        // Define a few css classes and prepare html attribute arrays to beautify the output.
93
94
        $tableheaderrowattributes = ["class" => "dtaTableHeaderRow"];
        $tablerowattributes = ["class" => "dtaTableRow"];
95
96
97
98
99
        $resultrowattributes = $tablerowattributes;
        $unknownattributes = 'dtaResultUnknown';
        $successattributes = 'dtaResultSuccess';
        $failureattributes = 'dtaResultFailure';
        $compilationerrorattributes = 'dtaResultCompilationError';
100

101
        // Summary table.
102
        $tmp = "";
103
        $tmp .= html_writer::tag("th", get_string("summary", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
104
        $tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]);
105
        $header = html_writer::tag("tr", $tmp, $tableheaderrowattributes);
106
107
108
109
        $header = html_writer::tag("thead", $header);

        $body = "";
        $tmp = "";
110
        $attributes = ["class" => "dtaTableData"];
111
112
        $tmp .= html_writer::tag(
            "td",
113
            get_string("total_items", self::COMPONENT_NAME),
114
115
116
117
118
119
120
            $attributes);

        $tmp .= html_writer::tag(
            "td",
            $summary->resultCount(),
            $attributes);

121
122
        $resultrowattributes = $tablerowattributes;
        $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $unknownattributes;
123

124
        $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
125
126

        $tmp = "";
127
        $tmp .= html_writer::tag("td", get_string("tests_successful", self::COMPONENT_NAME), $attributes);
128
129
        $tmp .= html_writer::tag( "td", $summary->successfulCount(), $attributes);

130
        $resultrowattributes = $tablerowattributes;
131
        $successrate = "?";
132
133

        if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) {
134
            $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $unknownattributes;
135
        } else {
136
137
            $successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 );
            if ($successrate < 50) {
138
                $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
139
            } else if ($successrate < 75) {
140
                $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $failureattributes;
141
            } else {
142
                $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
143
144
            }
        }
145
        $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
146
147

        $tmp = "";
148
        $tmp .= html_writer::tag("td", get_string("failures", self::COMPONENT_NAME), $attributes);
149
150
        $tmp .= html_writer::tag("td", $summary->failedCount(), $attributes);

151
        $resultrowattributes = $tablerowattributes;
152
        if ($summary->failedCount() > 0) {
153
            $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $failureattributes;
154
        } else {
155
            $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
156
        }
157
        $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
158
159

        $tmp = "";
160
        $tmp .= html_writer::tag("td", get_string("compilation_errors", self::COMPONENT_NAME), $attributes);
161
162
        $tmp .= html_writer::tag("td", $summary->compilationErrorCount(), $attributes);

163
        $resultrowattributes = $tablerowattributes;
164
        if ($summary->compilationErrorCount() > 0) {
165
            $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
166
        } else {
167
            $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
168
        }
169
        $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
170
171

        $tmp = "";
172
        $tmp .= html_writer::tag("td", get_string("unknown_state", self::COMPONENT_NAME), $attributes);
173
174
        $tmp .= html_writer::tag("td", $summary->unknownCount(), $attributes);

175
        $resultrowattributes = $tablerowattributes;
176
        if ($summary->unknownCount() > 0) {
177
            $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $unknownattributes;
178
        } else {
179
            $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
180
        }
181
        $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
182
183

        $tmp = "";
184
        $tmp .= html_writer::tag("td", html_writer::tag("b", get_string("success_rate", self::COMPONENT_NAME)), $attributes);
185
186
187
188
        $tmp .= html_writer::tag(
            "td",
            html_writer::tag("b", $summary->successfulCount()
                . "/" . (($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0) ? $summary->resultCount()
189
                . " (" . $successrate . "%)"
190
191
192
                    : "?")),
            $attributes);

193
        $resultrowattributes = $tablerowattributes;
194
        if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) {
195
            $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $unknownattributes;
196
        } else {
197
            if ($successrate < 50) {
198
                $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
199
            } else if ($successrate < 75) {
200
                $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $failureattributes;
201
            } else {
202
                $resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
203
204
            }
        }
205
        $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
206
207

        $body = html_writer::tag("tbody", $body);
208
        $table = html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);
209
210
211

        $html .= $table;

212
213
        // Add empty div for spacing between summary and compentency table.
        $html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);
214
        
Lückemeyer's avatar
Lückemeyer committed
215
        // Competency assessment table.
216
        $body = "";
217
218
219
220
221
222
223
224
        $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);
Lückemeyer's avatar
Lückemeyer committed
225
        
226
        for ($index=0, $size=count($overallcompetencies); $index<$size; $index++) {
227
228
            $comp=$overallcompetencies[$index];
            $shown=$showncompetencies[$index];
229
            // If the competency was actually assessed by the assignment and tests, add a row in the table.
230
            if($comp!="0") {
231
232
233
                // New copy of base attributes array.
                $resultrowattributes = $tablerowattributes;
                $tmp = "";
234
                $tmp .= html_writer::tag("td", get_string("comp" . $index, self::COMPONENT_NAME), $resultrowattributes);                
Lückemeyer's avatar
Lückemeyer committed
235
                $tmp .= html_writer::tag("td", 100*floatval($shown)/floatval($comp) . "% " .
236
                    "(" . $shown . " / " . $comp . ")", $resultrowattributes);
Lückemeyer's avatar
Lückemeyer committed
237
                $tmp .= html_writer::tag("td", get_string("comp_expl" . $index, self::COMPONENT_NAME), $resultrowattributes);    
238
239
                
                $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
240
            }
241
242
243
244
245
        }
        $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.
246
        $html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);
247

248
        // Details table.
249
        $tmp = "";
250
        $tmp .= html_writer::tag("th", get_string("details", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
251
        $tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]);
252
        $header = html_writer::tag("tr", $tmp, $tableheaderrowattributes);
253
254
255
        $header = html_writer::tag("thead", $header);

        $body = "";
256
        $spacerrow = null;
257
        foreach ($summary->results as $r) {
258
            // Add spacer first if not null.
259
260
            if (!is_null($spacerrow)) {
                $body .= $spacerrow;
261
262
            }

263
264
            // New copy of base attributes array.
            $resultrowattributes = $tablerowattributes;
265

266
            // Check which css class to add for the colored left-border according to resuls state.
267
            if ($r->state == 0) {
268
                $resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultUnknown';
269
            } else if ($r->state == 1) {
270
                $resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultSuccess';
271
            } else if ($r->state == 2) {
272
                $resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultFailure';
273
            } else if ($r->state == 3) {
274
                $resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultCompilationError';
275
276
277
278
279
            }

            $tmp = "";
            $tmp .= html_writer::tag(
                "td",
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
                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),
301
                $attributes);
302

303
304
305
306
            $tmp .= html_writer::tag(
                "td",
                $r->name,
                $attributes);
307
            $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
308
309
310
311

            $tmp = "";
            $tmp .= html_writer::tag(
                "td",
312
                get_string("status", self::COMPONENT_NAME),
313
314
315
316
317
318
                $attributes);

            $tmp .= html_writer::tag(
                "td",
                DtaResult::getStateName($r->state),
                $attributes);
319
            $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
320

321
            // If state is something different than successful, show additional rows.
322
323
324
325
            if ($r->state != 1) {
                $tmp = "";
                $tmp .= html_writer::tag(
                    "td",
326
                    get_string("failure_type", self::COMPONENT_NAME),
327
                    $attributes);
328

329
330
331
332
                $tmp .= html_writer::tag(
                    "td",
                    $r->failureType,
                    $attributes);
333
                $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
334

335
336
337
                $tmp = "";
                $tmp .= html_writer::tag(
                    "td",
338
                    get_string("failure_reason", self::COMPONENT_NAME),
339
                    $attributes);
340

341
342
343
344
                $tmp .= html_writer::tag(
                    "td",
                    $r->failureReason,
                    $attributes);
345
                $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
346

347
                // Only show line, column and position if they have useful values.
348
349
350
351
                if (!is_null($r->lineNumber) && $r->lineNumber > 0) {
                    $tmp = "";
                    $tmp .= html_writer::tag(
                        "td",
Lückemeyer's avatar
Lückemeyer committed
352
                        get_string("line_no", self::COMPONENT_NAME),
353
354
355
356
357
358
                        $attributes);

                    $tmp .= html_writer::tag(
                        "td",
                        $r->lineNumber,
                        $attributes);
359
                    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
360
361
362
                }

                if (!is_null($r->columnNumber) && $r->columnNumber > 0) {
363
364
365
                    $tmp = "";
                    $tmp .= html_writer::tag(
                        "td",
366
                        get_string("col_no", self::COMPONENT_NAME),
367
                        $attributes);
368

369
370
371
372
373
                    $tmp .= html_writer::tag(
                        "td",
                        $r->columnNumber,
                        $attributes);
                    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
374
375
376
                }

                if (!is_null($r->position) && $r->position > 0) {
377
378
379
                    $tmp = "";
                    $tmp .= html_writer::tag(
                        "td",
380
                        get_string("pos", self::COMPONENT_NAME),
381
                        $attributes);
382

383
384
385
386
387
                    $tmp .= html_writer::tag(
                        "td",
                        $r->position,
                        $attributes);
                    $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
388
389
390
391
392
                }

                $tmp = "";
                $tmp .= html_writer::tag(
                    "td",
393
                    get_string("stacktrace", self::COMPONENT_NAME),
394
395
396
397
                    $attributes);

                $tmp .= html_writer::tag(
                    "td",
398
                    html_writer::tag("details", $r->stacktrace, ["class" => "dtaStacktraceDetails"]),
399
                    $attributes);
400
                $body .= html_writer::tag("tr", $tmp, $resultrowattributes);
401
402
            }

403
            // Set spacerrow value if null for next round separation.
404
            if (is_null($spacerrow)) {
405
                $spacerrow = html_writer::empty_tag("tr", ["class" => "dtaTableSpacer"]);
406
407
            }
        }
408
        $html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);
409

410
        // Wrap generated html into final div.
411
412
413
414
415
416
        $html = html_writer::div($html, "dtaSubmissionDetails");

        return $html;
    }

}