Passed
Push — 1.11.x ( 680d76...6673eb )
by
unknown
13:22 queued 51s
created

ExerciseShowFunctions::displayOnlyOfficeAnswer()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 50
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 26
c 4
b 0
f 0
dl 0
loc 50
rs 9.1928
cc 5
nc 6
nop 7
1
<?php
2
3
/* See license terms in /license.txt */
4
5
class ExerciseShowFunctions
6
{
7
    /**
8
     * Shows the answer to a fill-in-the-blanks question, as HTML.
9
     *
10
     * @param Exercise $exercise
11
     * @param int      $feedbackType
12
     * @param string   $answer
13
     * @param int      $id                           Exercise ID
14
     * @param int      $questionId                   Question ID
15
     * @param int      $resultsDisabled
16
     * @param string   $originalStudentAnswer
17
     * @param bool     $showTotalScoreAndUserChoices
18
     */
19
    public static function display_fill_in_blanks_answer(
20
        $exercise,
21
        $feedbackType,
22
        $answer,
23
        $id,
24
        $questionId,
25
        $resultsDisabled,
26
        $originalStudentAnswer,
27
        $showTotalScoreAndUserChoices
28
    ) {
29
        $answerHTML = FillBlanks::getHtmlDisplayForAnswer(
30
            $answer,
31
            $feedbackType,
32
            $resultsDisabled,
33
            $showTotalScoreAndUserChoices,
34
            $exercise
35
        );
36
37
        if (empty($id)) {
38
            echo '<tr><td>';
39
            echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY);
40
            echo '</td></tr>';
41
        } else {
42
            echo '<tr><td>';
43
            echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY);
44
            echo '</td>';
45
            echo '</tr>';
46
        }
47
    }
48
49
    /**
50
     * Shows the answer to a calculated question, as HTML.
51
     *
52
     *  @param Exercise $exercise
53
     * @param string    Answer text
54
     * @param int       Exercise ID
55
     * @param int       Question ID
56
     */
57
    public static function display_calculated_answer(
58
        $exercise,
59
        $feedback_type,
60
        $answer,
61
        $id,
62
        $questionId,
63
        $resultsDisabled,
64
        $showTotalScoreAndUserChoices,
65
        $expectedChoice = '',
66
        $choice = '',
67
        $status = ''
68
    ) {
69
        $answer = explode(':::', $answer);
70
        $answer = $answer[0];
71
        if ($exercise->showExpectedChoice()) {
72
            if (empty($id)) {
73
                echo '<tr><td>'.Security::remove_XSS($answer).'</td>';
74
                echo '<td>'.Security::remove_XSS($choice).'</td>';
75
                if ($exercise->showExpectedChoiceColumn()) {
76
                    echo '<td>'.Security::remove_XSS($expectedChoice).'</td>';
77
                }
78
79
                echo '<td>'.Security::remove_XSS($status).'</td>';
80
                echo '</tr>';
81
            } else {
82
                echo '<tr><td>';
83
                echo Security::remove_XSS($answer);
84
                echo '</td><td>';
85
                echo Security::remove_XSS($choice);
86
                echo '</td>';
87
                if ($exercise->showExpectedChoiceColumn()) {
88
                    echo '<td>';
89
                    echo Security::remove_XSS($expectedChoice);
90
                    echo '</td>';
91
                }
92
                echo '<td>';
93
                echo Security::remove_XSS($status);
94
                echo '</td>';
95
                echo '</tr>';
96
            }
97
        } else {
98
            if (empty($id)) {
99
                echo '<tr><td>'.Security::remove_XSS($answer).'</td></tr>';
100
            } else {
101
                echo '<tr><td>';
102
                echo Security::remove_XSS($answer);
103
                echo '</tr>';
104
            }
105
        }
106
    }
107
108
    /**
109
     * Shows the answer to an upload question.
110
     *
111
     * @param float|null $questionScore   Only used to check if > 0
112
     * @param int        $resultsDisabled Unused
113
     */
