Completed
Push — master ( 9b8b24...6e1754 )
by Julito
58:58
created

SurveyUtil::store_answer()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 44
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 24
nc 4
nop 6
dl 0
loc 44
rs 8.5806
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CSurvey;
5
use ChamiloSession as Session;
6
7
/**
8
 * This class offers a series of general utility functions for survey querying and display
9
 * @package chamilo.survey
10
 */
11
class SurveyUtil
12
{
13
    /**
14
     * Checks whether the given survey has a pagebreak question as the first
15
     * or the last question.
16
     * If so, break the current process, displaying an error message
17
     * @param    integer $survey_id Survey ID (database ID)
18
     * @param    boolean $continue Optional. Whether to continue the current
19
     * process or exit when breaking condition found. Defaults to true (do not break).
20
     * @return    void
21
     */
22
    public static function check_first_last_question($survey_id, $continue = true)
23
    {
24
        // Table definitions
25
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
26
        $course_id = api_get_course_int_id();
27
28
        // Getting the information of the question
29
        $sql = "SELECT * FROM $tbl_survey_question
30
                WHERE c_id = $course_id AND survey_id='".Database::escape_string($survey_id)."'
31
                ORDER BY sort ASC";
32
        $result = Database::query($sql);
33
        $total = Database::num_rows($result);
34
        $counter = 1;
35
        $error = false;
36
        while ($row = Database::fetch_array($result, 'ASSOC')) {
37
            if ($counter == 1 && $row['type'] == 'pagebreak') {
38
                echo Display::return_message(get_lang('PagebreakNotFirst'), 'error', false);
39
                $error = true;
40
            }
41
            if ($counter == $total && $row['type'] == 'pagebreak') {
42
                echo Display::return_message(get_lang('PagebreakNotLast'), 'error', false);
43
                $error = true;
44
            }
45
            $counter++;
46
        }
47
48
        if (!$continue && $error) {
49
            Display::display_footer();
50
            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...
51
        }
52
    }
53
54
    /**
55
     * This function removes an (or multiple) answer(s) of a user on a question of a survey
56
     *
57
     * @param mixed   The user id or email of the person who fills the survey
58
     * @param integer The survey id
59
     * @param integer The question id
60
     * @param integer The option id
61
     *
62
     * @author Patrick Cool <[email protected]>, Ghent University
63
     * @version January 2007
64
     */
65
    public static function remove_answer($user, $survey_id, $question_id, $course_id)
66
    {
67
        $course_id = intval($course_id);
68
        // table definition
69
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
70
        $sql = "DELETE FROM $table
71
				WHERE
72
				    c_id = $course_id AND
73
                    user = '".Database::escape_string($user)."' AND
74
                    survey_id = '".intval($survey_id)."' AND
75
                    question_id = '".intval($question_id)."'";
76
        Database::query($sql);
77
    }
78
79
    /**
80
     * This function stores an answer of a user on a question of a survey
81
     *
82
     * @param mixed   The user id or email of the person who fills the survey
83
     * @param integer Survey id
84
     * @param integer Question id
85
     * @param integer Option id
86
     * @param string  Option value
87
     * @param array $survey_data Survey data settings
88
     * @return bool False if insufficient data, true otherwise
89
     *
90
     * @author Patrick Cool <[email protected]>, Ghent University
91
     * @version January 2007
92
     */
93
    public static function store_answer(
94
        $user,
95
        $survey_id,
96
        $question_id,
97
        $option_id,
98
        $option_value,
99
        $survey_data
100
    ) {
101
        // If the question_id is empty, don't store an answer
102
        if (empty($question_id)) {
103
            return false;
104
        }
105
        // Table definition
106
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
107
108
        // Make the survey anonymous
109
        if ($survey_data['anonymous'] == 1) {
110
            $surveyUser = Session::read('surveyuser');
111
            if (empty($surveyUser)) {
112
                $user = md5($user.time());
113
                Session::write('surveyuser', $user);
114
            } else {
115
                $user = Session::read('surveyuser');
116
            }
117
        }
118
119
        $course_id = $survey_data['c_id'];
120
121
        $sql = "INSERT INTO $table_survey_answer (c_id, user, survey_id, question_id, option_id, value) VALUES (
122
				$course_id,
123
				'".Database::escape_string($user)."',
124
				'".Database::escape_string($survey_id)."',
125
				'".Database::escape_string($question_id)."',
126
				'".Database::escape_string($option_id)."',
127
				'".Database::escape_string($option_value)."'
128
				)";
129
        Database::query($sql);
130
        $insertId = Database::insert_id();
131
132
        $sql = "UPDATE $table_survey_answer SET answer_id = $insertId 
133
                WHERE iid = $insertId";
134
        Database::query($sql);
135
136
        return true;
137
    }
138
139
    /**
140
     * This function checks the parameters that are used in this page
141
     *
142
     * @return string $people_filled The header, an error and the footer if any parameter fails, else it returns true
143
     * @author Patrick Cool <[email protected]>, Ghent University
144
     * @version February 2007
145
     */
146
    public static function check_parameters($people_filled)
147
    {
148
        $error = false;
149
150
        // Getting the survey data
151
        $survey_data = SurveyManager::get_survey($_GET['survey_id']);
152
153
        // $_GET['survey_id'] has to be numeric
154
        if (!is_numeric($_GET['survey_id'])) {
155
            $error = get_lang('IllegalSurveyId');
156
        }
157
158
        // $_GET['action']
159
        $allowed_actions = array(
160
            'overview',
161
            'questionreport',
162
            'userreport',
163
            'comparativereport',
164
            'completereport',
165
            'deleteuserreport'
166
        );
167
        if (isset($_GET['action']) && !in_array($_GET['action'], $allowed_actions)) {
168
            $error = get_lang('ActionNotAllowed');
169
        }
170
171
        // User report
172
        if (isset($_GET['action']) && $_GET['action'] == 'userreport') {
173
            if ($survey_data['anonymous'] == 0) {
174
                foreach ($people_filled as $key => & $value) {
175
                    $people_filled_userids[] = $value['invited_user'];
176
                }
177
            } else {
178
                $people_filled_userids = $people_filled;
179
            }
180
181
            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...
182
                $error = get_lang('UnknowUser');
183
            }
184
        }
185
186
        // Question report
187
        if (isset($_GET['action']) && $_GET['action'] == 'questionreport') {
188
            if (isset($_GET['question']) && !is_numeric($_GET['question'])) {
189
                $error = get_lang('UnknowQuestion');
190
            }
191
        }
192
193
        if ($error) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $error of type false|string is loosely compared to true; this is ambiguous if the string can be empty. 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 string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
194
            $tool_name = get_lang('Reporting');
195
            Display::addFlash(
196
                Display::return_message(
197
                    get_lang('Error').': '.$error,
198
                    'error',
199
                    false
200
                )
201
            );
202
            Display::display_header($tool_name);
203
            Display::display_footer();
204
            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...
205
        } else {
206
            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...
207
        }
208
    }
209
210
    /**
211
     * This function deals with the action handling
212
     * @param array $survey_data
213
     * @param array $people_filled
214
     * @return void
215
     * @author Patrick Cool <[email protected]>, Ghent University
216
     * @version February 2007
217
     */
218
    public static function handle_reporting_actions($survey_data, $people_filled)
219
    {
220
        $action = isset($_GET['action']) ? $_GET['action'] : null;
221
222
        // Getting the number of question
223
        $temp_questions_data = SurveyManager::get_questions($_GET['survey_id']);
224
225
        // Sorting like they should be displayed and removing the non-answer question types (comment and pagebreak)
226
        $my_temp_questions_data = $temp_questions_data == null ? array() : $temp_questions_data;
227
        $questions_data = array();
228
229
        foreach ($my_temp_questions_data as $key => & $value) {
230
            if ($value['type'] != 'comment' && $value['type'] != 'pagebreak') {
231
                $questions_data[$value['sort']] = $value;
232
            }
233
        }
234
235
        // Counting the number of questions that are relevant for the reporting
236
        $survey_data['number_of_questions'] = count($questions_data);
237
238
        if ($action == 'questionreport') {
239
            self::display_question_report($survey_data);
240
        }
241
        if ($action == 'userreport') {
242
            self::display_user_report($people_filled, $survey_data);
243
        }
244
        if ($action == 'comparativereport') {
245
            self::display_comparative_report();
246
        }
247
        if ($action == 'completereport') {
248
            self::display_complete_report($survey_data);
249
        }
250
        if ($action == 'deleteuserreport') {
251
            self::delete_user_report($_GET['survey_id'], $_GET['user']);
252
        }
253
    }
254
255
    /**
256
     * This function deletes the report of an user who wants to retake the survey
257
     * @param integer $survey_id
258
     * @param integer $user_id
259
     * @return void
260
     * @author Christian Fasanando Flores <[email protected]>
261
     * @version November 2008
262
     */
263
    public static function delete_user_report($survey_id, $user_id)
264
    {
265
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
266
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
267
        $table_survey = Database::get_course_table(TABLE_SURVEY);
268
269
        $course_id = api_get_course_int_id();
270
        $survey_id = (int) $survey_id;
271
        $user_id = Database::escape_string($user_id);
272
273
        if (!empty($survey_id) && !empty($user_id)) {
274
            // delete data from survey_answer by user_id and survey_id
275
            $sql = "DELETE FROM $table_survey_answer
276
			        WHERE c_id = $course_id AND survey_id = '".$survey_id."' AND user = '".$user_id."'";
277
            Database::query($sql);
278
            // update field answered from survey_invitation by user_id and survey_id
279
            $sql = "UPDATE $table_survey_invitation SET answered = '0'
280
			        WHERE
281
			            c_id = $course_id AND
282
			            survey_code = (
283
                            SELECT code FROM $table_survey
284
                            WHERE
285
                                c_id = $course_id AND
286
                                survey_id = '".$survey_id."'
287
                        ) AND
288
			            user = '".$user_id."'";
289
            $result = Database::query($sql);
290
        }
291
292
        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...
293
            $message = get_lang('SurveyUserAnswersHaveBeenRemovedSuccessfully').'<br />
294
					<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action=userreport&survey_id='
295
                .$survey_id.'">'.
296
                get_lang('GoBack').'</a>';
297
            echo Display::return_message($message, 'confirmation', false);
298
        }
299
    }
300
301
    /**
302
     * This function displays the user report which is basically nothing more
303
     * than a one-page display of all the questions
304
     * of the survey that is filled with the answers of the person who filled the survey.
305
     *
306
     * @return string html code of the one-page survey with the answers of the selected user
307
     * @author Patrick Cool <[email protected]>, Ghent University
308
     * @version February 2007 - Updated March 2008
309
     */
310
    public static function display_user_report($people_filled, $survey_data)
311
    {
312
        // Database table definitions
313
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
314
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
315
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
316
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
317
318
        // Actions bar
319
        echo '<div class="actions">';
320
        echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?survey_id='.$surveyId.'&'.api_get_cidreq().'">'.
321
            Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('ReportingOverview'), '', ICON_SIZE_MEDIUM)
322
            .'</a>';
323
        if (isset($_GET['user'])) {
324
            if (api_is_allowed_to_edit()) {
325
                // The delete link
326
                echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action=deleteuserreport&survey_id='
327
                    .$surveyId.'&'.api_get_cidreq().'&user='.Security::remove_XSS($_GET['user']).'" >'.
328
                    Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_MEDIUM).'</a>';
329
            }
330
331
            // Export the user report
332
            echo '<a href="javascript: void(0);" onclick="document.form1a.submit();">'
333
                .Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a> ';
334
            echo '<a href="javascript: void(0);" onclick="document.form1b.submit();">'
335
                .Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a> ';
336
            echo '<form id="form1a" name="form1a" method="post" action="'.api_get_self().'?action='
337
                .Security::remove_XSS($_GET['action']).'&survey_id='.$surveyId.'&'.api_get_cidreq().'&user_id='
