Completed
Push — master ( af42cb...3888f0 )
by Julito
13:17
created

createAnswersForm()   F

Complexity

Conditions 20
Paths 12672

Size

Total Lines 163
Code Lines 112

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 20
eloc 112
nc 12672
nop 1
dl 0
loc 163
rs 0
c 1
b 0
f 0

How to fix   Long Method    Complexity   

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:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use ChamiloSession as Session;
5
6
/**
7
 * Class MultipleAnswerTrueFalseDegreeCertainty
8
 * This class allows to instantiate an object of type MULTIPLE_ANSWER
9
 * (MULTIPLE CHOICE, MULTIPLE ANSWER), extending the class question.
10
 *
11
 * @package chamilo.exercise
12
 */
13
class MultipleAnswerTrueFalseDegreeCertainty extends Question
14
{
15
    const LEVEL_DARKGREEN = 1;
16
    const LEVEL_LIGHTGREEN = 2;
17
    const LEVEL_WHITE = 3;
18
    const LEVEL_LIGHTRED = 4;
19
    const LEVEL_DARKRED = 5;
20
21
    public static $typePicture = 'mccert.png';
22
    public static $explanationLangVar = 'MultipleAnswerTrueFalseDegreeCertainty';
23
    public $optionsTitle;
24
    public $options;
25
26
    /**
27
     * Constructor.
28
     */
29
    public function __construct()
30
    {
31
        parent::__construct();
32
        $this->type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY;
33
        $this->isContent = $this->getIsContent();
34
        $this->optionsTitle = [1 => 'Answers', 2 => 'DegreeOfCertaintyThatMyAnswerIsCorrect'];
35
        $this->options = [
36
            1 => 'True',
37
            2 => 'False',
38
            3 => '50%',
39
            4 => '60%',
40
            5 => '70%',
41
            6 => '80%',
42
            7 => '90%',
43
            8 => '100%',
44
        ];
45
    }
46
47
    /**
48
     * Redefines Question::createAnswersForm: creates the HTML form to answer the question.
49
     *
50
     * @uses \globals $text and $class, defined in the calling script
51
     *
52
     * @param FormValidator $form
53
     *
54
     * @throws Exception
55
     * @throws HTML_QuickForm_Error
56
     */
57
    public function createAnswersForm($form)
58
    {
59
        global $text;
60
        $nbAnswers = isset($_POST['nb_answers']) ? (int) $_POST['nb_answers'] : 4;
61
        // The previous default value was 2. See task #1759.
62
        $nbAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0));
63
64
        $courseId = api_get_course_int_id();
65
        $objEx = Session::read('objExercise');
66
        $renderer = &$form->defaultRenderer();
67
        $defaults = [];
68
69
        $html = '<table class="data_table"><tr style="text-align: center;"><th>'
70
            .get_lang('Number')
71
            .'</th><th>'
72
            .get_lang('True')
73
            .'</th><th>'
74
            .get_lang('False')
75
            .'</th><th>'
76
            .get_lang('Answer')
77
            .'</th>';
78
79
        // show column comment when feedback is enable
80
        if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
81
            $html .= '<th>'.get_lang('Comment').'</th>';
82
        }
83
        $html .= '</tr>';
84
        $form->addElement('label', get_lang('Answers').'<br /> <img src="../img/fill_field.png">', $html);
85
86
        $correct = 0;
87
        $answer = null;
88
        if (!empty($this->id)) {
89
            $answer = new Answer($this->id);
90
            $answer->read();
91
            if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
92
                $nbAnswers = $answer->nbrAnswers;
93
            }
94
        }
95
96
        $form->addElement('hidden', 'nb_answers');
97
        $boxesNames = [];
98
99
        if ($nbAnswers < 1) {
100
            $nbAnswers = 1;
101
            echo Display::return_message(get_lang('YouHaveToCreateAtLeastOneAnswer'));
102
        }
103
104
        // Can be more options
105
        $optionData = Question::readQuestionOption($this->id, $courseId);
106
107
        for ($i = 1; $i <= $nbAnswers; $i++) {
108
            $renderer->setElementTemplate(
109
                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
110
                'correct['.$i.']'
111
            );
112
            $renderer->setElementTemplate(
113
                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
114
                'counter['.$i.']'
115
            );
116
            $renderer->setElementTemplate(
117
                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
118
                'answer['.$i.']'
119
            );
120
            $renderer->setElementTemplate(
121
                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
122
                'comment['.$i.']'
123
            );
124
125
            $answerNumber = $form->addElement('text', 'counter['.$i.']', null, 'value="'.$i.'"');
126
            $answerNumber->freeze();
127
128
            $defaults['answer['.$i.']'] = '';
129
            $defaults['comment['.$i.']'] = '';
130
            $defaults['correct['.$i.']'] = '';
131
132
            if (is_object($answer)) {
133
                $defaults['answer['.$i.']'] = $answer->answer[$i];
134
                $defaults['comment['.$i.']'] = $answer->comment[$i];
135
                $defaults['weighting['.$i.']'] = float_format($answer->weighting[$i], 1);
136
                $correct = $answer->correct[$i];
137
                $defaults['correct['.$i.']'] = $correct;
138
                $j = 1;
139
                if (!empty($optionData)) {
140
                    foreach ($optionData as $id => $data) {
141
                        $form->addElement('radio', 'correct['.$i.']', null, null, $id);
142
                        $j++;
143
                        if ($j == 3) {
144
                            break;
145
                        }
146
                    }
147
                }
148
            } else {
149
                $form->addElement('radio', 'correct['.$i.']', null, null, 1);
150
                $form->addElement('radio', 'correct['.$i.']', null, null, 2);
151
            }
152
153
            $boxesNames[] = 'correct['.$i.']';
154
            $form->addElement(
155
                'html_editor',
156
                'answer['.$i.']',
157
                null,
158
                ['style' => 'vertical-align:middle;'],
159
                ['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']
160
            );
161
            $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required');
162
163
            // show comment when feedback is enable
164
            if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) {
165
                $form->addElement(
166
                    'html_editor',
167
                    'comment['.$i.']',
168
                    null,
169
                    ['style' => 'vertical-align:middle;'],
170
                    ['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']
171
                );
172
            }
173
            $form->addElement('html', '</tr>');
174
        }
175
176
        $form->addElement('html', '</table>');