114
    public static function displayUploadAnswer(
115
        string $feedbackType,
116
        string $answer,
117
        int $exeId,
118
        int $questionId,
119
        $questionScore = null,
120
        $resultsDisabled = 0
121
    ) {
122
        if (!empty($answer)) {
123
            $exeInfo = Event::get_exercise_results_by_attempt($exeId);
0 ignored issues
show
Bug introduced by
The method get_exercise_results_by_attempt() does not exist on Event. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

123
            /** @scrutinizer ignore-call */ 
124
            $exeInfo = Event::get_exercise_results_by_attempt($exeId);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
124
            if (empty($exeInfo)) {
125
                global $exercise_stat_info;
126
                $userId = $exercise_stat_info['exe_user_id'];
127
            } else {
128
                $userId = $exeInfo[$exeId]['exe_user_id'];
129
            }
130
            $userWebpath = UserManager::getUserPathById($userId, 'web').'my_files'.'/upload_answer/'.$exeId.'/'.$questionId.'/';
131
            $filesNames = explode('|', $answer);
132
            echo '<tr><td>';
133
            foreach ($filesNames as $filename) {
134
                $filename = Security::remove_XSS($filename);
135
                echo '<p><a href="'.$userWebpath.$filename.'" target="_blank">'.$filename.'</a></p>';
136
            }
137
            echo '</td></tr>';
138
        }
139
140
        if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
141
            $comments = Event::get_comments($exeId, $questionId);
0 ignored issues
show
Bug introduced by
The method get_comments() does not exist on Event. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

141
            /** @scrutinizer ignore-call */ 
142
            $comments = Event::get_comments($exeId, $questionId);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
142
            if ($questionScore > 0 || !empty($comments)) {
143
            } else {
144
                echo '<tr>';
145
                echo Display::tag('td', ExerciseLib::getNotCorrectedYetText());
146
                echo '</tr>';
147
            }
148
        }
149
    }
150
151
    /**
152
     * Shows the answer to a free-answer question, as HTML.
153
     *
154
     * @param string    Answer text
155
     * @param int       Exercise ID
156
     * @param int       Question ID
157
     */
158
    public static function display_free_answer(
159
        $feedback_type,
160
        $answer,
161
        $exe_id,
162
        $questionId,
163
        $questionScore = null,
164
        $resultsDisabled = 0
165
    ) {
166
        $comments = Event::get_comments($exe_id, $questionId);
167
168
        if (!empty($answer)) {
169
            echo '<tr><td>';
170
            echo Security::remove_XSS($answer);
171
            echo '</td></tr>';
172
        }
173
174
        if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedback_type) {
175
            if ($questionScore > 0 || !empty($comments)) {
176
            } else {
177
                echo '<tr>';
178
                echo Display::tag('td', ExerciseLib::getNotCorrectedYetText());
179
                echo '</tr>';
180
            }
181
        }
182
    }
183
184
    /**
185
     * @param $feedback_type
186
     * @param $answer
187
     * @param $id
188
     * @param $questionId
189
     * @param null $fileUrl
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $fileUrl is correct as it would always require null to be passed?
Loading history...
190
     * @param int  $resultsDisabled
191
     * @param int  $questionScore
192
     */
193
    public static function display_oral_expression_answer(
194
        $feedback_type,
195
        $answer,
196
        $id,
197
        $questionId,
198
        $fileUrl = null,
199
        $resultsDisabled = 0,
200
        $questionScore = 0
201
    ) {
202
        if (isset($fileUrl)) {
203
            echo '
204
                <tr>
205
                    <td><audio src="'.$fileUrl.'" controls></audio></td>
206
                </tr>
207
            ';
208
        }
209
210
        if (empty($id)) {
211
            echo '<tr>';
212
            if (!empty($answer) && ($answer != basename($fileUrl))) {
213
                echo Display::tag('td', Security::remove_XSS($answer), ['width' => '55%']);
214
            }
215
            echo '</tr>';
216
            if (!$questionScore && EXERCISE_FEEDBACK_TYPE_EXAM != $feedback_type) {
217
                echo '<tr>';
218
                echo Display::tag('td', ExerciseLib::getNotCorrectedYetText(), ['width' => '45%']);
219
                echo '</tr>';
220
            } else {
221
                echo '<tr><td>&nbsp;</td></tr>';
222
            }
223
        } else {
224
            $text = '';
225
226
            if (is_array($answer) && !empty($answer['answer'])) {
227
                $text = $answer['answer'];
228
            } elseif (!is_array($answer)) {
229
                $text = $answer;
230
            }
231
232
            if (!empty($text)) {
233
                echo '<tr><td>';
234
                echo Security::remove_XSS($text);
235
                echo '</td></tr>';
236
            }
237
        }
238
    }
239
240
    /**
241
     * Displays the answer to a hotspot question.
242
     *
243
     * @param int    $feedback_type
244
     * @param int    $answerId
245
     * @param string $answer
246
     * @param string $studentChoice
247
     * @param string $answerComment
248
     * @param int    $resultsDisabled
249
     * @param int    $orderColor
250
     * @param bool   $showTotalScoreAndUserChoices
251
     */