338
                .Security::remove_XSS($_GET['user']).'">';
339
            echo '<input type="hidden" name="export_report" value="export_report">';
340
            echo '<input type="hidden" name="export_format" value="csv">';
341
            echo '</form>';
342
            echo '<form id="form1b" name="form1b" method="post" action="'.api_get_self().'?action='
343
                .Security::remove_XSS($_GET['action']).'&survey_id='.$surveyId.'&'.api_get_cidreq().'&user_id='
344
                .Security::remove_XSS($_GET['user']).'">';
345
            echo '<input type="hidden" name="export_report" value="export_report">';
346
            echo '<input type="hidden" name="export_format" value="xls">';
347
            echo '</form>';
348
            echo '<form id="form2" name="form2" method="post" action="'.api_get_self().'?action='
349
                .Security::remove_XSS($_GET['action']).'&survey_id='.$surveyId.'&'.api_get_cidreq().'">';
350
        }
351
        echo '</div>';
352
353
        // Step 1: selection of the user
354
        echo "<script>
355
        function jumpMenu(targ,selObj,restore) {
356
            eval(targ+\".location='\"+selObj.options[selObj.selectedIndex].value+\"'\");
357
            if (restore) selObj.selectedIndex=0;
358
        }
359
		</script>";
360
        echo get_lang('SelectUserWhoFilledSurvey').'<br />';
361
362
        echo '<select name="user" onchange="jumpMenu(\'parent\',this,0)">';
363
        echo '<option value="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='
364
            .Security::remove_XSS($_GET['action']).'&survey_id='.intval($_GET['survey_id']).'">'
365
            .get_lang('SelectUser').'</option>';
366
367
        foreach ($people_filled as $key => & $person) {
368
            if ($survey_data['anonymous'] == 0) {
369
                $name = $person['user_info']['complete_name_with_username'];
370
                $id = $person['user_id'];
371
                if ($id == '') {
372
                    $id = $person['invited_user'];
373
                    $name = $person['invited_user'];
374
                }
375
            } else {
376
                $name = get_lang('Anonymous').' '.($key + 1);
377
                $id = $person;
378
            }
379
            echo '<option value="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='
380
                .Security::remove_XSS($_GET['action']).'&survey_id='.intval($_GET['survey_id']).'&user='
381
                .Security::remove_XSS($id).'" ';
382
            if (isset($_GET['user']) && $_GET['user'] == $id) {
383
                echo 'selected="selected"';
384
            }
385
            echo '>'.$name.'</option>';
386
        }
387
        echo '</select>';
388
389
        $course_id = api_get_course_int_id();
390
        // Step 2: displaying the survey and the answer of the selected users
391
        if (isset($_GET['user'])) {
392
            echo Display::return_message(
393
                get_lang('AllQuestionsOnOnePage'),
394
                'normal',
395
                false
396
            );
397
398
            // Getting all the questions and options
399
            $sql = "SELECT
400
			            survey_question.question_id,
401
			            survey_question.survey_id,
402
			            survey_question.survey_question,
403
			            survey_question.display,
404
			            survey_question.max_value,
405
			            survey_question.sort,
406
			            survey_question.type,
407
                        survey_question_option.question_option_id,
408
                        survey_question_option.option_text,
409
                        survey_question_option.sort as option_sort
410
					FROM $table_survey_question survey_question
411
					LEFT JOIN $table_survey_question_option survey_question_option
412
					ON
413
					    survey_question.question_id = survey_question_option.question_id AND
414
					    survey_question_option.c_id = $course_id
415
					WHERE
416
					    survey_question.survey_id = '".intval($_GET['survey_id'])."' AND
417
                        survey_question.c_id = $course_id
418
					ORDER BY survey_question.sort, survey_question_option.sort ASC";
419
            $result = Database::query($sql);
420
            while ($row = Database::fetch_array($result, 'ASSOC')) {
421
                if ($row['type'] != 'pagebreak') {
422
                    $questions[$row['sort']]['question_id'] = $row['question_id'];
423
                    $questions[$row['sort']]['survey_id'] = $row['survey_id'];
424
                    $questions[$row['sort']]['survey_question'] = $row['survey_question'];
425
                    $questions[$row['sort']]['display'] = $row['display'];
426
                    $questions[$row['sort']]['type'] = $row['type'];
427
                    $questions[$row['sort']]['maximum_score'] = $row['max_value'];
428
                    $questions[$row['sort']]['options'][$row['question_option_id']] = $row['option_text'];
429
                }
430
            }
431
432
            // Getting all the answers of the user
433
            $sql = "SELECT * FROM $table_survey_answer
434
			        WHERE
435
                        c_id = $course_id AND
436
                        survey_id = '".intval($_GET['survey_id'])."' AND
437
                        user = '".Database::escape_string($_GET['user'])."'";
438
            $result = Database::query($sql);
439
            while ($row = Database::fetch_array($result, 'ASSOC')) {
440
                $answers[$row['question_id']][] = $row['option_id'];
441
                $all_answers[$row['question_id']][] = $row;
442
            }
443
444
            // Displaying all the questions
445
446
            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...
447
                // If the question type is a scoring then we have to format the answers differently
448
                switch ($question['type']) {
449
                    case 'score':
450
                        $finalAnswer = array();
451
                        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...
452
                            foreach ($all_answers[$question['question_id']] as $key => & $answer_array) {
453
                                $finalAnswer[$answer_array['option_id']] = $answer_array['value'];
454
                            }
455
                        }
456
                        break;
457
                    case 'multipleresponse':
458
                        $finalAnswer = isset($answers[$question['question_id']])
459
                            ? $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...
460
                            : '';
461
                        break;
462
                    default:
463
                        $finalAnswer = '';
464
                        if (isset($all_answers[$question['question_id']])) {
465
                            $finalAnswer = $all_answers[$question['question_id']][0]['option_id'];
466
                        }
467
                        break;
468
                }
469
470
                $ch_type = 'ch_'.$question['type'];
471
                /** @var survey_question $display */
472
                $display = new $ch_type;
473
474
                $url = api_get_self();
475
                $form = new FormValidator('question', 'post', $url);
476
                $form->addHtml('<div class="survey_question_wrapper"><div class="survey_question">');
477
                $form->addHtml($question['survey_question']);
478
                $display->render($form, $question, $finalAnswer);
0 ignored issues
show
Bug introduced by
It seems like $finalAnswer can also be of type string; however, parameter $answers of survey_question::render() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

478
                $display->render($form, $question, /** @scrutinizer ignore-type */ $finalAnswer);
Loading history...
479
                $form->addHtml('</div></div>');
480
                $form->display();
481
            }
482
        }
483
    }
484
485
    /**
486
     * This function displays the report by question.
487
     *
488
     * It displays a table with all the options of the question and the number of users who have answered positively on
489
     * the option. The number of users who answered positive on a given option is expressed in an absolute number, in a
490
     * percentage of the total and graphically using bars By clicking on the absolute number you get a list with the
491
     * persons who have answered this. You can then click on the name of the person and you will then go to the report
492
     * by user where you see all the answers of that user.
493
     *
494
     * @param    array    All the survey data
495
     * @return   string    html code that displays the report by question
496
     * @todo allow switching between horizontal and vertical.
497
     * @todo multiple response: percentage are probably not OK
498
     * @todo the question and option text have to be shortened and should expand when the user clicks on it.
499
     * @todo the pagebreak and comment question types should not be shown => removed from $survey_data before
500
     * @author Patrick Cool <[email protected]>, Ghent University
501
     * @version February 2007 - Updated March 2008
502
     */
503
    public static function display_question_report($survey_data)
504
    {
505
        $singlePage = isset($_GET['single_page']) ? intval($_GET['single_page']) : 0;
506
        $course_id = api_get_course_int_id();
507
        // Database table definitions
508
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
509
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
510
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
511
512
        // Determining the offset of the sql statement (the n-th question of the survey)
513
        $offset = !isset($_GET['question']) ? 0 : intval($_GET['question']);
514
        $currentQuestion = isset($_GET['question']) ? intval($_GET['question']) : 0;
515
        $questions = array();
516
        $surveyId = intval($_GET['survey_id']);
517
        $action = Security::remove_XSS($_GET['action']);
518
519
        echo '<div class="actions">';
520
        echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?survey_id='.$surveyId.'&'.api_get_cidreq().'">'.
521
            Display::return_icon(
522
                'back.png',
523
                get_lang('BackTo').' '.get_lang('ReportingOverview'),
524
                '',
525
                ICON_SIZE_MEDIUM
526
            ).'</a>';
527
        echo '</div>';
528
529
        if ($survey_data['number_of_questions'] > 0) {
530
            $limitStatement = null;
531
            if (!$singlePage) {
532
                echo '<div id="question_report_questionnumbers" class="pagination">';
533
                if ($currentQuestion != 0) {
534
                    echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action.'&'
535
                        .api_get_cidreq().'&survey_id='.$surveyId.'&question='.($offset - 1).'">'
536
                        .get_lang('PreviousQuestion').'</a></li>';
537
                }
538
539
                for ($i = 1; $i <= $survey_data['number_of_questions']; $i++) {
540
                    if ($offset != $i - 1) {
541
                        echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action.'&'
542
                            .api_get_cidreq().'&survey_id='.$surveyId.'&question='.($i - 1).'">'.$i.'</a></li>';
543
                    } else {
544
                        echo '<li class="disabled"s><a href="#">'.$i.'</a></li>';
545
                    }
546
                }
547
                if ($currentQuestion < ($survey_data['number_of_questions'] - 1)) {
548
                    echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action.'&'
549
                        .api_get_cidreq().'&survey_id='.$surveyId.'&question='.($offset + 1).'">'
550
                        .get_lang('NextQuestion').'</li></a>';
551
                }
552
                echo '</ul>';
553
                echo '</div>';
554
                $limitStatement = " LIMIT $offset, 1";
555
            }
556
557
            // Getting the question information
558
            $sql = "SELECT * FROM $table_survey_question
559
			        WHERE
560
			            c_id = $course_id AND
561
                        survey_id='".intval($_GET['survey_id'])."' AND
562
                        type <>'pagebreak' AND 
563
                        type <>'comment'
564
                    ORDER BY sort ASC
565
                    $limitStatement";
566
            $result = Database::query($sql);
567
            while ($row = Database::fetch_array($result)) {
568
                $questions[$row['question_id']] = $row;
569
            }
570
        }
571
572
        foreach ($questions as $question) {
573
            $chartData = array();
574
            $options = array();
575
            echo '<div class="title-question">';
576
            echo strip_tags(isset($question['survey_question']) ? $question['survey_question'] : null);
577
            echo '</div>';
578
579
            if ($question['type'] == 'score') {
580
                /** @todo This function should return the options as this is needed further in the code */
581
                $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...
582
            } elseif ($question['type'] == 'open') {
583
                /** @todo Also get the user who has answered this */
584
                $sql = "SELECT * FROM $table_survey_answer
585
                        WHERE
586
                            c_id = $course_id AND
587
                            survey_id='".intval($_GET['survey_id'])."' AND
588
                            question_id = '".intval($question['question_id'])."'";
589
                $result = Database::query($sql);
590
                while ($row = Database::fetch_array($result, 'ASSOC')) {
591
                    echo $row['option_id'].'<hr noshade="noshade" size="1" />';
592
                }
593
            } else {
594
                // Getting the options ORDER BY sort ASC
595
                $sql = "SELECT * FROM $table_survey_question_option
596
                        WHERE
597
                            c_id = $course_id AND
598
                            survey_id='".intval($_GET['survey_id'])."'
599
                            AND question_id = '".intval($question['question_id'])."'
600
                        ORDER BY sort ASC";
601
                $result = Database::query($sql);
602
                while ($row = Database::fetch_array($result, 'ASSOC')) {
603
                    $options[$row['question_option_id']] = $row;
604
                }
605
                // Getting the answers
606
                $sql = "SELECT *, count(answer_id) as total FROM $table_survey_answer
607
                        WHERE
608
                            c_id = $course_id AND
609
                            survey_id='".intval($_GET['survey_id'])."'
610
                            AND question_id = '".intval($question['question_id'])."'
611
                        GROUP BY option_id, value";
612
                $result = Database::query($sql);
613
                $number_of_answers = array();
614
                $data = array();
615
                while ($row = Database::fetch_array($result, 'ASSOC')) {
616
                    if (!isset($number_of_answers[$row['question_id']])) {
617
                        $number_of_answers[$row['question_id']] = 0;
618
                    }
619
                    $number_of_answers[$row['question_id']] += $row['total'];
620
                    $data[$row['option_id']] = $row;
621
                }
622
623
                foreach ($options as $option) {
624
                    $optionText = strip_tags($option['option_text']);
625
                    $optionText = html_entity_decode($optionText);
626
                    $votes = isset($data[$option['question_option_id']]['total']) ?
627
                        $data[$option['question_option_id']]['total'] : '0';
628
                    array_push($chartData, array('option' => $optionText, 'votes' => $votes));
629
                }
630
                $chartContainerId = 'chartContainer'.$question['question_id'];
631
                echo '<div id="'.$chartContainerId.'" class="col-md-12">';
632
                echo self::drawChart($chartData, false, $chartContainerId);
633
634
                // displaying the table: headers
635
                echo '<table class="display-survey table">';
636
                echo '	<tr>';
637
                echo '		<th>&nbsp;</th>';
638
                echo '		<th>'.get_lang('AbsoluteTotal').'</th>';
639
                echo '		<th>'.get_lang('Percentage').'</th>';
640
                echo '		<th>'.get_lang('VisualRepresentation').'</th>';
641
                echo '	<tr>';
642
643
                // Displaying the table: the content
644
                if (is_array($options)) {
645
                    foreach ($options as $key => & $value) {
646
                        $absolute_number = null;
647
                        if (isset($data[$value['question_option_id']])) {
648
                            $absolute_number = $data[$value['question_option_id']]['total'];
649
                        }
650
                        if ($question['type'] == 'percentage' && empty($absolute_number)) {
651
                            continue;
652
                        }
653
                        $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...
654
                            ? $number_of_answers[$option['question_id']]
655
                            : 0;
656
                        if ($number_of_answers[$option['question_id']] == 0) {
657
                            $answers_number = 0;
658
                        } else {
659
                            $answers_number = $absolute_number / $number_of_answers[$option['question_id']] * 100;
660
                        }
661
                        echo '	<tr>';
662
                        echo '		<td class="center">'.$value['option_text'].'</td>';
663
                        echo '		<td class="center">';
664
                        if ($absolute_number != 0) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $absolute_number of type null|mixed to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
665
                            echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action
666
                                .'&survey_id='.$surveyId.'&question='.$offset.'&viewoption='
667
                                .$value['question_option_id'].'">'.$absolute_number.'</a>';
668
                        } else {
669
                            echo '0';
670
                        }
671
672
                        echo '      </td>';
673
                        echo '		<td class="center">'.round($answers_number, 2).' %</td>';
674
                        echo '		<td class="center">';
675
                        $size = $answers_number * 2;
676
                        if ($size > 0) {
677
                            echo '<div style="border:1px solid #264269; background-color:#aecaf4; height:10px; width:'
678
                                .$size.'px">&nbsp;</div>';
679
                        } else {
680
                            echo '<div style="text-align: left;">'.get_lang("NoDataAvailable").'</div>';
681
                        }
682
                        echo ' </td>';
683
                        echo ' </tr>';
684
                    }
685
                }
686
                // displaying the table: footer (totals)
687
                echo '	<tr>';
688
                echo '		<td class="total"><b>'.get_lang('Total').'</b></td>';
689
                echo '		<td class="total"><b>'
690
                    .($number_of_answers[$option['question_id']] == 0
691
                        ? '0'
692
                        : $number_of_answers[$option['question_id']])
693
                    .'</b></td>';
694
                echo '		<td class="total">&nbsp;</td>';
695
                echo '		<td class="total">&nbsp;</td>';
696
                echo '	</tr>';
697
                echo '</table>';
698
                echo '</div>';
699
            }
700
        }
