Passed
Push — master ( 190bd7...86c511 )
by Julito
09:39
created

SurveyUtil::get_survey_invitations_data()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 14
nc 2
nop 0
dl 0
loc 26
rs 9.7998
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CSurvey;
5
use Chamilo\CourseBundle\Entity\CSurveyAnswer;
6
use ChamiloSession as Session;
7
8
/**
9
 * This class offers a series of general utility functions for survey querying and display.
10
 *
11
 * @package chamilo.survey
12
 */
13
class SurveyUtil
14
{
15
    /**
16
     * Checks whether the given survey has a pagebreak question as the first
17
     * or the last question.
18
     * If so, break the current process, displaying an error message.
19
     *
20
     * @param int  $survey_id Survey ID (database ID)
21
     * @param bool $continue  Optional. Whether to continue the current
22
     *                        process or exit when breaking condition found. Defaults to true (do not break).
23
     */
24
    public static function check_first_last_question($survey_id, $continue = true)
25
    {
26
        // Table definitions
27
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
28
        $course_id = api_get_course_int_id();
29
30
        // Getting the information of the question
31
        $sql = "SELECT * FROM $tbl_survey_question
32
                WHERE c_id = $course_id AND survey_id='".Database::escape_string($survey_id)."'
33
                ORDER BY sort ASC";
34
        $result = Database::query($sql);
35
        $total = Database::num_rows($result);
36
        $counter = 1;
37
        $error = false;
38
        while ($row = Database::fetch_array($result, 'ASSOC')) {
39
            if ($counter == 1 && $row['type'] == 'pagebreak') {
40
                echo Display::return_message(get_lang('PagebreakNotFirst'), 'error', false);
41
                $error = true;
42
            }
43
            if ($counter == $total && $row['type'] == 'pagebreak') {
44
                echo Display::return_message(get_lang('PagebreakNotLast'), 'error', false);
45
                $error = true;
46
            }
47
            $counter++;
48
        }
49
50
        if (!$continue && $error) {
51
            Display::display_footer();
52
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
53
        }
54
    }
55
56
    /**
57
     * This function removes an (or multiple) answer(s) of a user on a question of a survey.
58
     *
59
     * @param mixed   The user id or email of the person who fills the survey
60
     * @param int The survey id
61
     * @param int The question id
62
     * @param int The option id
63
     *
64
     * @author Patrick Cool <[email protected]>, Ghent University
65
     *
66
     * @version January 2007
67
     */
68
    public static function remove_answer($user, $survey_id, $question_id, $course_id)
69
    {
70
        $course_id = intval($course_id);
71
        // table definition
72
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
73
        $sql = "DELETE FROM $table
74
				WHERE
75
				    c_id = $course_id AND
76
                    user = '".Database::escape_string($user)."' AND
77
                    survey_id = '".intval($survey_id)."' AND
78
                    question_id = '".intval($question_id)."'";
79
        Database::query($sql);
80
    }
81
82
    /**
83
     * This function stores an answer of a user on a question of a survey.
84
     *
85
     * @param mixed   The user id or email of the person who fills the survey
86
     * @param int Survey id
87
     * @param int Question id
88
     * @param int Option id
89
     * @param string  Option value
90
     * @param array $survey_data Survey data settings
91
     *
92
     * @return bool False if insufficient data, true otherwise
93
     *
94
     * @author Patrick Cool <[email protected]>, Ghent University
95
     *
96
     * @version January 2007
97
     */
98
    public static function store_answer(
99
        $user,
100
        $survey_id,
101
        $question_id,
102
        $option_id,
103
        $option_value,
104
        $survey_data
105
    ) {
106
        // If the question_id is empty, don't store an answer
107
        if (empty($question_id)) {
108
            return false;
109
        }
110
111
        // Table definition
112
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
113
114
        // Make the survey anonymous
115
        if ($survey_data['anonymous'] == 1) {
116
            $surveyUser = Session::read('surveyuser');
117
            if (empty($surveyUser)) {
118
                $user = md5($user.time());
119
                Session::write('surveyuser', $user);
120
            } else {
121
                $user = Session::read('surveyuser');
122
            }
123
        }
124
125
        $answer = new CSurveyAnswer();
126
        $answer
127
            ->setCId($survey_data['c_id'])
128
            ->setUser($user)
129
            ->setSurveyId($survey_id)
130
            ->setQuestionId($question_id)
131
            ->setOptionId($option_id)
132
            ->setValue($option_value)
133
        ;
134
135
        $em = Database::getManager();
136
        $em->persist($answer);
137
        $em->flush();
138
139
        $insertId = $answer->getIid();
140
        if ($insertId) {
141
            $sql = "UPDATE $table_survey_answer SET answer_id = $insertId 
142
                WHERE iid = $insertId";
143
            Database::query($sql);
144
        }
145
146
        return true;
147
    }
148
149
    /**
150
     * This function checks the parameters that are used in this page.
151
     *
152
     * @return string $people_filled The header, an error and the footer if any parameter fails, else it returns true
153
     *
154
     * @author Patrick Cool <[email protected]>, Ghent University
155
     *
156
     * @version February 2007
157
     */
158
    public static function check_parameters($people_filled)
159
    {
160
        $error = false;
161
162
        // Getting the survey data
163
        $survey_data = SurveyManager::get_survey($_GET['survey_id']);
164
165
        // $_GET['survey_id'] has to be numeric
166
        if (!is_numeric($_GET['survey_id'])) {
167
            $error = get_lang('IllegalSurveyId');
168
        }
169
170
        // $_GET['action']
171
        $allowed_actions = [
172
            'overview',
173
            'questionreport',
174
            'userreport',
175
            'comparativereport',
176
            'completereport',
177
            'deleteuserreport',
178
        ];
179
        if (isset($_GET['action']) && !in_array($_GET['action'], $allowed_actions)) {
180
            $error = get_lang('ActionNotAllowed');
181
        }
182
183
        // User report
184
        if (isset($_GET['action']) && $_GET['action'] == 'userreport') {
185
            if ($survey_data['anonymous'] == 0) {
186
                foreach ($people_filled as $key => &$value) {
187
                    $people_filled_userids[] = $value['invited_user'];
188
                }
189
            } else {
190
                $people_filled_userids = $people_filled;
191
            }
192
193
            if (isset($_GET['user']) && !in_array($_GET['user'], $people_filled_userids)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $people_filled_userids does not seem to be defined for all execution paths leading up to this point.
Loading history...
194
                $error = get_lang('UnknowUser');
195
            }
196
        }
197
198
        // Question report
199
        if (isset($_GET['action']) && $_GET['action'] == 'questionreport') {
200
            if (isset($_GET['question']) && !is_numeric($_GET['question'])) {
201
                $error = get_lang('UnknowQuestion');
202
            }
203
        }
204
205
        if ($error) {
206
            $tool_name = get_lang('Reporting');
207
            Display::addFlash(
208
                Display::return_message(
209
                    get_lang('Error').': '.$error,
210
                    'error',
211
                    false
212
                )
213
            );
214
            Display::display_header($tool_name);
215
            Display::display_footer();
216
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
217
        } else {
218
            return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type string.
Loading history...
219
        }
220
    }
221
222
    /**
223
     * This function deals with the action handling.
224
     *
225
     * @param array $survey_data
226
     * @param array $people_filled
227
     *
228
     * @author Patrick Cool <[email protected]>, Ghent University
229
     *
230
     * @version February 2007
231
     */
232
    public static function handle_reporting_actions($survey_data, $people_filled)
233
    {
234
        $action = isset($_GET['action']) ? $_GET['action'] : null;
235
236
        // Getting the number of question
237
        $temp_questions_data = SurveyManager::get_questions($_GET['survey_id']);
238
239
        // Sorting like they should be displayed and removing the non-answer question types (comment and pagebreak)
240
        $my_temp_questions_data = $temp_questions_data == null ? [] : $temp_questions_data;
241
        $questions_data = [];
242
243
        foreach ($my_temp_questions_data as $key => &$value) {
244
            if ($value['type'] != 'pagebreak') {
245
                $questions_data[$value['sort']] = $value;
246
            }
247
        }
248
249
        // Counting the number of questions that are relevant for the reporting
250
        $survey_data['number_of_questions'] = count($questions_data);
251
252
        if ($action == 'questionreport') {
253
            self::display_question_report($survey_data);
254
        }
255
        if ($action == 'userreport') {
256
            self::display_user_report($people_filled, $survey_data);
257
        }
258
        if ($action == 'comparativereport') {
259
            self::display_comparative_report();
260
        }
261
        if ($action == 'completereport') {
262
            self::display_complete_report($survey_data);
263
        }
264
        if ($action == 'deleteuserreport') {
265
            self::delete_user_report($_GET['survey_id'], $_GET['user']);
266
        }
267
    }
268
269
    /**
270
     * This function deletes the report of an user who wants to retake the survey.
271
     *
272
     * @param int $survey_id
273
     * @param int $user_id
274
     *
275
     * @author Christian Fasanando Flores <[email protected]>
276
     *
277
     * @version November 2008
278
     */
279
    public static function delete_user_report($survey_id, $user_id)
280
    {
281
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
282
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
283
        $table_survey = Database::get_course_table(TABLE_SURVEY);
284
285
        $course_id = api_get_course_int_id();
286
        $survey_id = (int) $survey_id;
287
        $user_id = Database::escape_string($user_id);
288
289
        if (!empty($survey_id) && !empty($user_id)) {
290
            // delete data from survey_answer by user_id and survey_id
291
            $sql = "DELETE FROM $table_survey_answer
292
			        WHERE c_id = $course_id AND survey_id = '".$survey_id."' AND user = '".$user_id."'";
293
            Database::query($sql);
294
            // update field answered from survey_invitation by user_id and survey_id
295
            $sql = "UPDATE $table_survey_invitation SET answered = '0'
296
			        WHERE
297
			            c_id = $course_id AND
298
			            survey_code = (
299
                            SELECT code FROM $table_survey
300
                            WHERE
301
                                c_id = $course_id AND
302
                                survey_id = '".$survey_id."'
303
                        ) AND
304
			            user = '".$user_id."'";
305
            $result = Database::query($sql);
306
        }
307
308
        if ($result !== false) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.
Loading history...
309
            $message = get_lang('SurveyUserAnswersHaveBeenRemovedSuccessfully').'<br />
310
					<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action=userreport&survey_id='
311
                .$survey_id.'">'.
312
                get_lang('GoBack').'</a>';
313
            echo Display::return_message($message, 'confirmation', false);
314
        }
315
    }
316
317
    /**
318
     * This function displays the user report which is basically nothing more
319
     * than a one-page display of all the questions
320
     * of the survey that is filled with the answers of the person who filled the survey.
321
     *
322
     * @return string html code of the one-page survey with the answers of the selected user
323
     *
324
     * @author Patrick Cool <[email protected]>, Ghent University
325
     *
326
     * @version February 2007 - Updated March 2008
327
     */
328
    public static function display_user_report($people_filled, $survey_data)
329
    {
330
        // Database table definitions
331
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
332
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
333
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
334
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
335
336
        // Actions bar
337
        echo '<div class="actions">';
338
        echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?survey_id='.$surveyId.'&'.api_get_cidreq().'">'.
339
            Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('ReportingOverview'), '', ICON_SIZE_MEDIUM)
340
            .'</a>';
341
        if (isset($_GET['user'])) {
342
            if (api_is_allowed_to_edit()) {
343
                // The delete link
344
                echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action=deleteuserreport&survey_id='
345
                    .$surveyId.'&'.api_get_cidreq().'&user='.Security::remove_XSS($_GET['user']).'" >'.
346
                    Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_MEDIUM).'</a>';
347
            }
348
349
            // Export the user report
350
            echo '<a href="javascript: void(0);" onclick="document.form1a.submit();">'
351
                .Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a> ';
352
            echo '<a href="javascript: void(0);" onclick="document.form1b.submit();">'
353
                .Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a> ';
354
            echo '<form id="form1a" name="form1a" method="post" action="'.api_get_self().'?action='
355
                .Security::remove_XSS($_GET['action']).'&survey_id='.$surveyId.'&'.api_get_cidreq().'&user_id='
356
                .Security::remove_XSS($_GET['user']).'">';
357
            echo '<input type="hidden" name="export_report" value="export_report">';
358
            echo '<input type="hidden" name="export_format" value="csv">';
359
            echo '</form>';
360
            echo '<form id="form1b" name="form1b" method="post" action="'.api_get_self().'?action='
361
                .Security::remove_XSS($_GET['action']).'&survey_id='.$surveyId.'&'.api_get_cidreq().'&user_id='
362
                .Security::remove_XSS($_GET['user']).'">';
363
            echo '<input type="hidden" name="export_report" value="export_report">';
364
            echo '<input type="hidden" name="export_format" value="xls">';
365
            echo '</form>';
366
            echo '<form id="form2" name="form2" method="post" action="'.api_get_self().'?action='
367
                .Security::remove_XSS($_GET['action']).'&survey_id='.$surveyId.'&'.api_get_cidreq().'">';
368
        }
369
        echo '</div>';
370
371
        // Step 1: selection of the user
372
        echo "<script>
373
        function jumpMenu(targ,selObj,restore) {
374
            eval(targ+\".location='\"+selObj.options[selObj.selectedIndex].value+\"'\");
375
            if (restore) selObj.selectedIndex=0;
376
        }
377
		</script>";
378
        echo get_lang('SelectUserWhoFilledSurvey').'<br />';
379
380
        echo '<select name="user" onchange="jumpMenu(\'parent\',this,0)">';
381
        echo '<option value="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='
382
            .Security::remove_XSS($_GET['action']).'&survey_id='.intval($_GET['survey_id']).'">'
383
            .get_lang('SelectUser').'</option>';
384
385
        foreach ($people_filled as $key => &$person) {
386
            if ($survey_data['anonymous'] == 0) {
387
                $name = $person['user_info']['complete_name_with_username'];
388
                $id = $person['user_id'];
389
                if ($id == '') {
390
                    $id = $person['invited_user'];
391
                    $name = $person['invited_user'];
392
                }
393
            } else {
394
                $name = get_lang('Anonymous').' '.($key + 1);
395
                $id = $person;
396
            }
397
            echo '<option value="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='
398
                .Security::remove_XSS($_GET['action']).'&survey_id='.intval($_GET['survey_id']).'&user='
399
                .Security::remove_XSS($id).'" ';
400
            if (isset($_GET['user']) && $_GET['user'] == $id) {
401
                echo 'selected="selected"';
402
            }
403
            echo '>'.$name.'</option>';
404
        }
405
        echo '</select>';
406
407
        $course_id = api_get_course_int_id();
408
        // Step 2: displaying the survey and the answer of the selected users
409
        if (isset($_GET['user'])) {
410
            echo Display::return_message(
411
                get_lang('AllQuestionsOnOnePage'),
412
                'normal',
413
                false
414
            );
415
416
            // Getting all the questions and options
417
            $sql = "SELECT
418
			            survey_question.question_id,
419
			            survey_question.survey_id,
420
			            survey_question.survey_question,
421
			            survey_question.display,
422
			            survey_question.max_value,
423
			            survey_question.sort,
424
			            survey_question.type,
425
                        survey_question_option.question_option_id,
426
                        survey_question_option.option_text,
427
                        survey_question_option.sort as option_sort
428
					FROM $table_survey_question survey_question
429
					LEFT JOIN $table_survey_question_option survey_question_option
430
					ON
431
					    survey_question.question_id = survey_question_option.question_id AND
432
					    survey_question_option.c_id = $course_id
433
					WHERE
434
					    survey_question.survey_id = '".intval($_GET['survey_id'])."' AND
435
                        survey_question.c_id = $course_id
436
					ORDER BY survey_question.sort, survey_question_option.sort ASC";
437
            $result = Database::query($sql);
438
            while ($row = Database::fetch_array($result, 'ASSOC')) {
439
                if ($row['type'] != 'pagebreak') {
440
                    $questions[$row['sort']]['question_id'] = $row['question_id'];
441
                    $questions[$row['sort']]['survey_id'] = $row['survey_id'];
442
                    $questions[$row['sort']]['survey_question'] = $row['survey_question'];
443
                    $questions[$row['sort']]['display'] = $row['display'];
444
                    $questions[$row['sort']]['type'] = $row['type'];
445
                    $questions[$row['sort']]['maximum_score'] = $row['max_value'];
446
                    $questions[$row['sort']]['options'][$row['question_option_id']] = $row['option_text'];
447
                }
448
            }
449
450
            // Getting all the answers of the user
451
            $sql = "SELECT * FROM $table_survey_answer
452
			        WHERE
453
                        c_id = $course_id AND
454
                        survey_id = '".intval($_GET['survey_id'])."' AND
455
                        user = '".Database::escape_string($_GET['user'])."'";
456
            $result = Database::query($sql);
457
            while ($row = Database::fetch_array($result, 'ASSOC')) {
458
                $answers[$row['question_id']][] = $row['option_id'];
459
                $all_answers[$row['question_id']][] = $row;
460
            }
461
462
            // Displaying all the questions
463
464
            foreach ($questions as &$question) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $questions does not seem to be defined for all execution paths leading up to this point.
Loading history...
465
                // If the question type is a scoring then we have to format the answers differently
466
                switch ($question['type']) {
467
                    case 'score':
468
                        $finalAnswer = [];
469
                        if (is_array($question) && is_array($all_answers)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $all_answers does not seem to be defined for all execution paths leading up to this point.
Loading history...
470
                            foreach ($all_answers[$question['question_id']] as $key => &$answer_array) {
471
                                $finalAnswer[$answer_array['option_id']] = $answer_array['value'];
472
                            }
473
                        }
474
                        break;
475
                    case 'multipleresponse':
476
                        $finalAnswer = isset($answers[$question['question_id']])
477
                            ? $answers[$question['question_id']]
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $answers does not seem to be defined for all execution paths leading up to this point.
Loading history...
478
                            : '';
479
                        break;
480
                    default:
481
                        $finalAnswer = '';
482
                        if (isset($all_answers[$question['question_id']])) {
483
                            $finalAnswer = $all_answers[$question['question_id']][0]['option_id'];
484
                        }
485
                        break;
486
                }
487
488
                $ch_type = 'ch_'.$question['type'];
489
                if (class_exists($ch_type)) {
490
                    /** @var survey_question $display */
491
                    $display = new $ch_type();
492
493
                    $url = api_get_self();
494
                    $form = new FormValidator('question', 'post', $url);
495
                    $form->addHtml('<div class="survey_question_wrapper"><div class="survey_question">');
496
                    $form->addHtml($question['survey_question']);
497
                    $display->render($form, $question, $finalAnswer);
498
                    $form->addHtml('</div></div>');
499
                    $form->display();
500
                }
501
            }
502
        }
503
    }