252
    public static function display_hotspot_answer(
253
        $exercise,
254
        $feedback_type,
255
        $answerId,
256
        $answer,
257
        $studentChoice,
258
        $answerComment,
259
        $resultsDisabled,
260
        $orderColor,
261
        $showTotalScoreAndUserChoices
262
    ) {
263
        $hide_expected_answer = false;
264
        switch ($resultsDisabled) {
265
            case RESULT_DISABLE_SHOW_SCORE_ONLY:
266
                if (0 == $feedback_type) {
267
                    $hide_expected_answer = true;
268
                }
269
                break;
270
            case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
271
            case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
272
                $hide_expected_answer = true;
273
                if ($showTotalScoreAndUserChoices) {
274
                    $hide_expected_answer = false;
275
                }
276
                break;
277
            case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
278
                $hide_expected_answer = true;
279
                if ($showTotalScoreAndUserChoices) {
280
                    $hide_expected_answer = false;
281
                }
282
                if (false === $showTotalScoreAndUserChoices && empty($studentChoice)) {
283
                    return '';
284
                }
285
                break;
286
        }
287
288
        if (!$hide_expected_answer
289
            && !$studentChoice
290
            && in_array($resultsDisabled, [RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER])
291
        ) {
292
            return;
293
        }
294
295
        $hotspotColors = [
296
            '', // $i starts from 1 on next loop (ugly fix)
297
            '#4271B5',
298
            '#FE8E16',
299
            '#45C7F0',
300
            '#BCD631',
301
            '#D63173',
302
            '#D7D7D7',
303
            '#90AFDD',
304
            '#AF8640',
305
            '#4F9242',
306
            '#F4EB24',
307
            '#ED2024',
308
            '#3B3B3B',
309
            '#F7BDE2',
310
        ];
311
312
        $content = '<tr>';
313
        $content .= '<td class="text-center" width="5%">';
314
        $content .= '<span class="fa fa-square fa-fw fa-2x" aria-hidden="true" style="color:'.
315
            $hotspotColors[$orderColor].'"></span>';
316
        $content .= '</td>';
317
        $content .= '<td class="text-left" width="25%">';
318
        $content .= "$answerId - $answer";
319
        $content .= '</td>';
320
321
        if (false === $exercise->hideComment) {
322
            $content .= '<td class="text-left" width="10%">';
323
            if (!$hide_expected_answer) {
324
                $status = Display::label(get_lang('Incorrect'), 'danger');
325
                if ($studentChoice) {
326
                    $status = Display::label(get_lang('Correct'), 'success');
327
                }
328
                $content .= $status;
329
            } else {
330
                $content .= '&nbsp;';
331
            }
332
            $content .= '</td>';
333
334
            if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedback_type) {
335
                $content .= '<td class="text-left" width="60%">';
336
                if ($studentChoice) {
337
                    $content .= '<span style="font-weight: bold; color: #008000;">'.Security::remove_XSS(nl2br($answerComment)).'</span>';
338
                } else {
339
                    $content .= '&nbsp;';
340
                }
341
                $content .= '</td>';
342
            } else {
343
                $content .= '<td class="text-left" width="60%">&nbsp;</td>';
344
            }
345
        }
346
347
        $content .= '</tr>';
348
349
        echo $content;
350
    }