701
        if (isset($_GET['viewoption'])) {
702
            echo '<div class="answered-people">';
703
            echo '<h4>'.get_lang('PeopleWhoAnswered').': '
704
                .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 572. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
705
706
            if (is_numeric($_GET['value'])) {
707
                $sql_restriction = "AND value='".Database::escape_string($_GET['value'])."'";
708
            }
709
710
            $sql = "SELECT user FROM $table_survey_answer
711
                    WHERE
712
                        c_id = $course_id AND
713
                        option_id = '".Database::escape_string($_GET['viewoption'])."'
714
                        $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...
715
            $result = Database::query($sql);
716
            echo '<ul>';
717
            while ($row = Database::fetch_array($result, 'ASSOC')) {
718
                $user_info = api_get_user_info($row['user']);
719
                echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action=userreport&survey_id='
720
                    .$surveyId.'&user='.$row['user'].'">'
721
                    .$user_info['complete_name_with_username']
722
                    .'</a></li>';
723
            }
724
            echo '</ul>';
725
            echo '</div>';
726
        }
727
    }
728
729
    /**
730
     * Display score data about a survey question
731
     * @param    array    Question info
732
     * @param    integer    The offset of results shown
733
     * @return   void    (direct output)
734
     */
735
    public static function display_question_report_score($survey_data, $question, $offset)
736
    {
737
        // Database table definitions
738
        $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : '';
739
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
740
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
741
        $course_id = api_get_course_int_id();
742
743
        // Getting the options
744
        $sql = "SELECT * FROM $table_survey_question_option
745
                WHERE
746
                    c_id = $course_id AND
747
                    survey_id='".intval($_GET['survey_id'])."' AND
748
                    question_id = '".intval($question['question_id'])."'
749
                ORDER BY sort ASC";
750
        $result = Database::query($sql);
751
        while ($row = Database::fetch_array($result)) {
752
            $options[$row['question_option_id']] = $row;
753
        }
754
755
        // Getting the answers
756
        $sql = "SELECT *, count(answer_id) as total 
757
                FROM $table_survey_answer
758
                WHERE
759
                   c_id = $course_id AND
760
                   survey_id='".intval($_GET['survey_id'])."' AND
761
                   question_id = '".Database::escape_string($question['question_id'])."'
762
                GROUP BY option_id, value";
763
        $result = Database::query($sql);
764
        $number_of_answers = 0;
765
        while ($row = Database::fetch_array($result)) {
766
            $number_of_answers += $row['total'];
767
            $data[$row['option_id']][$row['value']] = $row;
768
        }
769
770
        $chartData = array();
771
        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...
772
            $optionText = strip_tags($option['option_text']);
773
            $optionText = html_entity_decode($optionText);
774
            for ($i = 1; $i <= $question['max_value']; $i++) {
775
                $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...
776
                if (empty($votes)) {
777
                    $votes = '0';
778
                }
779
                array_push(
780
                    $chartData,
781
                    array(
782
                        'serie' => $optionText,
783
                        'option' => $i,
784
                        'votes' => $votes
785
                    )
786
                );
787
            }
788
        }
789
        echo '<div id="chartContainer" class="col-md-12">';
790
        echo self::drawChart($chartData, true);
791
        echo '</div>';
792
793
        // Displaying the table: headers
794
        echo '<table class="data_table">';
795
        echo '	<tr>';
796
        echo '		<th>&nbsp;</th>';
797
        echo '		<th>'.get_lang('Score').'</th>';
798
        echo '		<th>'.get_lang('AbsoluteTotal').'</th>';
799
        echo '		<th>'.get_lang('Percentage').'</th>';
800
        echo '		<th>'.get_lang('VisualRepresentation').'</th>';
801
        echo '	<tr>';
802
        // Displaying the table: the content
803
        foreach ($options as $key => & $value) {
804
            for ($i = 1; $i <= $question['max_value']; $i++) {
805
                $absolute_number = $data[$value['question_option_id']][$i]['total'];
806
                echo '	<tr>';
807
                echo '		<td>'.$value['option_text'].'</td>';
808
                echo '		<td>'.$i.'</td>';
809
                echo '		<td><a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='.$action
810
                    .'&survey_id='.intval($_GET['survey_id']).'&question='.Security::remove_XSS($offset)
811
                    .'&viewoption='.$value['question_option_id'].'&value='.$i.'">'.$absolute_number.'</a></td>';
812
                echo '		<td>'.round($absolute_number / $number_of_answers * 100, 2).' %</td>';
813
                echo '		<td>';
814
                $size = ($absolute_number / $number_of_answers * 100 * 2);
815
                if ($size > 0) {
816
                    echo '<div style="border:1px solid #264269; background-color:#aecaf4; height:10px; width:'.$size.'px">&nbsp;</div>';
817
                }
818
                echo '		</td>';
819
                echo '	</tr>';
820
            }
821
        }
822
        // Displaying the table: footer (totals)
823
        echo '	<tr>';
824
        echo '		<td style="border-top:1px solid black"><b>'.get_lang('Total').'</b></td>';
825
        echo '		<td style="border-top:1px solid black">&nbsp;</td>';
826
        echo '		<td style="border-top:1px solid black"><b>'.$number_of_answers.'</b></td>';
827
        echo '		<td style="border-top:1px solid black">&nbsp;</td>';
828
        echo '		<td style="border-top:1px solid black">&nbsp;</td>';
829
        echo '	</tr>';
830
831
        echo '</table>';
832
    }
833
834
    /**
835
     * This functions displays the complete reporting
836
     * @return string    HTML code
837
     * @todo open questions are not in the complete report yet.
838
     * @author Patrick Cool <[email protected]>, Ghent University
839
     * @version February 2007
840
     */
841
    public static function display_complete_report($survey_data)