177
        $form->addElement('html', '<br />');
178
179
        // 3 scores
180
        $form->addElement('text', 'option[1]', get_lang('Correct'), ['class' => 'span1', 'value' => '1']);
181
        $form->addElement('text', 'option[2]', get_lang('Wrong'), ['class' => 'span1', 'value' => '-0.5']);
182
183
        $form->addElement('hidden', 'option[3]', 0);
184
185
        $form->addRule('option[1]', get_lang('ThisFieldIsRequired'), 'required');
186
        $form->addRule('option[2]', get_lang('ThisFieldIsRequired'), 'required');
187
188
        $form->addElement('html', '</tr><table>');
189
        $form->addElement('hidden', 'options_count', 3);
190
        $form->addElement('html', '</table><br /><br />');
191
192
        //Extra values True, false,  Dont known
193
        if (!empty($this->extra)) {
194
            $scores = explode(':', $this->extra);
195
            if (!empty($scores)) {
196
                for ($i = 1; $i <= 3; $i++) {
197
                    $defaults['option['.$i.']'] = $scores[$i - 1];
198
                }
199
            }
200
        }
201
202
        if ($objEx->edit_exercise_in_lp === true) {
203
            $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'), 'class="btn btn-danger minus"');
204
            $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'), 'class="btn btn-primary plus"');
205
            //$text and $class defined in calling script
206
            $form->addElement('submit', 'submitQuestion', $text, 'class = "btn btn-primary"');
207
        }
208
        $renderer->setElementTemplate('{element}&nbsp;', 'lessAnswers');
209
        $renderer->setElementTemplate('{element}&nbsp;', 'submitQuestion');
210
        $renderer->setElementTemplate('{element}&nbsp;', 'moreAnswers');
211
        $form->addElement('html', '</div></div>');
212
        $defaults['correct'] = $correct;
213
214
        if (!empty($this->id)) {
215
            $form->setDefaults($defaults);
216
        } else {
217
            $form->setDefaults($defaults);
218
        }
219
        $form->setConstants(['nb_answers' => $nbAnswers]);
220
    }
221
222
    /**
223
     * abstract function which creates the form to create / edit the answers of the question.
224
     *
225
     * @param FormValidator $form
226
     * @param Exercise      $exercise
227
     */
228
    public function processAnswersCreation($form, $exercise)
229
    {
230
        $questionWeighting = 0;
231
        $objAnswer = new Answer($this->id);
232
        $nbAnswers = $form->getSubmitValue('nb_answers');
233
        $courseId = api_get_course_int_id();
234
        $correct = [];
235
        $options = Question::readQuestionOption($this->id, $courseId);
236
237
        if (!empty($options)) {
238
            foreach ($options as $optionData) {
239
                $id = $optionData['id'];
240
                unset($optionData['id']);
241
                Question::updateQuestionOption($id, $optionData, $courseId);
242
            }
243
        } else {
244
            for ($i = 1; $i <= 8; $i++) {
245
                $lastId = Question::saveQuestionOption($this->id, $this->options[$i], $courseId, $i);
246
                $correct[$i] = $lastId;
247
            }
248
        }
249
250
        /* Getting quiz_question_options (true, false, doubt) because
251
          it's possible that there are more options in the future */
252
        $newOptions = Question::readQuestionOption($this->id, $courseId);
253
        $sortedByPosition = [];
254
        foreach ($newOptions as $item) {
255
            $sortedByPosition[$item['position']] = $item;
256
        }
257
258
        /* Saving quiz_question.extra values that has the correct scores of
259
          the true, false, doubt options registered in this format
260
          XX:YY:ZZZ where XX is a float score value. */
261
        $extraValues = [];
262
        for ($i = 1; $i <= 3; $i++) {
263
            $score = trim($form->getSubmitValue('option['.$i.']'));
264
            $extraValues[] = $score;
265
        }
266
        $this->setExtra(implode(':', $extraValues));
267
268
        for ($i = 1; $i <= $nbAnswers; $i++) {
269
            $answer = trim($form->getSubmitValue('answer['.$i.']'));
270
            $comment = trim($form->getSubmitValue('comment['.$i.']'));
271
            $goodAnswer = trim($form->getSubmitValue('correct['.$i.']'));
272
            if (empty($options)) {
273
                // If this is the first time that the question is created then change
274
                // the default values from the form 1 and 2 by the correct "option id" registered
275
                $goodAnswer = $sortedByPosition[$goodAnswer]['id'];
276
            }
277
            $questionWeighting += $extraValues[0]; //By default 0 has the correct answers
278
            $objAnswer->createAnswer($answer, $goodAnswer, $comment, '', $i);
279
        }
280
281
        // saves the answers into the data base
282
        $objAnswer->save();
283
284
        // sets the total weighting of the question
285
        $this->updateWeighting($questionWeighting);
286
        $this->save($exercise);
287
    }
288
289
    /**
290
     * Show result table headers.
291
     *
292
     * @param Exercise $exercise
293
     * @param int      $counter
294
     * @param float    $score
295
     *
296
     * @return null|string
297
     */
298
    public function return_header($exercise, $counter = null, $score = null)
299
    {
300
        $header = parent::return_header($exercise, $counter, $score);
0 ignored issues
show
Bug introduced by
It seems like $score can also be of type double; however, parameter $score of Question::return_header() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

300
        $header = parent::return_header($exercise, $counter, /** @scrutinizer ignore-type */ $score);
Loading history...
301
        $header .= '<table class="'
302
            .$this->question_table_class
303
            .'"><tr><th>'
304
            .get_lang('Choice')
305
            .'</th><th>'
306
            .get_lang('ExpectedChoice')
307
            .'</th><th>'
308
            .get_lang('Answer')
309
            .'</th><th colspan="2" style="text-align:center;">'
310
            .get_lang('YourDegreeOfCertainty')
311
            .'</th>'
312
        ;
313
        if ($exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
314
            $header .= '<th>'.get_lang('Comment').'</th>';
315
        } else {
316
            $header .= '<th>&nbsp;</th>';
317
        }
318
        $header .= '</tr>';
319
320
        return $header;
321
    }
322
323
    /**
324
     * Get color code, status, label and description for the current answer.
325
     *
326
     * @param string $studentAnswer
327
     * @param string $expectedAnswer
328
     * @param int    $studentDegreeChoicePosition
329
     *
330
     * @return array An array with indexes 'color', 'background-color', 'status', 'label' and 'description'
331
     */