351
352
    public static function displayMultipleAnswerDropdown(
353
        Exercise $exercise,
354
        Answer $answer,
355
        array $correctAnswers,
356
        array $studentChoices,
357
        bool $showTotalScoreAndUserChoices = true
358
    ): string {
359
        if (true === $exercise->hideNoAnswer && empty($studentChoices)) {
360
            return '';
361
        }
362
363
        $studentChoices = array_filter(
364
            $studentChoices,
365
            function ($studentAnswerId) {
366
                return -1 !== (int) $studentAnswerId;
367
            }
368
        );
369
370
        $allChoices = array_unique(
371
            array_merge($correctAnswers, $studentChoices)
372
        );
373
        sort($allChoices);
374
375
        $checkboxOn = Display::return_icon('checkbox_on.png', null, null, ICON_SIZE_TINY);
376
        $checkboxOff = Display::return_icon('checkbox_off.png', null, null, ICON_SIZE_TINY);
377
378
        $labelSuccess = Display::label(get_lang('Correct'), 'success');
379
        $labelIncorrect = Display::label(get_lang('Incorrect'), 'danger');
380
381
        $html = '';
382
383
        foreach ($allChoices as $choice) {
384
            $isStudentAnswer = in_array($choice, $studentChoices);
385
            $isExpectedAnswer = in_array($choice, $correctAnswers);
386
            $isCorrectAnswer = $isStudentAnswer && $isExpectedAnswer;
387
            $answerPosition = array_search($choice, $answer->iid);
388
389
            $hideExpectedAnswer = false;
390
391
            switch ($exercise->selectResultsDisabled()) {
392
                case RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER:
393
                    $hideExpectedAnswer = true;
394
395
                    if (!$isCorrectAnswer && empty($studentChoices)) {
396
                        continue 2;
397
                    }
398
                    break;
399
                case RESULT_DISABLE_SHOW_SCORE_ONLY:
400
                    if (0 == $exercise->getFeedbackType()) {
401
                        $hideExpectedAnswer = true;
402
                    }
403
                    break;
404
                case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
405
                case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
406
                    $hideExpectedAnswer = true;
407
                    if ($showTotalScoreAndUserChoices) {
408
                        $hideExpectedAnswer = false;
409
                    }
410
                    break;
411
                case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
412
                    if (false === $showTotalScoreAndUserChoices && empty($studentChoices)) {
413
                        continue 2;
414
                    }
415
                    break;
416
            }
417
418
            $studentAnswerClass = '';
419
420
            if ($isCorrectAnswer
421
                && in_array(
422
                    $exercise->selectResultsDisabled(),
423
                    [
424
                        RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
425
                        RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
426
                    ]
427
                )
428
            ) {
429
                $studentAnswerClass = 'success';
430
            }
431
432
            $html .= '<tr class="'.$studentAnswerClass.'">';
433
            $html .= '<td class="text-center">'.($isStudentAnswer ? $checkboxOn : $checkboxOff).'</td>';
434
435
            if ($exercise->showExpectedChoiceColumn()) {
436
                $html .= '<td class="text-center">';
437
438
                if ($hideExpectedAnswer) {
439
                    $html .= '<span class="text-muted">&mdash;</span>';
440
                } else {
441
                    $html .= $isExpectedAnswer ? $checkboxOn : $checkboxOff;
442
                }
443
444
                $html .= '</td>';
445
            }
446
447
            $answerText = $answer->answer[$answerPosition] ?? get_lang('None');
448
449
            if ($exercise->export) {
450
                $answerText = strip_tags_blacklist($answerText, ['title', 'head']);
451
                // Fix answers that contains this tags
452
                $tags = ['<html>', '</html>', '<body>', '</body>'];
453
                $answerText = str_replace($tags, '', $answerText);
454
            }
455
456
            $html .= '<td>'.Security::remove_XSS($answerText).'</td>';
457
458
            if ($exercise->showExpectedChoice()) {
459
                $html .= '<td class="text-center">'.($isCorrectAnswer ? $labelSuccess : $labelIncorrect).'</td>';
460
            }
461
462
            $html .= '</tr>';
463
        }
464
465
        return $html;
466
    }
467
468
    /**
469
     * Display the answers to a multiple choice question.
470
     *
471
     * @param Exercise $exercise
472
     * @param int      $feedbackType                 Feedback type
473
     * @param int      $answerType                   Answer type
474
     * @param int      $studentChoice                Student choice
475
     * @param string   $answer                       Textual answer
476
     * @param string   $answerComment                Comment on answer
477
     * @param string   $answerCorrect                Correct answer comment
478
     * @param int      $id                           Exercise ID
479
     * @param int      $questionId                   Question ID
480
     * @param bool     $ans                          Whether to show the answer comment or not
481
     * @param bool     $resultsDisabled
482
     * @param bool     $showTotalScoreAndUserChoices
483
     * @param bool     $export
484
     */