504
505
    /**
506
     * This function displays the report by question.
507
     *
508
     * It displays a table with all the options of the question and the number of users who have answered positively on
509
     * the option. The number of users who answered positive on a given option is expressed in an absolute number, in a
510
     * percentage of the total and graphically using bars By clicking on the absolute number you get a list with the
511
     * persons who have answered this. You can then click on the name of the person and you will then go to the report
512
     * by user where you see all the answers of that user.
513
     *
514
     * @param    array    All the survey data
515
     *
516
     * @return string html code that displays the report by question
517
     *
518
     * @todo allow switching between horizontal and vertical.
519
     * @todo multiple response: percentage are probably not OK
520
     * @todo the question and option text have to be shortened and should expand when the user clicks on it.
521
     * @todo the pagebreak and comment question types should not be shown => removed from $survey_data before
522
     *
523
     * @author Patrick Cool <[email protected]>, Ghent University
524
     *
525
     * @version February 2007 - Updated March 2008
526
     */
527
    public static function display_question_report($survey_data)
528
    {
529
        $singlePage = isset($_GET['single_page']) ? (int) $_GET['single_page'] : 0;
530
        // Determining the offset of the sql statement (the n-th question of the survey)
531
        $offset = !isset($_GET['question']) ? 0 : (int) $_GET['question'];
532
        $currentQuestion = isset($_GET['question']) ? (int) $_GET['question'] : 0;
533
        $surveyId = (int) $_GET['survey_id'];
534
        $action = Security::remove_XSS($_GET['action']);
535
        $course_id = api_get_course_int_id();
536
537
        // Database table definitions
538
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
539
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
540
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
541
        $questions = [];
542
543
        echo '<div class="actions">';
544
        echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?survey_id='.$surveyId.'&'.api_get_cidreq().'">'.
545
            Display::return_icon(
546
                'back.png',
547
                get_lang('BackTo').' '.get_lang('ReportingOverview'),
548
                '',
549
                ICON_SIZE_MEDIUM
550
            ).'</a>';
551
        echo '</div>';
552
553
        if ($survey_data['number_of_questions'] > 0) {
554
            $limitStatement = null;
555
            if (!$singlePage) {
556
                echo '<div id="question_report_questionnumbers" class="pagination">';
557
                if ($currentQuestion != 0) {
558
                    echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action.'&'
559
                        .api_get_cidreq().'&survey_id='.$surveyId.'&question='.($offset - 1).'">'
560
                        .get_lang('PreviousQuestion').'</a></li>';
561
                }
562
563
                for ($i = 1; $i <= $survey_data['number_of_questions']; $i++) {
564
                    if ($offset != $i - 1) {
565
                        echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action.'&'
566
                            .api_get_cidreq().'&survey_id='.$surveyId.'&question='.($i - 1).'">'.$i.'</a></li>';
567
                    } else {
568
                        echo '<li class="disabled"s><a href="#">'.$i.'</a></li>';
569
                    }
570
                }
571
                if ($currentQuestion < ($survey_data['number_of_questions'] - 1)) {
572
                    echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action.'&'
573
                        .api_get_cidreq().'&survey_id='.$surveyId.'&question='.($offset + 1).'">'
574
                        .get_lang('NextQuestion').'</li></a>';
575
                }
576
                echo '</ul>';
577
                echo '</div>';
578
                $limitStatement = " LIMIT $offset, 1";
579
            }
580
581
            // Getting the question information
582
            $sql = "SELECT * FROM $table_survey_question
583
			        WHERE
584
			            c_id = $course_id AND
585
                        survey_id='".$surveyId."' AND
586
                        type <>'pagebreak'                        
587
                    ORDER BY sort ASC
588
                    $limitStatement";
589
            $result = Database::query($sql);
590
            while ($row = Database::fetch_array($result)) {
591
                $questions[$row['question_id']] = $row;
592
            }
593
        }
594
        foreach ($questions as $question) {
595
            $chartData = [];
596
            $options = [];
597
            $questionId = (int) $question['question_id'];
598
            echo '<div class="title-question">';
599
            echo strip_tags(isset($question['survey_question']) ? $question['survey_question'] : null);
600
            echo '</div>';
601
602
            if ($question['type'] == 'score') {
603
                /** @todo This function should return the options as this is needed further in the code */
604
                $options = self::display_question_report_score($survey_data, $question, $offset);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $options is correct as self::display_question_r...ta, $question, $offset) targeting SurveyUtil::display_question_report_score() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
605
            } elseif ($question['type'] == 'open' || $question['type'] == 'comment') {
606
                /** @todo Also get the user who has answered this */
607
                $sql = "SELECT * FROM $table_survey_answer
608
                        WHERE
609
                            c_id = $course_id AND
610
                            survey_id='".$surveyId."' AND
611
                            question_id = '".$questionId."'";
612
                $result = Database::query($sql);
613
                while ($row = Database::fetch_array($result, 'ASSOC')) {
614
                    echo $row['option_id'].'<hr noshade="noshade" size="1" />';
615
                }
616
            } else {
617
                // Getting the options ORDER BY sort ASC
618
                $sql = "SELECT * FROM $table_survey_question_option
619
                        WHERE
620
                            c_id = $course_id AND
621
                            survey_id='".$surveyId."'
622
                            AND question_id = '".$questionId."'
623
                        ORDER BY sort ASC";
624
                $result = Database::query($sql);
625
                while ($row = Database::fetch_array($result, 'ASSOC')) {
626
                    $options[$row['question_option_id']] = $row;
627
                }
628
                // Getting the answers
629
                $sql = "SELECT *, count(answer_id) as total FROM $table_survey_answer
630
                        WHERE
631
                            c_id = $course_id AND
632
                            survey_id='".$surveyId."'
633
                            AND question_id = '".$questionId."'
634
                        GROUP BY option_id, value";
635
                $result = Database::query($sql);
636
                $number_of_answers = [];
637
                $data = [];
638
                while ($row = Database::fetch_array($result, 'ASSOC')) {
639
                    if (!isset($number_of_answers[$row['question_id']])) {
640
                        $number_of_answers[$row['question_id']] = 0;
641
                    }
642
                    $number_of_answers[$row['question_id']] += $row['total'];
643
                    $data[$row['option_id']] = $row;
644
                }
645
646
                foreach ($options as $option) {
647
                    $optionText = strip_tags($option['option_text']);
648
                    $optionText = html_entity_decode($optionText);
649
                    $votes = isset($data[$option['question_option_id']]['total']) ?
650
                        $data[$option['question_option_id']]['total'] : '0';
651
                    array_push($chartData, ['option' => $optionText, 'votes' => $votes]);
652
                }
653
                $chartContainerId = 'chartContainer'.$question['question_id'];
654
                echo '<div id="'.$chartContainerId.'" class="col-md-12">';
655
                echo self::drawChart($chartData, false, $chartContainerId);
656
657
                // displaying the table: headers
658
                echo '<table class="display-survey table">';
659
                echo '	<tr>';
660
                echo '		<th>&nbsp;</th>';
661
                echo '		<th>'.get_lang('AbsoluteTotal').'</th>';
662
                echo '		<th>'.get_lang('Percentage').'</th>';
663
                echo '		<th>'.get_lang('VisualRepresentation').'</th>';
664
                echo '	<tr>';
665
666
                // Displaying the table: the content
667
                if (is_array($options)) {
668
                    foreach ($options as $key => &$value) {
669
                        $absolute_number = null;
670
                        if (isset($data[$value['question_option_id']])) {
671
                            $absolute_number = $data[$value['question_option_id']]['total'];
672
                        }
673
                        if ($question['type'] == 'percentage' && empty($absolute_number)) {
674
                            continue;
675
                        }
676
                        $number_of_answers[$option['question_id']] = isset($number_of_answers[$option['question_id']])
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $option does not seem to be defined for all execution paths leading up to this point.
Loading history...
677
                            ? $number_of_answers[$option['question_id']]
678
                            : 0;
679
                        if ($number_of_answers[$option['question_id']] == 0) {
680
                            $answers_number = 0;
681
                        } else {
682
                            $answers_number = $absolute_number / $number_of_answers[$option['question_id']] * 100;
683
                        }
684
                        echo '	<tr>';
685
                        echo '		<td class="center">'.$value['option_text'].'</td>';
686
                        echo '		<td class="center">';
687
                        if ($absolute_number != 0) {
688
                            echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action
689
                                .'&survey_id='.$surveyId.'&question='.$offset.'&viewoption='
690
                                .$value['question_option_id'].'">'.$absolute_number.'</a>';
691
                        } else {
692
                            echo '0';
693
                        }
694
695
                        echo '      </td>';
696
                        echo '		<td class="center">'.round($answers_number, 2).' %</td>';
697
                        echo '		<td class="center">';
698
                        $size = $answers_number * 2;
699
                        if ($size > 0) {
700
                            echo '<div style="border:1px solid #264269; background-color:#aecaf4; height:10px; width:'
701
                                .$size.'px">&nbsp;</div>';
702
                        } else {
703
                            echo '<div style="text-align: left;">'.get_lang("NoDataAvailable").'</div>';
704
                        }
705
                        echo ' </td>';
706
                        echo ' </tr>';
707
                    }
708
                }
709
                // displaying the table: footer (totals)
710
                $optionResult = '';
711
                if (isset($option['question_id']) && isset($number_of_answers[$option['question_id']])) {
712
                    if ($number_of_answers[$option['question_id']] == 0) {
713
                        $optionResult = '0';
714
                    } else {
715
                        $optionResult = $number_of_answers[$option['question_id']];
716
                    }
717
                }
718
719
                // displaying the table: footer (totals)
720
                echo '	<tr>';
721
                echo '		<td class="total"><b>'.get_lang('Total').'</b></td>';
722
                echo '		<td class="total"><b>'.$optionResult.'</b></td>';
723
                echo '		<td class="total">&nbsp;</td>';
724
                echo '		<td class="total">&nbsp;</td>';
725
                echo '	</tr>';
726
                echo '</table>';
727
                echo '</div>';
728
            }
729
        }
730
731
        if (isset($_GET['viewoption'])) {
732
            echo '<div class="answered-people">';
733
            echo '<h4>'.get_lang('PeopleWhoAnswered').': '
734
                .strip_tags($options[Security::remove_XSS($_GET['viewoption'])]['option_text']).'</h4>';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $options seems to be defined by a foreach iteration on line 594. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
735
736
            if (is_numeric($_GET['value'])) {
737
                $sql_restriction = "AND value='".Database::escape_string($_GET['value'])."'";
738
            }
739
740
            $sql = "SELECT user FROM $table_survey_answer
741
                    WHERE
742
                        c_id = $course_id AND
743
                        option_id = '".Database::escape_string($_GET['viewoption'])."'
744
                        $sql_restriction";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sql_restriction does not seem to be defined for all execution paths leading up to this point.
Loading history...
745
            $result = Database::query($sql);
746
            echo '<ul>';
747
            while ($row = Database::fetch_array($result, 'ASSOC')) {
748
                $user_info = api_get_user_info($row['user']);
749
                echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action=userreport&survey_id='
750
                    .$surveyId.'&user='.$row['user'].'">'
751
                    .$user_info['complete_name_with_username']
752
                    .'</a></li>';
753
            }
754
            echo '</ul>';
755
            echo '</div>';
756
        }
757
    }
758
759
    /**
760
     * Display score data about a survey question.
761
     *
762
     * @param    array    Question info
763
     * @param    int    The offset of results shown
764
     */
765
    public static function display_question_report_score($survey_data, $question, $offset)
766
    {
767
        // Database table definitions
768
        $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : '';
769
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
770
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
771
        $course_id = api_get_course_int_id();
772
773
        // Getting the options
774
        $sql = "SELECT * FROM $table_survey_question_option
775
                WHERE
776
                    c_id = $course_id AND
777
                    survey_id='".intval($_GET['survey_id'])."' AND
778
                    question_id = '".intval($question['question_id'])."'
779
                ORDER BY sort ASC";
780
        $result = Database::query($sql);
781
        while ($row = Database::fetch_array($result)) {
782
            $options[$row['question_option_id']] = $row;
783
        }
784
785
        // Getting the answers
786
        $sql = "SELECT *, count(answer_id) as total 
787
                FROM $table_survey_answer
788
                WHERE
789
                   c_id = $course_id AND
790
                   survey_id='".intval($_GET['survey_id'])."' AND
791
                   question_id = '".Database::escape_string($question['question_id'])."'
792
                GROUP BY option_id, value";
793
        $result = Database::query($sql);
794
        $number_of_answers = 0;
795
        while ($row = Database::fetch_array($result)) {
796
            $number_of_answers += $row['total'];
797
            $data[$row['option_id']][$row['value']] = $row;
798
        }
799
800
        $chartData = [];
801
        foreach ($options as $option) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $options does not seem to be defined for all execution paths leading up to this point.
Loading history...
802
            $optionText = strip_tags($option['option_text']);
803
            $optionText = html_entity_decode($optionText);
804
            for ($i = 1; $i <= $question['max_value']; $i++) {
805
                $votes = $data[$option['question_option_id']][$i]['total'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $data does not seem to be defined for all execution paths leading up to this point.
Loading history...
806
                if (empty($votes)) {
807
                    $votes = '0';
808
                }
809
                array_push(
810
                    $chartData,
811
                    [
812
                        'serie' => $optionText,
813
                        'option' => $i,
814
                        'votes' => $votes,
815
                    ]
816
                );
817
            }
818
        }
819
        echo '<div id="chartContainer" class="col-md-12">';
820
        echo self::drawChart($chartData, true);
821
        echo '</div>';
822
823
        // Displaying the table: headers
824
        echo '<table class="data_table">';
825
        echo '	<tr>';
826
        echo '		<th>&nbsp;</th>';
827
        echo '		<th>'.get_lang('Score').'</th>';
828
        echo '		<th>'.get_lang('AbsoluteTotal').'</th>';
829
        echo '		<th>'.get_lang('Percentage').'</th>';
830
        echo '		<th>'.get_lang('VisualRepresentation').'</th>';
831
        echo '	<tr>';
832
        // Displaying the table: the content
833
        foreach ($options as $key => &$value) {
834
            for ($i = 1; $i <= $question['max_value']; $i++) {
835
                $absolute_number = $data[$value['question_option_id']][$i]['total'];
836
                echo '	<tr>';
837
                echo '		<td>'.$value['option_text'].'</td>';
838
                echo '		<td>'.$i.'</td>';
839
                echo '		<td><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action
840
                    .'&survey_id='.intval($_GET['survey_id']).'&question='.Security::remove_XSS($offset)
841
                    .'&viewoption='.$value['question_option_id'].'&value='.$i.'">'.$absolute_number.'</a></td>';
842
                echo '		<td>'.round($absolute_number / $number_of_answers * 100, 2).' %</td>';
843
                echo '		<td>';
844
                $size = ($absolute_number / $number_of_answers * 100 * 2);
845
                if ($size > 0) {
846
                    echo '<div style="border:1px solid #264269; background-color:#aecaf4; height:10px; width:'.$size.'px">&nbsp;</div>';
847
                }
848
                echo '		</td>';
849
                echo '	</tr>';
850
            }
851
        }
852
        // Displaying the table: footer (totals)
853
        echo '	<tr>';
854
        echo '		<td style="border-top:1px solid black"><b>'.get_lang('Total').'</b></td>';
855
        echo '		<td style="border-top:1px solid black">&nbsp;</td>';
856
        echo '		<td style="border-top:1px solid black"><b>'.$number_of_answers.'</b></td>';
857
        echo '		<td style="border-top:1px solid black">&nbsp;</td>';
858
        echo '		<td style="border-top:1px solid black">&nbsp;</td>';
859
        echo '	</tr>';
860
861
        echo '</table>';
862
    }
863
864
    /**
865
     * This functions displays the complete reporting.
866
     *
867
     * @return string HTML code
868
     *
869
     * @todo open questions are not in the complete report yet.
870
     *
871
     * @author Patrick Cool <[email protected]>, Ghent University
872
     *
873
     * @version February 2007
874
     */
875
    public static function display_complete_report($survey_data)