332
    public function getResponseDegreeInfo($studentAnswer, $expectedAnswer, $studentDegreeChoicePosition)
333
    {
334
        $result = [];
335
        if ($studentDegreeChoicePosition == 3) {
336
            $result = [
337
                'color' => '#000000',
338
                'background-color' => '#F6BA2A',
339
                'status' => self::LEVEL_WHITE,
340
                'label' => get_lang('DegreeOfCertaintyDeclaredIgnorance'),
341
                'description' => get_lang('DegreeOfCertaintyDeclaredIgnoranceDescription'),
342
            ];
343
        } else {
344
            $checkResult = $studentAnswer == $expectedAnswer ? true : false;
345
            if ($checkResult) {
346
                if ($studentDegreeChoicePosition >= 6) {
347
                    $result = [
348
                        'color' => '#FFFFFF',
349
                        'background-color' => '#1E9C55',
350
                        'status' => self::LEVEL_DARKGREEN,
351
                        'label' => get_lang('DegreeOfCertaintyVerySure'),
352
                        'description' => get_lang('DegreeOfCertaintyVerySureDescription'),
353
                    ];
354
                } elseif ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) {
355
                    $result = [
356
                        'color' => '#000000',
357
                        'background-color' => '#B1E183',
358
                        'status' => self::LEVEL_LIGHTGREEN,
359
                        'label' => get_lang('DegreeOfCertaintyPrettySure'),
360
                        'description' => get_lang('DegreeOfCertaintyPrettySureDescription'),
361
                    ];
362
                }
363
            } else {
364
                if ($studentDegreeChoicePosition >= 6) {
365
                    $result = [
366
                        'color' => '#FFFFFF',
367
                        'background-color' => '#ED4040',
368
                        'status' => self::LEVEL_DARKRED,
369
                        'label' => get_lang('DegreeOfCertaintyVeryUnsure'),
370
                        'description' => get_lang('DegreeOfCertaintyVeryUnsureDescription'),
371
                    ];
372
                } elseif ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) {
373
                    $result = [
374
                        'color' => '#000000',
375
                        'background-color' => '#F79B88',
376
                        'status' => self::LEVEL_LIGHTRED,
377
                        'label' => get_lang('DegreeOfCertaintyUnsure'),
378
                        'description' => get_lang('DegreeOfCertaintyUnsureDescription'),
379
                    ];
380
                }
381
            }
382
        }
383
384
        return $result;
385
    }
386
387
    /**
388
     * Method to show the code color and his meaning for the test result.
389
     */
390
    public static function showColorCodes()
391
    {
392
        ?>
393
        <table class="fc-border-separate" cellspacing="0" style="width:600px;
394
            margin: auto; border: 3px solid #A39E9E;" >
395
            <tr style="border-bottom: 1px solid #A39E9E;">
396
                <td style="width:15%; height:30px; background-color: #088A08; border-right: 1px solid #A39E9E;">
397
                    &nbsp;
398
                </td>
399
                <td style="padding-left:10px;">
400
                    <b><?php echo get_lang('DegreeOfCertaintyVerySure'); ?> :</b>
401
                    <?php echo get_lang('DegreeOfCertaintyVerySureDescription'); ?>
402
                </td>
403
            </tr>
404
            <tr style="border-bottom: 1px solid #A39E9E;">
405
                <td style="width:15%; height:30px; background-color: #A9F5A9; border-right: 1px solid #A39E9E;">
406
                    &nbsp;
407
                </td>
408
                <td style="padding-left:10px;">
409
                    <b><?php echo get_lang('DegreeOfCertaintyPrettySure'); ?> :</b>
410
                    <?php echo get_lang('DegreeOfCertaintyPrettySureDescription'); ?>
411
                </td>
412
            </tr>
413
            <tr style="border: 1px solid #A39E9E;">
414
                <td style="width:15%; height:30px; background-color: #FFFFFF; border-right: 1px solid #A39E9E;">
415
                    &nbsp;
416
                </td>
417
                <td style="padding-left:10px;">
418
                    <b><?php echo get_lang('DegreeOfCertaintyDeclaredIgnorance'); ?> :</b>
419
                    <?php echo get_lang('DegreeOfCertaintyDeclaredIgnoranceDescription'); ?>
420
                </td>
421
            </tr>
422
            <tr style="border: 1px solid #A39E9E;">
423
                <td style="width:15%; height:30px; background-color: #F6CECE; border-right: 1px solid #A39E9E;">
424
                    &nbsp;
425
                </td>
426
                <td style="padding-left:10px;">
427
                    <b><?php echo get_lang('DegreeOfCertaintyUnsure'); ?> :</b>
428
                    <?php echo get_lang('DegreeOfCertaintyUnsureDescription'); ?>
429
                </td>
430
            </tr>
431
            <tr style="border-bottom: 1px solid #A39E9E;">
432
                <td style="width:15%; height:30px; background-color: #FE2E2E; border-right: 1px solid #A39E9E;">
433
                    &nbsp;
434
                </td>
435
                <td style="padding-left:10px;">
436
                    <b><?php echo get_lang('DegreeOfCertaintyVeryUnsure'); ?> :</b>
437
                    <?php echo get_lang('DegreeOfCertaintyVeryUnsureDescription'); ?>
438
                </td>
439
            </tr>
440
        </table><br/>
441
        <?php
442
    }
443
444
    /**
445
     * Display basic bar charts of results by category of questions.
446
     *
447
     * @param array  $scoreListAll
448
     * @param string $title        The block title
449
     * @param int    $sizeRatio
450
     *
451
     * @return string The HTML/CSS code for the charts block
452
     */
453
    public static function displayDegreeChartByCategory($scoreListAll, $title, $sizeRatio = 1)