485
    public static function display_unique_or_multiple_answer(
486
        $exercise,
487
        $feedbackType,
488
        $answerType,
489
        $studentChoice,
490
        $answer,
491
        $answerComment,
492
        $answerCorrect,
493
        $id,
494
        $questionId,
495
        $ans,
496
        $resultsDisabled,
497
        $showTotalScoreAndUserChoices,
498
        $export = false
499
    ) {
500
        if (true === $exercise->hideNoAnswer && empty($studentChoice)) {
501
            return '';
502
        }
503
        if ($export) {
504
            $answer = strip_tags_blacklist($answer, ['title', 'head']);
505
            // Fix answers that contains this tags
506
            $tags = [
507
                '<html>',
508
                '</html>',
509
                '<body>',
510
                '</body>',
511
            ];
512
            $answer = str_replace($tags, '', $answer);
513
        }
514
515
        $studentChoiceInt = (int) $studentChoice;
516
        $answerCorrectChoice = (int) $answerCorrect;
517
518
        $hide_expected_answer = false;
519
        $showComment = false;
520
        switch ($resultsDisabled) {
521
            case RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER:
522
                $hide_expected_answer = true;
523
                $showComment = true;
524
                if (!$answerCorrect && empty($studentChoice)) {
525
                    return '';
526
                }
527
                break;
528
            case RESULT_DISABLE_SHOW_SCORE_ONLY:
529
                if (0 == $feedbackType) {
530
                    $hide_expected_answer = true;
531
                }
532
                break;
533
            case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
534
            case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
535
                $hide_expected_answer = true;
536
                if ($showTotalScoreAndUserChoices) {
537
                    $hide_expected_answer = false;
538
                }
539
                break;
540
            case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
541
                if (false === $showTotalScoreAndUserChoices && empty($studentChoiceInt)) {
542
                    return '';
543
                }
544
                break;
545
        }
546
547
        $icon = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
548
        $icon .= $studentChoice ? '_on' : '_off';
549
        $icon .= '.png';
550
        $iconAnswer = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
551
        $iconAnswer .= $answerCorrect ? '_on' : '_off';
552
        $iconAnswer .= '.png';
553
554
        $studentChoiceClass = '';
555
        if (in_array(
556
            $resultsDisabled,
557
            [
558
                RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
559
                RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
560
            ]
561
        )
562
        ) {
563
            if ($answerCorrect) {
564
                $studentChoiceClass = 'success';
565
            }
566
        }
567
568
        echo '<tr class="'.$studentChoiceClass.'">';
569
570
        echo '<td width="5%">';
571
        echo Display::return_icon($icon, null, null, ICON_SIZE_TINY);
572
        echo '</td>';
573
        if ($exercise->showExpectedChoiceColumn()) {
574
            if (false === $hide_expected_answer) {
575
                echo '<td width="5%">';
576
                echo Display::return_icon($iconAnswer, null, null, ICON_SIZE_TINY);
577
                echo '</td>';
578
            } else {
579
                echo '<td width="5%">';
580
                echo '-';
581
                echo '</td>';
582
            }
583
        }
584
585
        echo '<td width="40%">';
586
        echo Security::remove_XSS($answer);
587
        echo '</td>';
588
589
        if ($exercise->showExpectedChoice()) {
590
            $status = Display::label(get_lang('Incorrect'), 'danger');
591
            if ($answerCorrect || ($answerCorrect && $studentChoiceInt === $answerCorrectChoice)) {
592
                $status = Display::label(get_lang('Correct'), 'success');
593
            }
594
            echo '<td width="20%">';
595
            // Show only status for the selected student answer BT#16256
596
            if ($studentChoice) {
597
                echo $status;
598
            }
599
600
            echo '</td>';
601
        }
602
603
        if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
604
            $showComment = true;
605
        }
606
607
        if (false === $exercise->hideComment) {
608
            if ($showComment) {
609
                echo '<td width="20%">';
610
                $color = 'black';
611
                if ($answerCorrect) {
612
                    $color = 'green';
613
                }
614
                if ($hide_expected_answer) {
615
                    $color = '';
616
                }
617
                $comment = '<span style="font-weight: bold; color: '.$color.';">'.
618
                    Security::remove_XSS($answerComment).
619
                    '</span>';
620
                echo $comment;
621
                echo '</td>';
622
            } else {
623
                echo '<td>&nbsp;</td>';
624
            }
625
        }
626
627
        echo '</tr>';
628
    }
629
630
    /**
631
     * Display the answers to a multiple choice question.
632
     *
633
     * @param Exercise $exercise
634
     * @param int Answer type
635
     * @param int Student choice
636
     * @param string  Textual answer
637
     * @param string  Comment on answer
638
     * @param string  Correct answer comment
639
     * @param int Exercise ID
640
     * @param int Question ID
641
     * @param bool Whether to show the answer comment or not
642
     */