876
    {
877
        // Database table definitions
878
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
879
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
880
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
881
882
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
883
        $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : '';
884
885
        // Actions bar
886
        echo '<div class="actions">';
887
        echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?survey_id='.$surveyId.'&'.api_get_cidreq().'">'
888
            .Display::return_icon(
889
                'back.png',
890
                get_lang('BackTo').' '.get_lang('ReportingOverview'),
891
                [],
892
                ICON_SIZE_MEDIUM
893
            )
894
            .'</a>';
895
        echo '<a class="survey_export_link" href="javascript: void(0);" onclick="document.form1a.submit();">'
896
            .Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a>';
897
        echo '<a class="survey_export_link" href="javascript: void(0);" onclick="document.form1b.submit();">'
898
            .Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a>';
899
        echo '</div>';
900
901
        // The form
902
        echo '<form id="form1a" name="form1a" method="post" action="'.api_get_self().'?action='.$action.'&survey_id='
903
            .$surveyId.'&'.api_get_cidreq().'">';
904
        echo '<input type="hidden" name="export_report" value="export_report">';
905
        echo '<input type="hidden" name="export_format" value="csv">';
906
        echo '</form>';
907
        echo '<form id="form1b" name="form1b" method="post" action="'.api_get_self().'?action='.$action.'&survey_id='
908
            .$surveyId.'&'.api_get_cidreq().'">';
909
        echo '<input type="hidden" name="export_report" value="export_report">';
910
        echo '<input type="hidden" name="export_format" value="xls">';
911
        echo '</form>';
912
913
        echo '<form id="form2" name="form2" method="post" action="'.api_get_self().'?action='.$action.'&survey_id='
914
            .$surveyId.'&'.api_get_cidreq().'">';
915
916
        // The table
917
        echo '<br /><table class="data_table" border="1">';
918
        // Getting the number of options per question
919
        echo '	<tr>';
920
        echo '		<th>';
921
        if ((isset($_POST['submit_question_filter']) && $_POST['submit_question_filter']) ||
922
            (isset($_POST['export_report']) && $_POST['export_report'])
923
        ) {
924
            echo '<button class="cancel" type="submit" name="reset_question_filter" value="'
925
                .get_lang('ResetQuestionFilter').'">'.get_lang('ResetQuestionFilter').'</button>';
926
        }
927
        echo '<button class="save" type="submit" name="submit_question_filter" value="'.get_lang('SubmitQuestionFilter')
928
            .'">'.get_lang('SubmitQuestionFilter').'</button>';
929
        echo '</th>';
930
931
        $display_extra_user_fields = false;
932
        if (!(isset($_POST['submit_question_filter']) && $_POST['submit_question_filter'] ||
933
            isset($_POST['export_report']) && $_POST['export_report']) ||
934
            !empty($_POST['fields_filter'])
935
        ) {
936
            // Show user fields section with a big th colspan that spans over all fields
937
            $extra_user_fields = UserManager::get_extra_fields(
938
                0,
939
                0,
940
                5,
941
                'ASC',
942
                false,
943
                true
944
            );
945
            $num = count($extra_user_fields);
946
            if ($num > 0) {
947
                echo '<th '.($num > 0 ? ' colspan="'.$num.'"' : '').'>';
948
                echo '<label><input type="checkbox" name="fields_filter" value="1" checked="checked"/> ';
949
                echo get_lang('UserFields');
950
                echo '</label>';
951
                echo '</th>';
952
                $display_extra_user_fields = true;
953
            }
954
        }
955
956
        $course_id = api_get_course_int_id();
957
        $sql = "SELECT 
958
                  q.question_id, 
959
                  q.type, 
960
                  q.survey_question, 
961
                  count(o.question_option_id) as number_of_options
962
				FROM $table_survey_question q 
963
				LEFT JOIN $table_survey_question_option o
964
				ON q.question_id = o.question_id AND q.c_id = o.c_id
965
				WHERE 
966
				    q.survey_id = '".$surveyId."' AND
967
				    q.c_id = $course_id
968
				GROUP BY q.question_id
969
				ORDER BY q.sort ASC";
970
        $result = Database::query($sql);
971
        $questions = [];
972
        while ($row = Database::fetch_array($result)) {
973
            // We show the questions if
974
            // 1. there is no question filter and the export button has not been clicked
975
            // 2. there is a quesiton filter but the question is selected for display
976
            if (!(isset($_POST['submit_question_filter']) && $_POST['submit_question_filter']) ||
977
                (is_array($_POST['questions_filter']) && in_array($row['question_id'], $_POST['questions_filter']))
978
            ) {
979
                // We do not show comment and pagebreak question types
980
                if ($row['type'] != 'pagebreak') {
981
                    echo ' <th';
982
                    if ($row['number_of_options'] > 0 && $row['type'] != 'percentage') {
983
                        echo ' colspan="'.$row['number_of_options'].'"';
984
                    }
985
                    echo '>';
986
                    echo '<label><input type="checkbox" name="questions_filter[]" value="'.$row['question_id']
987
                        .'" checked="checked"/> ';
988
                    echo $row['survey_question'];
989
                    echo '</label>';
990
                    echo '</th>';
991
                }
992
                // No column at all if it's not a question
993
            }
994
            $questions[$row['question_id']] = $row;
995
        }
996
        echo '	</tr>';
997
        // Getting all the questions and options
998
        echo '	<tr>';
999
        echo '		<th>&nbsp;</th>'; // the user column
1000
1001
        if (!(isset($_POST['submit_question_filter']) && $_POST['submit_question_filter'] ||
1002
            isset($_POST['export_report']) && $_POST['export_report']) || !empty($_POST['fields_filter'])
1003
        ) {
1004
            //show the fields names for user fields
1005
            foreach ($extra_user_fields as &$field) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $extra_user_fields does not seem to be defined for all execution paths leading up to this point.
Loading history...
1006
                echo '<th>'.$field[3].'</th>';
1007
            }
1008
        }
1009
1010
        // cells with option (none for open question)
1011
        $sql = "SELECT 	
1012
                    sq.question_id, 
1013
                    sq.survey_id,
1014
                    sq.survey_question, 
1015
                    sq.display,
1016
                    sq.sort, 
1017
                    sq.type, 
1018
                    sqo.question_option_id,
1019
                    sqo.option_text, 
1020
                    sqo.sort as option_sort
1021
				FROM $table_survey_question sq
1022
				LEFT JOIN $table_survey_question_option sqo
1023
				ON sq.question_id = sqo.question_id AND sq.c_id = sqo.c_id
1024
				WHERE
1025
				    sq.survey_id = '".$surveyId."' AND
1026
                    sq.c_id = $course_id
1027
				ORDER BY sq.sort ASC, sqo.sort ASC";
1028
        $result = Database::query($sql);
1029
1030
        $display_percentage_header = 1;
1031
        $possible_answers = [];
1032
        // in order to display only once the cell option (and not 100 times)
1033
        while ($row = Database::fetch_array($result)) {
1034
            // We show the options if
1035
            // 1. there is no question filter and the export button has not been clicked
1036
            // 2. there is a question filter but the question is selected for display
1037
            if (!(isset($_POST['submit_question_filter']) && $_POST['submit_question_filter']) ||
1038
                (is_array($_POST['questions_filter']) && in_array($row['question_id'], $_POST['questions_filter']))
1039
            ) {
1040
                // <hub> modif 05-05-2010
1041
                if ($row['type'] == 'open' || $row['type'] == 'comment') {
1042
                    echo '<th>&nbsp;-&nbsp;</th>';
1043
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1044
                    $display_percentage_header = 1;
1045
                } elseif ($row['type'] == 'percentage' && $display_percentage_header) {
1046
                    echo '<th>&nbsp;%&nbsp;</th>';
1047
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1048
                    $display_percentage_header = 0;
1049
                } elseif ($row['type'] == 'percentage') {
1050
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1051
                } elseif ($row['type'] != 'pagebreak' && $row['type'] != 'percentage') {
1052
                    echo '<th>';
1053
                    echo $row['option_text'];
1054
                    echo '</th>';
1055
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1056
                    $display_percentage_header = 1;
1057
                }
1058
            }
1059
        }
1060
1061
        echo '	</tr>';
1062
1063
        // Getting all the answers of the users
1064
        $old_user = '';
1065
        $answers_of_user = [];
1066
        $sql = "SELECT * FROM $table_survey_answer
1067
                WHERE
1068
                    c_id = $course_id AND
1069
                    survey_id='".$surveyId."'
1070
                ORDER BY answer_id, user ASC";
1071
        $result = Database::query($sql);
1072
        $i = 1;
1073
        while ($row = Database::fetch_array($result)) {
1074
            if ($old_user != $row['user'] && $old_user != '') {
1075
                $userParam = $old_user;
1076
                if ($survey_data['anonymous'] != 0) {
1077
                    $userParam = $i;
1078
                    $i++;
1079
                }
1080
                self::display_complete_report_row(
1081
                    $survey_data,
1082
                    $possible_answers,
1083
                    $answers_of_user,
1084
                    $userParam,
1085
                    $questions,
1086
                    $display_extra_user_fields
1087
                );
1088
                $answers_of_user = [];
1089
            }
1090
            if (isset($questions[$row['question_id']]) &&
1091
                $questions[$row['question_id']]['type'] != 'open' &&
1092
                $questions[$row['question_id']]['type'] != 'comment'
1093
            ) {
1094
                $answers_of_user[$row['question_id']][$row['option_id']] = $row;
1095
            } else {
1096
                $answers_of_user[$row['question_id']][0] = $row;
1097
            }
1098
            $old_user = $row['user'];
1099
        }
1100
        $userParam = $old_user;
1101
        if ($survey_data['anonymous'] != 0) {
1102
            $userParam = $i;
1103
            $i++;
1104
        }
1105
        self::display_complete_report_row(
1106
            $survey_data,
1107
            $possible_answers,
1108
            $answers_of_user,
1109
            $userParam,
1110
            $questions,
1111
            $display_extra_user_fields
1112
        );
1113
        // This is to display the last user
1114
        echo '</table>';
1115
        echo '</form>';
1116
    }
1117
1118
    /**
1119
     * This function displays a row (= a user and his/her answers) in the table of the complete report.
1120
     *
1121
     * @param array $survey_data
1122
     * @param array    Possible options
1123
     * @param array    User answers
1124
     * @param mixed    User ID or user details string
1125
     * @param bool  Whether to show extra user fields or not
1126
     *
1127
     * @author Patrick Cool <[email protected]>, Ghent University
1128
     *
1129
     * @version February 2007 - Updated March 2008
1130
     */
1131
    public static function display_complete_report_row(
1132
        $survey_data,
1133
        $possible_options,
1134
        $answers_of_user,
1135
        $user,
1136
        $questions,
1137
        $display_extra_user_fields = false
1138
    ) {
1139
        $user = Security::remove_XSS($user);
1140
        echo '<tr>';
1141
        if ($survey_data['anonymous'] == 0) {
1142
            if (intval($user) !== 0) {
1143
                $userInfo = api_get_user_info($user);
1144
                if (!empty($userInfo)) {
1145
                    $user_displayed = $userInfo['complete_name_with_username'];
1146
                } else {
1147
                    $user_displayed = '-';
1148
                }
1149
                echo '<th>
1150
                    <a href="'.api_get_self().'?action=userreport&survey_id='.intval($_GET['survey_id']).'&user='.$user.'">'
1151
                    .$user_displayed.'</a>
1152
                    </th>'; // the user column
1153
            } else {
1154
                echo '<th>'.$user.'</th>'; // the user column
1155
            }
1156
        } else {
1157
            echo '<th>'.get_lang('Anonymous').' '.$user.'</th>';
1158
        }
1159
1160
        if ($display_extra_user_fields) {
1161
            // Show user fields data, if any, for this user
1162
            $user_fields_values = UserManager::get_extra_user_data(
1163
                $user,
1164
                false,
1165
                false,
1166
                false,
1167
                true
1168
            );
1169
            foreach ($user_fields_values as &$value) {
1170
                echo '<td align="center">'.$value.'</td>';
1171
            }
1172
        }
1173
1174
        if (is_array($possible_options)) {
1175
            foreach ($possible_options as $question_id => &$possible_option) {
1176
                if ($questions[$question_id]['type'] == 'open' || $questions[$question_id]['type'] == 'comment') {
1177
                    echo '<td align="center">';
1178
                    echo $answers_of_user[$question_id]['0']['option_id'];
1179
                    echo '</td>';
1180
                } else {
1181
                    foreach ($possible_option as $option_id => &$value) {
1182
                        if ($questions[$question_id]['type'] == 'percentage') {
1183
                            if (!empty($answers_of_user[$question_id][$option_id])) {
1184
                                echo "<td align='center'>";
1185
                                echo $answers_of_user[$question_id][$option_id]['value'];
1186
                                echo "</td>";
1187
                            }
1188
                        } else {
1189
                            echo '<td align="center">';
1190
                            if (!empty($answers_of_user[$question_id][$option_id])) {
1191
                                if ($answers_of_user[$question_id][$option_id]['value'] != 0) {
1192
                                    echo $answers_of_user[$question_id][$option_id]['value'];
1193
                                } else {
1194
                                    echo 'v';
1195
                                }
1196
                            }
1197
                        }
1198
                    }
1199
                }
1200
            }
1201
        }
1202
        echo '</tr>';
1203
    }
1204
1205
    /**
1206
     * Quite similar to display_complete_report(), returns an HTML string
1207
     * that can be used in a csv file.
1208
     *
1209
     * @todo consider merging this function with display_complete_report
1210
     *
1211
     * @return string The contents of a csv file
1212
     *
1213
     * @author Patrick Cool <[email protected]>, Ghent University
1214
     *
1215
     * @version February 2007
1216
     */
1217
    public static function export_complete_report($survey_data, $user_id = 0)
1218
    {
1219
        // Database table definitions
1220
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1221
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1222
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1223
1224
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
1225
1226
        if (empty($surveyId)) {
1227
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
1228
        }
1229
1230
        // The first column
1231
        $return = ';';
1232
1233
        // Show extra fields blank space (enough for extra fields on next line)
1234
        $extra_user_fields = UserManager::get_extra_fields(
1235
            0,
1236
            0,
1237
            5,
1238
            'ASC',
1239
            false,
1240
            true
1241
        );
1242
1243
        $num = count($extra_user_fields);
1244
        $return .= str_repeat(';', $num);
1245
        $course_id = api_get_course_int_id();
1246
1247
        $sql = "SELECT
1248
                    questions.question_id,
1249
                    questions.type,
1250
                    questions.survey_question,
1251
                    count(options.question_option_id) as number_of_options
1252
				FROM $table_survey_question questions
1253
                LEFT JOIN $table_survey_question_option options
1254
				ON questions.question_id = options.question_id AND options.c_id = questions.c_id
1255
				WHERE
1256
				    questions.survey_id = '".$surveyId."' AND
1257
                    questions.c_id = $course_id
1258
				GROUP BY questions.question_id
1259
				ORDER BY questions.sort ASC";
1260
        $result = Database::query($sql);
1261
        while ($row = Database::fetch_array($result)) {
1262
            // We show the questions if
1263
            // 1. there is no question filter and the export button has not been clicked
1264
            // 2. there is a quesiton filter but the question is selected for display
1265
            if (!(isset($_POST['submit_question_filter'])) ||
1266
                (isset($_POST['submit_question_filter']) &&
1267
                    is_array($_POST['questions_filter']) &&
1268
                    in_array($row['question_id'], $_POST['questions_filter']))
1269
            ) {
1270
                // We do not show comment and pagebreak question types
1271
                if ($row['type'] != 'pagebreak') {
1272
                    if ($row['number_of_options'] == 0 && ($row['type'] == 'open' || $row['type'] == 'comment')) {
1273
                        $return .= str_replace(
1274
                            "\r\n",
1275
                            '  ',
1276
                            api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)
1277
                        )
1278
                        .';';
1279
                    } else {
1280
                        for ($ii = 0; $ii < $row['number_of_options']; $ii++) {
1281
                            $return .= str_replace(
1282
                                "\r\n",
1283
                                '  ',
1284
                                api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)
1285
                            )
1286
                            .';';
1287
                        }
1288
                    }
1289
                }
1290
            }
1291
        }
1292
1293
        $return .= "\n";
1294
        // Getting all the questions and options
1295
        $return .= ';';
1296
        // Show the fields names for user fields
1297
        if (!empty($extra_user_fields)) {
1298
            foreach ($extra_user_fields as &$field) {
1299
                $return .= '"'
1300
                    .str_replace(
1301
                        "\r\n",
1302
                        '  ',
1303
                        api_html_entity_decode(strip_tags($field[3]), ENT_QUOTES)
1304
                    )
1305
                    .'";';
1306
            }
1307
        }
1308
1309
        $sql = "SELECT
1310
		            survey_question.question_id,
1311
		            survey_question.survey_id,
1312
		            survey_question.survey_question,
1313
		            survey_question.display,
1314
		            survey_question.sort,
1315
		            survey_question.type,
1316
                    survey_question_option.question_option_id,
1317
                    survey_question_option.option_text,
1318
                    survey_question_option.sort as option_sort
1319
				FROM $table_survey_question survey_question
1320
				LEFT JOIN $table_survey_question_option survey_question_option
1321
				ON
1322
				    survey_question.question_id = survey_question_option.question_id AND
1323
				    survey_question_option.c_id = survey_question.c_id
1324
				WHERE
1325
				    survey_question.survey_id = '".$surveyId."' AND
1326
				    survey_question.c_id = $course_id
1327
				ORDER BY survey_question.sort ASC, survey_question_option.sort ASC";
1328
        $result = Database::query($sql);
1329
        $possible_answers = [];
1330
        $possible_answers_type = [];
1331
        while ($row = Database::fetch_array($result)) {
1332
            // We show the options if
1333
            // 1. there is no question filter and the export button has not been clicked
1334
            // 2. there is a question filter but the question is selected for display
1335
            if (!(isset($_POST['submit_question_filter'])) || (
1336
                is_array($_POST['questions_filter']) &&
1337
                in_array($row['question_id'], $_POST['questions_filter'])
1338
            )
1339
            ) {
1340
                // We do not show comment and pagebreak question types
1341
                if ($row['type'] != 'pagebreak') {
1342
                    $row['option_text'] = str_replace(["\r", "\n"], ['', ''], $row['option_text']);
1343
                    $return .= api_html_entity_decode(strip_tags($row['option_text']), ENT_QUOTES).';';
1344
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1345
                    $possible_answers_type[$row['question_id']] = $row['type'];
1346
                }
1347
            }
1348
        }
1349
        $return .= "\n";
1350
1351
        // Getting all the answers of the users
1352
        $old_user = '';
1353
        $answers_of_user = [];
1354
        $sql = "SELECT * FROM $table_survey_answer
1355
		        WHERE c_id = $course_id AND survey_id='".$surveyId."'";
1356
        if ($user_id != 0) {
1357
            $sql .= "AND user='".Database::escape_string($user_id)."' ";
1358
        }
1359
        $sql .= "ORDER BY user ASC";
1360
1361
        $open_question_iterator = 1;
1362
        $result = Database::query($sql);
1363
        while ($row = Database::fetch_array($result)) {
1364
            if ($old_user != $row['user'] && $old_user != '') {
1365
                $return .= self::export_complete_report_row(
1366
                    $survey_data,
1367
                    $possible_answers,
1368
                    $answers_of_user,
1369
                    $old_user,
1370
                    true
1371
                );
1372
                $answers_of_user = [];
1373
            }
1374
            if ($possible_answers_type[$row['question_id']] == 'open' ||
1375
                $possible_answers_type[$row['question_id']] == 'comment'
1376
            ) {
1377
                $temp_id = 'open'.$open_question_iterator;
1378
                $answers_of_user[$row['question_id']][$temp_id] = $row;
1379
                $open_question_iterator++;
1380
            } else {
1381
                $answers_of_user[$row['question_id']][$row['option_id']] = $row;
1382
            }
1383
            $old_user = $row['user'];
1384
        }
1385
        // This is to display the last user
1386
        $return .= self::export_complete_report_row(
1387
            $survey_data,
1388
            $possible_answers,
1389
            $answers_of_user,
1390
            $old_user,
1391
            true
1392
        );
1393
1394
        return $return;
1395
    }
1396
1397
    /**
1398
     * Add a line to the csv file.
1399
     *
1400
     * @param array Possible answers
1401
     * @param array User's answers
0 ignored issues
show
Documentation Bug introduced by
The doc comment User's at position 0 could not be parsed: Unknown type name 'User's' at position 0 in User's.
Loading history...
1402
     * @param mixed User ID or user details as string - Used as a string in the result string
1403
     * @param bool Whether to display user fields or not
1404
     *
1405
     * @return string One line of the csv file
1406
     *
1407
     * @author Patrick Cool <[email protected]>, Ghent University
1408
     *
1409
     * @version February 2007
1410
     */