454
    {
455
        $maxHeight = 0;
456
        $groupCategoriesByBracket = false;
457
        if ($groupCategoriesByBracket) {
458
            $scoreList = [];
459
            $categoryPrefixList = [];
460
            // categoryPrefix['Math'] = firstCategoryId for this prefix
461
            // rebuild $scoreList factorizing data with category prefix
462
            foreach ($scoreListAll as $categoryId => $scoreListForCategory) {
463
                $objCategory = new Testcategory();
464
                $objCategoryNum = $objCategory->getCategory($categoryId);
465
                preg_match("/^\[([^]]+)\]/", $objCategoryNum->name, $matches);
466
467
                if (count($matches) > 1) {
468
                    // check if we have already see this prefix
469
                    if (array_key_exists($matches[1], $categoryPrefixList)) {
470
                        // add the result color for this entry
471
                        $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKGREEN] +=
472
                            $scoreListForCategory[self::LEVEL_DARKGREEN];
473
                        $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTGREEN] +=
474
                            $scoreListForCategory[self::LEVEL_LIGHTGREEN];
475
                        $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_WHITE] +=
476
                            $scoreListForCategory[self::LEVEL_WHITE];
477
                        $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTRED] +=
478
                            $scoreListForCategory[self::LEVEL_LIGHTRED];
479
                        $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKRED] +=
480
                            $scoreListForCategory[self::LEVEL_DARKRED];
481
                    } else {
482
                        $categoryPrefixList[$matches[1]] = $categoryId;
483
                        $scoreList[$categoryId] = $scoreListAll[$categoryId];
484
                    }
485
                } else {
486
                    // doesn't match the prefix '[math] Math category'
487
                    $scoreList[$categoryId] = $scoreListAll[$categoryId];
488
                }
489
            }
490
        } else {
491
            $scoreList = $scoreListAll;
492
        }
493
494
        // get the max height of item to have each table the same height if displayed side by side
495
        $testCategory = new TestCategory();
496
        foreach ($scoreList as $categoryId => $scoreListForCategory) {
497
            $category = $testCategory->getCategory($categoryId);
498
            if ($category) {
499
                $categoryQuestionName = $category->name;
500
            }
501
            list($noValue, $height) = self::displayDegreeChartChildren(
502
                $scoreListForCategory,
503
                300,
504
                '',
505
                1,
506
                0,
507
                false,
508
                true,
509
                0
510
            );
511
            if ($height > $maxHeight) {
512
                $maxHeight = $height;
513
            }
514
        }
515
516
        if (count($scoreList) > 1) {
517
            $boxWidth = $sizeRatio * 300 * 2 + 54;
518
        } else {
519
            $boxWidth = $sizeRatio * 300 + 54;
520
        }
521
522
        $html = '<div class="row-chart">';
523
        $html .= '<h4 class="chart-title">'.$title.'</h4>';
524
525
        $legendTitle = [
526
            'DegreeOfCertaintyVeryUnsure',
527
            'DegreeOfCertaintyUnsure',
528
            'DegreeOfCertaintyDeclaredIgnorance',
529
            'DegreeOfCertaintyPrettySure',
530
            'DegreeOfCertaintyVerySure',
531
        ];
532
        $html .= '<ul class="chart-legend">';
533
        foreach ($legendTitle as $i => $item) {
534
            $html .= '<li><i class="fa fa-square square_color'.$i.'" aria-hidden="true"></i> '.get_lang($item).'</li>';
535
        }
536
        $html .= '</ul>';
537
538
        // get the html of items
539
        $i = 0;
540
        $testCategory = new Testcategory();
541
        foreach ($scoreList as $categoryId => $scoreListForCategory) {
542
            $category = $testCategory->getCategory($categoryId);
543
            $categoryQuestionName = '';
544
            if ($category) {
545
                $categoryQuestionName = $category->name;
546
            }
547
548
            if ($categoryQuestionName === '') {
549
                $categoryName = get_lang('WithoutCategory');
550
            } else {
551
                $categoryName = $categoryQuestionName;
552
            }
553
554
            $html .= '<div class="col-md-4">';
555
            $html .= self::displayDegreeChartChildren(
556
                $scoreListForCategory,
557
                300,
558
                $categoryName,
559
                1,
560
                $maxHeight,
561
                false,
562
                false,
563
                $groupCategoriesByBracket
564
            );
565
            $html .= '</div>';
566
567
            if ($i == 2) {
568
                $html .= '<div style="clear:both; height: 10px;">&nbsp;</div>';
569
                $i = 0;
570
            } else {
571
                $i++;
572
            }
573
        }
574
        $html .= '</div>';
575
576
        return $html.'<div style="clear:both; height: 10px;" >&nbsp;</div>';
577
    }
578
579
    /**
580
     * Return HTML code for the $scoreList of MultipleAnswerTrueFalseDegreeCertainty questions.
581
     *
582
     * @param        $scoreList
583
     * @param        $widthTable
584
     * @param string $title
585
     * @param int    $sizeRatio
586
     * @param int    $minHeight
587
     * @param bool   $displayExplanationText
588
     * @param bool   $returnHeight
589
     * @param bool   $groupCategoriesByBracket
590
     * @param int    $numberOfQuestions
591
     *
592
     * @return array|string
593
     */