842
    {
843
        // Database table definitions
844
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
845
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
846
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
847
848
        $surveyId = isset($_GET['survey_id']) ? intval($_GET['survey_id']) : 0;
849
        $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : '';
850
851
        // Actions bar
852
        echo '<div class="actions">';
853
        echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?survey_id='.$surveyId.'&'.api_get_cidreq().'">'
854
            .Display::return_icon(
855
                'back.png',
856
                get_lang('BackTo').' '.get_lang('ReportingOverview'),
857
                [],
858
                ICON_SIZE_MEDIUM
859
            )
860
            .'</a>';
861
        echo '<a class="survey_export_link" href="javascript: void(0);" onclick="document.form1a.submit();">'
862
            .Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a>';
863
        echo '<a class="survey_export_link" href="javascript: void(0);" onclick="document.form1b.submit();">'
864
            .Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a>';
865
        echo '</div>';
866
867
        // The form
868
        echo '<form id="form1a" name="form1a" method="post" action="'.api_get_self().'?action='.$action.'&survey_id='
869
            .$surveyId.'&'.api_get_cidreq().'">';
870
        echo '<input type="hidden" name="export_report" value="export_report">';
871
        echo '<input type="hidden" name="export_format" value="csv">';
872
        echo '</form>';
873
        echo '<form id="form1b" name="form1b" method="post" action="'.api_get_self().'?action='.$action.'&survey_id='
874
            .$surveyId.'&'.api_get_cidreq().'">';
875
        echo '<input type="hidden" name="export_report" value="export_report">';
876
        echo '<input type="hidden" name="export_format" value="xls">';
877
        echo '</form>';
878
879
        echo '<form id="form2" name="form2" method="post" action="'.api_get_self().'?action='.$action.'&survey_id='
880
            .$surveyId.'&'.api_get_cidreq().'">';
881
882
        // The table
883
        echo '<br /><table class="data_table" border="1">';
884
        // Getting the number of options per question
885
        echo '	<tr>';
886
        echo '		<th>';
887
        if ((isset($_POST['submit_question_filter']) && $_POST['submit_question_filter']) ||
888
            (isset($_POST['export_report']) && $_POST['export_report'])
889
        ) {
890
            echo '<button class="cancel" type="submit" name="reset_question_filter" value="'
891
                .get_lang('ResetQuestionFilter').'">'.get_lang('ResetQuestionFilter').'</button>';
892
        }
893
        echo '<button class="save" type="submit" name="submit_question_filter" value="'.get_lang('SubmitQuestionFilter')
894
            .'">'.get_lang('SubmitQuestionFilter').'</button>';
895
        echo '</th>';
896
897
        $display_extra_user_fields = false;
898
        if (!(isset($_POST['submit_question_filter']) && $_POST['submit_question_filter'] ||
899
                isset($_POST['export_report']) && $_POST['export_report']) ||
900
            !empty($_POST['fields_filter'])
901
        ) {
902
            // Show user fields section with a big th colspan that spans over all fields
903
            $extra_user_fields = UserManager::get_extra_fields(
904
                0,
905
                0,
906
                5,
907
                'ASC',
908
                false,
909
                true
910
            );
911
            $num = count($extra_user_fields);
912
            if ($num > 0) {
913
                echo '<th '.($num > 0 ? ' colspan="'.$num.'"' : '').'>';
914
                echo '<label><input type="checkbox" name="fields_filter" value="1" checked="checked"/> ';
915
                echo get_lang('UserFields');
916
                echo '</label>';
917
                echo '</th>';
918
                $display_extra_user_fields = true;
919
            }
920
        }
921
922
        $course_id = api_get_course_int_id();
923
        $sql = "SELECT q.question_id, q.type, q.survey_question, count(o.question_option_id) as number_of_options
924
				FROM $table_survey_question q 
925
				LEFT JOIN $table_survey_question_option o
926
				ON q.question_id = o.question_id
927
				WHERE 
928
				    q.survey_id = '".$surveyId."' AND
929
				    q.c_id = $course_id AND
930
				    o.c_id = $course_id
931
				GROUP BY q.question_id
932
				ORDER BY q.sort ASC";
933
        $result = Database::query($sql);
934
        $questions = [];
935
        while ($row = Database::fetch_array($result)) {
936
            // We show the questions if
937
            // 1. there is no question filter and the export button has not been clicked
938
            // 2. there is a quesiton filter but the question is selected for display
939
            if (!(isset($_POST['submit_question_filter']) && $_POST['submit_question_filter']) ||
940
                (is_array($_POST['questions_filter']) && in_array($row['question_id'], $_POST['questions_filter']))
941
            ) {
942
                // We do not show comment and pagebreak question types
943
                if ($row['type'] != 'comment' && $row['type'] != 'pagebreak') {
944
                    echo ' <th';
945
                    // <hub> modified tst to include percentage
946
                    if ($row['number_of_options'] > 0 && $row['type'] != 'percentage') {
947
                        // </hub>
948
                        echo ' colspan="'.$row['number_of_options'].'"';
949
                    }
950
                    echo '>';
951
952
                    echo '<label><input type="checkbox" name="questions_filter[]" value="'.$row['question_id']
953
                        .'" checked="checked"/> ';
954
                    echo $row['survey_question'];
955
                    echo '</label>';
956
                    echo '</th>';
957
                }
958
                // No column at all if it's not a question
959
            }
960
            $questions[$row['question_id']] = $row;
961
        }
962
        echo '	</tr>';
963
        // Getting all the questions and options
964
        echo '	<tr>';
965
        echo '		<th>&nbsp;</th>'; // the user column
966
967
        if (!(isset($_POST['submit_question_filter']) && $_POST['submit_question_filter'] ||
968
                isset($_POST['export_report']) && $_POST['export_report']) || !empty($_POST['fields_filter'])) {
969
            //show the fields names for user fields
970
            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...
971
                echo '<th>'.$field[3].'</th>';
972
            }
973
        }
974
975
        // cells with option (none for open question)
976
        $sql = "SELECT 	
977
                    sq.question_id, sq.survey_id,
978
                    sq.survey_question, sq.display,
979
                    sq.sort, sq.type, sqo.question_option_id,
980
                    sqo.option_text, sqo.sort as option_sort
981
				FROM $table_survey_question sq
982
				LEFT JOIN $table_survey_question_option sqo
983
				ON sq.question_id = sqo.question_id
984
				WHERE
985
				    sq.survey_id = '".$surveyId."' AND
986
                    sq.c_id = $course_id AND
987
                    sqo.c_id = $course_id
988
				ORDER BY sq.sort ASC, sqo.sort ASC";
989
        $result = Database::query($sql);
990
991
        $display_percentage_header = 1;
992
        $possible_answers = [];
993
        // in order to display only once the cell option (and not 100 times)
994
        while ($row = Database::fetch_array($result)) {
995
            // We show the options if
996
            // 1. there is no question filter and the export button has not been clicked
997
            // 2. there is a question filter but the question is selected for display
998
            if (!(isset($_POST['submit_question_filter']) && $_POST['submit_question_filter']) ||
999
                (is_array($_POST['questions_filter']) && in_array($row['question_id'], $_POST['questions_filter']))
1000
            ) {
1001
                // <hub> modif 05-05-2010
1002
                // we do not show comment and pagebreak question types
1003
                if ($row['type'] == 'open') {
1004
                    echo '<th>&nbsp;-&nbsp;</th>';
1005
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1006
                    $display_percentage_header = 1;
1007
                } elseif ($row['type'] == 'percentage' && $display_percentage_header) {
1008
                    echo '<th>&nbsp;%&nbsp;</th>';
1009
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1010
                    $display_percentage_header = 0;
1011
                } elseif ($row['type'] == 'percentage') {
1012
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1013
                } elseif ($row['type'] <> 'comment' && $row['type'] <> 'pagebreak' && $row['type'] <> 'percentage') {
1014
                    echo '<th>';
1015
                    echo $row['option_text'];
1016
                    echo '</th>';
1017
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1018
                    $display_percentage_header = 1;
1019
                }
1020
                //no column at all if the question was not a question
1021
                // </hub>
1022
            }
1023
        }
1024
1025
        echo '	</tr>';
1026
1027
        // Getting all the answers of the users
1028
        $old_user = '';
1029
        $answers_of_user = array();
1030
        $sql = "SELECT * FROM $table_survey_answer
1031
                WHERE
1032
                    c_id = $course_id AND
1033
                    survey_id='".$surveyId."'
1034
                ORDER BY answer_id, user ASC";
1035
        $result = Database::query($sql);
1036
        $i = 1;
1037
        while ($row = Database::fetch_array($result)) {
1038
            if ($old_user != $row['user'] && $old_user != '') {
1039
                $userParam = $old_user;
1040
                if ($survey_data['anonymous'] != 0) {
1041
                    $userParam = $i;
1042
                    $i++;
1043
                }
1044
                self::display_complete_report_row(
1045
                    $survey_data,
1046
                    $possible_answers,
1047
                    $answers_of_user,
1048
                    $userParam,
1049
                    $questions,
1050
                    $display_extra_user_fields
1051
                );
1052
                $answers_of_user = array();
1053
            }
1054
            if (isset($questions[$row['question_id']]) && $questions[$row['question_id']]['type'] != 'open') {
1055
                $answers_of_user[$row['question_id']][$row['option_id']] = $row;
1056
            } else {
1057
                $answers_of_user[$row['question_id']][0] = $row;
1058
            }
1059
            $old_user = $row['user'];
1060
        }
1061
        $userParam = $old_user;
1062
        if ($survey_data['anonymous'] != 0) {
1063
            $userParam = $i;
1064
            $i++;
1065
        }
1066
        self::display_complete_report_row(
1067
            $survey_data,
1068
            $possible_answers,
1069
            $answers_of_user,
1070
            $userParam,
1071
            $questions,
1072
            $display_extra_user_fields
1073
        );
1074
        // This is to display the last user
1075
        echo '</table>';
1076
        echo '</form>';
1077
    }
1078
1079
    /**
1080
     * This function displays a row (= a user and his/her answers) in the table of the complete report.
1081
     *
1082
     * @param array $survey_data
1083
     * @param array    Possible options
1084
     * @param array    User answers
1085
     * @param mixed    User ID or user details string
1086
     * @param boolean  Whether to show extra user fields or not
1087
     * @author Patrick Cool <[email protected]>, Ghent University
1088
     * @version February 2007 - Updated March 2008
1089
     */
1090
    public static function display_complete_report_row(
1091
        $survey_data,
1092
        $possible_options,
1093
        $answers_of_user,
1094
        $user,
1095
        $questions,
1096
        $display_extra_user_fields = false
1097
    ) {
1098
        $user = Security::remove_XSS($user);
1099
        echo '<tr>';
1100
        if ($survey_data['anonymous'] == 0) {
1101
            if (intval($user) !== 0) {
1102
                $userInfo = api_get_user_info($user);
1103
                if (!empty($userInfo)) {
1104
                    $user_displayed = $userInfo['complete_name_with_username'];
1105
                } else {
1106
                    $user_displayed = '-';
1107
                }
1108
                echo '<th>
1109
                    <a href="'.api_get_self().'?action=userreport&survey_id='.intval($_GET['survey_id']).'&user='.$user.'">'
1110
                    .$user_displayed.'</a>
1111
                    </th>'; // the user column
1112
            } else {
1113
                echo '<th>'.$user.'</th>'; // the user column
1114
            }
1115
        } else {
1116
            echo '<th>'.get_lang('Anonymous').' '.$user.'</th>';
1117
        }
1118
1119
        if ($display_extra_user_fields) {
1120
            // Show user fields data, if any, for this user
1121
            $user_fields_values = UserManager::get_extra_user_data(
1122
                intval($user),
1123
                false,
1124
                false,
1125
                false,
1126
                true
1127
            );
1128
            foreach ($user_fields_values as & $value) {
1129
                echo '<td align="center">'.$value.'</td>';
1130
            }
1131
        }
1132
        if (is_array($possible_options)) {
1133
            // <hub> modified to display open answers and percentage
1134
            foreach ($possible_options as $question_id => & $possible_option) {
1135
                if ($questions[$question_id]['type'] == 'open') {
1136
                    echo '<td align="center">';
1137
                    echo $answers_of_user[$question_id]['0']['option_id'];
1138
                    echo '</td>';
1139
                } else {
1140
                    foreach ($possible_option as $option_id => & $value) {
1141
                        if ($questions[$question_id]['type'] == 'percentage') {
1142
                            if (!empty($answers_of_user[$question_id][$option_id])) {
1143
                                echo "<td align='center'>";
1144
                                echo $answers_of_user[$question_id][$option_id]['value'];
1145
                                echo "</td>";
1146
                            }
1147
                        } else {
1148
                            echo '<td align="center">';
1149
                            if (!empty($answers_of_user[$question_id][$option_id])) {
1150
                                if ($answers_of_user[$question_id][$option_id]['value'] != 0) {
1151
                                    echo $answers_of_user[$question_id][$option_id]['value'];
1152
                                } else {
1153
                                    echo 'v';
1154
                                }
1155
                            }
1156
                        }
1157
                    }
1158
                }
1159
            }
1160
        }
1161
        echo '</tr>';
1162
    }
1163
1164
    /**
1165
     * Quite similar to display_complete_report(), returns an HTML string
1166
     * that can be used in a csv file
1167
     * @todo consider merging this function with display_complete_report
1168
     * @return    string    The contents of a csv file
1169
     * @author Patrick Cool <[email protected]>, Ghent University
1170
     * @version February 2007
1171
     */
1172
    public static function export_complete_report($survey_data, $user_id = 0)