1411
    public static function export_complete_report_row(
1412
        $survey_data,
1413
        $possible_options,
1414
        $answers_of_user,
1415
        $user,
1416
        $display_extra_user_fields = false
1417
    ) {
1418
        $return = '';
1419
        if ($survey_data['anonymous'] == 0) {
1420
            if (intval($user) !== 0) {
1421
                $userInfo = api_get_user_info($user);
1422
                if (!empty($userInfo)) {
1423
                    $user_displayed = $userInfo['complete_name_with_username'];
1424
                } else {
1425
                    $user_displayed = '-';
1426
                }
1427
                $return .= $user_displayed.';';
1428
            } else {
1429
                $return .= $user.';';
1430
            }
1431
        } else {
1432
            $return .= '-;'; // The user column
1433
        }
1434
1435
        if ($display_extra_user_fields) {
1436
            // Show user fields data, if any, for this user
1437
            $user_fields_values = UserManager::get_extra_user_data(
1438
                $user,
1439
                false,
1440
                false,
1441
                false,
1442
                true
1443
            );
1444
            foreach ($user_fields_values as &$value) {
1445
                $return .= '"'.str_replace('"', '""', api_html_entity_decode(strip_tags($value), ENT_QUOTES)).'";';
1446
            }
1447
        }
1448
1449
        if (is_array($possible_options)) {
1450
            foreach ($possible_options as $question_id => $possible_option) {
1451
                if (is_array($possible_option) && count($possible_option) > 0) {
1452
                    foreach ($possible_option as $option_id => &$value) {
1453
                        $my_answer_of_user = !isset($answers_of_user[$question_id]) || isset($answers_of_user[$question_id]) && $answers_of_user[$question_id] == null ? [] : $answers_of_user[$question_id];
1454
                        $key = array_keys($my_answer_of_user);
1455
                        if (isset($key[0]) && substr($key[0], 0, 4) == 'open') {
1456
                            $return .= '"'.
1457
                                str_replace(
1458
                                    '"',
1459
                                    '""',
1460
                                    api_html_entity_decode(
1461
                                        strip_tags(
1462
                                            $answers_of_user[$question_id][$key[0]]['option_id']
1463
                                        ),
1464
                                        ENT_QUOTES
1465
                                    )
1466
                                ).
1467
                                '"';
1468
                        } elseif (!empty($answers_of_user[$question_id][$option_id])) {
1469
                            //$return .= 'v';
1470
                            if ($answers_of_user[$question_id][$option_id]['value'] != 0) {
1471
                                $return .= $answers_of_user[$question_id][$option_id]['value'];
1472
                            } else {
1473
                                $return .= 'v';
1474
                            }
1475
                        }
1476
                        $return .= ';';
1477
                    }
1478
                }
1479
            }
1480
        }
1481
        $return .= "\n";
1482
1483
        return $return;
1484
    }
1485
1486
    /**
1487
     * Quite similar to display_complete_report(), returns an HTML string
1488
     * that can be used in a csv file.
1489
     *
1490
     * @todo consider merging this function with display_complete_report
1491
     *
1492
     * @return string The contents of a csv file
1493
     *
1494
     * @author Patrick Cool <[email protected]>, Ghent University
1495
     *
1496
     * @version February 2007
1497
     */
1498
    public static function export_complete_report_xls($survey_data, $filename, $user_id = 0)
1499
    {
1500
        $course_id = api_get_course_int_id();
1501
        $user_id = (int) $user_id;
1502
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
1503
1504
        if (empty($course_id) || empty($surveyId)) {
1505
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
1506
        }
1507
1508
        // Show extra fields blank space (enough for extra fields on next line)
1509
        // Show user fields section with a big th colspan that spans over all fields
1510
        $extra_user_fields = UserManager::get_extra_fields(
1511
            0,
1512
            0,
1513
            5,
1514
            'ASC',
1515
            false,
1516
            true
1517
        );
1518
        $list = [];
1519
        $num = count($extra_user_fields);
1520
        for ($i = 0; $i < $num; $i++) {
1521
            $list[0][] = '';
1522
        }
1523
1524
        $display_extra_user_fields = true;
1525
1526
        // Database table definitions
1527
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1528
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1529
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1530
1531
        // First line (questions)
1532
        $sql = "SELECT
1533
                    questions.question_id,
1534
                    questions.type,
1535
                    questions.survey_question,
1536
                    count(options.question_option_id) as number_of_options
1537
				FROM $table_survey_question questions
1538
				LEFT JOIN $table_survey_question_option options
1539
                ON questions.question_id = options.question_id AND options.c_id = questions.c_id
1540
				WHERE
1541
				    questions.survey_id = $surveyId AND
1542
				    questions.c_id = $course_id
1543
				GROUP BY questions.question_id
1544
				ORDER BY questions.sort ASC";
1545
        $result = Database::query($sql);
1546
        $line = 1;
1547
        $column = 1;
1548
        while ($row = Database::fetch_array($result)) {
1549
            // We show the questions if
1550
            // 1. there is no question filter and the export button has not been clicked
1551
            // 2. there is a quesiton filter but the question is selected for display
1552
            if (!(isset($_POST['submit_question_filter'])) ||
1553
                (isset($_POST['submit_question_filter']) && is_array($_POST['questions_filter']) &&
1554
                in_array($row['question_id'], $_POST['questions_filter']))
1555
            ) {
1556
                // We do not show comment and pagebreak question types
1557
                if ($row['type'] != 'pagebreak') {
1558
                    if ($row['number_of_options'] == 0 && ($row['type'] == 'open' || $row['type'] == 'comment')) {
1559
                        $list[$line][$column] = api_html_entity_decode(
1560
                            strip_tags($row['survey_question']),
1561
                            ENT_QUOTES
1562
                        );
1563
                        $column++;
1564
                    } else {
1565
                        for ($ii = 0; $ii < $row['number_of_options']; $ii++) {
1566
                            $list[$line][$column] = api_html_entity_decode(
1567
                                strip_tags($row['survey_question']),
1568
                                ENT_QUOTES
1569
                            );
1570
                            $column++;
1571
                        }
1572
                    }
1573
                }
1574
            }
1575
        }
1576
1577
        $line++;
1578
        $column = 1;
1579
        // Show extra field values
1580
        if ($display_extra_user_fields) {
1581
            // Show the fields names for user fields
1582
            foreach ($extra_user_fields as &$field) {
1583
                $list[$line][$column] = api_html_entity_decode(strip_tags($field[3]), ENT_QUOTES);
1584
                $column++;
1585
            }
1586
        }
1587
1588
        // Getting all the questions and options (second line)
1589
        $sql = "SELECT
1590
                    survey_question.question_id, 
1591
                    survey_question.survey_id, 
1592
                    survey_question.survey_question, 
1593
                    survey_question.display, 
1594
                    survey_question.sort, 
1595
                    survey_question.type,
1596
                    survey_question_option.question_option_id, 
1597
                    survey_question_option.option_text, 
1598
                    survey_question_option.sort as option_sort
1599
				FROM $table_survey_question survey_question
1600
				LEFT JOIN $table_survey_question_option survey_question_option
1601
				ON 
1602
				    survey_question.question_id = survey_question_option.question_id AND 
1603
				    survey_question_option.c_id = survey_question.c_id
1604
				WHERE 
1605
				    survey_question.survey_id = $surveyId AND
1606
				    survey_question.c_id = $course_id
1607
				ORDER BY survey_question.sort ASC, survey_question_option.sort ASC";
1608
        $result = Database::query($sql);
1609
        $possible_answers = [];
1610
        $possible_answers_type = [];
1611
        while ($row = Database::fetch_array($result)) {
1612
            // We show the options if
1613
            // 1. there is no question filter and the export button has not been clicked
1614
            // 2. there is a quesiton filter but the question is selected for display
1615
            if (!isset($_POST['submit_question_filter']) ||
1616
                (isset($_POST['questions_filter']) && is_array($_POST['questions_filter']) &&
1617
                in_array($row['question_id'], $_POST['questions_filter']))
1618
            ) {
1619
                // We do not show comment and pagebreak question types
1620
                if ($row['type'] != 'pagebreak') {
1621
                    $list[$line][$column] = api_html_entity_decode(
1622
                        strip_tags($row['option_text']),
1623
                        ENT_QUOTES
1624
                    );
1625
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1626
                    $possible_answers_type[$row['question_id']] = $row['type'];
1627
                    $column++;
1628
                }
1629
            }
1630
        }
1631
1632
        // Getting all the answers of the users
1633
        $line++;
1634
        $column = 0;
1635
        $old_user = '';
1636
        $answers_of_user = [];
1637
        $sql = "SELECT * FROM $table_survey_answer
1638
                WHERE c_id = $course_id AND survey_id = $surveyId";
1639
        if ($user_id != 0) {
1640
            $sql .= " AND user='".$user_id."' ";
1641
        }
1642
        $sql .= " ORDER BY user ASC";
1643
1644
        $open_question_iterator = 1;
1645
        $result = Database::query($sql);
1646
        while ($row = Database::fetch_array($result)) {
1647
            if ($old_user != $row['user'] && $old_user != '') {
1648
                $return = self::export_complete_report_row_xls(
1649
                    $survey_data,
1650
                    $possible_answers,
1651
                    $answers_of_user,
1652
                    $old_user,
1653
                    true
1654
                );
1655
                foreach ($return as $elem) {
0 ignored issues
show
Bug introduced by
The expression $return of type string is not traversable.
Loading history...
1656
                    $list[$line][$column] = $elem;
1657
                    $column++;
1658
                }
1659
                $answers_of_user = [];
1660
                $line++;
1661
                $column = 0;
1662
            }
1663
            if ($possible_answers_type[$row['question_id']] == 'open' || $possible_answers_type[$row['question_id']] == 'comment') {
1664
                $temp_id = 'open'.$open_question_iterator;
1665
                $answers_of_user[$row['question_id']][$temp_id] = $row;
1666
                $open_question_iterator++;
1667
            } else {
1668
                $answers_of_user[$row['question_id']][$row['option_id']] = $row;
1669
            }
1670
            $old_user = $row['user'];
1671
        }
1672
1673
        $return = self::export_complete_report_row_xls(
1674
            $survey_data,
1675
            $possible_answers,
1676
            $answers_of_user,
1677
            $old_user,
1678
            true
1679
        );
1680
1681
        // this is to display the last user
1682
        foreach ($return as $elem) {
0 ignored issues
show
Bug introduced by
The expression $return of type string is not traversable.
Loading history...
1683
            $list[$line][$column] = $elem;
1684
            $column++;
1685
        }
1686
1687
        Export::arrayToXls($list, $filename);
1688
1689
        return null;
1690
    }
1691
1692
    /**
1693
     * Add a line to the csv file.
1694
     *
1695
     * @param array Possible answers
1696
     * @param array User's answers
0 ignored issues
show
Documentation Bug introduced by
The doc comment User's at position 0 could not be parsed: Unknown type name 'User's' at position 0 in User's.
Loading history...
1697
     * @param mixed User ID or user details as string - Used as a string in the result string
1698
     * @param bool Whether to display user fields or not
1699
     *
1700
     * @return string One line of the csv file
1701
     */
1702
    public static function export_complete_report_row_xls(
1703
        $survey_data,
1704
        $possible_options,
1705
        $answers_of_user,
1706
        $user,
1707
        $display_extra_user_fields = false
1708
    ) {
1709
        $return = [];
1710
        if ($survey_data['anonymous'] == 0) {
1711
            if (intval($user) !== 0) {
1712
                $userInfo = api_get_user_info($user);
1713
                if ($userInfo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $userInfo 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...
1714
                    $user_displayed = $userInfo['complete_name_with_username'];
1715
                } else {
1716
                    $user_displayed = '-';
1717
                }
1718
                $return[] = $user_displayed;
1719
            } else {
1720
                $return[] = $user;
1721
            }
1722
        } else {
1723
            $return[] = '-'; // The user column
1724
        }
1725
1726
        if ($display_extra_user_fields) {
1727
            //show user fields data, if any, for this user
1728
            $user_fields_values = UserManager::get_extra_user_data(
1729
                intval($user),
1730
                false,
1731
                false,
1732
                false,
1733
                true
1734
            );
1735
            foreach ($user_fields_values as $value) {
1736
                $return[] = api_html_entity_decode(strip_tags($value), ENT_QUOTES);
1737
            }
1738
        }
1739
1740
        if (is_array($possible_options)) {
1741
            foreach ($possible_options as $question_id => &$possible_option) {
1742
                if (is_array($possible_option) && count($possible_option) > 0) {
1743
                    foreach ($possible_option as $option_id => &$value) {
1744
                        $my_answers_of_user = isset($answers_of_user[$question_id])
1745
                            ? $answers_of_user[$question_id]
1746
                            : [];
1747
                        $key = array_keys($my_answers_of_user);
1748
                        if (isset($key[0]) && substr($key[0], 0, 4) == 'open') {
1749
                            $return[] = api_html_entity_decode(
1750
                                strip_tags($answers_of_user[$question_id][$key[0]]['option_id']),
1751
                                ENT_QUOTES
1752
                            );
1753
                        } elseif (!empty($answers_of_user[$question_id][$option_id])) {
1754
                            if ($answers_of_user[$question_id][$option_id]['value'] != 0) {
1755
                                $return[] = $answers_of_user[$question_id][$option_id]['value'];
1756
                            } else {
1757
                                $return[] = 'v';
1758
                            }
1759
                        } else {
1760
                            $return[] = '';
1761
                        }
1762
                    }
1763
                }
1764
            }
1765
        }
1766
1767
        return $return;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $return returns the type array|string[] which is incompatible with the documented return type string.
Loading history...
1768
    }
1769
1770
    /**
1771
     * This function displays the comparative report which
1772
     * allows you to compare two questions
1773
     * A comparative report creates a table where one question
1774
     * is on the x axis and a second question is on the y axis.
1775
     * In the intersection is the number of people who have
1776
     * answered positive on both options.
1777
     *
1778
     * @return string HTML code
1779
     *
1780
     * @author Patrick Cool <[email protected]>, Ghent University
1781
     *
1782
     * @version February 2007
1783
     */
1784
    public static function display_comparative_report()
1785
    {
1786
        // Allowed question types for comparative report
1787
        $allowed_question_types = [
1788
            'yesno',
1789
            'multiplechoice',
1790
            'multipleresponse',
1791
            'dropdown',
1792
            'percentage',
1793
            'score',
1794
        ];
1795
1796
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
1797
1798
        // Getting all the questions
1799
        $questions = SurveyManager::get_questions($surveyId);
1800
1801
        // Actions bar
1802
        echo '<div class="actions">';
1803
        echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?survey_id='.$surveyId.'&'.api_get_cidreq()
1804
            .'">'
1805
            .Display::return_icon(
1806
                'back.png',
1807
                get_lang('BackTo').' '.get_lang('ReportingOverview'),
1808
                [],
1809
                ICON_SIZE_MEDIUM
1810
            )
1811
            .'</a>';
1812
        echo '</div>';
1813
1814
        // Displaying an information message that only the questions with predefined answers can be used in a comparative report
1815
        echo Display::return_message(get_lang('OnlyQuestionsWithPredefinedAnswers'), 'normal', false);
1816
1817
        $xAxis = isset($_GET['xaxis']) ? Security::remove_XSS($_GET['xaxis']) : '';
1818
        $yAxis = isset($_GET['yaxis']) ? Security::remove_XSS($_GET['yaxis']) : '';
1819
1820
        $url = api_get_self().'?'.api_get_cidreq().'&action='.Security::remove_XSS($_GET['action'])
1821
            .'&survey_id='.$surveyId.'&xaxis='.$xAxis.'&y='.$yAxis;
1822
1823
        $form = new FormValidator('compare', 'get', $url);
1824
        $form->addHidden('action', Security::remove_XSS($_GET['action']));
1825
        $form->addHidden('survey_id', $surveyId);
1826
        $optionsX = ['----'];
1827
        $optionsY = ['----'];
1828
        $defaults = [];
1829
        foreach ($questions as $key => &$question) {
1830
            if (is_array($allowed_question_types)) {
1831
                if (in_array($question['type'], $allowed_question_types)) {
1832
                    if (isset($_GET['xaxis']) && $_GET['xaxis'] == $question['question_id']) {
1833
                        $defaults['xaxis'] = $question['question_id'];
1834
                    }
1835
1836
                    if (isset($_GET['yaxis']) && $_GET['yaxis'] == $question['question_id']) {
1837
                        $defaults['yaxis'] = $question['question_id'];
1838
                    }
1839
1840
                    $optionsX[$question['question_id']] = api_substr(strip_tags($question['question']), 0, 50);
1841
                    $optionsY[$question['question_id']] = api_substr(strip_tags($question['question']), 0, 50);
1842
                }
1843
            }
1844
        }
1845
1846
        $form->addSelect('xaxis', get_lang('SelectXAxis'), $optionsX);
1847
        $form->addSelect('yaxis', get_lang('SelectYAxis'), $optionsY);
1848
1849
        $form->addButtonSearch(get_lang('CompareQuestions'));
1850
        $form->setDefaults($defaults);
1851
        $form->display();
1852
1853
        // Getting all the information of the x axis
1854
        if (is_numeric($xAxis)) {
1855
            $question_x = SurveyManager::get_question($xAxis);
1856
        }
1857
1858
        // Getting all the information of the y axis
1859
        if (is_numeric($yAxis)) {
1860
            $question_y = SurveyManager::get_question($yAxis);
1861
        }
1862
1863
        if (is_numeric($xAxis) && is_numeric($yAxis)) {
1864
            // Getting the answers of the two questions
1865
            $answers_x = self::get_answers_of_question_by_user($surveyId, $xAxis);
1866
            $answers_y = self::get_answers_of_question_by_user($surveyId, $yAxis);
1867
1868
            // Displaying the table
1869
            $tableHtml = '<table border="1" class="data_table">';
1870
            $xOptions = [];
1871
            // The header
1872
            $tableHtml .= '<tr>';
1873
            for ($ii = 0; $ii <= count($question_x['answers']); $ii++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Comprehensibility Best Practice introduced by
The variable $question_x does not seem to be defined for all execution paths leading up to this point.
Loading history...
1874
                if ($ii == 0) {
1875
                    $tableHtml .= '<th>&nbsp;</th>';
1876
                } else {
1877
                    if ($question_x['type'] == 'score') {
1878
                        for ($x = 1; $x <= $question_x['maximum_score']; $x++) {
1879
                            $tableHtml .= '<th>'.$question_x['answers'][($ii - 1)].'<br />'.$x.'</th>';
1880
                        }
1881
                        $x = '';
1882
                    } else {
1883
                        $tableHtml .= '<th>'.$question_x['answers'][($ii - 1)].'</th>';
1884
                    }
1885
                    $optionText = strip_tags($question_x['answers'][$ii - 1]);
1886
                    $optionText = html_entity_decode($optionText);
1887
                    array_push($xOptions, trim($optionText));
1888
                }
1889
            }
1890
            $tableHtml .= '</tr>';
1891
            $chartData = [];
1892
            // The main part
1893
            for ($ij = 0; $ij < count($question_y['answers']); $ij++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Comprehensibility Best Practice introduced by
The variable $question_y does not seem to be defined for all execution paths leading up to this point.
Loading history...
1894
                $currentYQuestion = strip_tags($question_y['answers'][$ij]);
1895
                $currentYQuestion = html_entity_decode($currentYQuestion);
1896
                // The Y axis is a scoring question type so we have more rows than the options (actually options * maximum score)
1897
                if ($question_y['type'] == 'score') {
1898
                    for ($y = 1; $y <= $question_y['maximum_score']; $y++) {
1899
                        $tableHtml .= '<tr>';
1900
                        for ($ii = 0; $ii <= count($question_x['answers']); $ii++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1901
                            if ($question_x['type'] == 'score') {
1902
                                for ($x = 1; $x <= $question_x['maximum_score']; $x++) {
1903
                                    if ($ii == 0) {
1904
                                        $tableHtml .= '<th>'.$question_y['answers'][($ij)].' '.$y.'</th>';
1905
                                        break;
1906
                                    } else {
1907
                                        $tableHtml .= '<td align="center">';
1908
                                        $votes = self::comparative_check(
1909
                                            $answers_x,
1910
                                            $answers_y,
1911
                                            $question_x['answersid'][($ii - 1)],
1912
                                            $question_y['answersid'][($ij)],
1913
                                            $x,
1914
                                            $y
1915
                                        );
1916
                                        $tableHtml .= $votes;
1917
                                        array_push(
1918
                                            $chartData,
1919
                                            [
1920
                                                'serie' => [$currentYQuestion, $xOptions[$ii - 1]],
1921
                                                'option' => $x,
1922
                                                'votes' => $votes,
1923
                                            ]
1924
                                        );
1925
                                        $tableHtml .= '</td>';
1926
                                    }
1927
                                }
1928
                            } else {
1929
                                if ($ii == 0) {
1930
                                    $tableHtml .= '<th>'.$question_y['answers'][$ij].' '.$y.'</th>';
1931
                                } else {
1932
                                    $tableHtml .= '<td align="center">';
1933
                                    $votes = self::comparative_check(
1934
                                        $answers_x,
1935
                                        $answers_y,
1936
                                        $question_x['answersid'][($ii - 1)],
1937
                                        $question_y['answersid'][($ij)],
1938
                                        0,
1939
                                        $y
1940
                                    );
1941
                                    $tableHtml .= $votes;
1942
                                    array_push(
1943
                                        $chartData,
1944
                                        [
1945
                                            'serie' => [$currentYQuestion, $xOptions[$ii - 1]],
1946
                                            'option' => $y,
1947
                                            'votes' => $votes,
1948
                                        ]
1949
                                    );
1950
                                    $tableHtml .= '</td>';
1951
                                }
1952
                            }
1953
                        }
1954
                        $tableHtml .= '</tr>';
1955
                    }
1956
                } else {
1957
                    // The Y axis is NOT a score question type so the number of rows = the number of options
1958
                    $tableHtml .= '<tr>';
1959
                    for ($ii = 0; $ii <= count($question_x['answers']); $ii++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1960
                        if ($question_x['type'] == 'score') {
1961
                            for ($x = 1; $x <= $question_x['maximum_score']; $x++) {
1962
                                if ($ii == 0) {
1963
                                    $tableHtml .= '<th>'.$question_y['answers'][$ij].'</th>';
1964
                                    break;
1965
                                } else {
1966
                                    $tableHtml .= '<td align="center">';
1967
                                    $votes = self::comparative_check(
1968
                                        $answers_x,
1969
                                        $answers_y,
1970
                                        $question_x['answersid'][($ii - 1)],
1971
                                        $question_y['answersid'][($ij)],
1972
                                        $x,
1973
                                        0
1974
                                    );
1975
                                    $tableHtml .= $votes;
1976
                                    array_push(
1977
                                        $chartData,
1978
                                        [
1979
                                            'serie' => [$currentYQuestion, $xOptions[$ii - 1]],
1980
                                            'option' => $x,
1981
                                            'votes' => $votes,
1982
                                        ]
1983
                                    );
1984
                                    $tableHtml .= '</td>';
1985
                                }
1986
                            }
1987
                        } else {
1988
                            if ($ii == 0) {
1989
                                $tableHtml .= '<th>'.$question_y['answers'][($ij)].'</th>';
1990
                            } else {
1991
                                $tableHtml .= '<td align="center">';
1992
                                $votes = self::comparative_check(
1993
                                    $answers_x,
1994
                                    $answers_y,
1995
                                    $question_x['answersid'][($ii - 1)],
1996
                                    $question_y['answersid'][($ij)]
1997
                                );
1998
                                $tableHtml .= $votes;
1999
                                array_push(
2000
                                    $chartData,
2001
                                    [
2002
                                        'serie' => $xOptions[$ii - 1],
2003
                                        'option' => $currentYQuestion,
2004
                                        'votes' => $votes,
2005
                                    ]
2006
                                );
2007
                                $tableHtml .= '</td>';
2008
                            }
2009
                        }
2010
                    }
2011
                    $tableHtml .= '</tr>';
2012
                }
2013
            }
2014
            $tableHtml .= '</table>';
2015
            echo '<div id="chartContainer" class="col-md-12">';
2016
            echo self::drawChart($chartData, true);
2017
            echo '</div>';
2018
            echo $tableHtml;
2019
        }
2020
    }