594
    public static function displayDegreeChart(
595
        $scoreList,
596
        $widthTable,
0 ignored issues
show
Unused Code introduced by
The parameter $widthTable is not used and could be removed. ( Ignorable by Annotation )

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

596
        /** @scrutinizer ignore-unused */ $widthTable,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
597
        $title = '',
598
        $sizeRatio = 1,
599
        $minHeight = 0,
600
        $displayExplanationText = true,
601
        $returnHeight = false,
602
        $groupCategoriesByBracket = false,
603
        $numberOfQuestions = 0
604
    ) {
605
        $topAndBottomMargin = 10;
606
        $colorList = [
607
            self::LEVEL_DARKRED,
608
            self::LEVEL_LIGHTRED,
609
            self::LEVEL_WHITE,
610
            self::LEVEL_LIGHTGREEN,
611
            self::LEVEL_DARKGREEN,
612
        ];
613
614
        // get total attempt number
615
        $highterColorHeight = 0;
616
        foreach ($scoreList as $color => $number) {
617
            if ($number > $highterColorHeight) {
618
                $highterColorHeight = $number;
619
            }
620
        }
621
622
        $totalAttemptNumber = $numberOfQuestions;
623
        $verticalLineHeight = $highterColorHeight * $sizeRatio * 2 + 122 + $topAndBottomMargin * 2;
624
        if ($verticalLineHeight < $minHeight) {
625
            $minHeightCorrection = $minHeight - $verticalLineHeight;
626
            $verticalLineHeight += $minHeightCorrection;
627
        }
628
629
        // draw chart
630
        $html = '';
631
632
        if ($groupCategoriesByBracket) {
633
            $title = api_preg_replace("/[^]]*$/", '', $title);
634
            $title = ucfirst(api_preg_replace("/[\[\]]/", '', $title));
635
        }
636
637
        $titleDisplay = (strpos($title, "ensemble") > 0) ?
638
            $title."<br/>($totalAttemptNumber questions)" :
639
            $title;
640
        $textSize = (
641
            strpos($title, 'ensemble') > 0 ||
642
            strpos($title, 'votre dernier résultat à ce test') > 0
643
        ) ? 100 : 80;
644
645
        $html .= '<div class="row-chart">';
646
        $html .= '<h4 class="chart-title">'.$titleDisplay.'</h4>';
647
648
        $nbResponsesInc = 0;
649
        if (isset($scoreList[4])) {
650
            $nbResponsesInc += (int) $scoreList[4];
651
        }
652
        if (isset($scoreList[5])) {
653
            $nbResponsesInc += (int) $scoreList[5];
654
        }
655
656
        $nbResponsesIng = isset($scoreList[3]) ? $scoreList[3] : 0;
657
658
        $nbResponsesCor = 0;
659
        if (isset($scoreList[1])) {
660
            $nbResponsesCor += (int) $scoreList[1];
661
        }
662
        if (isset($scoreList[2])) {
663
            $nbResponsesCor += (int) $scoreList[2];
664
        }
665
666
        $IncorrectAnswers = sprintf(get_lang('IncorrectAnswersX'), $nbResponsesInc);
667
        $IgnoranceAnswers = sprintf(get_lang('IgnoranceAnswersX'), $nbResponsesIng);
668
        $CorrectAnswers = sprintf(get_lang('CorrectAnswersX'), $nbResponsesCor);
669
670
        $html .= '<div class="chart-grid">';
671
672
        $explainHistoList = null;
673
        if ($displayExplanationText) {
674
            // Display of histogram text
675
            $explainHistoList = [
676
                'DegreeOfCertaintyVeryUnsure',
677
                'DegreeOfCertaintyUnsure',
678
                'DegreeOfCertaintyDeclaredIgnorance',
679
                'DegreeOfCertaintyPrettySure',
680
                'DegreeOfCertaintyVerySure',
681
            ];
682
        }
683
684
        foreach ($colorList as $i => $color) {
685
            if (array_key_exists($color, $scoreList)) {
686
                $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom
687
            } else {
688
                $scoreOnBottom = 0;
689
            }
690
            $sizeBar = ($scoreOnBottom * $sizeRatio * 2).'px;';
691
692
            if ($i == 0) {
693
                $html .= '<div class="item">';
694
                $html .= '<div class="panel-certaint" style="min-height:'.$verticalLineHeight.'px; position: relative;">';
695
                $html .= '<div class="answers-title">'.$IncorrectAnswers.'</div>';
696
                $html .= '<ul class="certaint-list-two">';
697
            } elseif ($i == 3) {
698
                $html .= '<div class="item">';
699
                $html .= '<div class="panel-certaint" style="height:'.$verticalLineHeight.'px;  position: relative;">';
700
                $html .= '<div class="answers-title">'.$CorrectAnswers.'</div>';
701
                $html .= '<ul class="certaint-list-two">';
702
            } elseif ($i == 2) {
703
                $html .= '<div class="item">';
704
                $html .= '<div class="panel-certaint" style="height:'.$verticalLineHeight.'px;  position: relative;">';
705
                $html .= '<div class="answers-title">'.$IgnoranceAnswers.'</div>';
706
                $html .= '<ul class="certaint-list">';
707
            }
708
            $html .= '<li>';
709
            $html .= '<div class="certaint-score">';
710
            $html .= $scoreOnBottom;
711
            $html .= '</div>';
712
            $html .= '<div class="levelbar_'.$color.'" style="height:'.$sizeBar.'">&nbsp;</div>';
713
            $html .= '<div class="certaint-text">'.get_lang($explainHistoList[$i]).'</div>';
714
            $html .= '</li>';
715
716
            if ($i == 1 || $i == 2 || $i == 4) {
717
                $html .= '</ul>';
718
                $html .= '</div>';
719
                $html .= '</div>';
720
            }
721
        }
722
723
        $html .= '</div>';
724
        $html .= '</div>';
725
726
        if ($returnHeight) {
727
            return [$html, $verticalLineHeight];
728
        } else {
729
            return $html;
730
        }
731
    }
732
733
    /**
734
     * Return HTML code for the $scoreList of MultipleAnswerTrueFalseDegreeCertainty questions.
735
     *
736
     * @param        $scoreList
737
     * @param        $widthTable
738
     * @param string $title
739
     * @param int    $sizeRatio
740
     * @param int    $minHeight
741
     * @param bool   $displayExplanationText
742
     * @param bool   $returnHeight
743
     * @param bool   $groupCategoriesByBracket
744
     * @param int    $numberOfQuestions
745
     *
746
     * @return array|string
747
     */
