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

display_multiple_answer_true_false()   F

Complexity

Conditions 24
Paths 3025

Size

Total Lines 111
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
eloc 66
c 0
b 0
f 0
nc 3025
nop 12
dl 0
loc 111
rs 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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