2021
2022
    /**
2023
     * Get all the answers of a question grouped by user.
2024
     *
2025
     * @param int $survey_id   Survey ID
2026
     * @param int $question_id Question ID
2027
     *
2028
     * @return array Array containing all answers of all users, grouped by user
2029
     *
2030
     * @author Patrick Cool <[email protected]>, Ghent University
2031
     *
2032
     * @version February 2007 - Updated March 2008
2033
     */
2034
    public static function get_answers_of_question_by_user($survey_id, $question_id)
2035
    {
2036
        $course_id = api_get_course_int_id();
2037
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
2038
2039
        $sql = "SELECT * FROM $table_survey_answer
2040
                WHERE 
2041
                  c_id = $course_id AND 
2042
                  survey_id='".intval($survey_id)."' AND 
2043
                  question_id='".intval($question_id)."'
2044
                ORDER BY USER ASC";
2045
        $result = Database::query($sql);
2046
        $return = [];
2047
        while ($row = Database::fetch_array($result)) {
2048
            if ($row['value'] == 0) {
2049
                $return[$row['user']][] = $row['option_id'];
2050
            } else {
2051
                $return[$row['user']][] = $row['option_id'].'*'.$row['value'];
2052
            }
2053
        }
2054
2055
        return $return;
2056
    }
2057
2058
    /**
2059
     * Count the number of users who answer positively on both options.
2060
     *
2061
     * @param array All answers of the x axis
2062
     * @param array All answers of the y axis
2063
     * @param int x axis value (= the option_id of the first question)
2064
     * @param int y axis value (= the option_id of the second question)
2065
     *
2066
     * @return int Number of users who have answered positively to both options
2067
     *
2068
     * @author Patrick Cool <[email protected]>, Ghent University
2069
     *
2070
     * @version February 2007
2071
     */
2072
    public static function comparative_check(
2073
        $answers_x,
2074
        $answers_y,
2075
        $option_x,
2076
        $option_y,
2077
        $value_x = 0,
2078
        $value_y = 0
2079
    ) {
2080
        if ($value_x == 0) {
2081
            $check_x = $option_x;
2082
        } else {
2083
            $check_x = $option_x.'*'.$value_x;
2084
        }
2085
        if ($value_y == 0) {
2086
            $check_y = $option_y;
2087
        } else {
2088
            $check_y = $option_y.'*'.$value_y;
2089
        }
2090
2091
        $counter = 0;
2092
        if (is_array($answers_x)) {
2093
            foreach ($answers_x as $user => &$answers) {
2094
                // Check if the user has given $option_x as answer
2095
                if (in_array($check_x, $answers)) {
2096
                    // Check if the user has given $option_y as an answer
2097
                    if (!is_null($answers_y[$user]) &&
2098
                        in_array($check_y, $answers_y[$user])
2099
                    ) {
2100
                        $counter++;
2101
                    }
2102
                }
2103
            }
2104
        }
2105
2106
        return $counter;
2107
    }
2108
2109
    /**
2110
     * Save the invitation mail.
2111
     *
2112
     * @param string Text of the e-mail
2113
     * @param int Whether the mail contents are for invite mail (0, default) or reminder mail (1)
2114
     *
2115
     * @author Patrick Cool <[email protected]>, Ghent University
2116
     *
2117
     * @version January 2007
2118
     */
2119
    public static function save_invite_mail($mailtext, $mail_subject, $reminder = 0)
2120
    {
2121
        $course_id = api_get_course_int_id();
2122
        // Database table definition
2123
        $table_survey = Database::get_course_table(TABLE_SURVEY);
2124
2125
        // Reminder or not
2126
        if ($reminder == 0) {
2127
            $mail_field = 'invite_mail';
2128
        } else {
2129
            $mail_field = 'reminder_mail';
2130
        }
2131
2132
        $sql = "UPDATE $table_survey SET
2133
		        mail_subject='".Database::escape_string($mail_subject)."',
2134
		        $mail_field = '".Database::escape_string($mailtext)."'
2135
		        WHERE c_id = $course_id AND survey_id = '".intval($_GET['survey_id'])."'";
2136
        Database::query($sql);
2137
    }
2138
2139
    /**
2140
     * This function saves all the invitations of course users
2141
     * and additional users in the database
2142
     * and sends the invitations by email.
2143
     *
2144
     * @param $users_array Users $array array can be both a list of course uids AND a list of additional emailaddresses
2145
     * @param $invitation_title Title $string of the invitation, used as the title of the mail
2146
     * @param $invitation_text Text $string of the invitation, used as the text of the mail.
2147
     *                         The text has to contain a **link** string or this will automatically be added to the end
2148
     * @param int  $reminder
2149
     * @param bool $sendmail
2150
     * @param int  $remindUnAnswered
2151
     *
2152
     * @return bool $isAdditionalEmail
2153
     *
2154
     * @author Patrick Cool <[email protected]>, Ghent University
2155
     * @author Julio Montoya - Adding auto-generated link support
2156
     *
2157
     * @version January 2007
2158
     */
2159
    public static function saveInvitations(
2160
        $users_array,
2161
        $invitation_title,
2162
        $invitation_text,
2163
        $reminder = 0,
2164
        $sendmail = false,
2165
        $remindUnAnswered = 0,
2166
        $isAdditionalEmail = false
2167
    ) {
2168
        if (!is_array($users_array)) {
2169
            // Should not happen
2170
2171
            return 0;
0 ignored issues
show
Bug Best Practice introduced by
The expression return 0 returns the type integer which is incompatible with the documented return type boolean.
Loading history...
2172
        }
2173
2174
        // Getting the survey information
2175
        $survey_data = SurveyManager::get_survey($_GET['survey_id']);
2176
        $survey_invitations = self::get_invitations($survey_data['survey_code']);
2177
        $already_invited = self::get_invited_users($survey_data['code']);
2178
2179
        // Remind unanswered is a special version of remind all reminder
2180
        $exclude_users = [];
2181
        if ($remindUnAnswered == 1) { // Remind only unanswered users
2182
            $reminder = 1;
2183
            $exclude_users = SurveyManager::get_people_who_filled_survey($_GET['survey_id']);
2184
        }
2185
2186
        $counter = 0; // Nr of invitations "sent" (if sendmail option)
2187
        $course_id = api_get_course_int_id();
2188
        $session_id = api_get_session_id();
2189
2190
        if ($isAdditionalEmail == false) {
2191
            $result = CourseManager::separateUsersGroups($users_array);
2192
            $groupList = $result['groups'];
2193
            $users_array = $result['users'];
2194
2195
            foreach ($groupList as $groupId) {
2196
                $userGroupList = GroupManager::getStudents($groupId);
2197
                $userGroupIdList = array_column($userGroupList, 'user_id');
2198
                $users_array = array_merge($users_array, $userGroupIdList);
2199
2200
                $params = [
2201
                    'c_id' => $course_id,
2202
                    'session_id' => $session_id,
2203
                    'group_id' => $groupId,
2204
                    'survey_code' => $survey_data['code'],
2205
                ];
2206
2207
                $invitationExists = self::invitationExists(
2208
                    $course_id,
2209
                    $session_id,
2210
                    $groupId,
2211
                    $survey_data['code']
2212
                );
2213
                if (empty($invitationExists)) {
2214
                    self::save_invitation($params);
2215
                }
2216
            }
2217
        }
2218
2219
        $users_array = array_unique($users_array);
2220
        foreach ($users_array as $key => $value) {
2221
            if (!isset($value) || $value == '') {
2222
                continue;
2223
            }
2224
2225
            // Skip user if reminding only unanswered people
2226
            if (in_array($value, $exclude_users)) {
2227
                continue;
2228
            }
2229
2230
            // Get the unique invitation code if we already have it
2231
            if ($reminder == 1 && array_key_exists($value, $survey_invitations)) {
2232
                $invitation_code = $survey_invitations[$value]['invitation_code'];
2233
            } else {
2234
                $invitation_code = md5($value.microtime());
2235
            }
2236
            $new_user = false; // User not already invited
2237
            // Store the invitation if user_id not in $already_invited['course_users'] OR email is not in $already_invited['additional_users']
2238
            $addit_users_array = isset($already_invited['additional_users']) && !empty($already_invited['additional_users'])
2239
                    ? explode(';', $already_invited['additional_users'])
2240
                    : [];
2241
            $my_alredy_invited = $already_invited['course_users'] == null ? [] : $already_invited['course_users'];
2242
            if ((is_numeric($value) && !in_array($value, $my_alredy_invited)) ||
2243
                (!is_numeric($value) && !in_array($value, $addit_users_array))
2244
            ) {
2245
                $new_user = true;
2246
                if (!array_key_exists($value, $survey_invitations)) {
2247
                    $params = [
2248
                        'c_id' => $course_id,
2249
                        'session_id' => $session_id,
2250
                        'user' => $value,
2251
                        'survey_code' => $survey_data['code'],
2252
                        'invitation_code' => $invitation_code,
2253
                        'invitation_date' => api_get_utc_datetime(),
2254
                    ];
2255
                    self::save_invitation($params);
2256
                }
2257
            }
2258
2259
            // Send the email if checkboxed
2260
            if (($new_user || $reminder == 1) && $sendmail) {
2261
                // Make a change for absolute url
2262
                if (isset($invitation_text)) {
2263
                    $invitation_text = api_html_entity_decode($invitation_text, ENT_QUOTES);
2264
                    $invitation_text = str_replace('src="../../', 'src="'.api_get_path(WEB_PATH), $invitation_text);
2265
                    $invitation_text = trim(stripslashes($invitation_text));
2266
                }
2267
                self::send_invitation_mail(
2268
                    $value,
2269
                    $invitation_code,
2270
                    $invitation_title,
2271
                    $invitation_text
2272
                );
2273
                $counter++;
2274
            }
2275
        }
2276
2277
        return $counter; // Number of invitations sent
0 ignored issues
show
Bug Best Practice introduced by
The expression return $counter returns the type integer which is incompatible with the documented return type boolean.
Loading history...
2278
    }
2279
2280
    /**
2281
     * @param $params
2282
     *
2283
     * @return bool|int
2284
     */
2285
    public static function save_invitation($params)
2286
    {
2287
        // Database table to store the invitations data
2288
        $table = Database::get_course_table(TABLE_SURVEY_INVITATION);
2289
        if (!empty($params['c_id']) &&
2290
            (!empty($params['user']) || !empty($params['group_id'])) &&
2291
            !empty($params['survey_code'])
2292
        ) {
2293
            $params['survey_invitation_id'] = $params['survey_invitation_id'] ?? 0;
2294
            $params['reminder_date'] = $params['reminder_date'] ?? null;
2295
            $params['answered'] = $params['answered'] ?? 0;
2296
            $params['group_id'] = $params['group_id'] ?? 0;
2297
2298
2299
            $insertId = Database::insert($table, $params);
2300
            if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2301
                $sql = "UPDATE $table 
2302
                        SET survey_invitation_id = $insertId
2303
                        WHERE iid = $insertId";
2304
                Database::query($sql);
2305
            }
2306
2307
            return $insertId;
2308
        }
2309
2310
        return false;
2311
    }
2312
2313
    /**
2314
     * @param int    $courseId
2315
     * @param int    $sessionId
2316
     * @param int    $groupId
2317
     * @param string $surveyCode
2318
     *
2319
     * @return int
2320
     */
2321
    public static function invitationExists($courseId, $sessionId, $groupId, $surveyCode)
2322
    {
2323
        $table = Database::get_course_table(TABLE_SURVEY_INVITATION);
2324
        $courseId = intval($courseId);
2325
        $sessionId = intval($sessionId);
2326
        $groupId = intval($groupId);
2327
        $surveyCode = Database::escape_string($surveyCode);
2328
2329
        $sql = "SELECT survey_invitation_id FROM $table
2330
                WHERE
2331
                    c_id = $courseId AND
2332
                    session_id = $sessionId AND
2333
                    group_id = $groupId AND
2334
                    survey_code = '$surveyCode'
2335
                ";
2336
        $result = Database::query($sql);
2337
2338
        return Database::num_rows($result);
2339
    }
2340
2341
    /**
2342
     * Send the invitation by mail.
2343
     *
2344
     * @param int invitedUser - the userId (course user) or emailaddress of additional user
2345
     * $param string $invitation_code - the unique invitation code for the URL
2346
     */