748
    public static function displayDegreeChartChildren(
749
        $scoreList,
750
        $widthTable,
751
        $title = '',
752
        $sizeRatio = 1,
753
        $minHeight = 0,
754
        $displayExplanationText = true,
755
        $returnHeight = false,
756
        $groupCategoriesByBracket = false,
757
        $numberOfQuestions = 0
758
    ) {
759
        $topAndBottomMargin = 10;
760
        $colorList = [
761
            self::LEVEL_DARKRED,
762
            self::LEVEL_LIGHTRED,
763
            self::LEVEL_WHITE,
764
            self::LEVEL_LIGHTGREEN,
765
            self::LEVEL_DARKGREEN,
766
        ];
767
768
        // get total attempt number
769
        $highterColorHeight = 0;
770
        foreach ($scoreList as $color => $number) {
771
            if ($number > $highterColorHeight) {
772
                $highterColorHeight = $number;
773
            }
774
        }
775
776
        $totalAttemptNumber = $numberOfQuestions;
777
        $verticalLineHeight = $highterColorHeight * $sizeRatio * 2 + 122 + $topAndBottomMargin * 2;
778
        if ($verticalLineHeight < $minHeight) {
779
            $minHeightCorrection = $minHeight - $verticalLineHeight;
780
            $verticalLineHeight += $minHeightCorrection;
781
        }
782
783
        // draw chart
784
        $html = '';
785
786
        if ($groupCategoriesByBracket) {
787
            $title = api_preg_replace("/[^]]*$/", '', $title);
788
            $title = ucfirst(api_preg_replace("/[\[\]]/", '', $title));
789
        }
790
791
        $textSize = 80;
792
793
        $classGlobalChart = '';
794
        if ($displayExplanationText) {
795
            // global chart
796
            $classGlobalChart = 'globalChart';
797
        }
798
799
        $html .= '<table class="certaintyTable" style="height :'.$verticalLineHeight.'px; margin-bottom: 10px;" >';
800
        $html .= '<tr><th colspan="5" class="'.$classGlobalChart.'">'
801
            .$title
802
            .'</th><tr>'
803
        ;
804
805
        $nbResponsesInc = 0;
806
        if (isset($scoreList[4])) {
807
            $nbResponsesInc += (int) $scoreList[4];
808
        }
809
        if (isset($scoreList[5])) {
810
            $nbResponsesInc += (int) $scoreList[5];
811
        }
812
813
        $nbResponsesIng = isset($scoreList[3]) ? $scoreList[3] : 0;
814
815
        $nbResponsesCor = 0;
816
        if (isset($scoreList[1])) {
817
            $nbResponsesCor += (int) $scoreList[1];
818
        }
819
        if (isset($scoreList[2])) {
820
            $nbResponsesCor += (int) $scoreList[2];
821
        }
822
823
        $colWidth = $widthTable / 5;
824
825
        $html .= '<tr>
826
                <td class="firstLine borderRight '.$classGlobalChart.'" 
827
                    colspan="2" 
828
                    style="width:'.($colWidth * 2).'px; line-height: 15px; font-size:'.$textSize.'%;">'.
829
            sprintf(get_lang('IncorrectAnswersX'), $nbResponsesInc).'
830
                </td>
831
                <td class="firstLine borderRight '.$classGlobalChart.'" 
832
                    style="width:'.$colWidth.'px; line-height: 15px; font-size :'.$textSize.'%;">'.
833
            sprintf(get_lang('IgnoranceAnswersX'), $nbResponsesIng).'
834
                </td>
835
                <td class="firstLine '.$classGlobalChart.'" 
836
                    colspan="2" 
837
                    style="width:'.($colWidth * 2).'px; line-height: 15px; font-size:'.$textSize.'%;">'.
838
            sprintf(get_lang('CorrectAnswersX'), $nbResponsesCor).'
839
                </td>
840
            </tr>';
841
        $html .= '<tr>';
842
843
        foreach ($colorList as $i => $color) {
844
            if (array_key_exists($color, $scoreList)) {
845
                $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom
846
            } else {
847
                $scoreOnBottom = 0;
848
            }
849
            $sizeOnBottom = $scoreOnBottom * $sizeRatio * 2;
850
            if ($i == 1 || $i == 2) {
851
                $html .= '<td width="'
852
                    .$colWidth
853
                    .'px" style="border-right: 1px dotted #7FC5FF; vertical-align: bottom;font-size: '
854
                    .$textSize
855
                    .'%;">'
856
                ;
857
            } else {
858
                $html .= '<td width="'
859
                    .$colWidth
860
                    .'px" style="vertical-align: bottom;font-size: '
861
                    .$textSize
862
                    .'%;">'
863
                ;
864
            }
865
            $html .= '<div class="certaint-score">'
866
                .$scoreOnBottom
867
                .'</div><div class="levelbar_'
868
                .$color
869
                .'" style="height: '
870
                .$sizeOnBottom
871
                .'px;">&nbsp;</div>'
872
            ;
873
            $html .= '</td>';
874
        }
875
876
        $html .= '</tr>';
877
878
        if ($displayExplanationText) {
879
            // Display of histogram text
880
            $explainHistoList = [
881
                'DegreeOfCertaintyVeryUnsure',
882
                'DegreeOfCertaintyUnsure',
883
                'DegreeOfCertaintyDeclaredIgnorance',
884
                'DegreeOfCertaintyPrettySure',
885
                'DegreeOfCertaintyVerySure',
886
            ];
887
            $html .= '<tr>';
888
            $i = 0;
889
            foreach ($explainHistoList as $explain) {
890
                if ($i == 1 || $i == 2) {
891
                    $class = 'borderRight';
892
                } else {
893
                    $class = '';
894
                }
895
                $html .= '<td class="firstLine '
896
                    .$class
897
                    .' '
898
                    .$classGlobalChart
899
                    .'" style="width="'
900
                    .$colWidth
901
                    .'px; font-size:'
902
                    .$textSize
903
                    .'%;">'
904
                ;
905
                $html .= get_lang($explain);
906
                $html .= '</td>';
907
                $i++;
908
            }
909
            $html .= '</tr>';
910
        }
911
        $html .= '</table></center>';
912
913
        if ($returnHeight) {
914
            return [$html, $verticalLineHeight];
915
        } else {
916
            return $html;
917
        }
918
    }
919
920
    /**
921
     * return previous attempt id for this test for student, 0 if no previous attempt.
922
     *
923
     * @param $exeId
924
     *
925
     * @return int
926
     */
927
    public static function getPreviousAttemptId($exeId)
928
    {
929
        $tblTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
930
        $exeId = (int) $exeId;
931
        $sql = "SELECT * FROM $tblTrackEExercise
932
                WHERE exe_id = ".$exeId;
933
        $res = Database::query($sql);
934
935
        if (empty(Database::num_rows($res))) {
936
            // if we cannot find the exe_id
937
            return 0;
938
        }
939
940
        $data = Database::fetch_assoc($res);
941
        $courseCode = $data['c_id'];
942
        $exerciseId = $data['exe_exo_id'];
943
        $userId = $data['exe_user_id'];
944
        $attemptDate = $data['exe_date'];
945
946
        if ($attemptDate == '0000-00-00 00:00:00') {
947
            // incomplete attempt, close it before continue
948
            return 0;
949
        }
950
951
        // look for previous attempt
952
        $exerciseId = (int) $exerciseId;
953
        $userId = (int) $userId;
954
        $sql = "SELECT *
955
            FROM $tblTrackEExercise
956
            WHERE c_id = '$courseCode'
957
            AND exe_exo_id = $exerciseId
958
            AND exe_user_id = $userId
959
            AND status = ''
960
            AND exe_date > '0000-00-00 00:00:00'
961
            AND exe_date < '$attemptDate'
962
            ORDER BY exe_date DESC";
963
964
        $res = Database::query($sql);
965
966
        if (Database::num_rows($res) == 0) {
967
            // no previous attempt
968
            return 0;
969
        }
970
971
        $data = Database::fetch_assoc($res);
972
973
        return $data['exe_id'];
974
    }