1173
    {
1174
        // Database table definitions
1175
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1176
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1177
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1178
1179
        // The first column
1180
        $return = ';';
1181
1182
        // Show extra fields blank space (enough for extra fields on next line)
1183
        $extra_user_fields = UserManager::get_extra_fields(
1184
            0,
1185
            0,
1186
            5,
1187
            'ASC',
1188
            false,
1189
            true
1190
        );
1191
1192
        $num = count($extra_user_fields);
1193
        $return .= str_repeat(';', $num);
1194
1195
        $course_id = api_get_course_int_id();
1196
1197
        $sql = "SELECT
1198
                    questions.question_id,
1199
                    questions.type,
1200
                    questions.survey_question,
1201
                    count(options.question_option_id) as number_of_options
1202
				FROM $table_survey_question questions
1203
                LEFT JOIN $table_survey_question_option options
1204
				ON questions.question_id = options.question_id AND options.c_id = $course_id
1205
				WHERE
1206
				    questions.survey_id = '".intval($_GET['survey_id'])."' AND
1207
                    questions.c_id = $course_id
1208
				GROUP BY questions.question_id
1209
				ORDER BY questions.sort ASC";
1210
        $result = Database::query($sql);
1211
        while ($row = Database::fetch_array($result)) {
1212
            // We show the questions if
1213
            // 1. there is no question filter and the export button has not been clicked
1214
            // 2. there is a quesiton filter but the question is selected for display
1215
            if (!(isset($_POST['submit_question_filter'])) ||
1216
                (isset($_POST['submit_question_filter']) &&
1217
                    is_array($_POST['questions_filter']) &&
1218
                    in_array($row['question_id'], $_POST['questions_filter']))
1219
            ) {
1220
                // We do not show comment and pagebreak question types
1221
                if ($row['type'] != 'comment' && $row['type'] != 'pagebreak') {
1222
                    if ($row['number_of_options'] == 0 && $row['type'] == 'open') {
1223
                        $return .= str_replace(
1224
                            "\r\n",
1225
                            '  ',
1226
                            api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)
1227
                        )
1228
                        .';';
1229
                    } else {
1230
                        for ($ii = 0; $ii < $row['number_of_options']; $ii++) {
1231
                            $return .= str_replace(
1232
                                "\r\n",
1233
                                '  ',
1234
                                api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)
1235
                            )
1236
                            .';';
1237
                        }
1238
                    }
1239
                }
1240
            }
1241
        }
1242
        $return .= "\n";
1243
1244
        // Getting all the questions and options
1245
        $return .= ';';
1246
1247
        // Show the fields names for user fields
1248
        if (!empty($extra_user_fields)) {
1249
            foreach ($extra_user_fields as & $field) {
1250
                $return .= '"'
1251
                    .str_replace(
1252
                        "\r\n",
1253
                        '  ',
1254
                        api_html_entity_decode(strip_tags($field[3]), ENT_QUOTES)
1255
                    )
1256
                    .'";';
1257
            }
1258
        }
1259
1260
        $sql = "SELECT
1261
		            survey_question.question_id,
1262
		            survey_question.survey_id,
1263
		            survey_question.survey_question,
1264
		            survey_question.display,
1265
		            survey_question.sort,
1266
		            survey_question.type,
1267
                    survey_question_option.question_option_id,
1268
                    survey_question_option.option_text,
1269
                    survey_question_option.sort as option_sort
1270
				FROM $table_survey_question survey_question
1271
				LEFT JOIN $table_survey_question_option survey_question_option
1272
				ON
1273
				    survey_question.question_id = survey_question_option.question_id AND
1274
				    survey_question_option.c_id = $course_id
1275
				WHERE
1276
				    survey_question.survey_id = '".intval($_GET['survey_id'])."' AND
1277
				    survey_question.c_id = $course_id
1278
				ORDER BY survey_question.sort ASC, survey_question_option.sort ASC";
1279
        $result = Database::query($sql);
1280
        $possible_answers = array();
1281
        $possible_answers_type = array();
1282
        while ($row = Database::fetch_array($result)) {
1283
            // We show the options if
1284
            // 1. there is no question filter and the export button has not been clicked
1285
            // 2. there is a question filter but the question is selected for display
1286
            if (!(isset($_POST['submit_question_filter'])) || (
1287
                is_array($_POST['questions_filter']) &&
1288
                in_array($row['question_id'], $_POST['questions_filter']))
1289
            ) {
1290
                // We do not show comment and pagebreak question types
1291
                if ($row['type'] != 'comment' && $row['type'] != 'pagebreak') {
1292
                    $row['option_text'] = str_replace(array("\r", "\n"), array('', ''), $row['option_text']);
1293
                    $return .= api_html_entity_decode(strip_tags($row['option_text']), ENT_QUOTES).';';
1294
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1295
                    $possible_answers_type[$row['question_id']] = $row['type'];
1296
                }
1297
            }
1298
        }
1299
        $return .= "\n";
1300
1301
        // Getting all the answers of the users
1302
        $old_user = '';
1303
        $answers_of_user = array();
1304
        $sql = "SELECT * FROM $table_survey_answer
1305
		        WHERE c_id = $course_id AND survey_id='".intval($_GET['survey_id'])."'";
1306
        if ($user_id != 0) {
1307
            $sql .= "AND user='".Database::escape_string($user_id)."' ";
1308
        }
1309
        $sql .= "ORDER BY user ASC";
1310
1311
        $open_question_iterator = 1;
1312
        $result = Database::query($sql);
1313
        while ($row = Database::fetch_array($result)) {
1314
            if ($old_user != $row['user'] && $old_user != '') {
1315
                $return .= self::export_complete_report_row(
1316
                    $survey_data,
1317
                    $possible_answers,
1318
                    $answers_of_user,
1319
                    $old_user,
1320
                    true
1321
                );
1322
                $answers_of_user = array();
1323
            }
1324
            if ($possible_answers_type[$row['question_id']] == 'open') {
1325
                $temp_id = 'open'.$open_question_iterator;
1326
                $answers_of_user[$row['question_id']][$temp_id] = $row;
1327
                $open_question_iterator++;
1328
            } else {
1329
                $answers_of_user[$row['question_id']][$row['option_id']] = $row;
1330
            }
1331
            $old_user = $row['user'];
1332
        }
1333
        // This is to display the last user
1334
        $return .= self::export_complete_report_row(
1335
            $survey_data,
1336
            $possible_answers,
1337
            $answers_of_user,
1338
            $old_user,
1339
            true
1340
        );
1341
1342
        return $return;
1343
    }
1344
1345
    /**
1346
     * Add a line to the csv file
1347
     *
1348
     * @param array Possible answers
1349
     * @param array User's answers
1350
     * @param mixed User ID or user details as string - Used as a string in the result string
1351
     * @param boolean Whether to display user fields or not
1352
     * @return string One line of the csv file
1353
     * @author Patrick Cool <[email protected]>, Ghent University
1354
     * @version February 2007
1355
     */
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...
1356
    public static function export_complete_report_row(
1357
        $survey_data,
1358
        $possible_options,
1359
        $answers_of_user,
1360
        $user,
1361
        $display_extra_user_fields = false
1362
    ) {
1363
        $return = '';
1364
        if ($survey_data['anonymous'] == 0) {
1365
            if (intval($user) !== 0) {
1366
                $userInfo = api_get_user_info($user);
1367
                if (!empty($userInfo)) {
1368
                    $user_displayed = $userInfo['complete_name_with_username'];
1369
                } else {
1370
                    $user_displayed = '-';
1371
                }
1372
                $return .= $user_displayed.';';
1373
            } else {
1374
                $return .= $user.';';
1375
            }
1376
        } else {
1377
            $return .= '-;'; // The user column
1378
        }
1379
1380
        if ($display_extra_user_fields) {
1381
            // Show user fields data, if any, for this user
1382
            $user_fields_values = UserManager::get_extra_user_data(
1383
                $user,
1384
                false,
1385
                false,
1386
                false,
1387
                true
1388
            );
1389
            foreach ($user_fields_values as & $value) {
1390
                $return .= '"'.str_replace('"', '""', api_html_entity_decode(strip_tags($value), ENT_QUOTES)).'";';
1391
            }
1392
        }
1393
1394
        if (is_array($possible_options)) {
1395
            foreach ($possible_options as $question_id => $possible_option) {
1396
                if (is_array($possible_option) && count($possible_option) > 0) {
1397
                    foreach ($possible_option as $option_id => & $value) {
1398
                        $my_answer_of_user = !isset($answers_of_user[$question_id]) || isset($answers_of_user[$question_id]) && $answers_of_user[$question_id] == null ? array() : $answers_of_user[$question_id];
1399
                        $key = array_keys($my_answer_of_user);
1400
                        if (isset($key[0]) && substr($key[0], 0, 4) == 'open') {
1401
                            $return .= '"'.
1402
                                str_replace(
1403
                                    '"',
1404
                                    '""',
1405
                                    api_html_entity_decode(
1406
                                        strip_tags(
1407
                                            $answers_of_user[$question_id][$key[0]]['option_id']
1408
                                        ),
1409
                                        ENT_QUOTES
1410
                                    )
1411
                                ).
1412
                                '"';
1413
                        } elseif (!empty($answers_of_user[$question_id][$option_id])) {
1414
                            //$return .= 'v';
1415
                            if ($answers_of_user[$question_id][$option_id]['value'] != 0) {
1416
                                $return .= $answers_of_user[$question_id][$option_id]['value'];
1417
                            } else {
1418
                                $return .= 'v';
1419
                            }
1420
                        }
1421
                        $return .= ';';
1422
                    }
1423
                }
1424
            }
1425
        }
1426
        $return .= "\n";
1427
1428
        return $return;
1429
    }
1430
1431
    /**
1432
     * Quite similar to display_complete_report(), returns an HTML string
1433
     * that can be used in a csv file
1434
     * @todo consider merging this function with display_complete_report
1435
     * @return string The contents of a csv file
1436
     * @author Patrick Cool <[email protected]>, Ghent University
1437
     * @version February 2007
1438
     */
1439
    public static function export_complete_report_xls($survey_data, $filename, $user_id = 0)