2347
    public static function send_invitation_mail(
2348
        $invitedUser,
2349
        $invitation_code,
2350
        $invitation_title,
2351
        $invitation_text
2352
    ) {
2353
        $_user = api_get_user_info();
2354
        $_course = api_get_course_info();
2355
        $sessionId = api_get_session_id();
2356
2357
        // Replacing the **link** part with a valid link for the user
2358
        $link = api_get_path(WEB_CODE_PATH).'survey/fillsurvey.php?';
2359
        $link .= 'id_session='.$sessionId.'&course='.$_course['code'].'&invitationcode='.$invitation_code;
2360
2361
        $text_link = '<a href="'.$link.'">'.get_lang('ClickHereToAnswerTheSurvey')."</a><br />\r\n<br />\r\n"
2362
            .get_lang('OrCopyPasteTheFollowingUrl')." <br />\r\n ".$link;
2363
2364
        $replace_count = 0;
2365
        $full_invitation_text = api_str_ireplace('**link**', $text_link, $invitation_text, $replace_count);
2366
        if ($replace_count < 1) {
2367
            $full_invitation_text = $full_invitation_text."<br />\r\n<br />\r\n".$text_link;
2368
        }
2369
2370
        // Sending the mail
2371
        $sender_name = api_get_person_name($_user['firstName'], $_user['lastName'], null, PERSON_NAME_EMAIL_ADDRESS);
2372
        $sender_email = $_user['mail'];
2373
        $sender_user_id = api_get_user_id();
2374
2375
        $replyto = [];
2376
        if (api_get_setting('survey_email_sender_noreply') == 'noreply') {
2377
            $noreply = api_get_setting('noreply_email_address');
2378
            if (!empty($noreply)) {
2379
                $replyto['Reply-to'] = $noreply;
2380
                $sender_name = $noreply;
2381
                $sender_email = $noreply;
2382
                $sender_user_id = null;
2383
            }
2384
        }
2385
2386
        // Optionally: finding the e-mail of the course user
2387
        if (is_numeric($invitedUser)) {
2388
            MessageManager::send_message(
2389
                $invitedUser,
2390
                $invitation_title,
2391
                $full_invitation_text,
2392
                [],
2393
                [],
2394
                null,
2395
                null,
2396
                null,
2397
                null,
2398
                $sender_user_id
2399
            );
2400
        } else {
2401
            /** @todo check if the address is a valid email */
2402
            $recipient_email = $invitedUser;
2403
            @api_mail_html(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for api_mail_html(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

2403
            /** @scrutinizer ignore-unhandled */ @api_mail_html(

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2404
                '',
2405
                $recipient_email,
2406
                $invitation_title,
2407
                $full_invitation_text,
2408
                $sender_name,
2409
                $sender_email,
2410
                $replyto
2411
            );
2412
        }
2413
    }
2414
2415
    /**
2416
     * This function recalculates the number of users who have been invited and updates the survey table with this
2417
     * value.
2418
     *
2419
     * @param string Survey code
2420
     * @param int $courseId
2421
     * @param int $sessionId
2422
     *
2423
     * @return int
2424
     *
2425
     * @author Patrick Cool <[email protected]>, Ghent University
2426
     *
2427
     * @version January 2007
2428
     */
2429
    public static function update_count_invited($survey_code, $courseId = 0, $sessionId = 0)
2430
    {
2431
        $courseId = $courseId ?: api_get_course_int_id();
2432
        $sessionId = $sessionId ?: api_get_session_id();
2433
        $sessionCondition = api_get_session_condition($sessionId);
2434
2435
        // Database table definition
2436
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
2437
        $table_survey = Database::get_course_table(TABLE_SURVEY);
2438
2439
        // Counting the number of people that are invited
2440
        $sql = "SELECT count(user) as total
2441
                FROM $table_survey_invitation
2442
		        WHERE
2443
		            c_id = $courseId AND
2444
		            survey_code = '".Database::escape_string($survey_code)."' AND
2445
		            user <> ''
2446
		            $sessionCondition
2447
                ";
2448
        $result = Database::query($sql);
2449
        $row = Database::fetch_array($result);
2450
        $total_invited = $row['total'];
2451
2452
        // Updating the field in the survey table
2453
        $sql = "UPDATE $table_survey
2454
		        SET invited = '".Database::escape_string($total_invited)."'
2455
		        WHERE
2456
		            c_id = $courseId AND
2457
		            code = '".Database::escape_string($survey_code)."'
2458
		            $sessionCondition
2459
                ";
2460
        Database::query($sql);
2461
2462
        return $total_invited;
2463
    }
2464
2465
    /**
2466
     * This function gets all the invited users for a given survey code.
2467
     *
2468
     * @param string Survey code
2469
     * @param string optional - course database
2470
     *
2471
     * @return array Array containing the course users and additional users (non course users)
2472
     *
2473
     * @todo consider making $defaults['additional_users'] also an array
2474
     *
2475
     * @author Patrick Cool <[email protected]>, Ghent University
2476
     * @author Julio Montoya, adding c_id fixes - Dec 2012
2477
     *
2478
     * @version January 2007
2479
     */
2480
    public static function get_invited_users($survey_code, $course_code = '', $session_id = 0)
2481
    {
2482
        if (!empty($course_code)) {
2483
            $course_info = api_get_course_info($course_code);
2484
            $course_id = $course_info['real_id'];
2485
        } else {
2486
            $course_id = api_get_course_int_id();
2487
        }
2488
2489
        if (empty($session_id)) {
2490
            $session_id = api_get_session_id();
2491
        }
2492
2493
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
2494
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2495
2496
        // Selecting all the invitations of this survey AND the additional emailaddresses (the left join)
2497
        $order_clause = api_sort_by_first_name() ? ' ORDER BY firstname, lastname' : ' ORDER BY lastname, firstname';
2498
        $sql = "SELECT user, group_id
2499
				FROM $table_survey_invitation as table_invitation
2500
				WHERE
2501
				    table_invitation.c_id = $course_id AND
2502
                    survey_code='".Database::escape_string($survey_code)."' AND
2503
                    session_id = $session_id
2504
                ";
2505
2506
        $defaults = [];
2507
        $defaults['course_users'] = [];
2508
        $defaults['additional_users'] = []; // Textarea
2509
        $defaults['users'] = []; // user and groups
2510
2511
        $result = Database::query($sql);
2512
        while ($row = Database::fetch_array($result)) {
2513
            if (is_numeric($row['user'])) {
2514
                $defaults['course_users'][] = $row['user'];
2515
                $defaults['users'][] = 'USER:'.$row['user'];
2516
            } else {
2517
                if (!empty($row['user'])) {
2518
                    $defaults['additional_users'][] = $row['user'];
2519
                }
2520
            }
2521
2522
            if (isset($row['group_id']) && !empty($row['group_id'])) {
2523
                $defaults['users'][] = 'GROUP:'.$row['group_id'];
2524
            }
2525
        }
2526
2527
        if (!empty($defaults['course_users'])) {
2528
            $user_ids = implode("','", $defaults['course_users']);
2529
            $sql = "SELECT user_id FROM $table_user WHERE user_id IN ('$user_ids') $order_clause";
2530
            $result = Database::query($sql);
2531
            $fixed_users = [];
2532
            while ($row = Database::fetch_array($result)) {
2533
                $fixed_users[] = $row['user_id'];
2534
            }
2535
            $defaults['course_users'] = $fixed_users;
2536
        }
2537
2538
        if (!empty($defaults['additional_users'])) {
2539
            $defaults['additional_users'] = implode(';', $defaults['additional_users']);
2540
        }
2541
2542
        return $defaults;
2543
    }
2544
2545
    /**
2546
     * Get all the invitations.
2547
     *
2548
     * @param string Survey code
2549
     *
2550
     * @return array Database rows matching the survey code
2551
     *
2552
     * @author Patrick Cool <[email protected]>, Ghent University
2553
     *
2554
     * @version September 2007
2555
     */
2556
    public static function get_invitations($survey_code)
2557
    {
2558
        $course_id = api_get_course_int_id();
2559
        $sessionId = api_get_session_id();
2560
        // Database table definition
2561
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
2562
2563
        $sql = "SELECT * FROM $table_survey_invitation
2564
		        WHERE
2565
		            c_id = $course_id AND
2566
                    session_id = $sessionId AND
2567
		            survey_code = '".Database::escape_string($survey_code)."'";
2568
        $result = Database::query($sql);
2569
        $return = [];
2570
        while ($row = Database::fetch_array($result)) {
2571
            $return[$row['user']] = $row;
2572
        }
2573
2574
        return $return;
2575
    }
2576
2577
    /**
2578
     * This function displays the form for searching a survey.
2579
     *
2580
     * @author Patrick Cool <[email protected]>, Ghent University
2581
     *
2582
     * @version January 2007
2583
     *
2584
     * @todo consider moving this to surveymanager.inc.lib.php
2585
     */
2586
    public static function display_survey_search_form()
2587
    {
2588
        $url = api_get_path(WEB_CODE_PATH).'survey/survey_list.php?search=advanced&'.api_get_cidreq();
2589
        $form = new FormValidator('search', 'get', $url);
2590
        $form->addHeader(get_lang('SearchASurvey'));
2591
        $form->addText('keyword_title', get_lang('Title'));
2592
        $form->addText('keyword_code', get_lang('Code'));
2593
        $form->addSelectLanguage('keyword_language', get_lang('Language'));
2594
        $form->addHidden('cidReq', api_get_course_id());
2595
        $form->addButtonSearch(get_lang('Search'), 'do_search');
2596
        $form->display();
2597
    }
2598
2599
    /**
2600
     * Show table only visible by DRH users.
2601
     */
2602
    public static function displaySurveyListForDrh()
2603
    {
2604
        $parameters = [];
2605
        $parameters['cidReq'] = api_get_course_id();
2606
2607
        // Create a sortable table with survey-data
2608
        $table = new SortableTable(
2609
            'surveys',
2610
            'get_number_of_surveys',
2611
            'get_survey_data_drh',
2612
            2
2613
        );
2614
        $table->set_additional_parameters($parameters);
2615
        $table->set_header(0, '', false);
2616
        $table->set_header(1, get_lang('SurveyName'));
2617
        $table->set_header(2, get_lang('SurveyCode'));
2618
        $table->set_header(3, get_lang('NumberOfQuestions'));
2619
        $table->set_header(4, get_lang('Author'));
2620
        $table->set_header(5, get_lang('AvailableFrom'));
2621
        $table->set_header(6, get_lang('AvailableUntil'));
2622
        $table->set_header(7, get_lang('Invite'));
2623
        $table->set_header(8, get_lang('Anonymous'));
2624
2625
        if (api_get_configuration_value('allow_mandatory_survey')) {
2626
            $table->set_header(9, get_lang('IsMandatory'));
2627
            $table->set_header(10, get_lang('Modify'), false, 'width="150"');
2628
            $table->set_column_filter(9, 'anonymous_filter');
2629
            $table->set_column_filter(10, 'modify_filter_drh');
2630
        } else {
2631
            $table->set_header(9, get_lang('Modify'), false, 'width="150"');
2632
            $table->set_column_filter(9, 'modify_filter_drh');
2633
        }
2634
2635
        $table->set_column_filter(8, 'anonymous_filter');
2636
        $table->display();
2637
    }
2638
2639
    /**
2640
     * This function displays the sortable table with all the surveys.
2641
     *
2642
     *
2643
     * @author Patrick Cool <[email protected]>, Ghent University
2644
     *
2645
     * @version January 2007
2646
     */
2647
    public static function display_survey_list()
2648
    {
2649
        $parameters = [];
2650
        $parameters['cidReq'] = api_get_course_id();
2651
        if (isset($_GET['do_search']) && $_GET['do_search']) {
2652
            $message = get_lang('DisplaySearchResults').'<br />';
2653
            $message .= '<a href="'.api_get_self().'?'.api_get_cidreq().'">'.get_lang('DisplayAll').'</a>';
2654
            echo Display::return_message($message, 'normal', false);
2655
        }
2656
2657
        // Create a sortable table with survey-data
2658
        $table = new SortableTable(
2659
            'surveys',
2660
            'get_number_of_surveys',
2661
            'get_survey_data',
2662
            2
2663
        );
2664
        $table->set_additional_parameters($parameters);
2665
        $table->set_header(0, '', false);
2666
        $table->set_header(1, get_lang('SurveyName'));
2667
        $table->set_header(2, get_lang('SurveyCode'));
2668
        $table->set_header(3, get_lang('NumberOfQuestions'));
2669
        $table->set_header(4, get_lang('Author'));
2670
        //$table->set_header(5, get_lang('Language'));
2671
        //$table->set_header(6, get_lang('Shared'));
2672
        $table->set_header(5, get_lang('AvailableFrom'));
2673
        $table->set_header(6, get_lang('AvailableUntil'));
2674
        $table->set_header(7, get_lang('Invite'));
2675
        $table->set_header(8, get_lang('Anonymous'));
2676
2677
        if (api_get_configuration_value('allow_mandatory_survey')) {
2678
            $table->set_header(9, get_lang('IsMandatory'));
2679
            $table->set_header(10, get_lang('Modify'), false, 'width="150"');
2680
            $table->set_column_filter(8, 'anonymous_filter');
2681
            $table->set_column_filter(10, 'modify_filter');
2682
        } else {
2683
            $table->set_header(9, get_lang('Modify'), false, 'width="150"');
2684
            $table->set_column_filter(9, 'modify_filter');
2685
        }
2686
2687
        $table->set_column_filter(8, 'anonymous_filter');
2688
        $table->set_form_actions(['delete' => get_lang('DeleteSurvey')]);
2689
        $table->display();
2690
    }
2691
2692
    /**
2693
     * Survey list for coach.
2694
     */
2695
    public static function display_survey_list_for_coach()
2696
    {
2697
        $parameters = [];
2698
        $parameters['cidReq'] = api_get_course_id();
2699
        if (isset($_GET['do_search'])) {
2700
            $message = get_lang('DisplaySearchResults').'<br />';
2701
            $message .= '<a href="'.api_get_self().'?'.api_get_cidreq().'">'.get_lang('DisplayAll').'</a>';
2702
            echo Display::return_message($message, 'normal', false);
2703
        }
2704
2705
        // Create a sortable table with survey-data
2706
        $table = new SortableTable(
2707
            'surveys_coach',
2708
            'get_number_of_surveys_for_coach',
2709
            'get_survey_data_for_coach',
2710
            2
2711
        );
2712
        $table->set_additional_parameters($parameters);
2713
        $table->set_header(0, '', false);
2714
        $table->set_header(1, get_lang('SurveyName'));
2715
        $table->set_header(2, get_lang('SurveyCode'));
2716
        $table->set_header(3, get_lang('NumberOfQuestions'));
2717
        $table->set_header(4, get_lang('Author'));
2718
        $table->set_header(5, get_lang('AvailableFrom'));
2719
        $table->set_header(6, get_lang('AvailableUntil'));
2720
        $table->set_header(7, get_lang('Invite'));
2721
        $table->set_header(8, get_lang('Anonymous'));
2722
2723
        if (api_get_configuration_value('allow_mandatory_survey')) {
2724
            $table->set_header(9, get_lang('Modify'), false, 'width="130"');
2725
            $table->set_header(10, get_lang('Modify'), false, 'width="130"');
2726
            $table->set_column_filter(8, 'anonymous_filter');
2727
            $table->set_column_filter(10, 'modify_filter_for_coach');
2728
        } else {
2729
            $table->set_header(9, get_lang('Modify'), false, 'width="130"');
2730
            $table->set_column_filter(9, 'modify_filter_for_coach');
2731
        }
2732
2733
        $table->set_column_filter(8, 'anonymous_filter');
2734
        $table->display();
2735
    }
2736
2737
    /**
2738
     * Check if the hide_survey_edition configurations setting is enabled.
2739
     *
2740
     * @param string $surveyCode
2741
     *
2742
     * @return bool
2743
     */
2744
    public static function checkHideEditionToolsByCode($surveyCode)
2745
    {
2746
        $hideSurveyEdition = api_get_configuration_value('hide_survey_edition');
2747
2748
        if (false === $hideSurveyEdition) {
2749
            return false;
2750
        }
2751
2752
        if ('*' === $hideSurveyEdition['codes']) {
2753
            return true;
2754
        }
2755
2756
        if (in_array($surveyCode, $hideSurveyEdition['codes'])) {
2757
            return true;
2758
        }
2759
2760
        return false;
2761
    }
2762
2763
    /**
2764
     * This function changes the modify column of the sortable table.
2765
     *
2766
     * @param int  $survey_id the id of the survey
2767
     * @param bool $drh
2768
     *
2769
     * @throws \Doctrine\ORM\ORMException
2770
     * @throws \Doctrine\ORM\OptimisticLockException
2771
     * @throws \Doctrine\ORM\TransactionRequiredException
2772
     *
2773
     * @author Patrick Cool <[email protected]>, Ghent University
2774
     *
2775
     * @return string html code that are the actions that can be performed on any survey
2776
     *
2777
     * @version January 2007
2778
     */
2779
    public static function modify_filter($survey_id, $drh = false)
2780
    {
2781
        /** @var CSurvey $survey */
2782
        $survey = Database::getManager()->find('ChamiloCourseBundle:CSurvey', $survey_id);
2783
        $hideSurveyEdition = self::checkHideEditionToolsByCode($survey->getCode());
2784
2785
        if ($hideSurveyEdition) {
2786
            return '';
2787
        }
2788
2789
        if (empty($survey)) {
2790
            return '';
2791
        }
2792
2793
        $survey_id = $survey->getSurveyId();
2794
        $actions = [];
2795
        $hideReportingButton = api_get_configuration_value('hide_survey_reporting_button');
2796
        $codePath = api_get_path(WEB_CODE_PATH);
2797
        $params = [];
2798
        parse_str(api_get_cidreq(), $params);
2799
2800
        $reportingLink = Display::url(
2801
            Display::return_icon('statistics.png', get_lang('Reporting')),
2802
            $codePath.'survey/reporting.php?'.http_build_query($params + ['survey_id' => $survey_id])
2803
        );
2804
2805
        if ($drh) {
2806
            return $hideReportingButton ? '-' : $reportingLink;
2807
        }
2808
2809
        $type = $survey->getSurveyType();
2810
2811
        // Coach can see that only if the survey is in his session
2812
        if (api_is_allowed_to_edit() ||
2813
            api_is_element_in_the_session(TOOL_SURVEY, $survey_id)
2814
        ) {
2815
            $actions[] = Display::url(
2816
                Display::return_icon('edit.png', get_lang('Edit')),
2817
                $codePath.'survey/create_new_survey.php?'
2818
                    .http_build_query($params + ['action' => 'edit', 'survey_id' => $survey_id])
2819
            );
2820
2821
            if (SurveyManager::survey_generation_hash_available()) {
2822
                $actions[] = Display::url(
2823
                    Display::return_icon('new_link.png', get_lang('GenerateSurveyAccessLink')),
2824
                    $codePath.'survey/generate_link.php?'.http_build_query($params + ['survey_id' => $survey_id])
2825
                );
2826
            }
2827
2828
            if ($type != 3) {
2829
                $actions[] = Display::url(
2830
                    Display::return_icon('backup.png', get_lang('CopySurvey')),
2831
                    $codePath.'survey/copy_survey.php?'.http_build_query($params + ['survey_id' => $survey_id])
2832
                );
2833
2834
                $actions[] = Display::url(
2835
                    Display::return_icon('copy.png', get_lang('DuplicateSurvey')),
2836
                    $codePath.'survey/survey_list.php?'
2837
                        .http_build_query($params + ['action' => 'copy_survey', 'survey_id' => $survey_id])
2838
                );
2839
2840
                $actions[] = Display::url(
2841
                    Display::return_icon('star.png', get_lang('MultiplicateSurvey')),
2842
                    $codePath.'survey/survey_list.php?'
2843
                    .http_build_query($params + ['action' => 'multiplicate', 'survey_id' => $survey_id])
2844
                );
2845
2846
                $actions[] = Display::url(
2847
                    Display::return_icon('star_na.png', get_lang('RemoveMultiplicateQuestions')),
2848
                    $codePath.'survey/survey_list.php?'
2849
                    .http_build_query($params + ['action' => 'remove_multiplicate', 'survey_id' => $survey_id])
2850
                );
2851
2852
                $warning = addslashes(api_htmlentities(get_lang('EmptySurvey').'?', ENT_QUOTES));
2853
                $actions[] = Display::url(
2854
                    Display::return_icon('clean.png', get_lang('EmptySurvey')),
2855
                    $codePath.'survey/survey_list.php?'
2856
                        .http_build_query($params + ['action' => 'empty', 'survey_id' => $survey_id]),
2857
                    [
2858
                        'onclick' => "javascript: if (!confirm('".$warning."')) return false;",
2859
                    ]
2860
                );
2861
            }
2862
        }
2863
2864
        if ($type != 3) {
2865
            $actions[] = Display::url(
2866
                Display::return_icon('preview_view.png', get_lang('Preview')),
2867
                $codePath.'survey/preview.php?'.http_build_query($params + ['survey_id' => $survey_id])
2868
            );
2869
            }
2870
2871
            $actions[] = Display::url(
2872
                Display::return_icon('mail_send.png', get_lang('Publish')),
2873
                $codePath.'survey/survey_invite.php?'.http_build_query($params + ['survey_id' => $survey_id])
2874
            );
2875
2876
            if ($type != 3) {
2877
                $actions[] = $hideReportingButton ? null : $reportingLink;
2878
            }
2879
2880
        if (api_is_allowed_to_edit() ||
2881
            api_is_element_in_the_session(TOOL_SURVEY, $survey_id)
2882
        ) {
2883
            $warning = addslashes(api_htmlentities(get_lang('DeleteSurvey').'?', ENT_QUOTES));
2884
            $actions[] = Display::url(
2885
                Display::return_icon('delete.png', get_lang('Delete')),
2886
                $codePath.'survey/survey_list.php?'
2887
                    .http_build_query($params + ['action' => 'delete', 'survey_id' => $survey_id]),
2888
                [
2889
                    'onclick' => "javascript: if(!confirm('".$warning."')) return false;",
2890
                ]
2891
            );
2892
        }
2893
2894
        return implode(PHP_EOL, $actions);
2895
    }
2896
2897
    /**
2898
     * @param int $survey_id
2899
     *
2900
     * @return string
2901
     */
2902
    public static function modify_filter_for_coach($survey_id)
2903
    {
2904
        $survey_id = (int) $survey_id;
2905
        $actions = [];
2906
        $codePath = api_get_path(WEB_CODE_PATH);
2907
        $params = [];
2908
        parse_str(api_get_cidreq(), $params);
2909
        $actions[] = Display::url(
2910
            Display::return_icon('preview_view.png', get_lang('Preview')),
2911
            $codePath.'survey/preview.php?'.http_build_query($params + ['survey_id' => $survey_id])
2912
        );
2913
        $actions[] = Display::url(
2914
            Display::return_icon('mail_send.png', get_lang('Publish')),
2915
            $codePath.'survey/survey_invite.php?'.http_build_query($params + ['survey_id' => $survey_id])
2916
        );
2917
        $warning = addslashes(api_htmlentities(get_lang("EmptySurvey").'?', ENT_QUOTES));
2918
        $actions[] = Display::url(
2919
            Display::return_icon('clean.png', get_lang('EmptySurvey')),
2920
            $codePath.'survey/survey_list.php?'
2921
                .http_build_query($params + ['action' => 'empty', 'survey_id' => $survey_id]),
2922
            [
2923
                'onclick' => "javascript: if(!confirm('".$warning."')) return false;",
2924
            ]
2925
        );
2926
2927
        return implode(PHP_EOL, $actions);
2928
    }
2929
2930
    /**
2931
     * Returns "yes" when given parameter is one, "no" for any other value.
2932
     *
2933
     * @param int Whether anonymous or not
2934
     *
2935
     * @return string "Yes" or "No" in the current language
2936
     */
2937
    public static function anonymous_filter($anonymous)
2938
    {
2939
        if ($anonymous == 1) {
2940
            return get_lang('Yes');
2941
        } else {
2942
            return get_lang('No');
2943
        }
2944
    }
2945
2946
    /**
2947
     * This function handles the search restriction for the SQL statements.
2948
     *
2949
     * @return string Part of a SQL statement or false on error
2950
     *
2951
     * @author Patrick Cool <[email protected]>, Ghent University
2952
     *
2953
     * @version January 2007
2954
     */
2955
    public static function survey_search_restriction()
2956
    {
2957
        if (isset($_GET['do_search'])) {
2958
            if ($_GET['keyword_title'] != '') {
2959
                $search_term[] = 'title like "%" \''.Database::escape_string($_GET['keyword_title']).'\' "%"';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$search_term was never initialized. Although not strictly required by PHP, it is generally a good practice to add $search_term = array(); before regardless.
Loading history...
2960
            }
2961
            if ($_GET['keyword_code'] != '') {
2962
                $search_term[] = 'code =\''.Database::escape_string($_GET['keyword_code']).'\'';
2963
            }
2964
            if ($_GET['keyword_language'] != '%') {
2965
                $search_term[] = 'lang =\''.Database::escape_string($_GET['keyword_language']).'\'';
2966
            }
2967
            $my_search_term = ($search_term == null) ? [] : $search_term;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $search_term does not seem to be defined for all execution paths leading up to this point.
Loading history...
2968
            $search_restriction = implode(' AND ', $my_search_term);
2969
2970
            return $search_restriction;
2971
        } else {
2972
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
2973
        }
2974
    }
2975
2976
    /**
2977
     * This function calculates the total number of surveys.
2978
     *
2979
     * @return int Total number of surveys
2980
     *
2981
     * @author Patrick Cool <[email protected]>, Ghent University
2982
     *
2983
     * @version January 2007
2984
     */
2985
    public static function get_number_of_surveys()
2986
    {
2987
        $table_survey = Database::get_course_table(TABLE_SURVEY);
2988
        $course_id = api_get_course_int_id();
2989
2990
        $search_restriction = self::survey_search_restriction();
2991
        if ($search_restriction) {
2992
            $search_restriction = 'WHERE c_id = '.$course_id.' AND '.$search_restriction;
2993
        } else {
2994
            $search_restriction = "WHERE c_id = $course_id";
2995
        }
2996
        $sql = "SELECT count(survey_id) AS total_number_of_items
2997
		        FROM ".$table_survey.' '.$search_restriction;
2998
        $res = Database::query($sql);
2999
        $obj = Database::fetch_object($res);
3000
3001
        return $obj->total_number_of_items;
3002
    }
3003
3004
    /**
3005
     * @return int
3006
     */
3007
    public static function get_number_of_surveys_for_coach()
3008
    {
3009
        $survey_tree = new SurveyTree();
3010
3011
        return count($survey_tree->surveylist);
3012
    }
3013
3014
    /**
3015
     * This function gets all the survey data that is to be displayed in the sortable table.
3016
     *
3017
     * @param int    $from
3018
     * @param int    $number_of_items
3019
     * @param int    $column
3020
     * @param string $direction
3021
     * @param bool   $isDrh
3022
     *
3023
     * @return array
3024
     *
3025
     * @author Patrick Cool <[email protected]>, Ghent University
3026
     * @author Julio Montoya <[email protected]>, Beeznest - Adding intvals
3027
     *
3028
     * @version January 2007
3029
     */
3030
    public static function get_survey_data(
3031
        $from,
3032
        $number_of_items,
3033
        $column,
3034
        $direction,
3035
        $isDrh = false
3036
    ) {
3037
        $table_survey = Database::get_course_table(TABLE_SURVEY);
3038
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
3039
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
3040
        $mandatoryAllowed = api_get_configuration_value('allow_mandatory_survey');
3041
        $_user = api_get_user_info();
3042
3043
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
3044
3045
        // Searching
3046
        $search_restriction = self::survey_search_restriction();
3047
        if ($search_restriction) {
3048
            $search_restriction = ' AND '.$search_restriction;
3049
        }
3050
        $from = (int) $from;
3051
        $number_of_items = (int) $number_of_items;
3052
        $column = (int) $column;
3053
        if (!in_array(strtolower($direction), ['asc', 'desc'])) {
3054
            $direction = 'asc';
3055
        }
3056
3057
        // Condition for the session
3058
        $session_id = api_get_session_id();
3059
        $condition_session = api_get_session_condition($session_id);
3060
        $course_id = api_get_course_int_id();
3061
3062
        $sql = "
3063
            SELECT
3064
                survey.survey_id AS col0,
3065
                survey.title AS col1,
3066
                survey.code AS col2,
3067
                count(survey_question.question_id) AS col3, "
3068
                .(api_is_western_name_order()
3069
                ? "CONCAT(user.firstname, ' ', user.lastname)"
3070
                : "CONCAT(user.lastname, ' ', user.firstname)")
3071
                ."	AS col4,
3072
                survey.avail_from AS col5,
3073
                survey.avail_till AS col6,
3074
                survey.invited AS col7,
3075
                survey.anonymous AS col8,
3076
                survey.iid AS col9,
3077
                survey.session_id AS session_id,
3078
                survey.answered,
3079
                survey.invited,
3080
                survey.survey_type
3081
            FROM $table_survey survey
3082
            LEFT JOIN $table_survey_question survey_question
3083
            ON (survey.survey_id = survey_question.survey_id AND survey_question.c_id = $course_id)
3084
            LEFT JOIN $table_user user
3085
            ON (survey.author = user.user_id)
3086
            WHERE survey.c_id = $course_id
3087
            $search_restriction
3088
            $condition_session 
3089
            GROUP BY survey.survey_id
3090
            ORDER BY col$column $direction 
3091
            LIMIT $from,$number_of_items
3092
        ";
3093
        $res = Database::query($sql);
3094
        $surveys = [];
3095
        $array = [];
3096
        $efv = new ExtraFieldValue('survey');
3097
        while ($survey = Database::fetch_array($res)) {
3098
            $array[0] = $survey[0];
3099
            if (self::checkHideEditionToolsByCode($survey['col2'])) {
3100
                $array[1] = $survey[1];
3101
            } else {
3102
                // Doodle
3103
                if ($survey['survey_type'] == 3) {
3104
                    $array[1] = Display::url(
3105
                        $survey[1],
3106
                        api_get_path(WEB_CODE_PATH).'survey/meeting.php?survey_id='.$survey[0].'&'.api_get_cidreq()
3107
                    );
3108
            } else {
3109
                $array[1] = Display::url(
3110
                    $survey[1],
3111
                    api_get_path(WEB_CODE_PATH).'survey/survey.php?survey_id='.$survey[0].'&'.api_get_cidreq()
3112
                );
3113
            }
3114
            }
3115
3116
            // Validation when belonging to a session
3117
            $session_img = api_get_session_image($survey['session_id'], $_user['status']);
3118
            $array[2] = $survey[2].$session_img;
3119
            $array[3] = $survey[3];
3120
            $array[4] = $survey[4];
3121
            $array[5] = api_convert_and_format_date(
3122
                $survey[5],
3123
                $allowSurveyAvailabilityDatetime ? DATE_TIME_FORMAT_LONG : DATE_FORMAT_LONG
3124
            );
3125
            $array[6] = api_convert_and_format_date(
3126
                $survey[6],
3127
                $allowSurveyAvailabilityDatetime ? DATE_TIME_FORMAT_LONG : DATE_FORMAT_LONG
3128
            );
3129
            $array[7] =
3130
                Display::url(
3131
                    $survey['answered'],
3132
                    api_get_path(WEB_CODE_PATH).'survey/survey_invitation.php?view=answered&survey_id='.$survey[0].'&'
3133
                        .api_get_cidreq()
3134
                ).' / '.
3135
                Display::url(
3136
                    $survey['invited'],
3137
                    api_get_path(WEB_CODE_PATH).'survey/survey_invitation.php?view=invited&survey_id='.$survey[0].'&'
3138
                        .api_get_cidreq()
3139
                );
3140
            // Anon
3141
            $array[8] = $survey['col8'];
3142
            if ($mandatoryAllowed) {
3143
                $efvMandatory = $efv->get_values_by_handler_and_field_variable(
3144
                    $survey[9],
3145
                    'is_mandatory'
3146
                );
3147
3148
                $array[9] = $efvMandatory ? $efvMandatory['value'] : 0;
3149
                // Survey id
3150
                $array[10] = $survey['col9'];
3151
            } else {
3152
                // Survey id
3153
                $array[9] = $survey['col9'];
3154
            }
3155
3156
            if ($isDrh) {
3157
                $array[1] = $survey[1];
3158
                $array[7] = strip_tags($array[7]);
3159
            }
3160
3161
            $surveys[] = $array;
3162
        }
3163
3164
        return $surveys;
3165
    }
3166
3167
    /**
3168
     * @param $from
3169
     * @param $number_of_items
3170
     * @param $column
3171
     * @param $direction
3172
     *
3173
     * @return array
3174
     */
3175
    public static function get_survey_data_for_coach($from, $number_of_items, $column, $direction)
3176
    {
3177
        $mandatoryAllowed = api_get_configuration_value('allow_mandatory_survey');
3178
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
3179
        $survey_tree = new SurveyTree();
3180
        //$last_version_surveys = $survey_tree->get_last_children_from_branch($survey_tree->surveylist);
3181
        $last_version_surveys = $survey_tree->surveylist;
3182
        $list = [];
3183
        foreach ($last_version_surveys as &$survey) {
3184
            $list[] = $survey['id'];
3185
        }
3186
        if (count($list) > 0) {
3187
            $list_condition = " AND survey.survey_id IN (".implode(',', $list).") ";
3188
        } else {
3189
            $list_condition = '';
3190
        }
3191
3192
        $from = intval($from);
3193
        $number_of_items = intval($number_of_items);
3194
        $column = intval($column);
3195
        if (!in_array(strtolower($direction), ['asc', 'desc'])) {
3196
            $direction = 'asc';
3197
        }
3198
3199
        $table_survey = Database::get_course_table(TABLE_SURVEY);
3200
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
3201
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
3202
        $course_id = api_get_course_int_id();
3203
        $efv = new ExtraFieldValue('survey');
3204
3205
        $sql = "
3206
            SELECT 
3207
            survey.survey_id AS col0, 
3208
                survey.title AS col1, 
3209
                survey.code AS col2, 
3210
                count(survey_question.question_id) AS col3, 
3211
        "
3212
            .(api_is_western_name_order()
3213
                ? "CONCAT(user.firstname, ' ', user.lastname)"
3214
                : "CONCAT(user.lastname, ' ', user.firstname)")
3215
            ."	AS col4,
3216
                survey.avail_from AS col5,
3217
                survey.avail_till AS col6,
3218
                CONCAT('<a href=\"survey_invitation.php?view=answered&survey_id=',survey.survey_id,'\">',survey.answered,'</a> / <a href=\"survey_invitation.php?view=invited&survey_id=',survey.survey_id,'\">',survey.invited, '</a>') AS col7,
3219
                survey.anonymous AS col8,
3220
                survey.survey_id AS col9
3221
            FROM $table_survey survey
3222
            LEFT JOIN $table_survey_question survey_question
3223
            ON (survey.survey_id = survey_question.survey_id AND survey.c_id = survey_question.c_id),
3224
            $table_user user
3225
            WHERE survey.author = user.user_id AND survey.c_id = $course_id $list_condition
3226
        ";
3227
        $sql .= " GROUP BY survey.survey_id";
3228
        $sql .= " ORDER BY col$column $direction ";
3229
        $sql .= " LIMIT $from,$number_of_items";
3230
3231
        $res = Database::query($sql);
3232
        $surveys = [];
3233
        while ($survey = Database::fetch_array($res)) {
3234
            $survey['col5'] = api_convert_and_format_date(
3235
                $survey['col5'],
3236
                $allowSurveyAvailabilityDatetime ? DATE_TIME_FORMAT_LONG : DATE_FORMAT_LONG
3237
            );
3238
            $survey['col6'] = api_convert_and_format_date(
3239
                $survey['col6'],
3240
                $allowSurveyAvailabilityDatetime ? DATE_TIME_FORMAT_LONG : DATE_FORMAT_LONG
3241
            );
3242
3243
            if ($mandatoryAllowed) {
3244
                $survey['col10'] = $survey['col9'];
3245
                $efvMandatory = $efv->get_values_by_handler_and_field_variable(
3246
                    $survey['col9'],
3247
                    'is_mandatory'
3248
                );
3249
                $survey['col9'] = $efvMandatory['value'];
3250
            }
3251
            $surveys[] = $survey;
3252
        }
3253
3254
        return $surveys;
3255
    }
3256
3257
    /**
3258
     * Display all the active surveys for the given course user.
3259
     *
3260
     * @param int $user_id
3261
     *
3262
     * @author Patrick Cool <[email protected]>, Ghent University
3263
     *
3264
     * @version April 2007
3265
     */
3266
    public static function getSurveyList($user_id)
3267
    {
3268
        $_course = api_get_course_info();
3269
        $course_id = $_course['real_id'];
3270
        $user_id = (int) $user_id;
3271
        $sessionId = api_get_session_id();
3272
        $mandatoryAllowed = api_get_configuration_value('allow_mandatory_survey');
3273
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
3274
3275
        // Database table definitions
3276
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
3277
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
3278
        $table_survey = Database::get_course_table(TABLE_SURVEY);
3279
3280
        echo '<table id="list-survey" class="table ">';
3281
        echo '<thead>';
3282
        echo '<tr>';
3283
        echo '	<th>'.get_lang('SurveyName').'</th>';
3284
        echo '	<th class="text-center">'.get_lang('Anonymous').'</th>';
3285
        if ($mandatoryAllowed) {
3286
            echo '<th class="text-center">'.get_lang('IsMandatory').'</th>';
3287
        }
3288
        echo '</tr>';
3289
        echo '</thead>';
3290
        echo '<tbody>';
3291
3292
        /** @var \DateTime $now */
3293
        $now = api_get_utc_datetime(null, false, true);
3294
        $filterDate = $allowSurveyAvailabilityDatetime ? $now->format('Y-m-d H:i') : $now->format('Y-m-d');
3295
3296
        $sql = "SELECT *
3297
                FROM $table_survey survey 
3298
                INNER JOIN
3299
                $table_survey_invitation survey_invitation
3300
                ON (
3301
                    survey.code = survey_invitation.survey_code AND
3302
                    survey.c_id = survey_invitation.c_id AND 
3303
                    survey.session_id = survey_invitation.session_id
3304
                )
3305
				WHERE
3306
                    survey_invitation.user = $user_id AND                    
3307
                    survey.avail_from <= '$filterDate' AND
3308
                    survey.avail_till >= '$filterDate' AND
3309
                    survey.c_id = $course_id AND
3310
                    survey.session_id = $sessionId AND
3311
                    survey_invitation.c_id = $course_id
3312
				";
3313
        $result = Database::query($sql);
3314
3315
        $efv = new ExtraFieldValue('survey');
3316
3317
        while ($row = Database::fetch_array($result, 'ASSOC')) {
3318
            echo '<tr>';
3319
            if ($row['answered'] == 0) {
3320
                echo '<td>';
3321
                echo Display::return_icon(
3322
                    'statistics.png',
3323
                    get_lang('CreateNewSurvey'),
3324
                    [],
3325
                    ICON_SIZE_TINY
3326
                );
3327
                $url = api_get_path(WEB_CODE_PATH).'survey/fillsurvey.php?course='.$_course['sysCode']
3328
                    .'&invitationcode='.$row['invitation_code'].'&cidReq='.$_course['sysCode'].'&id_session='.$row['session_id'];
3329
                echo '<a href="'.$url.'">
3330
                    '.$row['title']
3331
                    .'</a></td>';
3332
            } else {
3333
                $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
3334
                    $user_id,
3335
                    $_course
3336
                );
3337
                $icon = Display::return_icon(
3338
                    'statistics_na.png',
3339
                    get_lang('Survey'),
3340
                    [],
3341
                    ICON_SIZE_TINY
3342
                );
3343
                $showLink = (!api_is_allowed_to_edit(false, true) || $isDrhOfCourse)
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: $showLink = (! api_is_al...= SURVEY_VISIBLE_TUTOR), Probably Intended Meaning: $showLink = ! api_is_all...= SURVEY_VISIBLE_TUTOR)
Loading history...
3344
                    && $row['visible_results'] != SURVEY_VISIBLE_TUTOR;
3345
3346
                echo '<td>';
3347
                echo $showLink
3348
                    ? Display::url(
3349
                        $icon.PHP_EOL.$row['title'],
3350
                        api_get_path(WEB_CODE_PATH).'survey/reporting.php?'.api_get_cidreq().'&'.http_build_query([
3351
                            'action' => 'questionreport',
3352
                            'survey_id' => $row['survey_id'],
3353
                        ])
3354
                    )
3355
                    : $icon.PHP_EOL.$row['title'];
3356
                echo '</td>';
3357
            }
3358
            echo '<td class="text-center">';
3359
            echo ($row['anonymous'] == 1) ? get_lang('Yes') : get_lang('No');
3360
            echo '</td>';
3361
            if ($mandatoryAllowed) {
3362
                $efvMandatory = $efv->get_values_by_handler_and_field_variable(
3363
                    $row['survey_id'],
3364
                    'is_mandatory'
3365
                );
3366
                echo '<td class="text-center">'.($efvMandatory['value'] ? get_lang('Yes') : get_lang('No')).'</td>';
3367
            }
3368
            echo '</tr>';
3369
        }
3370
        echo '</tbody>';
3371
        echo '</table>';
3372
    }