975
976
    /**
977
     * return an array of number of answer color for exe attempt
978
     * for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY
979
     * e.g.
980
     * [LEVEL_DARKGREEN => 3, LEVEL_LIGHTGREEN => 0, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12, LEVEL_DARKTRED => 0].
981
     *
982
     * @param $exeId
983
     *
984
     * @return array
985
     */
986
    public static function getColorNumberListForAttempt($exeId)
987
    {
988
        $result = [
989
            self::LEVEL_DARKGREEN => 0,
990
            self::LEVEL_LIGHTGREEN => 0,
991
            self::LEVEL_WHITE => 0,
992
            self::LEVEL_LIGHTRED => 0,
993
            self::LEVEL_DARKRED => 0,
994
        ];
995
996
        $attemptInfoList = self::getExerciseAttemptInfo($exeId);
997
998
        foreach ($attemptInfoList as $attemptInfo) {
999
            $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty();
1000
            $oQuestion->read($attemptInfo['question_id']);
1001
            if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
1002
                $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']);
1003
                if ($answerColor) {
1004
                    $result[$answerColor]++;
1005
                }
1006
            }
1007
        }
1008
1009
        return $result;
1010
    }
1011
1012
    /**
1013
     * return an array of number of color for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY
1014
     * for each question category.
1015
     *
1016
     * e.g.
1017
     * [
1018
     *      (categoryId=)5 => [LEVEL_DARKGREEN => 3, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12]
1019
     *      (categoryId=)2 => [LEVEL_DARKGREEN => 8, LEVEL_LIGHTRED => 2, LEVEL_DARKTRED => 8]
1020
     *      (categoryId=)0 => [LEVEL_DARKGREEN => 1,
1021
     *          LEVEL_LIGHTGREEN => 2,
1022
     *          LEVEL_WHITE => 6,
1023
     *          LEVEL_LIGHTRED => 1,
1024
     *          LEVEL_DARKTRED => 9]
1025
     * ]
1026
     *
1027
     * @param int $exeId
1028
     *
1029
     * @return array
1030
     */
1031
    public static function getColorNumberListForAttemptByCategory($exeId)
1032
    {
1033
        $result = [];
1034
        $attemptInfoList = self::getExerciseAttemptInfo($exeId);
1035
1036
        foreach ($attemptInfoList as $attemptInfo) {
1037
            $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty();
1038
            $oQuestion->read($attemptInfo['question_id']);
1039
            if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
1040
                $questionCategory = Testcategory::getCategoryForQuestion($attemptInfo['question_id']);
1041
1042
                if (!array_key_exists($questionCategory, $result)) {
1043
                    $result[$questionCategory] = [];
1044
                }
1045
1046
                $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']);
1047
                if ($answerColor && isset($result[$questionCategory])) {
1048
                    if (!isset($result[$questionCategory][$answerColor])) {
1049
                        $result[$questionCategory][$answerColor] = 0;
1050
                    }
1051
                    $result[$questionCategory][$answerColor]++;
1052
                }
1053
            }
1054
        }
1055
1056
        return $result;
1057
    }
1058
1059
    /**
1060
     * Return true if answer of $exeId, $questionId, $position is correct, otherwise return false.
1061
     *
1062
     * @param $exeId
1063
     * @param $questionId
1064
     * @param $position
1065
     *
1066
     * @return int
1067
     */
1068
    public static function getAnswerColor($exeId, $questionId, $position)
1069
    {
1070
        $attemptInfoList = self::getExerciseAttemptInfo($exeId, $questionId, $position);
1071
1072
        if (count($attemptInfoList) != 1) {
1073
            // havent got the answer
1074
            return 0;
1075
        }
1076
1077
        $answerCodes = $attemptInfoList[0]['answer'];
1078
1079
        // student answer
1080
        $splitAnswer = preg_split("/:/", $answerCodes);
1081
        // get correct answer option id
1082
        $correctAnswerOptionId = self::getCorrectAnswerOptionId($splitAnswer[0]);
1083
        if ($correctAnswerOptionId == 0) {
1084
            // error returning the correct answer option id
1085
            return 0;
1086
        }
1087
1088
        // get student answer option id
1089
        $studentAnswerOptionId = $splitAnswer[1];
1090
1091
        // we got the correct answer option id, let's compare ti with the student answer
1092
        $percentage = self::getPercentagePosition($splitAnswer[2]);
1093
        if ($studentAnswerOptionId == $correctAnswerOptionId) {
1094
            // yeah, student got correct answer
1095
            switch ($percentage) {
1096
                case 3:
1097
                    return self::LEVEL_WHITE;
1098
                case 4:
1099
                case 5:
1100
                    return self::LEVEL_LIGHTGREEN;
1101
                case 6:
1102
                case 7:
1103
                case 8:
1104
                    return self::LEVEL_DARKGREEN;
1105
                default:
1106
                    return 0;
1107
            }
1108
        } else {
1109
            // bummer, wrong answer dude
1110
            switch ($percentage) {
1111
                case 3:
1112
                    return self::LEVEL_WHITE;
1113
                case 4:
1114
                case 5:
1115
                    return self::LEVEL_LIGHTRED;
1116
                case 6:
1117
                case 7:
1118
                case 8:
1119
                    return self::LEVEL_DARKRED;
1120
                default:
1121
                    return 0;
1122
            }
1123
        }
1124
    }
1125
1126
    /**
1127
     * Return the position of certitude %age choose by student.
1128
     *
1129
     * @param $optionId
1130
     *
1131
     * @return int
1132
     */
1133
    public static function getPercentagePosition($optionId)
1134
    {
1135
        $tblAnswerOption = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
1136
        $courseId = api_get_course_int_id();
1137
        $optionId = (int) $optionId;
1138
        $sql = "SELECT position 
1139
                FROM $tblAnswerOption 
1140
                WHERE c_id = $courseId AND id = $optionId";
1141
        $res = Database::query($sql);
1142
1143
        if (Database::num_rows($res) == 0) {
1144
            return 0;
1145
        }
1146
1147
        $data = Database::fetch_assoc($res);
1148
1149
        return $data['position'];
1150
    }