1440
    {
1441
        $course_id = api_get_course_int_id();
1442
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
1443
1444
        if (empty($course_id) || empty($surveyId)) {
1445
            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...
1446
        }
1447
1448
        $spreadsheet = new PHPExcel();
1449
        $spreadsheet->setActiveSheetIndex(0);
1450
        $worksheet = $spreadsheet->getActiveSheet();
1451
        $line = 1;
1452
        $column = 1; // Skip the first column (row titles)
1453
1454
        // Show extra fields blank space (enough for extra fields on next line)
1455
        // Show user fields section with a big th colspan that spans over all fields
1456
        $extra_user_fields = UserManager::get_extra_fields(
1457
            0,
1458
            0,
1459
            5,
1460
            'ASC',
1461
            false,
1462
            true
1463
        );
1464
        $num = count($extra_user_fields);
1465
        for ($i = 0; $i < $num; $i++) {
1466
            $worksheet->setCellValueByColumnAndRow($column, $line, '');
1467
            $column++;
1468
        }
1469
1470
        $display_extra_user_fields = true;
1471
1472
        // Database table definitions
1473
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1474
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1475
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1476
1477
        // First line (questions)
1478
        $sql = "SELECT
1479
                    questions.question_id,
1480
                    questions.type,
1481
                    questions.survey_question,
1482
                    count(options.question_option_id) as number_of_options
1483
				FROM $table_survey_question questions
1484
				LEFT JOIN $table_survey_question_option options
1485
                ON questions.question_id = options.question_id AND options.c_id = $course_id
1486
				WHERE
1487
				    questions.survey_id = $surveyId AND
1488
				    questions.c_id = $course_id
1489
				GROUP BY questions.question_id
1490
				ORDER BY questions.sort ASC";
1491
        $result = Database::query($sql);
1492
        while ($row = Database::fetch_array($result)) {
1493
            // We show the questions if
1494
            // 1. there is no question filter and the export button has not been clicked
1495
            // 2. there is a quesiton filter but the question is selected for display
1496
            if (!(isset($_POST['submit_question_filter'])) ||
1497
                (isset($_POST['submit_question_filter']) && is_array($_POST['questions_filter']) &&
1498
                in_array($row['question_id'], $_POST['questions_filter']))
1499
            ) {
1500
                // We do not show comment and pagebreak question types
1501
                if ($row['type'] != 'comment' && $row['type'] != 'pagebreak') {
1502
                    if ($row['number_of_options'] == 0 && $row['type'] == 'open') {
1503
                        $worksheet->setCellValueByColumnAndRow(
1504
                            $column,
1505
                            $line,
1506
                            api_html_entity_decode(
1507
                                strip_tags($row['survey_question']),
1508
                                ENT_QUOTES
1509
                            )
1510
                        );
1511
                        $column++;
1512
                    } else {
1513
                        for ($ii = 0; $ii < $row['number_of_options']; $ii++) {
1514
                            $worksheet->setCellValueByColumnAndRow(
1515
                                $column,
1516
                                $line,
1517
                                api_html_entity_decode(
1518
                                    strip_tags($row['survey_question']),
1519
                                    ENT_QUOTES
1520
                                )
1521
                            );
1522
                            $column++;
1523
                        }
1524
                    }
1525
                }
1526
            }
1527
        }
1528
1529
        $line++;
1530
        $column = 1;
1531
        // Show extra field values
1532
        if ($display_extra_user_fields) {
1533
            // Show the fields names for user fields
1534
            foreach ($extra_user_fields as & $field) {
1535
                $worksheet->setCellValueByColumnAndRow(
1536
                    $column,
1537
                    $line,
1538
                    api_html_entity_decode(strip_tags($field[3]), ENT_QUOTES)
1539
                );
1540
                $column++;
1541
            }
1542
        }
1543
1544
        // Getting all the questions and options (second line)
1545
        $sql = "SELECT
1546
                    survey_question.question_id, 
1547
                    survey_question.survey_id, 
1548
                    survey_question.survey_question, 
1549
                    survey_question.display, 
1550
                    survey_question.sort, 
1551
                    survey_question.type,
1552
                    survey_question_option.question_option_id, 
1553
                    survey_question_option.option_text, 
1554
                    survey_question_option.sort as option_sort
1555
				FROM $table_survey_question survey_question
1556
				LEFT JOIN $table_survey_question_option survey_question_option
1557
				ON 
1558
				    survey_question.question_id = survey_question_option.question_id AND 
1559
				    survey_question_option.c_id = $course_id
1560
				WHERE 
1561
				    survey_question.survey_id = $surveyId AND
1562
				    survey_question.c_id = $course_id
1563
				ORDER BY survey_question.sort ASC, survey_question_option.sort ASC";
1564
        $result = Database::query($sql);
1565
        $possible_answers = array();
1566
        $possible_answers_type = array();
1567
        while ($row = Database::fetch_array($result)) {
1568
            // We show the options if
1569
            // 1. there is no question filter and the export button has not been clicked
1570
            // 2. there is a quesiton filter but the question is selected for display
1571
            if (!isset($_POST['submit_question_filter']) ||
1572
                (isset($_POST['questions_filter']) && is_array($_POST['questions_filter']) &&
1573
                in_array($row['question_id'], $_POST['questions_filter']))
1574
            ) {
1575
                // We do not show comment and pagebreak question types
1576
                if ($row['type'] != 'comment' && $row['type'] != 'pagebreak') {
1577
                    $worksheet->setCellValueByColumnAndRow(
1578
                        $column,
1579
                        $line,
1580
                        api_html_entity_decode(
1581
                            strip_tags($row['option_text']),
1582
                            ENT_QUOTES
1583
                        )
1584
                    );
1585
                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
1586
                    $possible_answers_type[$row['question_id']] = $row['type'];
1587
                    $column++;
1588
                }
1589
            }
1590
        }
1591
1592
        // Getting all the answers of the users
1593
        $line++;
1594
        $column = 0;
1595
        $old_user = '';
1596
        $answers_of_user = array();
1597
        $sql = "SELECT * FROM $table_survey_answer
1598
                WHERE c_id = $course_id AND survey_id = $surveyId";
1599
        if ($user_id != 0) {
1600
            $sql .= " AND user='".intval($user_id)."' ";
1601
        }
1602
        $sql .= " ORDER BY user ASC";
1603
1604
        $open_question_iterator = 1;
1605
        $result = Database::query($sql);
1606
        while ($row = Database::fetch_array($result)) {
1607
            if ($old_user != $row['user'] && $old_user != '') {
1608
                $return = self::export_complete_report_row_xls(
1609
                    $survey_data,
1610
                    $possible_answers,
1611
                    $answers_of_user,
1612
                    $old_user,
1613
                    true
1614
                );
1615
                foreach ($return as $elem) {
1616
                    $worksheet->setCellValueByColumnAndRow($column, $line, $elem);
1617
                    $column++;
1618
                }
1619
                $answers_of_user = array();
1620
                $line++;
1621
                $column = 0;
1622
            }
1623
            if ($possible_answers_type[$row['question_id']] == 'open') {
1624
                $temp_id = 'open'.$open_question_iterator;
1625
                $answers_of_user[$row['question_id']][$temp_id] = $row;
1626
                $open_question_iterator++;
1627
            } else {
1628
                $answers_of_user[$row['question_id']][$row['option_id']] = $row;
1629
            }
1630
            $old_user = $row['user'];
1631
        }
1632
1633
        $return = self::export_complete_report_row_xls(
1634
            $survey_data,
1635
            $possible_answers,
1636
            $answers_of_user,
1637
            $old_user,
1638
            true
1639
        );
1640
1641
        // this is to display the last user
1642
        foreach ($return as $elem) {
0 ignored issues
show
Bug introduced by
The expression $return of type string is not traversable.
Loading history...
1643
            $worksheet->setCellValueByColumnAndRow($column, $line, $elem);
1644
            $column++;
1645
        }
1646
1647
        $file = api_get_path(SYS_ARCHIVE_PATH).api_replace_dangerous_char($filename);
1648
        $writer = new PHPExcel_Writer_Excel2007($spreadsheet);
1649
        $writer->save($file);
1650
        DocumentManager::file_send_for_download($file, true, $filename);
1651
1652
        return null;
1653
    }
1654
1655
    /**
1656
     * Add a line to the csv file
1657
     *
1658
     * @param array Possible answers
1659
     * @param array User's answers
1660
     * @param mixed User ID or user details as string - Used as a string in the result string
1661
     * @param boolean Whether to display user fields or not
1662
     * @return string One line of the csv file
1663
     */
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...
1664
    public static function export_complete_report_row_xls(
1665
        $survey_data,
1666
        $possible_options,
1667
        $answers_of_user,
1668
        $user,
1669
        $display_extra_user_fields = false
1670
    ) {
1671
        $return = array();
1672
        if ($survey_data['anonymous'] == 0) {
1673
            if (intval($user) !== 0) {
1674
                $userInfo = api_get_user_info($user);
1675
                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...
1676
                    $user_displayed = $userInfo['complete_name_with_username'];
1677
                } else {
1678
                    $user_displayed = '-';
1679
                }
1680
                $return[] = $user_displayed;
1681
            } else {
1682
                $return[] = $user;
1683
            }
1684
        } else {
1685
            $return[] = '-'; // The user column
1686
        }
1687
1688
        if ($display_extra_user_fields) {
1689
            //show user fields data, if any, for this user
1690
            $user_fields_values = UserManager::get_extra_user_data(
1691
                intval($user),
1692
                false,
1693
                false,
1694
                false,
1695
                true
1696
            );
1697
            foreach ($user_fields_values as $value) {
1698
                $return[] = api_html_entity_decode(strip_tags($value), ENT_QUOTES);
1699
            }
1700
        }
1701
1702
        if (is_array($possible_options)) {
1703
            foreach ($possible_options as $question_id => & $possible_option) {
1704
                if (is_array($possible_option) && count($possible_option) > 0) {
1705
                    foreach ($possible_option as $option_id => & $value) {
1706
                        $my_answers_of_user = isset($answers_of_user[$question_id])
1707
                            ? $answers_of_user[$question_id]
1708
                            : [];
1709
                        $key = array_keys($my_answers_of_user);
1710
                        if (isset($key[0]) && substr($key[0], 0, 4) == 'open') {
1711
                            $return[] = api_html_entity_decode(
1712
                                strip_tags($answers_of_user[$question_id][$key[0]]['option_id']),
1713
                                ENT_QUOTES
1714
                            );
1715
                        } elseif (!empty($answers_of_user[$question_id][$option_id])) {
1716
                            if ($answers_of_user[$question_id][$option_id]['value'] != 0) {
1717
                                $return[] = $answers_of_user[$question_id][$option_id]['value'];
1718
                            } else {
1719
                                $return[] = 'v';
1720
                            }
1721
                        } else {
1722
                            $return[] = '';
1723
                        }
1724
                    }
1725
                }
1726
            }
1727
        }
1728
1729
        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...
1730
    }
1731
1732
    /**
1733
     * This function displays the comparative report which
1734
     * allows you to compare two questions
1735
     * A comparative report creates a table where one question
1736
     * is on the x axis and a second question is on the y axis.
1737
     * In the intersection is the number of people who have
1738
     * answered positive on both options.
1739
     *
1740
     * @return string HTML code
1741
     *
1742
     * @author Patrick Cool <[email protected]>, Ghent University
1743
     * @version February 2007
1744
     */
1745
    public static function display_comparative_report()
