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

displayDegreeChartChildren()   F

Complexity

Conditions 20
Paths 15360

Size

Total Lines 169
Code Lines 110

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 20
eloc 110
nc 15360
nop 9
dl 0
loc 169
rs 0
c 1
b 0
f 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
/* 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