3373
3374
    /**
3375
     * Creates a multi array with the user fields that we can show.
3376
     * We look the visibility with the api_get_setting function
3377
     * The username is always NOT able to change it.
3378
     *
3379
     * @author Julio Montoya Armas <[email protected]>, Chamilo: Personality Test modification
3380
     *
3381
     * @return array array[value_name][name], array[value_name][visibilty]
3382
     */
3383
    public static function make_field_list()
3384
    {
3385
        //	LAST NAME and FIRST NAME
3386
        $field_list_array = [];
3387
        $field_list_array['lastname']['name'] = get_lang('LastName');
3388
        $field_list_array['firstname']['name'] = get_lang('FirstName');
3389
3390
        if (api_get_setting('profile', 'name') != 'true') {
3391
            $field_list_array['firstname']['visibility'] = 0;
3392
            $field_list_array['lastname']['visibility'] = 0;
3393
        } else {
3394
            $field_list_array['firstname']['visibility'] = 1;
3395
            $field_list_array['lastname']['visibility'] = 1;
3396
        }
3397
3398
        $field_list_array['username']['name'] = get_lang('Username');
3399
        $field_list_array['username']['visibility'] = 0;
3400
3401
        //	OFFICIAL CODE
3402
        $field_list_array['official_code']['name'] = get_lang('OfficialCode');
3403
3404
        if (api_get_setting('profile', 'officialcode') != 'true') {
3405
            $field_list_array['official_code']['visibility'] = 1;
3406
        } else {
3407
            $field_list_array['official_code']['visibility'] = 0;
3408
        }
3409
3410
        // EMAIL
3411
        $field_list_array['email']['name'] = get_lang('Email');
3412
        if (api_get_setting('profile', 'email') != 'true') {
3413
            $field_list_array['email']['visibility'] = 1;
3414
        } else {
3415
            $field_list_array['email']['visibility'] = 0;
3416
        }
3417
3418
        // PHONE
3419
        $field_list_array['phone']['name'] = get_lang('Phone');
3420
        if (api_get_setting('profile', 'phone') != 'true') {
3421
            $field_list_array['phone']['visibility'] = 0;
3422
        } else {
3423
            $field_list_array['phone']['visibility'] = 1;
3424
        }
3425
        //	LANGUAGE
3426
        $field_list_array['language']['name'] = get_lang('Language');
3427
        if (api_get_setting('profile', 'language') != 'true') {
3428
            $field_list_array['language']['visibility'] = 0;
3429
        } else {
3430
            $field_list_array['language']['visibility'] = 1;
3431
        }
3432
3433
        // EXTRA FIELDS
3434
        $extra = UserManager::get_extra_fields(0, 50, 5, 'ASC');
3435
3436
        foreach ($extra as $id => $field_details) {
3437
            if ($field_details[6] == 0) {
3438
                continue;
3439
            }
3440
            switch ($field_details[2]) {
3441
                case UserManager::USER_FIELD_TYPE_TEXT:
3442
                    $field_list_array['extra_'.$field_details[1]]['name'] = $field_details[3];
3443
                    if ($field_details[7] == 0) {
3444
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 0;
3445
                    } else {
3446
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 1;
3447
                    }
3448
                    break;
3449
                case UserManager::USER_FIELD_TYPE_TEXTAREA:
3450
                    $field_list_array['extra_'.$field_details[1]]['name'] = $field_details[3];
3451
                    if ($field_details[7] == 0) {
3452
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 0;
3453
                    } else {
3454
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 1;
3455
                    }
3456
                    break;
3457
                case UserManager::USER_FIELD_TYPE_RADIO:
3458
                    $field_list_array['extra_'.$field_details[1]]['name'] = $field_details[3];
3459
                    if ($field_details[7] == 0) {
3460
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 0;
3461
                    } else {
3462
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 1;
3463
                    }
3464
                    break;
3465
                case UserManager::USER_FIELD_TYPE_SELECT:
3466
                    $get_lang_variables = false;
3467
                    if (in_array(
3468
                        $field_details[1],
3469
                        ['mail_notify_message', 'mail_notify_invitation', 'mail_notify_group_message']
3470
                    )
3471
                    ) {
3472
                        $get_lang_variables = true;
3473
                    }
3474
3475
                    if ($get_lang_variables) {
3476
                        $field_list_array['extra_'.$field_details[1]]['name'] = get_lang($field_details[3]);
3477
                    } else {
3478
                        $field_list_array['extra_'.$field_details[1]]['name'] = $field_details[3];
3479
                    }
3480
3481
                    if ($field_details[7] == 0) {
3482
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 0;
3483
                    } else {
3484
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 1;
3485
                    }
3486
                    break;
3487
                case UserManager::USER_FIELD_TYPE_SELECT_MULTIPLE:
3488
                    $field_list_array['extra_'.$field_details[1]]['name'] = $field_details[3];
3489
                    if ($field_details[7] == 0) {
3490
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 0;
3491
                    } else {
3492
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 1;
3493
                    }
3494
                    break;
3495
                case UserManager::USER_FIELD_TYPE_DATE:
3496
                    $field_list_array['extra_'.$field_details[1]]['name'] = $field_details[3];
3497
                    if ($field_details[7] == 0) {
3498
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 0;
3499
                    } else {
3500
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 1;
3501
                    }
3502
                    break;
3503
                case UserManager::USER_FIELD_TYPE_DATETIME:
3504
                    $field_list_array['extra_'.$field_details[1]]['name'] = $field_details[3];
3505
                    if ($field_details[7] == 0) {
3506
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 0;
3507
                    } else {
3508
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 1;
3509
                    }
3510
                    break;
3511
                case UserManager::USER_FIELD_TYPE_DOUBLE_SELECT:
3512
                    $field_list_array['extra_'.$field_details[1]]['name'] = $field_details[3];
3513
                    if ($field_details[7] == 0) {
3514
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 0;
3515
                    } else {
3516
                        $field_list_array['extra_'.$field_details[1]]['visibility'] = 1;
3517
                    }
3518
                    break;
3519
                case UserManager::USER_FIELD_TYPE_DIVIDER:
3520
                    //$form->addElement('static',$field_details[1], '<br /><strong>'.$field_details[3].'</strong>');
3521
                    break;
3522
            }
3523
        }
3524
3525
        return $field_list_array;
3526
    }