1746
    {
1747
        // Allowed question types for comparative report
1748
        $allowed_question_types = array(
1749
            'yesno',
1750
            'multiplechoice',
1751
            'multipleresponse',
1752
            'dropdown',
1753
            'percentage',
1754
            'score'
1755
        );
1756
1757
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
1758
1759
        // Getting all the questions
1760
        $questions = SurveyManager::get_questions($surveyId);
1761
1762
        // Actions bar
1763
        echo '<div class="actions">';
1764
        echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?survey_id='.$surveyId.'&'.api_get_cidreq()
1765
            .'">'
1766
            .Display::return_icon(
1767
                'back.png',
1768
                get_lang('BackTo').' '.get_lang('ReportingOverview'),
1769
                [],
1770
                ICON_SIZE_MEDIUM
1771
            )
1772
            .'</a>';
1773
        echo '</div>';
1774
1775
        // Displaying an information message that only the questions with predefined answers can be used in a comparative report
1776
        echo Display::return_message(get_lang('OnlyQuestionsWithPredefinedAnswers'), 'normal', false);
1777
1778
        $xAxis = isset($_GET['xaxis']) ? Security::remove_XSS($_GET['xaxis']) : '';
1779
        $yAxis = isset($_GET['yaxis']) ? Security::remove_XSS($_GET['yaxis']) : '';
1780
1781
        $url = api_get_self().'?'.api_get_cidreq().'&action='.Security::remove_XSS($_GET['action'])
1782
            .'&survey_id='.$surveyId.'&xaxis='.$xAxis.'&y='.$yAxis;
1783
1784
        $form = new FormValidator('compare', 'get', $url);
1785
        $form->addHidden('action', Security::remove_XSS($_GET['action']));
1786
        $form->addHidden('survey_id', $surveyId);
1787
        $optionsX = ['----'];
1788
        $optionsY = ['----'];
1789
        $defaults = [];
1790
        foreach ($questions as $key => & $question) {
1791
            if (is_array($allowed_question_types)) {
1792
                if (in_array($question['type'], $allowed_question_types)) {
1793
                    //echo '<option value="'.$question['question_id'].'"';
1794
                    if (isset($_GET['xaxis']) && $_GET['xaxis'] == $question['question_id']) {
1795
                        $defaults['xaxis'] = $question['question_id'];
1796
                    }
1797
1798
                    if (isset($_GET['yaxis']) && $_GET['yaxis'] == $question['question_id']) {
1799
                        $defaults['yaxis'] = $question['question_id'];
1800
                    }
1801
1802
                    $optionsX[$question['question_id']] = api_substr(strip_tags($question['question']), 0, 50);
1803
                    $optionsY[$question['question_id']] = api_substr(strip_tags($question['question']), 0, 50);
1804
                }
1805
            }
1806
        }
1807
1808
        $form->addSelect('xaxis', get_lang('SelectXAxis'), $optionsX);
1809
        $form->addSelect('yaxis', get_lang('SelectYAxis'), $optionsY);
1810
1811
        $form->addButtonSearch(get_lang('CompareQuestions'));
1812
        $form->setDefaults($defaults);
1813
        $form->display();
1814
1815
        // Getting all the information of the x axis
1816
        if (is_numeric($xAxis)) {
1817
            $question_x = SurveyManager::get_question($xAxis);
1818
        }
1819
1820
        // Getting all the information of the y axis
1821
        if (is_numeric($yAxis)) {
1822
            $question_y = SurveyManager::get_question($yAxis);
1823
        }
1824
1825
        if (is_numeric($xAxis) && is_numeric($yAxis)) {
1826
            // Getting the answers of the two questions
1827
            $answers_x = self::get_answers_of_question_by_user($surveyId, $xAxis);
1828
            $answers_y = self::get_answers_of_question_by_user($surveyId, $yAxis);
1829
1830
            // Displaying the table
1831
            $tableHtml = '<table border="1" class="data_table">';
1832
            $xOptions = array();
1833
            // The header
1834
            $tableHtml .= '<tr>';
1835
            for ($ii = 0; $ii <= count($question_x['answers']); $ii++) {
0 ignored issues
show
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...
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...
1836
                if ($ii == 0) {
1837
                    $tableHtml .= '<th>&nbsp;</th>';
1838
                } else {
1839
                    if ($question_x['type'] == 'score') {
1840
                        for ($x = 1; $x <= $question_x['maximum_score']; $x++) {
1841
                            $tableHtml .= '<th>'.$question_x['answers'][($ii - 1)].'<br />'.$x.'</th>';
1842
                        }
1843
                        $x = '';
1844
                    } else {
1845
                        $tableHtml .= '<th>'.$question_x['answers'][($ii - 1)].'</th>';
1846
                    }
1847
                    $optionText = strip_tags($question_x['answers'][$ii - 1]);
1848
                    $optionText = html_entity_decode($optionText);
1849
                    array_push($xOptions, trim($optionText));
1850
                }
1851
            }
1852
            $tableHtml .= '</tr>';
1853
            $chartData = array();
1854
            // The main part
1855
            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...
1856
                $currentYQuestion = strip_tags($question_y['answers'][$ij]);
1857
                $currentYQuestion = html_entity_decode($currentYQuestion);
1858
                // The Y axis is a scoring question type so we have more rows than the options (actually options * maximum score)
1859
                if ($question_y['type'] == 'score') {
1860
                    for ($y = 1; $y <= $question_y['maximum_score']; $y++) {
1861
                        $tableHtml .= '<tr>';
1862
                        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...
1863
                            if ($question_x['type'] == 'score') {
1864
                                for ($x = 1; $x <= $question_x['maximum_score']; $x++) {
1865
                                    if ($ii == 0) {
1866
                                        $tableHtml .= '<th>'.$question_y['answers'][($ij)].' '.$y.'</th>';
1867
                                        break;
1868
                                    } else {
1869
                                        $tableHtml .= '<td align="center">';
1870
                                        $votes = self::comparative_check(
1871
                                            $answers_x,
1872
                                            $answers_y,
1873
                                            $question_x['answersid'][($ii - 1)],
1874
                                            $question_y['answersid'][($ij)],
1875
                                            $x,
1876
                                            $y
1877
                                        );
1878
                                        $tableHtml .= $votes;
1879
                                        array_push(
1880
                                            $chartData,
1881
                                            array(
1882
                                                'serie' => array($currentYQuestion, $xOptions[$ii - 1]),
1883
                                                'option' => $x,
1884
                                                'votes' => $votes
1885
                                            )
1886
                                        );
1887
                                        $tableHtml .= '</td>';
1888
                                    }
1889
                                }
1890
                            } else {
1891
                                if ($ii == 0) {
1892
                                    $tableHtml .= '<th>'.$question_y['answers'][$ij].' '.$y.'</th>';
1893
                                } else {
1894
                                    $tableHtml .= '<td align="center">';
1895
                                    $votes = self::comparative_check(
1896
                                        $answers_x,
1897
                                        $answers_y,
1898
                                        $question_x['answersid'][($ii - 1)],
1899
                                        $question_y['answersid'][($ij)],
1900
                                        0,
1901
                                        $y
1902
                                    );
1903
                                    $tableHtml .= $votes;
1904
                                    array_push(
1905
                                        $chartData,
1906
                                        array(
1907
                                            'serie' => array($currentYQuestion, $xOptions[$ii - 1]),
1908
                                            'option' => $y,
1909
                                            'votes' => $votes
1910
                                        )
1911
                                    );
1912
                                    $tableHtml .= '</td>';
1913
                                }
1914
                            }
1915
                        }
1916
                        $tableHtml .= '</tr>';
1917
                    }
1918
                } else {
1919
                    // The Y axis is NOT a score question type so the number of rows = the number of options
1920
                    $tableHtml .= '<tr>';
1921
                    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...
1922
                        if ($question_x['type'] == 'score') {
1923
                            for ($x = 1; $x <= $question_x['maximum_score']; $x++) {
1924
                                if ($ii == 0) {
1925
                                    $tableHtml .= '<th>'.$question_y['answers'][$ij].'</th>';
1926
                                    break;
1927
                                } else {
1928
                                    $tableHtml .= '<td align="center">';
1929
                                    $votes = self::comparative_check(
1930
                                        $answers_x,
1931
                                        $answers_y,
1932
                                        $question_x['answersid'][($ii - 1)],
1933
                                        $question_y['answersid'][($ij)],
1934
                                        $x,
1935
                                        0
1936
                                    );
1937
                                    $tableHtml .= $votes;
1938
                                    array_push(
1939
                                        $chartData,
1940
                                        array(
1941
                                            'serie' => array($currentYQuestion, $xOptions[$ii - 1]),
1942
                                            'option' => $x,
1943
                                            'votes' => $votes
1944
                                        )
1945
                                    );
1946
                                    $tableHtml .= '</td>';
1947
                                }
1948
                            }
1949
                        } else {
1950
                            if ($ii == 0) {
1951
                                $tableHtml .= '<th>'.$question_y['answers'][($ij)].'</th>';
1952
                            } else {
1953
                                $tableHtml .= '<td align="center">';
1954
                                $votes = self::comparative_check(
1955
                                    $answers_x,
1956
                                    $answers_y,
1957
                                    $question_x['answersid'][($ii - 1)],
1958
                                    $question_y['answersid'][($ij)]
1959
                                );
1960
                                $tableHtml .= $votes;
1961
                                array_push(
1962
                                    $chartData,
1963
                                    array(
1964
                                        'serie' => $xOptions[$ii - 1],
1965
                                        'option' => $currentYQuestion,
1966
                                        'votes' => $votes
1967
                                    )
1968
                                );
1969
                                $tableHtml .= '</td>';
1970
                            }
1971
                        }
1972
                    }
1973
                    $tableHtml .= '</tr>';
1974
                }
1975
            }
1976
            $tableHtml .= '</table>';
1977
            echo '<div id="chartContainer" class="col-md-12">';
1978
            echo self::drawChart($chartData, true);
1979
            echo '</div>';
1980
            echo $tableHtml;
1981
        }
1982
    }
1983
1984
    /**
1985
     * Get all the answers of a question grouped by user
1986
     *
1987
     * @param integer $survey_id Survey ID
1988
     * @param integer $question_id Question ID
1989
     * @return array Array containing all answers of all users, grouped by user
1990
     *
1991
     * @author Patrick Cool <[email protected]>, Ghent University
1992
     * @version February 2007 - Updated March 2008
1993
     */
1994
    public static function get_answers_of_question_by_user($survey_id, $question_id)
1995
    {
1996
        $course_id = api_get_course_int_id();
1997
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1998
1999
        $sql = "SELECT * FROM $table_survey_answer
2000
                WHERE 
2001
                  c_id = $course_id AND 
2002
                  survey_id='".intval($survey_id)."' AND 
2003
                  question_id='".intval($question_id)."'
2004
                ORDER BY USER ASC";
2005
        $result = Database::query($sql);
2006
        $return = [];
2007
        while ($row = Database::fetch_array($result)) {
2008
            if ($row['value'] == 0) {
2009
                $return[$row['user']][] = $row['option_id'];
2010
            } else {
2011
                $return[$row['user']][] = $row['option_id'].'*'.$row['value'];
2012
            }
2013
        }
2014
2015
        return $return;
2016
    }
2017
2018
    /**
2019
     * Count the number of users who answer positively on both options
2020
     *
2021
     * @param array All answers of the x axis
2022
     * @param array All answers of the y axis
2023
     * @param integer x axis value (= the option_id of the first question)
2024
     * @param integer y axis value (= the option_id of the second question)
2025
     * @return integer Number of users who have answered positively to both options
2026
     *
2027
     * @author Patrick Cool <[email protected]>, Ghent University
2028
     * @version February 2007
2029
     */
2030
    public static function comparative_check(
2031
        $answers_x,
2032
        $answers_y,
2033
        $option_x,
2034
        $option_y,
2035
        $value_x = 0,
2036
        $value_y = 0
2037
    ) {
2038
        if ($value_x == 0) {
2039
            $check_x = $option_x;
2040
        } else {
2041
            $check_x = $option_x.'*'.$value_x;
2042
        }
2043
        if ($value_y == 0) {
2044
            $check_y = $option_y;
2045
        } else {
2046
            $check_y = $option_y.'*'.$value_y;
2047
        }
2048
2049
        $counter = 0;
2050
        if (is_array($answers_x)) {
2051
            foreach ($answers_x as $user => & $answers) {
2052
                // Check if the user has given $option_x as answer
2053
                if (in_array($check_x, $answers)) {
2054
                    // Check if the user has given $option_y as an answer
2055
                    if (!is_null($answers_y[$user]) &&
2056
                        in_array($check_y, $answers_y[$user])
2057
                    ) {
2058
                        $counter++;
2059
                    }
2060
                }
2061
            }
2062
        }
2063
2064
        return $counter;
2065
    }
2066
2067
    /**
2068
     * Get all the information about the invitations of a certain survey
2069
     *
2070
     * @return array Lines of invitation [user, code, date, empty element]
2071
     *
2072
     * @author Patrick Cool <[email protected]>, Ghent University
2073
     * @version January 2007
2074
     *
2075
     * @todo use survey_id parameter instead of $_GET
2076
     */
2077
    public static function get_survey_invitations_data()
2078
    {
2079
        $course_id = api_get_course_int_id();
2080
        // Database table definition
2081
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
2082
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2083
2084
        $sql = "SELECT
2085
					survey_invitation.user as col1,
2086
					survey_invitation.invitation_code as col2,
2087
					survey_invitation.invitation_date as col3,
2088
					'' as col4
2089
                FROM $table_survey_invitation survey_invitation
2090
                LEFT JOIN $table_user user
2091
                ON survey_invitation.user = user.user_id
2092
                WHERE
2093
                    survey_invitation.c_id = $course_id AND
2094
                    survey_invitation.survey_id = '".intval($_GET['survey_id'])."' AND
2095
                    session_id='".api_get_session_id()."'  ";
2096
        $res = Database::query($sql);
2097
        $data = [];
2098
        while ($row = Database::fetch_array($res)) {
2099
            $data[] = $row;
2100
        }
2101
2102
        return $data;
2103
    }
2104
2105
    /**
2106
     * Get the total number of survey invitations for a given survey (through $_GET['survey_id'])
2107
     *
2108
     * @return integer Total number of survey invitations
2109
     *
2110
     * @todo use survey_id parameter instead of $_GET
2111
     *
2112
     * @author Patrick Cool <[email protected]>, Ghent University
2113
     * @version January 2007
2114
     */