1151
1152
    /**
1153
     * return the correct id from c_quiz_question_option for question idAuto.
1154
     *
1155
     * @param $idAuto
1156
     *
1157
     * @return int
1158
     */
1159
    public static function getCorrectAnswerOptionId($idAuto)
1160
    {
1161
        $tblAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER);
1162
        $courseId = api_get_course_int_id();
1163
        $idAuto = (int) $idAuto;
1164
        $sql = "SELECT correct FROM $tblAnswer
1165
                WHERE c_id = $courseId AND id_auto = $idAuto";
1166
1167
        $res = Database::query($sql);
1168
        $data = Database::fetch_assoc($res);
1169
        if (Database::num_rows($res) > 0) {
1170
            return $data['correct'];
1171
        } else {
1172
            return 0;
1173
        }
1174
    }
1175
1176
    /**
1177
     * return an array of exe info from track_e_attempt.
1178
     *
1179
     * @param int $exeId
1180
     * @param int $questionId
1181
     * @param int $position
1182
     *
1183
     * @return array
1184
     */
1185
    public static function getExerciseAttemptInfo($exeId, $questionId = -1, $position = -1)
1186
    {
1187
        $result = [];
1188
        $and = '';
1189
        $questionId = (int) $questionId;
1190
        $position = (int) $position;
1191
1192
        if ($questionId >= 0) {
1193
            $and .= " AND question_id = $questionId";
1194
        }
1195
        if ($position >= 0) {
1196
            $and .= " AND position = $position";
1197
        }
1198
1199
        $tblExeAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1200
        $cId = api_get_course_int_id();
1201
        $sql = "SELECT * FROM $tblExeAttempt
1202
                WHERE c_id = $cId AND exe_id = $exeId $and";
1203
1204
        $res = Database::query($sql);
1205
        while ($data = Database::fetch_assoc($res)) {
1206
            $result[] = $data;
1207
        }
1208
1209
        return $result;
1210
    }
1211
1212
    /**
1213
     * @param int $exeId
1214
     *
1215
     * @return int
1216
     */
1217
    public static function getNumberOfQuestionsForExeId($exeId)
1218
    {
1219
        $tableTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1220
        $exeId = (int) $exeId;
1221
1222
        $sql = "SELECT exe_exo_id 
1223
                FROM $tableTrackEExercise
1224
                WHERE exe_id=".$exeId;
1225
        $res = Database::query($sql);
1226
        $data = Database::fetch_assoc($res);
1227
        if ($data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1228
            $exerciseId = $data['exe_exo_id'];
1229
1230
            $objectExercise = new Exercise();
1231
            $objectExercise->read($exerciseId);
1232
1233
            return $objectExercise->get_count_question_list();
1234
        }
1235
1236
        return 0;
1237
    }
1238
1239
    /**
1240
     * Display student chart results for these question types.
1241
     *
1242
     * @param int      $exeId
1243
     * @param Exercise $objExercice
1244
     *
1245
     * @return string
1246
     */
1247
    public static function displayStudentsChartResults($exeId, $objExercice)
1248
    {
1249
        $numberOfQuestions = self::getNumberOfQuestionsForExeId($exeId);
1250
        $globalScoreList = self::getColorNumberListForAttempt($exeId);
1251
        $html = self::displayDegreeChart(
1252
            $globalScoreList,
1253
            600,
1254
            get_lang('YourOverallResultForTheTest'),
1255
            2,
1256
            0,
1257
            true,
1258
            false,
1259
            false,
1260
            $numberOfQuestions
1261
        );
1262
        $html .= '<br/>';
1263
1264
        $previousAttemptId = self::getPreviousAttemptId($exeId);
1265
        if ($previousAttemptId > 0) {
1266
            $previousAttemptScoreList = self::getColorNumberListForAttempt(
1267
                $previousAttemptId
1268
            );
1269
            $html .= self::displayDegreeChart(
1270
                $previousAttemptScoreList,
1271
                600,
1272
                get_lang('ForComparisonYourLastResultToThisTest'),
1273
                2
1274
            );
1275
            $html .= '<br/>';
1276
        }
1277
1278
        $list = self::getColorNumberListForAttemptByCategory($exeId);
1279
        $html .= self::displayDegreeChartByCategory(
1280
            $list,
1281
            get_lang('YourResultsByDiscipline'),
1282
            1,
1283
            $objExercice
1284
        );
1285
        $html .= '<br/>';
1286
1287
        return $html;
1288
    }
1289
1290
    /**
1291
     * send mail to student with degre certainty result test.
1292
     *
1293
     * @param int      $userId
1294
     * @param Exercise $objExercise
1295
     * @param int      $exeId
1296
     */
1297
    public static function sendQuestionCertaintyNotification($userId, $objExercise, $exeId)
1298
    {
1299
        $userInfo = api_get_user_info($userId);
1300
        $recipientName = api_get_person_name($userInfo['firstname'],
1301
            $userInfo['lastname'],
1302
            null,
1303
            PERSON_NAME_EMAIL_ADDRESS
1304
        );
1305
        $subject = "[".get_lang('DoNotReply')."] "
1306
            .html_entity_decode(get_lang('ResultAccomplishedTest')." \"".$objExercise->title."\"");
1307
1308
        // message sended to the student
1309
        $message = get_lang('Dear').' '.$recipientName.",<br /><br />";
1310
        $exerciseLink = "<a href='".api_get_path(WEB_CODE_PATH)."/exercise/result.php?show_headers=1&"
1311
            .api_get_cidreq()
1312
            ."&id=$exeId'>";
1313
        $exerciseTitle = $objExercise->title;
1314
1315
        $message .= sprintf(
1316
            get_lang('MessageQuestionCertainty'),
1317
            $exerciseTitle,
1318
            api_get_path(WEB_PATH),
1319
            $exerciseLink
1320
        );
1321
1322
        // show histogram
1323
        $message .= self::displayStudentsChartResults($exeId, $objExercise);
1324
        $message .= get_lang('KindRegards');
1325
        $message = api_preg_replace("/\\\n/", '', $message);
1326
1327
        MessageManager::send_message_simple($userId, $subject, $message);
1328
    }
1329
}
1330