3527
3528
    /**
3529
     * @author Isaac Flores Paz <[email protected]>
3530
     *
3531
     * @param int    $user_id     User ID
3532
     * @param string $survey_code
3533
     * @param int    $user_answer User in survey answer table (user id or anonymous)
3534
     *
3535
     * @return bool
3536
     */
3537
    public static function show_link_available($user_id, $survey_code, $user_answer)
3538
    {
3539
        $table_survey = Database::get_course_table(TABLE_SURVEY);
3540
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
3541
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
3542
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
3543
3544
        $survey_code = Database::escape_string($survey_code);
3545
        $user_id = intval($user_id);
3546
        $user_answer = Database::escape_string($user_answer);
3547
        $course_id = api_get_course_int_id();
3548
3549
        $sql = 'SELECT COUNT(*) as count
3550
                FROM '.$table_survey_invitation.'
3551
		        WHERE
3552
		            user='.$user_id.' AND
3553
		            survey_code="'.$survey_code.'" AND 
3554
		            answered="1" AND 
3555
		            c_id = '.$course_id;
3556
3557
        $sql2 = 'SELECT COUNT(*) as count 
3558
                 FROM '.$table_survey.' s 
3559
                 INNER JOIN '.$table_survey_question.' q 
3560
                 ON s.survey_id=q.survey_id
3561
				 WHERE 
3562
				    s.code="'.$survey_code.'" AND 
3563
				    q.type NOT IN("pagebreak","comment") AND s.c_id = '.$course_id.' AND q.c_id = '.$course_id.' ';
3564
3565
        $sql3 = 'SELECT COUNT(DISTINCT question_id) as count 
3566
                 FROM '.$table_survey_answer.'
3567
				 WHERE survey_id=(
3568
				    SELECT survey_id FROM '.$table_survey.'
3569
				    WHERE 
3570
				        code = "'.$survey_code.'" AND 
3571
				        c_id = '.$course_id.' 
3572
                    )  AND 
3573
                user="'.$user_answer.'" AND 
3574
                c_id = '.$course_id;
3575
3576
        $result = Database::query($sql);
3577
        $result2 = Database::query($sql2);
3578
        $result3 = Database::query($sql3);
3579
3580
        $row = Database::fetch_array($result, 'ASSOC');
3581
        $row2 = Database::fetch_array($result2, 'ASSOC');
3582
        $row3 = Database::fetch_array($result3, 'ASSOC');
3583
3584
        if ($row['count'] == 1 && $row3['count'] != $row2['count']) {
3585
            return true;
3586
        } else {
3587
            return false;
3588
        }
3589
    }
3590
3591
    /**
3592
     * Display survey question chart.
3593
     *
3594
     * @param array  $chartData
3595
     * @param bool   $hasSerie         Tells if the chart has a serie. False by default
3596
     * @param string $chartContainerId
3597
     *
3598
     * @return string (direct output)
3599
     */
3600
    public static function drawChart(
3601
        $chartData,
3602
        $hasSerie = false,
3603
        $chartContainerId = 'chartContainer'
3604
    ) {
3605
        $htmlChart = '';
3606
        if (api_browser_support("svg")) {
3607
            $htmlChart .= api_get_js("d3/d3.v3.5.4.min.js");
3608
            $htmlChart .= api_get_js("dimple.v2.1.2.min.js").'
3609
            <script>
3610
            var svg = dimple.newSvg("#'.$chartContainerId.'", "100%", 400);
3611
            var data = [';
3612
            $serie = [];
3613
            $order = [];
3614
            foreach ($chartData as $chartDataElement) {
3615
                $htmlChart .= '{"';
3616
                if (!$hasSerie) {
3617
                    $htmlChart .= get_lang("Option").'":"'.$chartDataElement['option'].'", "';
3618
                    array_push($order, $chartDataElement['option']);
3619
                } else {
3620
                    if (!is_array($chartDataElement['serie'])) {
3621
                        $htmlChart .= get_lang("Option").'":"'.$chartDataElement['serie'].'", "'.
3622
                            get_lang("Score").'":"'.$chartDataElement['option'].'", "';
3623
                        array_push($serie, $chartDataElement['serie']);
3624
                    } else {
3625
                        $htmlChart .= get_lang("Serie").'":"'.$chartDataElement['serie'][0].'", "'.
3626
                            get_lang("Option").'":"'.$chartDataElement['serie'][1].'", "'.
3627
                            get_lang("Score").'":"'.$chartDataElement['option'].'", "';
3628
                    }
3629
                }
3630
                $htmlChart .= get_lang("Votes").'":"'.$chartDataElement['votes'].
3631
                    '"},';
3632
            }
3633
            rtrim($htmlChart, ",");
3634
            $htmlChart .= '];
3635
                var myChart = new dimple.chart(svg, data);
3636
                myChart.addMeasureAxis("y", "'.get_lang("Votes").'");';
3637
            if (!$hasSerie) {
3638
                $htmlChart .= 'var xAxisCategory = myChart.addCategoryAxis("x", "'.get_lang("Option").'");
3639
                    xAxisCategory.addOrderRule('.json_encode($order).');
3640
                    myChart.addSeries("'.get_lang("Option").'", dimple.plot.bar);';
3641
            } else {
3642
                if (!is_array($chartDataElement['serie'])) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $chartDataElement seems to be defined by a foreach iteration on line 3614. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
3643
                    $serie = array_values(array_unique($serie));
3644
                    $htmlChart .= 'var xAxisCategory = myChart.addCategoryAxis("x", ["'.get_lang("Option").'","'
3645
                        .get_lang("Score").'"]);
3646
                        xAxisCategory.addOrderRule('.json_encode($serie).');
3647
                        xAxisCategory.addGroupOrderRule("'.get_lang("Score").'");
3648
                        myChart.addSeries("'.get_lang("Option").'", dimple.plot.bar);';
3649
                } else {
3650
                    $htmlChart .= 'myChart.addCategoryAxis("x", ["'.get_lang("Option").'","'.get_lang("Score").'"]);
3651
                        myChart.addSeries("'.get_lang("Serie").'", dimple.plot.bar);';
3652
                }
3653
            }
3654
            $htmlChart .= 'myChart.draw();
3655
                </script>';
3656
        }
3657
3658
        return $htmlChart;
3659
    }
3660
3661
    /**
3662
     * Set a flag to the current survey as answered by the current user.
3663
     *
3664
     * @param string $surveyCode The survey code
3665
     * @param int    $courseId   The course ID
3666
     */
3667
    public static function flagSurveyAsAnswered($surveyCode, $courseId)
3668
    {
3669
        $currentUserId = api_get_user_id();
3670
        $flag = sprintf("%s-%s-%d", $courseId, $surveyCode, $currentUserId);
3671
3672
        if (!isset($_SESSION['filled_surveys'])) {
3673
            $_SESSION['filled_surveys'] = [];
3674
        }
3675
3676
        $_SESSION['filled_surveys'][] = $flag;
3677
    }
3678
3679
    /**
3680
     * Check whether a survey was answered by the current user.
3681
     *
3682
     * @param string $surveyCode The survey code
3683
     * @param int    $courseId   The course ID
3684
     *
3685
     * @return bool
3686
     */
3687
    public static function isSurveyAnsweredFlagged($surveyCode, $courseId)
3688
    {
3689
        $currentUserId = api_get_user_id();
3690
        $flagToCheck = sprintf("%s-%s-%d", $courseId, $surveyCode, $currentUserId);
3691
3692
        if (!isset($_SESSION['filled_surveys'])) {
3693
            return false;
3694
        }
3695
3696
        if (!is_array($_SESSION['filled_surveys'])) {
3697
            return false;
3698
        }
3699
3700
        foreach ($_SESSION['filled_surveys'] as $flag) {
3701
            if ($flagToCheck != $flag) {
3702
                continue;
3703
            }
3704
3705
            return true;
3706
        }
3707
3708
        return false;
3709
    }
3710
3711
    /**
3712
     * Check if the current survey has answers.
3713
     *
3714
     * @param int $surveyId
3715
     *
3716
     * @return bool return true if the survey has answers, false otherwise
3717
     */
3718
    public static function checkIfSurveyHasAnswers($surveyId)
3719
    {
3720
        $tableSurveyAnswer = Database::get_course_table(TABLE_SURVEY_ANSWER);
3721
        $courseId = api_get_course_int_id();
3722
        $surveyId = (int) $surveyId;
3723
3724
        if (empty($courseId) || empty($surveyId)) {
3725
            return false;
3726
        }
3727
3728
        $sql = "SELECT * FROM $tableSurveyAnswer
3729
                WHERE
3730
                    c_id = $courseId AND
3731
                    survey_id = '".$surveyId."'
3732
                ORDER BY answer_id, user ASC";
3733
        $result = Database::query($sql);
3734
        $response = Database::affected_rows($result);
3735
3736
        return $response > 0;
3737
    }
3738
3739
    /**
3740
     * Get the pending surveys for a user.
3741
     *
3742
     * @param int $userId
3743
     *
3744
     * @return array
3745
     */
3746
    public static function getUserPendingInvitations($userId)
3747
    {
3748
        $now = api_get_utc_datetime(null, false, true);
3749
3750
        $dql = "
3751
            SELECT s, si FROM ChamiloCourseBundle:CSurvey s
3752
            INNER JOIN ChamiloCourseBundle:CSurveyInvitation si
3753
                WITH (s.code = si.surveyCode AND s.cId = si.cId AND s.sessionId = si.sessionId )
3754
            WHERE 
3755
                si.user = :user_id AND 
3756
                s.availFrom <= :now AND 
3757
                s.availTill >= :now AND 
3758
                si.answered = 0
3759
            ORDER BY s.availTill ASC
3760
        ";
3761
3762
        $pendingSurveys = Database::getManager()
3763
            ->createQuery($dql)
3764
            ->setParameters(['user_id' => $userId, 'now' => $now->format('Y-m-d')])
3765
            ->getResult();
3766
3767
        return $pendingSurveys;
3768
    }
3769
}
3770