643
    public static function display_multiple_answer_true_false(
644
        $exercise,
645
        $feedbackType,
646
        $answerType,
647
        $studentChoice,
648
        $answer,
649
        $answerComment,
650
        $answerCorrect,
651
        $id,
652
        $questionId,
653
        $ans,
654
        $resultsDisabled,
655
        $showTotalScoreAndUserChoices
656
    ) {
657
        $hide_expected_answer = false;
658
        $hideStudentChoice = false;
659
        switch ($resultsDisabled) {
660
            //case RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING:
661
            case RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER:
662
                $hideStudentChoice = false;
663
                $hide_expected_answer = true;
664
                break;
665
            case RESULT_DISABLE_SHOW_SCORE_ONLY:
666
                if (0 == $feedbackType) {
667
                    $hide_expected_answer = true;
668
                }
669
                break;
670
            case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
671
            case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
672
                $hide_expected_answer = true;
673
                if ($showTotalScoreAndUserChoices) {
674
                    $hide_expected_answer = false;
675
                }
676
                break;
677
            case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
678
                if (false === $showTotalScoreAndUserChoices && empty($studentChoice)) {
679
                    return '';
680
                }
681
                break;
682
        }
683
684
        $content = '<tr>';
685
        if (false === $hideStudentChoice) {
686
            $content .= '<td width="5%">';
687
            $course_id = api_get_course_int_id();
688
            $new_options = Question::readQuestionOption($questionId, $course_id);
689
            // Your choice
690
            if (isset($new_options[$studentChoice])) {
691
                $content .= get_lang($new_options[$studentChoice]['name']);
692
            } else {
693
                $content .= '-';
694
            }
695
            $content .= '</td>';
696
        }
697
698
        // Expected choice
699
        if ($exercise->showExpectedChoiceColumn()) {
700
            if (!$hide_expected_answer) {
701
                $content .= '<td width="5%">';
702
                if (isset($new_options[$answerCorrect])) {
703
                    $content .= get_lang($new_options[$answerCorrect]['name']);
704
                } else {
705
                    $content .= '-';
706
                }
707
                $content .= '</td>';
708
            }
709
        }
710
711
        $content .= '<td width="40%">';
712
        $content .= Security::remove_XSS($answer);
713
        $content .= '</td>';
714
715
        if ($exercise->showExpectedChoice()) {
716
            $status = Display::label(get_lang('Incorrect'), 'danger');
717
            if (isset($new_options[$studentChoice])) {
718
                if ($studentChoice == $answerCorrect) {
719
                    $status = Display::label(get_lang('Correct'), 'success');
720
                }
721
            }
722
            $content .= '<td width="20%">';
723
            $content .= $status;
724
            $content .= '</td>';
725
        }
726
727
        if (false === $exercise->hideComment) {
728
            if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
729
                $content .= '<td width="20%">';
730
                $color = 'black';
731
                if (isset($new_options[$studentChoice]) || in_array(
732
                        $exercise->results_disabled,
733
                        [
734
                            RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
735
                            RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
736
                        ]
737
                    )
738
                ) {
739
                    if ($studentChoice == $answerCorrect) {
740
                        $color = 'green';
741
                    }
742
743
                    if ($hide_expected_answer) {
744
                        $color = '';
745
                    }
746
                    $content .= '<span style="font-weight: bold; color: '.$color.';">'.Security::remove_XSS(nl2br($answerComment)).'</span>';
747
                }
748
                $content .= '</td>';
749
            }
750
        }
751
        $content .= '</tr>';
752
753
        echo $content;
754
    }
755
756
    /**
757
     * Display the answers to a multiple choice question.
758
     *
759
     * @param Exercise $exercise
760
     * @param int      $feedbackType
761
     * @param int      $studentChoice
762
     * @param int      $studentChoiceDegree
763
     * @param string   $answer
764
     * @param string   $answerComment
765
     * @param int      $answerCorrect
766
     * @param int      $questionId
767
     * @param bool     $inResultsDisabled
768
     */
769
    public static function displayMultipleAnswerTrueFalseDegreeCertainty(
770
        $exercise,
771
        $feedbackType,
772
        $studentChoice,
773
        $studentChoiceDegree,
774
        $answer,
775
        $answerComment,
776
        $answerCorrect,
777
        $questionId,
778
        $inResultsDisabled
779
    ) {
780
        $hideExpectedAnswer = false;
781
        if (0 == $feedbackType && 2 == $inResultsDisabled) {
782
            $hideExpectedAnswer = true;
783
        }
784
785
        echo '<tr><td width="5%">';
786
        $question = new MultipleAnswerTrueFalseDegreeCertainty();
787
        $courseId = api_get_course_int_id();
788
        $newOptions = Question::readQuestionOption($questionId, $courseId);
789
790
        // Your choice
791
        if (isset($newOptions[$studentChoice])) {
792
            echo get_lang($newOptions[$studentChoice]['name']);
793
        } else {
794
            echo '-';
795
        }
796
        echo '</td>';
797
798
        // Expected choice
799
        if ($exercise->showExpectedChoiceColumn()) {
800
            echo '<td width="5%">';
801
            if (!$hideExpectedAnswer) {
802
                if (isset($newOptions[$answerCorrect])) {
803
                    echo get_lang($newOptions[$answerCorrect]['name']);
804
                } else {
805
                    echo '-';
806
                }
807
            } else {
808
                echo '-';
809
            }
810
            echo '</td>';
811
        }
812
813
        echo '<td width="20%">';
814
        echo Security::remove_XSS($answer);
815
        echo '</td><td width="5%" style="text-align:center;">';
816
        if (isset($newOptions[$studentChoiceDegree])) {
817
            echo $newOptions[$studentChoiceDegree]['name'];
818
        }
819
        echo '</td>';
820
821
        $position = isset($newOptions[$studentChoiceDegree]) ? $newOptions[$studentChoiceDegree]['position'] : '';
822
        $degreeInfo = $question->getResponseDegreeInfo(
823
            $studentChoice,
824
            $answerCorrect,
825
            $position
826
        );
827
828
        $degreeInfo['color'] = isset($degreeInfo['color']) ? $degreeInfo['color'] : '';
829
        $degreeInfo['background-color'] = isset($degreeInfo['background-color']) ? $degreeInfo['background-color'] : '';
830
        $degreeInfo['description'] = isset($degreeInfo['description']) ? $degreeInfo['description'] : '';
831
        $degreeInfo['label'] = isset($degreeInfo['label']) ? $degreeInfo['label'] : '';
832
833
        echo '
834
            <td width="15%">
835
                <div style="text-align:center;color: '.$degreeInfo['color'].';
836
                    background-color: '.$degreeInfo['background-color'].';
837
                    line-height:30px;height:30px;width: 100%;margin:auto;"
838
                    title="'.$degreeInfo['description'].'">'.
839
                    nl2br($degreeInfo['label']).
840
                '</div>
841
            </td>';
842
843
        if (false === $exercise->hideComment) {
844
            if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
845
                echo '<td width="20%">';
846
                if (isset($newOptions[$studentChoice])) {
847
                    echo '<span style="font-weight: bold; color: black;">'.nl2br($answerComment).'</span>';
848
                }
849
                echo '</td>';
850
            } else {
851
                echo '<td>&nbsp;</td>';
852
            }
853
        }