2115
    public static function get_number_of_survey_invitations()
2116
    {
2117
        $course_id = api_get_course_int_id();
2118
2119
        // Database table definition
2120
        $table = Database::get_course_table(TABLE_SURVEY_INVITATION);
2121
2122
        $sql = "SELECT count(user) AS total
2123
		        FROM $table
2124
		        WHERE
2125
                    c_id = $course_id AND
2126
                    survey_id='".intval($_GET['survey_id'])."' AND
2127
                    session_id='".api_get_session_id()."' ";
2128
        $res = Database::query($sql);
2129
        $row = Database::fetch_array($res, 'ASSOC');
2130
2131
        return $row['total'];
2132
    }
2133
2134
    /**
2135
     * Save the invitation mail
2136
     *
2137
     * @param string Text of the e-mail
2138
     * @param integer Whether the mail contents are for invite mail (0, default) or reminder mail (1)
2139
     *
2140
     * @author Patrick Cool <[email protected]>, Ghent University
2141
     * @version January 2007
2142
     */
2143
    public static function save_invite_mail($mailtext, $mail_subject, $reminder = 0)
2144
    {
2145
        $course_id = api_get_course_int_id();
2146
        // Database table definition
2147
        $table_survey = Database::get_course_table(TABLE_SURVEY);
2148
2149
        // Reminder or not
2150
        if ($reminder == 0) {
2151
            $mail_field = 'invite_mail';
2152
        } else {
2153
            $mail_field = 'reminder_mail';
2154
        }
2155
2156
        $sql = "UPDATE $table_survey SET
2157
		        mail_subject='".Database::escape_string($mail_subject)."',
2158
		        $mail_field = '".Database::escape_string($mailtext)."'
2159
		        WHERE c_id = $course_id AND survey_id = '".intval($_GET['survey_id'])."'";
2160
        Database::query($sql);
2161
    }
2162
2163
    /**
2164
     * This function saves all the invitations of course users
2165
     * and additional users in the database
2166
     * and sends the invitations by email
2167
     *
2168
     * @param $users_array Users $array array can be both a list of course uids AND a list of additional emailaddresses
2169
     * @param $invitation_title Title $string of the invitation, used as the title of the mail
2170
     * @param $invitation_text Text $string of the invitation, used as the text of the mail.
2171
     *                         The text has to contain a **link** string or this will automatically be added to the end
2172
     * @param int $reminder
2173
     * @param bool $sendmail
2174
     * @param int $remindUnAnswered
2175
     * @return int
2176
     * @internal param
2177
     * @internal param
2178
     * @internal param
2179
     *                 The text has to contain a **link** string or this will automatically be added to the end
2180
     * @author Patrick Cool <[email protected]>, Ghent University
2181
     * @author Julio Montoya - Adding auto-generated link support
2182
     * @version January 2007
2183
     */
2184
    public static function saveInvitations(
2185
        $users_array,
2186
        $invitation_title,
2187
        $invitation_text,
2188
        $reminder = 0,
2189
        $sendmail = false,
2190
        $remindUnAnswered = 0
2191
    ) {
2192
        if (!is_array($users_array)) {
2193
            // Should not happen
2194
2195
            return 0;
2196
        }
2197
2198
        // Getting the survey information
2199
        $survey_data = SurveyManager::get_survey($_GET['survey_id']);
2200
        $survey_invitations = self::get_invitations($survey_data['survey_code']);
2201
        $already_invited = self::get_invited_users($survey_data['code']);
2202
2203
        // Remind unanswered is a special version of remind all reminder
2204
        $exclude_users = array();
2205
        if ($remindUnAnswered == 1) { // Remind only unanswered users
2206
            $reminder = 1;
2207
            $exclude_users = SurveyManager::get_people_who_filled_survey($_GET['survey_id']);
2208
        }
2209
2210
        $counter = 0; // Nr of invitations "sent" (if sendmail option)
2211
        $course_id = api_get_course_int_id();
2212
        $session_id = api_get_session_id();
2213
        $result = CourseManager::separateUsersGroups($users_array);
2214
2215
        $groupList = $result['groups'];
2216
        $users_array = $result['users'];
2217
2218
        foreach ($groupList as $groupId) {
2219
            $userGroupList = GroupManager::getStudents($groupId);
2220
            $userGroupIdList = array_column($userGroupList, 'user_id');
2221
            $users_array = array_merge($users_array, $userGroupIdList);
2222
2223
            $params = array(
2224
                'c_id' => $course_id,
2225
                'session_id' => $session_id,
2226
                'group_id' => $groupId,
2227
                'survey_code' => $survey_data['code']
2228
            );
2229
2230
            $invitationExists = self::invitationExists(
2231
                $course_id,
2232
                $session_id,
2233
                $groupId,
2234
                $survey_data['code']
2235
            );
2236
            if (empty($invitationExists)) {
2237
                self::save_invitation($params);
2238
            }
2239
        }
2240
2241
        $users_array = array_unique($users_array);
2242
2243
        foreach ($users_array as $key => $value) {
2244
            if (!isset($value) || $value == '') {
2245
                continue;
2246
            }
2247
2248
            // Skip user if reminding only unanswered people
2249
            if (in_array($value, $exclude_users)) {
2250
                continue;
2251
            }
2252
2253
            // Get the unique invitation code if we already have it
2254
            if ($reminder == 1 && array_key_exists($value, $survey_invitations)) {
2255
                $invitation_code = $survey_invitations[$value]['invitation_code'];
2256
            } else {
2257
                $invitation_code = md5($value.microtime());
2258
            }
2259
            $new_user = false; // User not already invited
2260
            // Store the invitation if user_id not in $already_invited['course_users'] OR email is not in $already_invited['additional_users']
2261
            $addit_users_array = isset($already_invited['additional_users']) && !empty($already_invited['additional_users'])
2262
                    ? explode(';', $already_invited['additional_users'])
2263
                    : array();
2264
            $my_alredy_invited = $already_invited['course_users'] == null ? array() : $already_invited['course_users'];
2265
            if ((is_numeric($value) && !in_array($value, $my_alredy_invited)) ||
2266
                (!is_numeric($value) && !in_array($value, $addit_users_array))
2267
            ) {
2268
                $new_user = true;
2269
                if (!array_key_exists($value, $survey_invitations)) {
2270
                    $params = array(
2271
                        'c_id' => $course_id,
2272
                        'session_id' => $session_id,
2273
                        'user' => $value,
2274
                        'survey_code' => $survey_data['code'],
2275
                        'invitation_code' => $invitation_code,
2276
                        'invitation_date' => api_get_utc_datetime()
2277
                    );
2278
                    self::save_invitation($params);
2279
                }
2280
            }
2281
2282
            // Send the email if checkboxed
2283
            if (($new_user || $reminder == 1) && $sendmail) {
2284
                // Make a change for absolute url
2285
                if (isset($invitation_text)) {
2286
                    $invitation_text = api_html_entity_decode($invitation_text, ENT_QUOTES);
2287
                    $invitation_text = str_replace('src="../../', 'src="'.api_get_path(WEB_PATH), $invitation_text);
2288
                    $invitation_text = trim(stripslashes($invitation_text));
2289
                }
2290
                self::send_invitation_mail(
2291
                    $value,
2292
                    $invitation_code,
2293
                    $invitation_title,
2294
                    $invitation_text
2295
                );
2296
                $counter++;
2297
            }
2298
        }
2299
2300
        return $counter; // Number of invitations sent
2301
    }
2302
2303
    /**
2304
     * @param $params
2305
     * @return bool|int
2306
     */
2307
    public static function save_invitation($params)
2308
    {
2309
        // Database table to store the invitations data
2310
        $table = Database::get_course_table(TABLE_SURVEY_INVITATION);
2311
        if (!empty($params['c_id']) &&
2312
            (!empty($params['user']) || !empty($params['group_id'])) &&
2313
            !empty($params['survey_code'])
2314
        ) {
2315
            $insertId = Database::insert($table, $params);
2316
            if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type integer|false 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...
2317
                $sql = "UPDATE $table 
2318
                        SET survey_invitation_id = $insertId
2319
                        WHERE iid = $insertId";
2320
                Database::query($sql);
2321
            }
2322
2323
            return $insertId;
2324
        }
2325
2326
        return false;
2327
    }
2328
2329
    /**
2330
     * @param int $courseId
2331
     * @param int $sessionId
2332
     * @param int $groupId
2333
     * @param string $surveyCode
2334
     * @return int
2335
     */
2336
    public static function invitationExists($courseId, $sessionId, $groupId, $surveyCode)
2337
    {
2338
        $table = Database::get_course_table(TABLE_SURVEY_INVITATION);
2339
        $courseId = intval($courseId);
2340
        $sessionId = intval($sessionId);
2341
        $groupId = intval($groupId);
2342
        $surveyCode = Database::escape_string($surveyCode);
2343
2344
        $sql = "SELECT survey_invitation_id FROM $table
2345
                WHERE
2346
                    c_id = $courseId AND
2347
                    session_id = $sessionId AND
2348
                    group_id = $groupId AND
2349
                    survey_code = '$surveyCode'
2350
                ";
2351
        $result = Database::query($sql);
2352
2353
        return Database::num_rows($result);
2354
    }
2355
2356
    /**
2357
     * Send the invitation by mail.
2358
     *
2359
     * @param int invitedUser - the userId (course user) or emailaddress of additional user
2360
     * $param string $invitation_code - the unique invitation code for the URL
2361
     * @return void
2362
     */
2363
    public static function send_invitation_mail(
2364
        $invitedUser,
2365
        $invitation_code,
2366
        $invitation_title,
2367
        $invitation_text
2368
    ) {
2369
        $_user = api_get_user_info();
2370
        $_course = api_get_course_info();
2371
2372
        // Replacing the **link** part with a valid link for the user
2373
        $survey_link = api_get_path(WEB_CODE_PATH).'survey/fillsurvey.php?course='.$_course['code'].'&invitationcode='
2374
            .$invitation_code;
2375
        $text_link = '<a href="'.$survey_link.'">'.get_lang('ClickHereToAnswerTheSurvey')."</a><br />\r\n<br />\r\n"
2376
            .get_lang('OrCopyPasteTheFollowingUrl')." <br />\r\n ".$survey_link;
2377
2378
        $replace_count = 0;
2379
        $full_invitation_text = api_str_ireplace('**link**', $text_link, $invitation_text, $replace_count);
2380
        if ($replace_count < 1) {
2381
            $full_invitation_text = $full_invitation_text."<br />\r\n<br />\r\n".$text_link;
2382
        }
2383
2384
        // Sending the mail
2385
        $sender_name = api_get_person_name($_user['firstName'], $_user['lastName'], null, PERSON_NAME_EMAIL_ADDRESS);
2386
        $sender_email = $_user['mail'];
2387
        $sender_user_id = api_get_user_id();
2388
2389
        $replyto = array();
2390
        if (api_get_setting('survey_email_sender_noreply') == 'noreply') {
2391
            $noreply = api_get_setting('noreply_email_address');
2392
            if (!empty($noreply)) {
2393
                $replyto['Reply-to'] = $noreply;
2394
                $sender_name = $noreply;
2395
                $sender_email = $noreply;
2396
                $sender_user_id = null;
2397
            }
2398
        }
2399
2400
        // Optionally: finding the e-mail of the course user
2401
        if (is_numeric($invitedUser)) {
2402
            MessageManager::send_message(
2403
                $invitedUser,
2404
                $invitation_title,
2405
                $full_invitation_text,
2406
                [],
2407
                [],
2408
                null,
2409
                null,
2410
                null,
2411
                null,
2412
                $sender_user_id
2413
            );
2414
        } else {
2415
            /** @todo check if the address is a valid email */
2416
            $recipient_email = $invitedUser;
2417
            @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

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