854
855
        echo '</tr>';
856
    }
857
858
    /**
859
     * Display the answers to a multiple choice question.
860
     *
861
     * @param Exercise $exercise
862
     * @param int Answer type
863
     * @param int Student choice
864
     * @param string  Textual answer
865
     * @param string  Comment on answer
866
     * @param string  Correct answer comment
867
     * @param int Exercise ID
868
     * @param int Question ID
869
     * @param bool Whether to show the answer comment or not
870
     */
871
    public static function display_multiple_answer_combination_true_false(
872
        $exercise,
873
        $feedbackType,
874
        $answerType,
875
        $studentChoice,
876
        $answer,
877
        $answerComment,
878
        $answerCorrect,
879
        $id,
880
        $questionId,
881
        $ans,
882
        $resultsDisabled,
883
        $showTotalScoreAndUserChoices
884
    ) {
885
        $hide_expected_answer = false;
886
        $hideStudentChoice = false;
887
        switch ($resultsDisabled) {
888
            case RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING:
889
            case RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER:
890
                $hideStudentChoice = true;
891
                $hide_expected_answer = true;
892
                break;
893
            case RESULT_DISABLE_SHOW_SCORE_ONLY:
894
                if (0 == $feedbackType) {
895
                    $hide_expected_answer = true;
896
                }
897
                break;
898
            case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
899
            case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
900
                $hide_expected_answer = true;
901
                if ($showTotalScoreAndUserChoices) {
902
                    $hide_expected_answer = false;
903
                }
904
                break;
905
            case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
906
                if (false === $showTotalScoreAndUserChoices && empty($studentChoice)) {
907
                    return '';
908
                }
909
                break;
910
        }
911
912
        echo '<tr>';
913
        if (false === $hideStudentChoice) {
914
            echo '<td width="5%">';
915
            // Your choice
916
            $question = new MultipleAnswerCombinationTrueFalse();
917
            if (isset($question->options[$studentChoice])) {
918
                echo $question->options[$studentChoice];
919
            } else {
920
                echo $question->options[2];
921
            }
922
            echo '</td>';
923
        }
924
925
        // Expected choice
926
        if ($exercise->showExpectedChoiceColumn()) {
927
            if (!$hide_expected_answer) {
928
                echo '<td width="5%">';
929
                if (isset($question->options[$answerCorrect])) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question does not seem to be defined for all execution paths leading up to this point.
Loading history...
930
                    echo $question->options[$answerCorrect];
931
                } else {
932
                    echo $question->options[2];
933
                }
934
                echo '</td>';
935
            }
936
        }
937
938
        echo '<td width="40%">';
939
        echo Security::remove_XSS($answer);
940
        echo '</td>';
941
942
        if ($exercise->showExpectedChoice()) {
943
            $status = '';
944
            if (isset($studentChoice)) {
945
                $status = Display::label(get_lang('Incorrect'), 'danger');
946
                if ($studentChoice == $answerCorrect) {
947
                    $status = Display::label(get_lang('Correct'), 'success');
948
                }
949
            }
950
            echo '<td width="20%">';
951
            echo $status;
952
            echo '</td>';
953
        }
954
955
        if (false === $exercise->hideComment) {
956
            if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
957
                echo '<td width="20%">';
958
                //@todo replace this harcoded value
959
                if ($studentChoice || in_array(
960
                        $resultsDisabled,
961
                        [
962
                            RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
963
                            RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
964
                        ]
965
                    )
966
                ) {
967
                    $color = 'black';
968
                    if ($studentChoice == $answerCorrect) {
969
                        $color = 'green';
970
                    }
971
                    if ($hide_expected_answer) {
972
                        $color = '';
973
                    }
974
                    echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
975
                }
976
                echo '</td>';
977
            } else {
978
                echo '<td>&nbsp;</td>';
979
            }
980
        }
981
        echo '</tr>';
982
    }
983
984
    /**
985
     * @param int  $feedbackType
986
     * @param int  $exeId
987
     * @param int  $questionId
988
     * @param null $questionScore
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $questionScore is correct as it would always require null to be passed?
Loading history...
989
     * @param int  $resultsDisabled
990
     */
991
    public static function displayAnnotationAnswer(
992
        $feedbackType,
993
        $exeId,
994
        $questionId,
995
        $questionScore = null,
996
        $resultsDisabled = 0
997
    ) {
998
        $comments = Event::get_comments($exeId, $questionId);
999
        if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
1000
            if ($questionScore <= 0 && empty($comments)) {
1001
                echo '<br />'.ExerciseLib::getNotCorrectedYetText();
1002
            }
1003
        }
1004
    }
1005
1006
    /**
1007
     * Displays the submitted OnlyOffice document in an iframe.
1008
     *
1009
     * @param string $feedbackType   The feedback type of the exercise.
1010
     * @param int    $exeId          The execution ID.
1011
     * @param int    $userId         The user ID.
1012
     * @param int    $exerciseId     The exercise ID.
1013
     * @param int    $questionId     The question ID.
1014
     * @param int    $questionScore  Score assigned to the response.
1015
     * @param bool   $autorefresh    If true, auto-refresh the iframe after a short delay (used in result view).
1016
     */
1017
    public static function displayOnlyOfficeAnswer(
1018
        string $feedbackType,
1019
        int $exeId,
1020
        int $userId,
1021
        int $exerciseId,
1022
        int $questionId,
1023
        int $questionScore = 0,
1024
        bool $autorefresh = false
1025
    ): void {
1026
        $filePathPattern = api_get_path(SYS_COURSE_PATH).api_get_course_path()."/exercises/onlyoffice/{$exerciseId}/{$questionId}/{$userId}/response_{$exeId}.*";
1027
        $files = glob($filePathPattern);
1028
1029
        if (!empty($files)) {
1030
            $fileUrl = api_get_course_path() . "/exercises/onlyoffice/{$exerciseId}/{$questionId}/{$userId}/" . basename($files[0]);
1031
            $iframeId = "onlyoffice_result_frame_{$exerciseId}_{$questionId}_{$exeId}_{$userId}";
1032
            $loaderId = "onlyoffice_loader_{$exerciseId}_{$questionId}_{$exeId}_{$userId}";
1033
            $iframeSrc = OnlyofficeTools::getPathToView($fileUrl, false, $exeId, $questionId, true);
1034
            $iframeSrc .= '&t=' . time();
1035
            echo '
1036
                <tr>
1037
                    <td>
1038
                        <p><b>' . get_lang('SubmittedDocument') . ':</b></p>';
1039
                        if ($autorefresh) {
1040
                            echo '
1041
                        <div id="' . $loaderId . '">
1042
                            <p><em>' . get_lang('LoadingLatestVersion') . '...</em></p>
1043
                        </div>
1044
                        <iframe id="' . $iframeId . '" src="' . $iframeSrc . '" width="100%" height="600px" style="border:none; display:none;"></iframe>';
1045
                            echo "<script>
1046
                            setTimeout(function() {
1047
                                var iframe = document.getElementById('{$iframeId}');
1048
                                var loader = document.getElementById('{$loaderId}');
1049
                                if (iframe && loader) {
1050
                                    iframe.src = iframe.src + '&reload=' + new Date().getTime();
1051
                                    iframe.style.display = 'block';
1052
                                    loader.style.display = 'none';
1053
                                }
1054
                            }, 5000);
1055
                    </script>";
1056
            } else {
1057
                echo '
1058
                <iframe id="' . $iframeId . '" src="' . $iframeSrc . '" width="100%" height="600px" style="border:none;"></iframe>';
1059
            }
1060
            echo '</td></tr>';
1061
        } else {
1062
            echo '<tr><td>' . get_lang('NoOfficeDocProvided') . '</td></tr>';
1063
        }
1064
1065
        if ($questionScore <= 0 && EXERCISE_FEEDBACK_TYPE_EXAM !== $feedbackType) {
1066
            echo '<tr><td>' . ExerciseLib::getNotCorrectedYetText() . '</td></tr>';
1067
        }
1068
    }
1069
}
1070