Passed
Push — 1.11.x ( 85ee03...c9e0c2 )
by Julito
09:52
created

SurveyManager::parseMultiplicateUserList()   B

Complexity

Conditions 9
Paths 11

Size

Total Lines 70
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 55
nc 11
nop 4
dl 0
loc 70
rs 7.4262
c 0
b 0
f 0

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CSurveyInvitation;
5
6
/**
7
 * Class SurveyManager.
8
 *
9
 * @package chamilo.survey
10
 *
11
 * @author Patrick Cool <[email protected]>, Ghent University:
12
 * cleanup, refactoring and rewriting large parts (if not all) of the code
13
 * @author Julio Montoya <[email protected]>, Personality Test modification
14
 * and rewriting large parts of the code
15
 * @author cfasanando
16
 *
17
 * @todo move this file to inc/lib
18
 * @todo use consistent naming for the functions (save vs store for instance)
19
 */
20
class SurveyManager
21
{
22
    /**
23
     * @param $code
24
     *
25
     * @return string
26
     */
27
    public static function generate_unique_code($code)
28
    {
29
        if (empty($code)) {
30
            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...
31
        }
32
        $course_id = api_get_course_int_id();
33
        $table = Database::get_course_table(TABLE_SURVEY);
34
        $code = Database::escape_string($code);
35
        $num = 0;
36
        $new_code = $code;
37
        while (true) {
38
            $sql = "SELECT * FROM $table
39
                    WHERE code = '$new_code' AND c_id = $course_id";
40
            $result = Database::query($sql);
41
            if (Database::num_rows($result)) {
42
                $num++;
43
                $new_code = $code.$num;
44
            } else {
45
                break;
46
            }
47
        }
48
49
        return $code.$num;
50
    }
51
52
    /**
53
     * Deletes all survey invitations of a user.
54
     *
55
     * @param int $user_id
56
     *
57
     * @return bool
58
     * @assert ('') === false
59
     */
60
    public static function delete_all_survey_invitations_by_user($user_id)
61
    {
62
        $user_id = (int) $user_id;
63
        if (empty($user_id)) {
64
            return false;
65
        }
66
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
67
        $table_survey = Database::get_course_table(TABLE_SURVEY);
68
69
        $sql = "SELECT survey_invitation_id, survey_code
70
                FROM $table_survey_invitation WHERE user = '$user_id' AND c_id <> 0 ";
71
        $result = Database::query($sql);
72
        while ($row = Database::fetch_array($result, 'ASSOC')) {
73
            $survey_invitation_id = $row['survey_invitation_id'];
74
            $survey_code = $row['survey_code'];
75
            $sql2 = "DELETE FROM $table_survey_invitation
76
                    WHERE survey_invitation_id = '$survey_invitation_id' AND c_id <> 0";
77
            if (Database::query($sql2)) {
78
                $sql3 = "UPDATE $table_survey SET
79
                            invited = invited-1
80
                        WHERE c_id <> 0 AND code ='$survey_code'";
81
                Database::query($sql3);
82
            }
83
        }
84
    }
85
86
    /**
87
     * @param string $course_code
88
     * @param int    $session_id
89
     *
90
     * @return array
91
     * @assert ('') === false
92
     */
93
    public static function get_surveys($course_code, $session_id = 0)
94
    {
95
        if (empty($course_code)) {
96
            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 array.
Loading history...
97
        }
98
        $course_info = api_get_course_info($course_code);
99
100
        if (empty($course_info)) {
101
            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 array.
Loading history...
102
        }
103
104
        $sessionCondition = api_get_session_condition($session_id, true, true);
105
106
        $table = Database::get_course_table(TABLE_SURVEY);
107
        $sql = "SELECT * FROM $table
108
                WHERE c_id = {$course_info['real_id']} $sessionCondition ";
109
        $result = Database::query($sql);
110
        $result = Database::store_result($result, 'ASSOC');
111
112
        return $result;
113
    }
114
115
    /**
116
     * Retrieves all the survey information.
117
     *
118
     * @param int  $survey_id the id of the survey
119
     * @param bool $shared    this parameter determines if
120
     *                        we have to get the information of a survey from the central (shared) database or from the
121
     *                        course database
122
     * @param string course code optional
123
     *
124
     * @author Patrick Cool <[email protected]>, Ghent University
125
     *
126
     * @version February 2007
127
     * @assert ('') === false
128
     *
129
     * @return array
130
     *
131
     * @todo this is the same function as in create_new_survey.php
132
     */
133
    public static function get_survey(
134
        $survey_id,
135
        $shared = 0,
136
        $course_code = '',
137
        $simple_return = false
138
    ) {
139
        $my_course_id = api_get_course_id();
140
141
        // Table definition
142
        if (!empty($course_code)) {
143
            $my_course_id = $course_code;
144
        } elseif (isset($_GET['course'])) {
145
            $my_course_id = Security::remove_XSS($_GET['course']);
146
        }
147
148
        $courseInfo = api_get_course_info($my_course_id);
149
        $survey_id = (int) $survey_id;
150
        $table_survey = Database::get_course_table(TABLE_SURVEY);
151
152
        if ($shared != 0) {
153
            $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
154
            $sql = "SELECT * FROM $table_survey
155
                    WHERE survey_id='".$survey_id."' ";
156
        } else {
157
            if (empty($courseInfo)) {
158
                return [];
159
            }
160
            $sql = "SELECT * FROM $table_survey
161
		            WHERE
162
		                survey_id='".$survey_id."' AND
163
		                c_id = ".$courseInfo['real_id'];
164
        }
165
166
        $result = Database::query($sql);
167
        $return = [];
168
169
        if (Database::num_rows($result) > 0) {
170
            $return = Database::fetch_array($result, 'ASSOC');
171
            if ($simple_return) {
172
                return $return;
173
            }
174
            // We do this (temporarily) to have the array match the quickform elements immediately
175
            // idealiter the fields in the db match the quickform fields
176
            $return['survey_code'] = $return['code'];
177
            $return['survey_title'] = $return['title'];
178
            $return['survey_subtitle'] = $return['subtitle'];
179
            $return['survey_language'] = $return['lang'];
180
            $return['start_date'] = $return['avail_from'];
181
            $return['end_date'] = $return['avail_till'];
182
            $return['survey_share'] = $return['is_shared'];
183
            $return['survey_introduction'] = $return['intro'];
184
            $return['survey_thanks'] = $return['surveythanks'];
185
            $return['survey_type'] = $return['survey_type'];
186
            $return['one_question_per_page'] = $return['one_question_per_page'];
187
            $return['show_form_profile'] = $return['show_form_profile'];
188
            $return['input_name_list'] = isset($return['input_name_list']) ? $return['input_name_list'] : null;
189
            $return['shuffle'] = $return['shuffle'];
190
            $return['parent_id'] = $return['parent_id'];
191
            $return['survey_version'] = $return['survey_version'];
192
            $return['anonymous'] = $return['anonymous'];
193
            $return['c_id'] = isset($return['c_id']) ? $return['c_id'] : 0;
194
            $return['session_id'] = isset($return['session_id']) ? $return['session_id'] : 0;
195
        }
196
197
        return $return;
198
    }
199
200
    /**
201
     * @param string $code
202
     *
203
     * @return string
204
     */
205
    public static function generateSurveyCode($code)
206
    {
207
        return strtolower(CourseManager::generate_course_code($code));
208
    }
209
210
    /**
211
     * This function stores a survey in the database.
212
     *
213
     * @param array $values
214
     *
215
     * @return array $return the type of return message that has to be displayed and the message in it
216
     *
217
     * @author Patrick Cool <[email protected]>, Ghent University
218
     *
219
     * @version February 2007
220
     */
221
    public static function store_survey($values)
222
    {
223
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
224
        $_user = api_get_user_info();
225
        $course_id = api_get_course_int_id();
226
        $session_id = api_get_session_id();
227
        $courseCode = api_get_course_id();
228
        $table_survey = Database::get_course_table(TABLE_SURVEY);
229
        $shared_survey_id = 0;
230
231
        if (!isset($values['survey_id'])) {
232
            // Check if the code doesn't soon exists in this language
233
            $sql = 'SELECT 1 FROM '.$table_survey.'
234
			        WHERE
235
			            c_id = '.$course_id.' AND
236
			            code = "'.Database::escape_string($values['survey_code']).'" AND
237
			            lang = "'.Database::escape_string($values['survey_language']).'"';
238
            $rs = Database::query($sql);
239
            if (Database::num_rows($rs) > 0) {
240
                Display::addFlash(
241
                    Display::return_message(
242
                        get_lang('ThisSurveyCodeSoonExistsInThisLanguage'),
243
                        'error'
244
                    )
245
                );
246
                $return['type'] = 'error';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.
Loading history...
247
                $return['id'] = isset($values['survey_id']) ? $values['survey_id'] : 0;
248
249
                return $return;
250
            }
251
252
            if (!isset($values['anonymous'])) {
253
                $values['anonymous'] = 0;
254
            }
255
256
            $values['anonymous'] = (int) $values['anonymous'];
257
            $extraParams = [];
258
            if ($values['anonymous'] == 0) {
259
                // Input_name_list
260
                $values['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : 0;
261
                $extraParams['show_form_profile'] = $values['show_form_profile'];
262
263
                if ($values['show_form_profile'] == 1) {
264
                    // Input_name_list
265
                    $fields = explode(',', $values['input_name_list']);
266
                    $field_values = '';
267
                    foreach ($fields as &$field) {
268
                        if ($field != '') {
269
                            if ($values[$field] == '') {
270
                                $values[$field] = 0;
271
                            }
272
                            $field_values .= $field.':'.$values[$field].'@';
273
                        }
274
                    }
275
                    $extraParams['form_fields'] = $field_values;
276
                } else {
277
                    $extraParams['form_fields'] = '';
278
                }
279
            } else {
280
                // Input_name_list
281
                $extraParams['show_form_profile'] = 0;
282
                $extraParams['form_fields'] = '';
283
            }
284
285
            $extraParams['one_question_per_page'] = isset($values['one_question_per_page']) ? $values['one_question_per_page'] : 0;
286
            $extraParams['shuffle'] = isset($values['shuffle']) ? $values['shuffle'] : 0;
287
288
            if ($values['survey_type'] == 1) {
289
                $extraParams['survey_type'] = 1;
290
                $extraParams['parent_id'] = $values['parent_id'];
291
292
                // Logic for versioning surveys
293
                if (!empty($values['parent_id'])) {
294
                    $versionValue = '';
295
                    $sql = 'SELECT survey_version
296
                            FROM '.$table_survey.'
297
					        WHERE
298
					            c_id = '.$course_id.' AND
299
					            parent_id = '.intval($values['parent_id']).'
300
                            ORDER BY survey_version DESC
301
                            LIMIT 1';
302
                    $rs = Database::query($sql);
303
                    if (Database::num_rows($rs) === 0) {
304
                        $sql = 'SELECT survey_version FROM '.$table_survey.'
305
						        WHERE
306
						            c_id = '.$course_id.' AND
307
						            survey_id = '.intval($values['parent_id']);
308
                        $rs = Database::query($sql);
309
                        $getversion = Database::fetch_array($rs, 'ASSOC');
310
                        if (empty($getversion['survey_version'])) {
311
                            $versionValue = ++$getversion['survey_version'];
312
                        } else {
313
                            $versionValue = $getversion['survey_version'];
314
                        }
315
                    } else {
316
                        $row = Database::fetch_array($rs, 'ASSOC');
317
                        $pos = api_strpos($row['survey_version']);
0 ignored issues
show
Bug introduced by
The call to api_strpos() has too few arguments starting with needle. ( Ignorable by Annotation )

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

317
                        $pos = /** @scrutinizer ignore-call */ api_strpos($row['survey_version']);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
318
                        if ($pos === false) {
319
                            $row['survey_version'] = $row['survey_version'] + 1;
320
                            $versionValue = $row['survey_version'];
321
                        } else {
322
                            $getlast = explode('\.', $row['survey_version']);
323
                            $lastversion = array_pop($getlast);
324
                            $lastversion = $lastversion + 1;
325
                            $add = implode('.', $getlast);
326
                            if ($add != '') {
327
                                $insertnewversion = $add.'.'.$lastversion;
328
                            } else {
329
                                $insertnewversion = $lastversion;
330
                            }
331
                            $versionValue = $insertnewversion;
332
                        }
333
                    }
334
                    $extraParams['survey_version'] = $versionValue;
335
                }
336
            }
337
338
            $params = [
339
                'c_id' => $course_id,
340
                'code' => self::generateSurveyCode($values['survey_code']),
341
                'title' => $values['survey_title'],
342
                'subtitle' => $values['survey_subtitle'],
343
                'author' => $_user['user_id'],
344
                'lang' => $values['survey_language'],
345
                'is_shared' => $shared_survey_id,
346
                'template' => 'template',
347
                'intro' => $values['survey_introduction'],
348
                'surveythanks' => $values['survey_thanks'],
349
                'creation_date' => api_get_utc_datetime(),
350
                'anonymous' => $values['anonymous'],
351
                'session_id' => api_get_session_id(),
352
                'visible_results' => $values['visible_results'],
353
            ];
354
355
            if (!empty($values['start_date'])) {
356
                if ($allowSurveyAvailabilityDatetime) {
357
                    $params['avail_from'] = api_get_utc_datetime($values['start_date'].':00');
358
                } else {
359
                    $params['avail_from'] = $values['start_date'];
360
                }
361
            }
362
363
            if (!empty($values['end_date'])) {
364
                if ($allowSurveyAvailabilityDatetime) {
365
                    $params['avail_till'] = api_get_utc_datetime($values['end_date'].':00');
366
                } else {
367
                    $params['avail_till'] = $values['end_date'];
368
                }
369
            }
370
371
            if (isset($values['survey_type']) && !empty($values['survey_type'])) {
372
                $params['survey_type'] = $values['survey_type'];
373
            }
374
375
            $params = array_merge($params, $extraParams);
376
377
            $survey_id = Database::insert($table_survey, $params);
378
            if ($survey_id > 0) {
379
                $sql = "UPDATE $table_survey SET survey_id = $survey_id
380
                        WHERE iid = $survey_id";
381
                Database::query($sql);
382
383
                // Insert into item_property
384
                api_item_property_update(
385
                    api_get_course_info(),
386
                    TOOL_SURVEY,
387
                    $survey_id,
0 ignored issues
show
Bug introduced by
It seems like $survey_id can also be of type false; however, parameter $item_id of api_item_property_update() does only seem to accept integer, 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

387
                    /** @scrutinizer ignore-type */ $survey_id,
Loading history...
388
                    'SurveyAdded',
389
                    api_get_user_id()
390
                );
391
            }
392
393
            if ($values['survey_type'] == 1 && !empty($values['parent_id'])) {
394
                self::copy_survey($values['parent_id'], $survey_id);
0 ignored issues
show
Bug introduced by
It seems like $survey_id can also be of type false; however, parameter $new_survey_id of SurveyManager::copy_survey() does only seem to accept integer, 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

394
                self::copy_survey($values['parent_id'], /** @scrutinizer ignore-type */ $survey_id);
Loading history...
395
            }
396
397
            Display::addFlash(
398
                Display::return_message(
399
                    get_lang('SurveyCreatedSuccesfully'),
400
                    'success'
401
                )
402
            );
403
            $return['id'] = $survey_id;
404
        } else {
405
            // Check whether the code doesn't soon exists in this language
406
            $sql = 'SELECT 1 FROM '.$table_survey.'
407
			        WHERE
408
			            c_id = '.$course_id.' AND
409
			            code = "'.Database::escape_string($values['survey_code']).'" AND
410
			            lang = "'.Database::escape_string($values['survey_language']).'" AND
411
			            survey_id !='.intval($values['survey_id']);
412
            $rs = Database::query($sql);
413
            if (Database::num_rows($rs) > 0) {
414
                Display::addFlash(
415
                    Display::return_message(
416
                        get_lang('ThisSurveyCodeSoonExistsInThisLanguage'),
417
                        'error'
418
                    )
419
                );
420
                $return['type'] = 'error';
421
                $return['id'] = isset($values['survey_id']) ? $values['survey_id'] : 0;
422
423
                return $return;
424
            }
425
426
            if (!isset($values['anonymous'])
427
                || (isset($values['anonymous']) && $values['anonymous'] == '')
428
            ) {
429
                $values['anonymous'] = 0;
430
            }
431
432
            $extraParams = [];
433
            $extraParams['one_question_per_page'] = isset($values['one_question_per_page']) ? $values['one_question_per_page'] : 0;
434
            $extraParams['shuffle'] = isset($values['shuffle']) ? $values['shuffle'] : 0;
435
436
            if ($values['anonymous'] == 0) {
437
                $extraParams['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : 0;
438
                if ($extraParams['show_form_profile'] == 1) {
439
                    $fields = explode(',', $values['input_name_list']);
440
                    $field_values = '';
441
                    foreach ($fields as &$field) {
442
                        if ($field != '') {
443
                            if (!isset($values[$field]) ||
444
                                (isset($values[$field]) && $values[$field] == '')
445
                            ) {
446
                                $values[$field] = 0;
447
                            }
448
                            $field_values .= $field.':'.$values[$field].'@';
449
                        }
450
                    }
451
                    $extraParams['form_fields'] = $field_values;
452
                } else {
453
                    $extraParams['form_fields'] = '';
454
                }
455
            } else {
456
                $extraParams['show_form_profile'] = 0;
457
                $extraParams['form_fields'] = '';
458
            }
459
460
            $params = [
461
                'title' => $values['survey_title'],
462
                'subtitle' => $values['survey_subtitle'],
463
                'author' => $_user['user_id'],
464
                'lang' => $values['survey_language'],
465
                'avail_from' => $allowSurveyAvailabilityDatetime
466
                    ? api_get_utc_datetime($values['start_date'].':00')
467
                    : $values['start_date'],
468
                'avail_till' => $allowSurveyAvailabilityDatetime
469
                    ? api_get_utc_datetime($values['end_date'].':59')
470
                    : $values['end_date'],
471
                'is_shared' => $shared_survey_id,
472
                'template' => 'template',
473
                'intro' => $values['survey_introduction'],
474
                'surveythanks' => $values['survey_thanks'],
475
                'anonymous' => $values['anonymous'],
476
                'session_id' => api_get_session_id(),
477
                'visible_results' => $values['visible_results'],
478
            ];
479
480
            $params = array_merge($params, $extraParams);
481
            Database::update(
482
                $table_survey,
483
                $params,
484
                [
485
                    'c_id = ? AND survey_id = ?' => [
486
                        $course_id,
487
                        $values['survey_id'],
488
                    ],
489
                ]
490
            );
491
492
            // Update into item_property (update)
493
            api_item_property_update(
494
                api_get_course_info(),
495
                TOOL_SURVEY,
496
                $values['survey_id'],
497
                'SurveyUpdated',
498
                api_get_user_id()
499
            );
500
501
            Display::addFlash(
502
                Display::return_message(
503
                    get_lang('SurveyUpdatedSuccesfully'),
504
                    'confirmation'
505
                )
506
            );
507
508
            $return['id'] = $values['survey_id'];
509
        }
510
511
        $survey_id = (int) $return['id'];
512
513
        // Gradebook
514
        $gradebook_option = false;
515
        if (isset($values['survey_qualify_gradebook'])) {
516
            $gradebook_option = $values['survey_qualify_gradebook'] > 0;
517
        }
518
519
        $gradebook_link_type = 8;
520
        $link_info = GradebookUtils::isResourceInCourseGradebook(
521
            $courseCode,
522
            $gradebook_link_type,
523
            $survey_id,
524
            $session_id
525
        );
526
527
        $gradebook_link_id = isset($link_info['id']) ? $link_info['id'] : false;
528
529
        if ($gradebook_option) {
530
            if ($survey_id > 0) {
531
                $title_gradebook = ''; // Not needed here.
532
                $description_gradebook = ''; // Not needed here.
533
                $survey_weight = floatval($_POST['survey_weight']);
534
                $max_score = 1;
535
536
                if (!$gradebook_link_id) {
537
                    GradebookUtils::add_resource_to_course_gradebook(
538
                        $values['category_id'],
539
                        $courseCode,
540
                        $gradebook_link_type,
541
                        $survey_id,
542
                        $title_gradebook,
543
                        $survey_weight,
544
                        $max_score,
545
                        $description_gradebook,
546
                        1,
547
                        $session_id
548
                    );
549
                } else {
550
                    GradebookUtils::updateResourceFromCourseGradebook(
551
                        $gradebook_link_id,
552
                        $courseCode,
553
                        $survey_weight
554
                    );
555
                }
556
            }
557
        } else {
558
            // Delete everything of the gradebook for this $linkId
559
            GradebookUtils::remove_resource_from_course_gradebook($gradebook_link_id);
560
        }
561
562
        return $return;
563
    }
564
565
    /**
566
     * This function stores a shared survey in the central database.
567
     *
568
     * @param array $values
569
     *
570
     * @return array $return the type of return message that has to be displayed and the message in it
571
     *
572
     * @author Patrick Cool <[email protected]>, Ghent University
573
     *
574
     * @version February 2007
575
     */
576
    public function store_shared_survey($values)
577
    {
578
        $_user = api_get_user_info();
579
        $_course = api_get_course_info();
580
581
        // Table definitions
582
        $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
583
584
        if (!$values['survey_id'] ||
585
            !is_numeric($values['survey_id']) ||
586
            $values['survey_share']['survey_share'] == 'true'
587
        ) {
588
            $sql = "INSERT INTO $table_survey (code, title, subtitle, author, lang, template, intro, surveythanks, creation_date, course_code) VALUES (
589
                    '".Database::escape_string($values['survey_code'])."',
590
                    '".Database::escape_string($values['survey_title'])."',
591
                    '".Database::escape_string($values['survey_subtitle'])."',
592
                    '".intval($_user['user_id'])."',
593
                    '".Database::escape_string($values['survey_language'])."',
594
                    '".Database::escape_string('template')."',
595
                    '".Database::escape_string($values['survey_introduction'])."',
596
                    '".Database::escape_string($values['survey_thanks'])."',
597
                    '".api_get_utc_datetime()."',
598
                    '".$_course['id']."')";
599
            Database::query($sql);
600
            $return = Database::insert_id();
601
602
            $sql = "UPDATE $table_survey SET survey_id = $return WHERE iid = $return";
603
            Database::query($sql);
604
        } else {
605
            $sql = "UPDATE $table_survey SET
606
                        code 			= '".Database::escape_string($values['survey_code'])."',
607
                        title 			= '".Database::escape_string($values['survey_title'])."',
608
                        subtitle 		= '".Database::escape_string($values['survey_subtitle'])."',
609
                        author 			= '".intval($_user['user_id'])."',
610
                        lang 			= '".Database::escape_string($values['survey_language'])."',
611
                        template 		= '".Database::escape_string('template')."',
612
                        intro			= '".Database::escape_string($values['survey_introduction'])."',
613
                        surveythanks	= '".Database::escape_string($values['survey_thanks'])."'
614
					WHERE survey_id = '".Database::escape_string($values['survey_share']['survey_share'])."'";
615
            Database::query($sql);
616
            $return = $values['survey_share']['survey_share'];
617
        }
618
619
        return $return;
620
    }
621
622
    /**
623
     * This function deletes a survey (and also all the question in that survey.
624
     *
625
     * @param int  $survey_id id of the survey that has to be deleted
626
     * @param bool $shared
627
     * @param int  $course_id
628
     *
629
     * @return true
630
     *
631
     * @author Patrick Cool <[email protected]>, Ghent University
632
     *
633
     * @version January 2007
634
     */
635
    public static function delete_survey($survey_id, $shared = false, $course_id = 0)
636
    {
637
        // Database table definitions
638
        if (empty($course_id)) {
639
            $course_id = api_get_course_int_id();
640
        }
641
642
        $survey_id = (int) $survey_id;
643
644
        if (empty($survey_id)) {
645
            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 true.
Loading history...
646
        }
647
648
        $course_info = api_get_course_info_by_id($course_id);
649
        $course_id = $course_info['real_id'];
650
651
        $table_survey = Database::get_course_table(TABLE_SURVEY);
652
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
653
654
        if ($shared) {
655
            $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
656
            // Deleting the survey
657
            $sql = "DELETE FROM $table_survey
658
                    WHERE survey_id='".$survey_id."'";
659
            Database::query($sql);
660
        } else {
661
            $sql = "DELETE FROM $table_survey
662
                    WHERE c_id = $course_id AND survey_id='".$survey_id."'";
663
            Database::query($sql);
664
        }
665
666
        // Deleting groups of this survey
667
        $sql = "DELETE FROM $table_survey_question_group
668
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
669
        Database::query($sql);
670
671
        // Deleting the questions of the survey
672
        self::delete_all_survey_questions($survey_id, $shared);
673
674
        // Update into item_property (delete)
675
        api_item_property_update(
676
            $course_info,
677
            TOOL_SURVEY,
678
            $survey_id,
679
            'SurveyDeleted',
680
            api_get_user_id()
681
        );
682
683
        Skill::deleteSkillsFromItem($survey_id, ITEM_TYPE_SURVEY);
684
685
        return true;
686
    }
687
688
    /**
689
     * @param int $survey_id
690
     * @param int $new_survey_id
691
     * @param int $targetCourseId
692
     *
693
     * @return bool
694
     */
695
    public static function copy_survey(
696
        $survey_id,
697
        $new_survey_id = null,
698
        $targetCourseId = null
699
    ) {
700
        $course_id = api_get_course_int_id();
701
        if (!$targetCourseId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $targetCourseId of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === null 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...
702
            $targetCourseId = $course_id;
703
        }
704
705
        // Database table definitions
706
        $table_survey = Database::get_course_table(TABLE_SURVEY);
707
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
708
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
709
        $table_survey_options = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
710
        $survey_id = (int) $survey_id;
711
712
        // Get groups
713
        $survey_data = self::get_survey($survey_id, 0, null, true);
714
        if (empty($survey_data)) {
715
            return true;
716
        }
717
718
        if (empty($new_survey_id)) {
719
            $params = $survey_data;
720
            $params['code'] = self::generate_unique_code($params['code']);
721
            $params['c_id'] = $targetCourseId;
722
            unset($params['survey_id']);
723
            $params['session_id'] = api_get_session_id();
724
            $params['title'] = $params['title'].' '.get_lang('Copy');
725
            unset($params['iid']);
726
            $new_survey_id = Database::insert($table_survey, $params);
727
728
            if ($new_survey_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $new_survey_id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
729
                $sql = "UPDATE $table_survey SET survey_id = $new_survey_id
730
                        WHERE iid = $new_survey_id";
731
                Database::query($sql);
732
733
                // Insert into item_property
734
                api_item_property_update(
735
                    api_get_course_info(),
736
                    TOOL_SURVEY,
737
                    $new_survey_id,
738
                    'SurveyAdded',
739
                    api_get_user_id()
740
                );
741
            }
742
        } else {
743
            $new_survey_id = (int) $new_survey_id;
744
        }
745
746
        $sql = "SELECT * FROM $table_survey_question_group
747
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
748
        $res = Database::query($sql);
749
        while ($row = Database::fetch_array($res, 'ASSOC')) {
750
            $params = [
751
                'c_id' => $targetCourseId,
752
                'name' => $row['name'],
753
                'description' => $row['description'],
754
                'survey_id' => $new_survey_id,
755
            ];
756
            $insertId = Database::insert($table_survey_question_group, $params);
757
758
            $sql = "UPDATE $table_survey_question_group SET id = iid
759
                    WHERE iid = $insertId";
760
            Database::query($sql);
761
762
            $group_id[$row['id']] = $insertId;
763
        }
764
765
        // Get questions
766
        $sql = "SELECT * FROM $table_survey_question
767
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
768
        $res = Database::query($sql);
769
        while ($row = Database::fetch_array($res, 'ASSOC')) {
770
            $params = [
771
                'c_id' => $targetCourseId,
772
                'survey_id' => $new_survey_id,
773
                'survey_question' => $row['survey_question'],
774
                'survey_question_comment' => $row['survey_question_comment'],
775
                'type' => $row['type'],
776
                'display' => $row['display'],
777
                'sort' => $row['sort'],
778
                'shared_question_id' => $row['shared_question_id'],
779
                'max_value' => $row['max_value'],
780
                'survey_group_pri' => $row['survey_group_pri'],
781
                'survey_group_sec1' => $row['survey_group_sec1'],
782
                'survey_group_sec2' => $row['survey_group_sec2'],
783
            ];
784
785
            if (api_get_configuration_value('allow_required_survey_questions')) {
786
                if (isset($row['is_required'])) {
787
                    $params['is_required'] = $row['is_required'];
788
                }
789
            }
790
791
            $insertId = Database::insert($table_survey_question, $params);
792
            if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
793
                $sql = "UPDATE $table_survey_question SET question_id = iid WHERE iid = $insertId";
794
                Database::query($sql);
795
                $question_id[$row['question_id']] = $insertId;
796
            }
797
        }
798
799
        // Get questions options
800
        $sql = "SELECT * FROM $table_survey_options
801
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
802
803
        $res = Database::query($sql);
804
        while ($row = Database::fetch_array($res, 'ASSOC')) {
805
            $params = [
806
                'c_id' => $targetCourseId,
807
                'question_id' => $question_id[$row['question_id']],
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_id does not seem to be defined for all execution paths leading up to this point.
Loading history...
808
                'survey_id' => $new_survey_id,
809
                'option_text' => $row['option_text'],
810
                'sort' => $row['sort'],
811
                'value' => $row['value'],
812
            ];
813
            $insertId = Database::insert($table_survey_options, $params);
814
            if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
815
                $sql = "UPDATE $table_survey_options SET question_option_id = $insertId
816
                        WHERE iid = $insertId";
817
                Database::query($sql);
818
            }
819
        }
820
821
        return $new_survey_id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $new_survey_id also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
822
    }
823
824
    /**
825
     * This function duplicates a survey (and also all the question in that survey.
826
     *
827
     * @param int $surveyId id of the survey that has to be duplicated
828
     * @param int $courseId id of the course which survey has to be duplicated
829
     *
830
     * @return true
831
     *
832
     * @author Eric Marguin <[email protected]>, Elixir Interactive
833
     *
834
     * @version October 2007
835
     */
836
    public static function empty_survey($surveyId, $courseId = 0)
837
    {
838
        // Database table definitions
839
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
840
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
841
        $table_survey = Database::get_course_table(TABLE_SURVEY);
842
843
        $courseId = (int) $courseId;
844
        $courseId = empty($courseId) ? api_get_course_int_id() : $courseId;
845
        $surveyId = (int) $surveyId;
846
847
        $datas = self::get_survey($surveyId);
848
        $session_where = '';
849
        if (api_get_session_id() != 0) {
850
            $session_where = ' AND session_id = "'.api_get_session_id().'" ';
851
        }
852
853
        $sql = 'DELETE FROM '.$table_survey_invitation.'
854
		        WHERE
855
		            c_id = '.$courseId.' AND
856
		            survey_code = "'.Database::escape_string($datas['code']).'" '.$session_where.' ';
857
        Database::query($sql);
858
859
        $sql = 'DELETE FROM '.$table_survey_answer.'
860
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
861
        Database::query($sql);
862
863
        $sql = 'UPDATE '.$table_survey.' SET invited=0, answered=0
864
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
865
        Database::query($sql);
866
867
        return true;
868
    }
869
870
    /**
871
     * This function recalculates the number of people who have taken the survey (=filled at least one question).
872
     *
873
     * @param array  $survey_data
874
     * @param array  $user
875
     * @param string $survey_code
876
     *
877
     * @return bool
878
     *
879
     * @author Patrick Cool <[email protected]>, Ghent University
880
     *
881
     * @version February 2007
882
     */
883
    public static function update_survey_answered($survey_data, $user, $survey_code)
884
    {
885
        if (empty($survey_data)) {
886
            return false;
887
        }
888
889
        // Database table definitions
890
        $table_survey = Database::get_course_table(TABLE_SURVEY);
891
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
892
893
        $survey_id = (int) $survey_data['survey_id'];
894
        $course_id = (int) $survey_data['c_id'];
895
        $session_id = $survey_data['session_id'];
896
897
        // Getting a list with all the people who have filled the survey
898
        /*$people_filled = self::get_people_who_filled_survey($survey_id, false, $course_id);
899
        $number = count($people_filled);*/
900
901
        // Storing this value in the survey table
902
        $sql = "UPDATE $table_survey
903
		        SET answered = answered + 1
904
		        WHERE
905
                    c_id = $course_id AND
906
		            survey_id = ".$survey_id;
907
        Database::query($sql);
908
909
        $allow = api_get_configuration_value('survey_answered_at_field');
910
        // Requires DB change:
911
        // ALTER TABLE c_survey_invitation ADD answered_at DATETIME DEFAULT NULL;
912
        $answeredAt = '';
913
        if ($allow) {
914
            $answeredAt = "answered_at = '".api_get_utc_datetime()."',";
915
        }
916
917
        // Storing that the user has finished the survey.
918
        $sql = "UPDATE $table_survey_invitation
919
                SET $answeredAt answered = 1
920
                WHERE
921
                    c_id = $course_id AND
922
                    session_id = $session_id AND
923
                    user ='".Database::escape_string($user)."' AND
924
                    survey_code='".Database::escape_string($survey_code)."'";
925
        Database::query($sql);
926
    }
927
928
    /**
929
     * This function return the "icon" of the question type.
930
     *
931
     * @param string $type
932
     *
933
     * @author Patrick Cool <[email protected]>, Ghent University
934
     *
935
     * @version February 2007
936
     */
937
    public static function icon_question($type)
938
    {
939
        // the possible question types
940
        $possible_types = [
941
            'personality',
942
            'yesno',
943
            'multiplechoice',
944
            'multipleresponse',
945
            'open',
946
            'dropdown',
947
            'comment',
948
            'pagebreak',
949
            'percentage',
950
            'score',
951
        ];
952
953
        // the images array
954
        $icon_question = [
955
            'yesno' => 'yesno.png',
956
            'personality' => 'yesno.png',
957
            'multiplechoice' => 'mcua.png',
958
            'multipleresponse' => 'mcma.png',
959
            'open' => 'open_answer.png',
960
            'dropdown' => 'dropdown.png',
961
            'percentage' => 'percentagequestion.png',
962
            'score' => 'scorequestion.png',
963
            'comment' => 'commentquestion.png',
964
            'pagebreak' => 'page_end.png',
965
        ];
966
967
        if (in_array($type, $possible_types)) {
968
            return $icon_question[$type];
969
        } else {
970
            return false;
971
        }
972
    }
973
974
    /**
975
     * This function retrieves all the information of a question.
976
     *
977
     * @param int  $question_id the id of the question
978
     * @param bool $shared
979
     *
980
     * @return array
981
     *
982
     * @author Patrick Cool <[email protected]>, Ghent University
983
     *
984
     * @version January 2007
985
     *
986
     * @todo one sql call should do the trick
987
     */
988
    public static function get_question($question_id, $shared = false)
989
    {
990
        // Table definitions
991
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
992
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
993
        $course_id = api_get_course_int_id();
994
        $question_id = (int) $question_id;
995
996
        $sql = "SELECT * FROM $tbl_survey_question
997
                WHERE c_id = $course_id AND question_id='".$question_id."'
998
                ORDER BY `sort` ";
999
1000
        $sqlOption = "  SELECT * FROM $table_survey_question_option
1001
                        WHERE c_id = $course_id AND question_id='".$question_id."'
1002
                        ORDER BY `sort` ";
1003
1004
        if ($shared) {
1005
            $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1006
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1007
1008
            $sql = "SELECT * FROM $tbl_survey_question
1009
                    WHERE question_id='".$question_id."'
1010
                    ORDER BY `sort` ";
1011
            $sqlOption = "SELECT * FROM $table_survey_question_option
1012
                          WHERE question_id='".$question_id."'
1013
                          ORDER BY `sort` ";
1014
        }
1015
1016
        // Getting the information of the question
1017
1018
        $result = Database::query($sql);
1019
        $row = Database::fetch_array($result, 'ASSOC');
1020
1021
        $return['survey_id'] = $row['survey_id'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.
Loading history...
1022
        $return['question_id'] = $row['question_id'];
1023
        $return['type'] = $row['type'];
1024
        $return['question'] = $row['survey_question'];
1025
        $return['horizontalvertical'] = $row['display'];
1026
        $return['shared_question_id'] = $row['shared_question_id'];
1027
        $return['maximum_score'] = $row['max_value'];
1028
        $return['is_required'] = api_get_configuration_value('allow_required_survey_questions')
1029
            ? $row['is_required']
1030
            : false;
1031
1032
        if ($row['survey_group_pri'] != 0) {
1033
            $return['assigned'] = $row['survey_group_pri'];
1034
            $return['choose'] = 1;
1035
        } else {
1036
            $return['assigned1'] = $row['survey_group_sec1'];
1037
            $return['assigned2'] = $row['survey_group_sec2'];
1038
            $return['choose'] = 2;
1039
        }
1040
1041
        // Getting the information of the question options
1042
        $result = Database::query($sqlOption);
1043
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1044
            /** @todo this should be renamed to options instead of answers */
1045
            $return['answers'][] = $row['option_text'];
1046
            $return['values'][] = $row['value'];
1047
1048
            /** @todo this can be done more elegantly (used in reporting) */
1049
            $return['answersid'][] = $row['question_option_id'];
1050
        }
1051
1052
        return $return;
1053
    }
1054
1055
    /**
1056
     * This function gets all the question of any given survey.
1057
     *
1058
     * @param int $surveyId the id of the survey
1059
     * @param int $courseId
1060
     *
1061
     * @return array containing all the questions of the survey
1062
     *
1063
     * @author Patrick Cool <[email protected]>, Ghent University
1064
     *
1065
     * @version February 2007
1066
     *
1067
     * @todo one sql call should do the trick
1068
     */
1069
    public static function get_questions($surveyId, $courseId = 0)
1070
    {
1071
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1072
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1073
1074
        $courseId = (int) $courseId;
1075
        $surveyId = (int) $surveyId;
1076
1077
        if (empty($courseId)) {
1078
            $courseId = api_get_course_int_id();
1079
        }
1080
1081
        // Getting the information of the question
1082
        $sql = "SELECT * FROM $tbl_survey_question
1083
		        WHERE c_id = $courseId AND survey_id='".$surveyId."'";
1084
        $result = Database::query($sql);
1085
        $return = [];
1086
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1087
            $return[$row['question_id']]['survey_id'] = $row['survey_id'];
1088
            $return[$row['question_id']]['question_id'] = $row['question_id'];
1089
            $return[$row['question_id']]['type'] = $row['type'];
1090
            $return[$row['question_id']]['question'] = $row['survey_question'];
1091
            $return[$row['question_id']]['horizontalvertical'] = $row['display'];
1092
            $return[$row['question_id']]['maximum_score'] = $row['max_value'];
1093
            $return[$row['question_id']]['sort'] = $row['sort'];
1094
            $return[$row['question_id']]['survey_question_comment'] = $row['survey_question_comment'];
1095
        }
1096
1097
        // Getting the information of the question options
1098
        $sql = "SELECT * FROM $table_survey_question_option
1099
		        WHERE c_id = $courseId AND survey_id='".$surveyId."'";
1100
        $result = Database::query($sql);
1101
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1102
            $return[$row['question_id']]['answers'][] = $row['option_text'];
1103
        }
1104
1105
        return $return;
1106
    }
1107
1108
    /**
1109
     * This function saves a question in the database.
1110
     * This can be either an update of an existing survey or storing a new survey.
1111
     *
1112
     * @param array $survey_data
1113
     * @param array $form_content all the information of the form
1114
     *
1115
     * @return string
1116
     *
1117
     * @author Patrick Cool <[email protected]>, Ghent University
1118
     *
1119
     * @version January 2007
1120
     */
1121
    public static function save_question($survey_data, $form_content)
1122
    {
1123
        $return_message = '';
1124
        if (strlen($form_content['question']) > 1) {
1125
            // Checks length of the question
1126
            $empty_answer = false;
1127
1128
            if ($survey_data['survey_type'] == 1) {
1129
                if (empty($form_content['choose'])) {
1130
                    $return_message = 'PleaseChooseACondition';
1131
1132
                    return $return_message;
1133
                }
1134
1135
                if (($form_content['choose'] == 2) &&
1136
                    ($form_content['assigned1'] == $form_content['assigned2'])
1137
                ) {
1138
                    $return_message = 'ChooseDifferentCategories';
1139
1140
                    return $return_message;
1141
                }
1142
            }
1143
1144
            if ($form_content['type'] != 'percentage') {
1145
                if (isset($form_content['answers'])) {
1146
                    for ($i = 0; $i < count($form_content['answers']); $i++) {
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...
1147
                        if (strlen($form_content['answers'][$i]) < 1) {
1148
                            $empty_answer = true;
1149
                            break;
1150
                        }
1151
                    }
1152
                }
1153
            }
1154
1155
            if ($form_content['type'] == 'score') {
1156
                if (strlen($form_content['maximum_score']) < 1) {
1157
                    $empty_answer = true;
1158
                }
1159
            }
1160
            $course_id = api_get_course_int_id();
1161
            if (!$empty_answer) {
1162
                // Table definitions
1163
                $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1164
1165
                // Getting all the information of the survey
1166
                $survey_data = self::get_survey($form_content['survey_id']);
1167
1168
                // Storing the question in the shared database
1169
                if (is_numeric($survey_data['survey_share']) && $survey_data['survey_share'] != 0) {
1170
                    $shared_question_id = self::save_shared_question($form_content, $survey_data);
0 ignored issues
show
Bug Best Practice introduced by
The method SurveyManager::save_shared_question() is not static, but was called statically. ( Ignorable by Annotation )

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

1170
                    /** @scrutinizer ignore-call */ 
1171
                    $shared_question_id = self::save_shared_question($form_content, $survey_data);
Loading history...
1171
                    $form_content['shared_question_id'] = $shared_question_id;
1172
                }
1173
1174
                // Storing a new question
1175
                if ($form_content['question_id'] == '' || !is_numeric($form_content['question_id'])) {
1176
                    // Finding the max sort order of the questions in the given survey
1177
                    $sql = "SELECT max(sort) AS max_sort
1178
					        FROM $tbl_survey_question
1179
                            WHERE c_id = $course_id AND survey_id='".intval($form_content['survey_id'])."'";
1180
                    $result = Database::query($sql);
1181
                    $row = Database::fetch_array($result, 'ASSOC');
1182
                    $max_sort = $row['max_sort'];
1183
1184
                    // Some variables defined for survey-test type
1185
                    $extraParams = [];
1186
                    if (isset($_POST['choose'])) {
1187
                        if ($_POST['choose'] == 1) {
1188
                            $extraParams['survey_group_pri'] = $_POST['assigned'];
1189
                        } elseif ($_POST['choose'] == 2) {
1190
                            $extraParams['survey_group_sec1'] = $_POST['assigned1'];
1191
                            $extraParams['survey_group_sec2'] = $_POST['assigned2'];
1192
                        }
1193
                    }
1194
1195
                    $questionComment = isset($form_content['question_comment'])
1196
                        ? $form_content['question_comment']
1197
                        : '';
1198
                    $maxScore = isset($form_content['maximum_score']) ? $form_content['maximum_score'] : '';
1199
                    $display = isset($form_content['horizontalvertical']) ? $form_content['horizontalvertical'] : '';
1200
1201
                    $params = [
1202
                        'c_id' => $course_id,
1203
                        'survey_id' => $form_content['survey_id'],
1204
                        'survey_question' => $form_content['question'],
1205
                        'survey_question_comment' => $questionComment,
1206
                        'type' => $form_content['type'],
1207
                        'display' => $display,
1208
                        'sort' => $max_sort + 1,
1209
                        'shared_question_id' => $form_content['shared_question_id'],
1210
                        'max_value' => $maxScore,
1211
                    ];
1212
1213
                    if (api_get_configuration_value('allow_required_survey_questions')) {
1214
                        $params['is_required'] = isset($form_content['is_required']);
1215
                    }
1216
1217
                    $params = array_merge($params, $extraParams);
1218
                    $question_id = Database::insert($tbl_survey_question, $params);
1219
                    if ($question_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $question_id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1220
                        $sql = "UPDATE $tbl_survey_question SET question_id = $question_id
1221
                                WHERE iid = $question_id";
1222
                        Database::query($sql);
1223
1224
                        $form_content['question_id'] = $question_id;
1225
                        $return_message = 'QuestionAdded';
1226
                    }
1227
                } else {
1228
                    // Updating an existing question
1229
                    $extraParams = [];
1230
                    if (isset($_POST['choose'])) {
1231
                        if ($_POST['choose'] == 1) {
1232
                            $extraParams['survey_group_pri'] = $_POST['assigned'];
1233
                            $extraParams['survey_group_sec1'] = 0;
1234
                            $extraParams['survey_group_sec2'] = 0;
1235
                        } elseif ($_POST['choose'] == 2) {
1236
                            $extraParams['survey_group_pri'] = 0;
1237
                            $extraParams['survey_group_sec1'] = $_POST['assigned1'];
1238
                            $extraParams['survey_group_sec2'] = $_POST['assigned2'];
1239
                        }
1240
                    }
1241
1242
                    $maxScore = isset($form_content['maximum_score']) ? $form_content['maximum_score'] : null;
1243
                    $questionComment = isset($form_content['question_comment'])
1244
                        ? $form_content['question_comment']
1245
                        : null;
1246
1247
                    // Adding the question to the survey_question table
1248
                    $params = [
1249
                        'survey_question' => $form_content['question'],
1250
                        'survey_question_comment' => $questionComment,
1251
                        'display' => $form_content['horizontalvertical'],
1252
                    ];
1253
1254
                    if (api_get_configuration_value('allow_required_survey_questions')) {
1255
                        $params['is_required'] = isset($form_content['is_required']);
1256
                    }
1257
1258
                    $params = array_merge($params, $extraParams);
1259
                    Database::update(
1260
                        $tbl_survey_question,
1261
                        $params,
1262
                        [
1263
                            'c_id = ? AND question_id = ?' => [
1264
                                $course_id,
1265
                                $form_content['question_id'],
1266
                            ],
1267
                        ]
1268
                    );
1269
                    $return_message = 'QuestionUpdated';
1270
                }
1271
1272
                if (!empty($form_content['survey_id'])) {
1273
                    //Updating survey
1274
                    api_item_property_update(
1275
                        api_get_course_info(),
1276
                        TOOL_SURVEY,
1277
                        $form_content['survey_id'],
1278
                        'SurveyUpdated',
1279
                        api_get_user_id()
1280
                    );
1281
                }
1282
1283
                // Storing the options of the question
1284
                self::save_question_options($form_content, $survey_data);
1285
            } else {
1286
                $return_message = 'PleasFillAllAnswer';
1287
            }
1288
        } else {
1289
            $return_message = 'PleaseEnterAQuestion';
1290
        }
1291
1292
        if (!empty($return_message)) {
1293
            Display::addFlash(Display::return_message(get_lang($return_message)));
1294
        }
1295
1296
        return $return_message;
1297
    }
1298
1299
    /**
1300
     * This function saves the question in the shared database.
1301
     *
1302
     * @param array $form_content all the information of the form
1303
     * @param array $survey_data  all the information of the survey
1304
     *
1305
     * @author Patrick Cool <[email protected]>, Ghent University
1306
     *
1307
     * @version February 2007
1308
     *
1309
     * @return int
1310
     *
1311
     * @todo editing of a shared question
1312
     */
1313
    public function save_shared_question($form_content, $survey_data)
1314
    {
1315
        $_course = api_get_course_info();
1316
1317
        // Table definitions
1318
        $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1319
1320
        // Storing a new question
1321
        if ($form_content['shared_question_id'] == '' ||
1322
            !is_numeric($form_content['shared_question_id'])
1323
        ) {
1324
            // Finding the max sort order of the questions in the given survey
1325
            $sql = "SELECT max(sort) AS max_sort FROM $tbl_survey_question
1326
                    WHERE survey_id='".intval($survey_data['survey_share'])."'
1327
                    AND code='".Database::escape_string($_course['id'])."'";
1328
            $result = Database::query($sql);
1329
            $row = Database::fetch_array($result, 'ASSOC');
1330
            $max_sort = $row['max_sort'];
1331
1332
            // Adding the question to the survey_question table
1333
            $sql = "INSERT INTO $tbl_survey_question (survey_id, survey_question, survey_question_comment, type, display, sort, code) VALUES (
1334
                    '".Database::escape_string($survey_data['survey_share'])."',
1335
                    '".Database::escape_string($form_content['question'])."',
1336
                    '".Database::escape_string($form_content['question_comment'])."',
1337
                    '".Database::escape_string($form_content['type'])."',
1338
                    '".Database::escape_string($form_content['horizontalvertical'])."',
1339
                    '".Database::escape_string($max_sort + 1)."',
1340
                    '".Database::escape_string($_course['id'])."')";
1341
            Database::query($sql);
1342
            $shared_question_id = Database::insert_id();
1343
        } else {
1344
            // Updating an existing question
1345
            // adding the question to the survey_question table
1346
            $sql = "UPDATE $tbl_survey_question SET
1347
                        survey_question = '".Database::escape_string($form_content['question'])."',
1348
                        survey_question_comment = '".Database::escape_string($form_content['question_comment'])."',
1349
                        display = '".Database::escape_string($form_content['horizontalvertical'])."'
1350
                    WHERE
1351
                        question_id = '".intval($form_content['shared_question_id'])."' AND
1352
                        code = '".Database::escape_string($_course['id'])."'";
1353
            Database::query($sql);
1354
            $shared_question_id = $form_content['shared_question_id'];
1355
        }
1356
1357
        return $shared_question_id;
1358
    }
1359
1360
    /**
1361
     * This functions moves a question of a survey up or down.
1362
     *
1363
     * @param string $direction
1364
     * @param int    $survey_question_id
1365
     * @param int    $survey_id
1366
     *
1367
     * @author Patrick Cool <[email protected]>, Ghent University
1368
     *
1369
     * @version January 2007
1370
     */
1371
    public static function move_survey_question(
1372
        $direction,
1373
        $survey_question_id,
1374
        $survey_id
1375
    ) {
1376
        // Table definition
1377
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1378
        $course_id = api_get_course_int_id();
1379
1380
        if ($direction == 'moveup') {
1381
            $sort = 'DESC';
1382
        }
1383
        if ($direction == 'movedown') {
1384
            $sort = 'ASC';
1385
        }
1386
1387
        $survey_id = (int) $survey_id;
1388
1389
        // Finding the two questions that needs to be swapped
1390
        $sql = "SELECT * FROM $table_survey_question
1391
		        WHERE c_id = $course_id AND survey_id='".$survey_id."'
1392
		        ORDER BY sort $sort";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sort does not seem to be defined for all execution paths leading up to this point.
Loading history...
1393
        $result = Database::query($sql);
1394
        $found = false;
1395
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1396
            if ($found) {
1397
                $question_id_two = $row['question_id'];
1398
                $question_sort_two = $row['sort'];
1399
                $found = false;
1400
            }
1401
            if ($row['question_id'] == $survey_question_id) {
1402
                $found = true;
1403
                $question_id_one = $row['question_id'];
1404
                $question_sort_one = $row['sort'];
1405
            }
1406
        }
1407
1408
        $sql = "UPDATE $table_survey_question
1409
                SET sort = '".Database::escape_string($question_sort_two)."'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_sort_two does not seem to be defined for all execution paths leading up to this point.
Loading history...
1410
		        WHERE c_id = $course_id AND question_id='".intval($question_id_one)."'";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_id_one does not seem to be defined for all execution paths leading up to this point.
Loading history...
1411
        Database::query($sql);
1412
1413
        $sql = "UPDATE $table_survey_question
1414
                SET sort = '".Database::escape_string($question_sort_one)."'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_sort_one does not seem to be defined for all execution paths leading up to this point.
Loading history...
1415
		        WHERE c_id = $course_id AND question_id='".intval($question_id_two)."'";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_id_two does not seem to be defined for all execution paths leading up to this point.
Loading history...
1416
        Database::query($sql);
1417
    }
1418
1419
    /**
1420
     * This function deletes all the questions of a given survey
1421
     * This function is normally only called when a survey is deleted.
1422
     *
1423
     * @param int $survey_id the id of the survey that has to be deleted
1424
     *
1425
     * @return bool
1426
     *
1427
     * @author Patrick Cool <[email protected]>, Ghent University
1428
     *
1429
     * @version January 2007
1430
     */
1431
    public static function delete_all_survey_questions($survey_id, $shared = false)
1432
    {
1433
        $course_id = api_get_course_int_id();
1434
        $survey_id = (int) $survey_id;
1435
1436
        // Table definitions
1437
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1438
        $course_condition = " c_id = $course_id AND ";
1439
        if ($shared) {
1440
            $course_condition = '';
1441
            $table_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1442
        }
1443
1444
        $sql = "DELETE FROM $table_survey_question
1445
		        WHERE $course_condition survey_id = '".$survey_id."'";
1446
1447
        // Deleting the survey questions
1448
        Database::query($sql);
1449
1450
        // Deleting all the options of the questions of the survey
1451
        self::delete_all_survey_questions_options($survey_id, $shared);
1452
1453
        // Deleting all the answers on this survey
1454
        self::delete_all_survey_answers($survey_id);
1455
1456
        return true;
1457
    }
1458
1459
    /**
1460
     * This function deletes a survey question and all its options.
1461
     *
1462
     * @param int  $survey_id   the id of the survey
1463
     * @param int  $question_id the id of the question
1464
     * @param bool $shared
1465
     *
1466
     * @todo also delete the answers to this question
1467
     *
1468
     * @author Patrick Cool <[email protected]>, Ghent University
1469
     *
1470
     * @version March 2007
1471
     */
1472
    public static function delete_survey_question($survey_id, $question_id, $shared = false)
1473
    {
1474
        $survey_id = (int) $survey_id;
1475
        $question_id = (int) $question_id;
1476
        $course_id = api_get_course_int_id();
1477
1478
        if ($shared) {
1479
            self::delete_shared_survey_question($survey_id, $question_id);
1480
        }
1481
1482
        // Table definitions
1483
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
1484
        // Deleting the survey questions
1485
        $sql = "DELETE FROM $table
1486
		        WHERE
1487
		            c_id = $course_id AND
1488
		            survey_id='".$survey_id."' AND
1489
		            question_id='".$question_id."'";
1490
        Database::query($sql);
1491
1492
        // Deleting the options of the question of the survey
1493
        self::delete_survey_question_option($survey_id, $question_id, $shared);
1494
    }
1495
1496
    /**
1497
     * This function deletes a shared survey question from the main database and all its options.
1498
     *
1499
     * @param int $question_id the id of the question
1500
     *
1501
     * @todo delete all the options of this question
1502
     *
1503
     * @author Patrick Cool <[email protected]>, Ghent University
1504
     *
1505
     * @version March 2007
1506
     */
1507
    public static function delete_shared_survey_question($survey_id, $question_id)
0 ignored issues
show
Unused Code introduced by
The parameter $survey_id is not used and could be removed. ( Ignorable by Annotation )

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

1507
    public static function delete_shared_survey_question(/** @scrutinizer ignore-unused */ $survey_id, $question_id)

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

Loading history...
1508
    {
1509
        // Table definitions
1510
        $table_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1511
        $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1512
1513
        // First we have to get the shared_question_id
1514
        $question_data = self::get_question($question_id);
1515
1516
        // Deleting the survey questions
1517
        $sql = "DELETE FROM $table_survey_question
1518
		        WHERE question_id='".intval($question_data['shared_question_id'])."'";
1519
        Database::query($sql);
1520
1521
        // Deleting the options of the question of the survey question
1522
        $sql = "DELETE FROM $table_survey_question_option
1523
		        WHERE question_id='".intval($question_data['shared_question_id'])."'";
1524
        Database::query($sql);
1525
    }
1526
1527
    /**
1528
     * This function stores the options of the questions in the table.
1529
     *
1530
     * @param array $form_content
1531
     *
1532
     * @author Patrick Cool <[email protected]>, Ghent University
1533
     *
1534
     * @version January 2007
1535
     *
1536
     * @todo writing the update statement when editing a question
1537
     */
1538
    public static function save_question_options($form_content, $survey_data)
1539
    {
1540
        $course_id = api_get_course_int_id();
1541
        // A percentage question type has options 1 -> 100
1542
        if ($form_content['type'] == 'percentage') {
1543
            for ($i = 1; $i < 101; $i++) {
1544
                $form_content['answers'][] = $i;
1545
            }
1546
        }
1547
1548
        if (is_numeric($survey_data['survey_share']) && $survey_data['survey_share'] != 0) {
1549
            self::save_shared_question_options($form_content, $survey_data);
0 ignored issues
show
Bug Best Practice introduced by
The method SurveyManager::save_shared_question_options() is not static, but was called statically. ( Ignorable by Annotation )

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

1549
            self::/** @scrutinizer ignore-call */ 
1550
                  save_shared_question_options($form_content, $survey_data);
Loading history...
1550
        }
1551
1552
        // Table definition
1553
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1554
1555
        // We are editing a question so we first have to remove all the existing options from the database
1556
        if (is_numeric($form_content['question_id'])) {
1557
            $sql = "DELETE FROM $table_survey_question_option
1558
			        WHERE c_id = $course_id AND question_id = '".intval($form_content['question_id'])."'";
1559
            Database::query($sql);
1560
        }
1561
1562
        $counter = 1;
1563
        if (isset($form_content['answers']) && is_array($form_content['answers'])) {
1564
            for ($i = 0; $i < count($form_content['answers']); $i++) {
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...
1565
                $values = isset($form_content['values']) ? $form_content['values'][$i] : '';
1566
1567
                $params = [
1568
                    'c_id' => $course_id,
1569
                    'question_id' => $form_content['question_id'],
1570
                    'survey_id' => $form_content['survey_id'],
1571
                    'option_text' => $form_content['answers'][$i],
1572
                    'value' => $values,
1573
                    'sort' => $counter,
1574
                ];
1575
                $insertId = Database::insert($table_survey_question_option, $params);
1576
                if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1577
                    $sql = "UPDATE $table_survey_question_option
1578
                            SET question_option_id = $insertId
1579
                            WHERE iid = $insertId";
1580
                    Database::query($sql);
1581
1582
                    $counter++;
1583
                }
1584
            }
1585
        }
1586
    }
1587
1588
    /**
1589
     * This function stores the options of the questions in the shared table.
1590
     *
1591
     * @param array $form_content
1592
     *
1593
     * @author Patrick Cool <[email protected]>, Ghent University
1594
     *
1595
     * @version February 2007
1596
     *
1597
     * @todo writing the update statement when editing a question
1598
     */
1599
    public function save_shared_question_options($form_content, $survey_data)
1600
    {
1601
        if (is_array($form_content) && is_array($form_content['answers'])) {
1602
            // Table definition
1603
            $table = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1604
1605
            // We are editing a question so we first have to remove all the existing options from the database
1606
            $sql = "DELETE FROM $table
1607
                    WHERE question_id = '".Database::escape_string($form_content['shared_question_id'])."'";
1608
            Database::query($sql);
1609
1610
            $counter = 1;
1611
            foreach ($form_content['answers'] as &$answer) {
1612
                $params = [
1613
                    'question_id' => $form_content['shared_question_id'],
1614
                    'survey_id' => $survey_data['is_shared'],
1615
                    'option_text' => $answer,
1616
                    'sort' => $counter,
1617
                ];
1618
                Database::insert($table, $params);
1619
1620
                $counter++;
1621
            }
1622
        }
1623
    }
1624
1625
    /**
1626
     * This function deletes all the options of the questions of a given survey
1627
     * This function is normally only called when a survey is deleted.
1628
     *
1629
     * @param int $survey_id the id of the survey that has to be deleted
1630
     *
1631
     * @return true
1632
     *
1633
     * @author Patrick Cool <[email protected]>, Ghent University
1634
     *
1635
     * @version January 2007
1636
     */
1637
    public static function delete_all_survey_questions_options($survey_id, $shared = false)
1638
    {
1639
        // Table definitions
1640
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1641
        $course_id = api_get_course_int_id();
1642
        $course_condition = " c_id = $course_id AND ";
1643
        if ($shared) {
1644
            $course_condition = '';
1645
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1646
        }
1647
1648
        $sql = "DELETE FROM $table_survey_question_option
1649
                WHERE $course_condition survey_id='".intval($survey_id)."'";
1650
1651
        // Deleting the options of the survey questions
1652
        Database::query($sql);
1653
1654
        return true;
1655
    }
1656
1657
    /**
1658
     * This function deletes the options of a given question.
1659
     *
1660
     * @param int  $survey_id
1661
     * @param int  $question_id
1662
     * @param bool $shared
1663
     *
1664
     * @return bool
1665
     *
1666
     * @author Patrick Cool <[email protected]>, Ghent University
1667
     * @author Julio Montoya
1668
     *
1669
     * @version March 2007
1670
     */
1671
    public static function delete_survey_question_option(
1672
        $survey_id,
1673
        $question_id,
1674
        $shared = false
1675
    ) {
1676
        $course_id = api_get_course_int_id();
1677
        $course_condition = " c_id = $course_id AND ";
1678
1679
        // Table definitions
1680
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1681
        if ($shared) {
1682
            $course_condition = '';
1683
            $table = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1684
        }
1685
1686
        // Deleting the options of the survey questions
1687
        $sql = "DELETE FROM $table
1688
		        WHERE
1689
		            $course_condition survey_id='".intval($survey_id)."' AND
1690
		            question_id='".intval($question_id)."'";
1691
        Database::query($sql);
1692
1693
        return true;
1694
    }
1695
1696
    /**
1697
     * SURVEY ANSWERS FUNCTIONS.
1698
     */
1699
1700
    /**
1701
     * This function deletes all the answers anyone has given on this survey
1702
     * This function is normally only called when a survey is deleted.
1703
     *
1704
     * @param $survey_id the id of the survey that has to be deleted
1705
     *
1706
     * @return true
1707
     *
1708
     * @todo write the function
1709
     *
1710
     * @author Patrick Cool <[email protected]>, Ghent University
1711
     *
1712
     * @version January 2007,december 2008
1713
     */
1714
    public static function delete_all_survey_answers($survey_id)
1715
    {
1716
        $course_id = api_get_course_int_id();
1717
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
1718
        $survey_id = (int) $survey_id;
1719
        $sql = "DELETE FROM $table
1720
                WHERE c_id = $course_id AND survey_id = $survey_id";
1721
        Database::query($sql);
1722
1723
        return true;
1724
    }
1725
1726
    /**
1727
     * @param int $user_id
1728
     * @param int $survey_id
1729
     * @param int $course_id
1730
     *
1731
     * @return bool
1732
     */
1733
    public static function is_user_filled_survey($user_id, $survey_id, $course_id)
1734
    {
1735
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
1736
        $user_id = (int) $user_id;
1737
        $course_id = (int) $course_id;
1738
        $survey_id = (int) $survey_id;
1739
1740
        $sql = "SELECT DISTINCT user
1741
                FROM $table
1742
                WHERE
1743
                    c_id		= $course_id AND
1744
                    user		= $user_id AND
1745
                    survey_id	= $survey_id";
1746
        $result = Database::query($sql);
1747
        if (Database::num_rows($result)) {
1748
            return true;
1749
        }
1750
1751
        return false;
1752
    }
1753
1754
    /**
1755
     * This function gets all the persons who have filled the survey.
1756
     *
1757
     * @param int $survey_id
1758
     *
1759
     * @return array
1760
     *
1761
     * @author Patrick Cool <[email protected]>, Ghent University
1762
     *
1763
     * @version February 2007
1764
     */
1765
    public static function get_people_who_filled_survey(
1766
        $survey_id,
1767
        $all_user_info = false,
1768
        $course_id = null
1769
    ) {
1770
        // Database table definition
1771
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1772
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1773
1774
        // Variable initialisation
1775
        $return = [];
1776
1777
        if (empty($course_id)) {
1778
            $course_id = api_get_course_int_id();
1779
        } else {
1780
            $course_id = (int) $course_id;
1781
        }
1782
1783
        $survey_id = (int) $survey_id;
1784
1785
        if ($all_user_info) {
1786
            $order_clause = api_sort_by_first_name()
1787
                ? ' ORDER BY user.firstname, user.lastname'
1788
                : ' ORDER BY user.lastname, user.firstname';
1789
            $sql = "SELECT DISTINCT
1790
			            answered_user.user as invited_user,
1791
			            user.firstname,
1792
			            user.lastname,
1793
			            user.user_id
1794
                    FROM $table_survey_answer answered_user
1795
                    LEFT JOIN $table_user as user ON answered_user.user = user.user_id
1796
                    WHERE
1797
                        answered_user.c_id = $course_id AND
1798
                        survey_id= '".$survey_id."' ".
1799
                $order_clause;
1800
        } else {
1801
            $sql = "SELECT DISTINCT user FROM $table_survey_answer
1802
			        WHERE c_id = $course_id AND survey_id= '".$survey_id."'  ";
1803
1804
            if (api_get_configuration_value('survey_anonymous_show_answered')) {
1805
                $tblInvitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
1806
                $tblSurvey = Database::get_course_table(TABLE_SURVEY);
1807
1808
                $sql = "SELECT i.user FROM $tblInvitation i
1809
                    INNER JOIN $tblSurvey s
1810
                    ON i.survey_code = s.code
1811
                        AND i.c_id = s.c_id
1812
                        AND i.session_id = s.session_id
1813
                    WHERE i.answered IS TRUE AND s.iid = $survey_id";
1814
            }
1815
        }
1816
1817
        $res = Database::query($sql);
1818
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1819
            if ($all_user_info) {
1820
                $userInfo = api_get_user_info($row['user_id']);
1821
                $row['user_info'] = $userInfo;
1822
                $return[] = $row;
1823
            } else {
1824
                $return[] = $row['user'];
1825
            }
1826
        }
1827
1828
        return $return;
1829
    }
1830
1831
    /**
1832
     * @return bool
1833
     */
1834
    public static function survey_generation_hash_available()
1835
    {
1836
        if (extension_loaded('mcrypt')) {
1837
            return true;
1838
        }
1839
1840
        return false;
1841
    }
1842
1843
    /**
1844
     * @param int $survey_id
1845
     * @param int $course_id
1846
     * @param int $session_id
1847
     * @param int $group_id
1848
     *
1849
     * @return string
1850
     */
1851
    public static function generate_survey_hash($survey_id, $course_id, $session_id, $group_id)
1852
    {
1853
        $hash = hash('sha512', api_get_security_key().'_'.$course_id.'_'.$session_id.'_'.$group_id.'_'.$survey_id);
1854
1855
        return $hash;
1856
    }
1857
1858
    /**
1859
     * @param int    $survey_id
1860
     * @param int    $course_id
1861
     * @param int    $session_id
1862
     * @param int    $group_id
1863
     * @param string $hash
1864
     *
1865
     * @return bool
1866
     */
1867
    public static function validate_survey_hash($survey_id, $course_id, $session_id, $group_id, $hash)
1868
    {
1869
        $generatedHash = self::generate_survey_hash($survey_id, $course_id, $session_id, $group_id);
1870
        if ($generatedHash == $hash) {
1871
            return true;
1872
        }
1873
1874
        return false;
1875
    }
1876
1877
    /**
1878
     * @param int $survey_id
1879
     * @param int $course_id
1880
     * @param int $session_id
1881
     * @param int $group_id
1882
     *
1883
     * @return string
1884
     */
1885
    public static function generate_survey_link(
1886
        $survey_id,
1887
        $course_id,
1888
        $session_id,
1889
        $group_id
1890
    ) {
1891
        $code = self::generate_survey_hash(
1892
            $survey_id,
1893
            $course_id,
1894
            $session_id,
1895
            $group_id
1896
        );
1897
1898
        return api_get_path(WEB_CODE_PATH).'survey/link.php?h='.$code.'&i='.$survey_id.'&c='.intval($course_id).'&s='
1899
            .intval($session_id).'&g='.$group_id;
1900
    }
1901
1902
    /**
1903
     * Check if the current user has mandatory surveys no-answered
1904
     * and redirect to fill the first found survey.
1905
     */
1906
    public static function protectByMandatory()
1907
    {
1908
        if (strpos($_SERVER['SCRIPT_NAME'], 'fillsurvey.php') !== false) {
1909
            return;
1910
        }
1911
1912
        $userId = api_get_user_id();
1913
        $courseId = api_get_course_int_id();
1914
        $sessionId = api_get_session_id();
1915
1916
        if (!$userId) {
1917
            return;
1918
        }
1919
1920
        if (!$courseId) {
1921
            return;
1922
        }
1923
1924
        try {
1925
            /** @var CSurveyInvitation $invitation */
1926
            $invitation = Database::getManager()
1927
                ->createQuery("
1928
                    SELECT i FROM ChamiloCourseBundle:CSurveyInvitation i
1929
                    INNER JOIN ChamiloCourseBundle:CSurvey s
1930
                        WITH (s.code = i.surveyCode AND s.cId = i.cId AND s.sessionId = i.sessionId)
1931
                    INNER JOIN ChamiloCoreBundle:ExtraFieldValues efv WITH efv.itemId = s.iid
1932
                    INNER JOIN ChamiloCoreBundle:ExtraField ef WITH efv.field = ef.id
1933
                    WHERE
1934
                        i.answered = 0 AND
1935
                        i.cId = :course AND
1936
                        i.user = :user AND
1937
                        i.sessionId = :session AND
1938
                        :now BETWEEN s.availFrom AND s.availTill AND
1939
                        ef.variable = :variable AND
1940
                        efv.value = 1 AND
1941
                        s.surveyType != 3
1942
                    ORDER BY s.availTill ASC
1943
                ")
1944
                ->setMaxResults(1)
1945
                ->setParameters([
1946
                    'course' => $courseId,
1947
                    'user' => $userId,
1948
                    'session' => $sessionId,
1949
                    'now' => new DateTime('UTC', new DateTimeZone('UTC')),
1950
                    'variable' => 'is_mandatory',
1951
                ])
1952
                ->getSingleResult();
1953
        } catch (Exception $e) {
1954
            $invitation = null;
1955
        }
1956
1957
        if (!$invitation) {
1958
            return;
1959
        }
1960
1961
        Display::addFlash(
1962
            Display::return_message(get_lang('MandatorySurveyNoAnswered'), 'warning')
1963
        );
1964
1965
        $url = SurveyUtil::generateFillSurveyLink(
1966
            $invitation->getInvitationCode(),
1967
            api_get_course_info(),
1968
            api_get_session_id()
1969
        );
1970
1971
        header('Location: '.$url);
1972
        exit;
1973
    }
1974
1975
    /**
1976
     * This function empty surveys (invitations and answers).
1977
     *
1978
     * @param int $surveyId id of the survey to empty
1979
     *
1980
     * @return bool
1981
     */
1982
    public static function emptySurveyFromId($surveyId)
1983
    {
1984
        // Database table definitions
1985
        $surveyInvitationTable = Database:: get_course_table(TABLE_SURVEY_INVITATION);
1986
        $surveyAnswerTable = Database:: get_course_table(TABLE_SURVEY_ANSWER);
1987
        $surveyTable = Database:: get_course_table(TABLE_SURVEY);
1988
        $surveyId = (int) $surveyId;
1989
        $surveyData = self::get_survey($surveyId);
1990
        if (empty($surveyData)) {
1991
            return false;
1992
        }
1993
1994
        $surveyCode = $surveyData['survey_code'];
1995
        $courseId = (int) $surveyData['c_id'];
1996
        $sessionId = (int) $surveyData['session_id'];
1997
1998
        $sql = "DELETE FROM $surveyInvitationTable
1999
                WHERE session_id = $sessionId AND c_id = $courseId AND survey_code = '$surveyCode' ";
2000
        Database::query($sql);
2001
2002
        $sql = "DELETE FROM $surveyAnswerTable
2003
               WHERE survey_id = $surveyId AND c_id = $courseId ";
2004
        Database::query($sql);
2005
2006
        $sql = "UPDATE $surveyTable
2007
                SET invited = 0, answered = 0
2008
                WHERE survey_id = $surveyId AND c_id = $courseId AND session_id = $sessionId ";
2009
        Database::query($sql);
2010
2011
        return true;
2012
    }
2013
2014
    /**
2015
     * This function copy survey specifying course id and session id where will be copied.
2016
     *
2017
     * @param int $surveyId
2018
     * @param int $targetCourseId  target course id
2019
     * @param int $targetSessionId target session id
2020
     *
2021
     * @return bool|int when fails or return the new survey id
2022
     */
2023
    public static function copySurveySession($surveyId, $targetCourseId, $targetSessionId)
2024
    {
2025
        // Database table definitions
2026
        $surveyTable = Database::get_course_table(TABLE_SURVEY);
2027
        $surveyQuestionGroupTable = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
2028
        $surveyQuestionTable = Database::get_course_table(TABLE_SURVEY_QUESTION);
2029
        $surveyOptionsTable = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2030
        $surveyId = (int) $surveyId;
2031
        $targetCourseId = (int) $targetCourseId;
2032
        $targetSessionId = (int) $targetSessionId;
2033
2034
        $surveyData = self::get_survey($surveyId, 0, '', true);
2035
        if (empty($surveyData) || empty($targetCourseId)) {
2036
            return false;
2037
        }
2038
2039
        $originalCourseId = $surveyData['c_id'];
2040
        $originalSessionId = $surveyData['session_id'];
2041
2042
        $surveyData['code'] = self::generate_unique_code($surveyData['code']);
2043
        $surveyData['c_id'] = $targetCourseId;
2044
        $surveyData['session_id'] = $targetSessionId;
2045
        // Add a "Copy" suffix if copied inside the same course
2046
        if ($targetCourseId == $originalCourseId) {
2047
            $surveyData['title'] = $surveyData['title'].' '.get_lang('Copy');
2048
        }
2049
        unset($surveyData['iid']);
2050
        unset($surveyData['id']);
2051
2052
        $newSurveyId = Database::insert($surveyTable, $surveyData);
2053
2054
        if ($newSurveyId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $newSurveyId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2055
            $sql = "UPDATE $surveyTable SET survey_id = $newSurveyId
2056
                    WHERE iid = $newSurveyId";
2057
            Database::query($sql);
2058
2059
            $sql = "SELECT * FROM $surveyQuestionGroupTable
2060
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId ";
2061
            $res = Database::query($sql);
2062
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2063
                $params = [
2064
                    'c_id' => $targetCourseId,
2065
                    'name' => $row['name'],
2066
                    'description' => $row['description'],
2067
                    'survey_id' => $newSurveyId,
2068
                ];
2069
                $insertId = Database::insert($surveyQuestionGroupTable, $params);
2070
                if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2071
                    $sql = "UPDATE $surveyQuestionGroupTable SET id = iid WHERE iid = $insertId";
2072
                    Database::query($sql);
2073
                    $group_id[$row['id']] = $insertId;
2074
                }
2075
            }
2076
2077
            // Get questions
2078
            $sql = "SELECT * FROM $surveyQuestionTable
2079
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId";
2080
            $res = Database::query($sql);
2081
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2082
                $params = [
2083
                    'c_id' => $targetCourseId,
2084
                    'survey_id' => $newSurveyId,
2085
                    'survey_question' => $row['survey_question'],
2086
                    'survey_question_comment' => $row['survey_question_comment'],
2087
                    'type' => $row['type'],
2088
                    'display' => $row['display'],
2089
                    'sort' => $row['sort'],
2090
                    'shared_question_id' => $row['shared_question_id'],
2091
                    'max_value' => $row['max_value'],
2092
                    'survey_group_pri' => $row['survey_group_pri'],
2093
                    'survey_group_sec1' => $row['survey_group_sec1'],
2094
                    'survey_group_sec2' => $row['survey_group_sec2'],
2095
                ];
2096
2097
                if (api_get_configuration_value('allow_required_survey_questions')) {
2098
                    if (isset($row['is_required'])) {
2099
                        $params['is_required'] = $row['is_required'];
2100
                    }
2101
                }
2102
2103
                $insertId = Database::insert($surveyQuestionTable, $params);
2104
                if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2105
                    $sql = "UPDATE $surveyQuestionTable
2106
                            SET question_id = iid
2107
                            WHERE iid = $insertId";
2108
                    Database::query($sql);
2109
2110
                    $question_id[$row['question_id']] = $insertId;
2111
                }
2112
            }
2113
2114
            // Get questions options
2115
            $sql = "SELECT * FROM $surveyOptionsTable
2116
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId";
2117
2118
            $res = Database::query($sql);
2119
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2120
                $params = [
2121
                    'c_id' => $targetCourseId,
2122
                    'question_id' => $question_id[$row['question_id']],
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_id does not seem to be defined for all execution paths leading up to this point.
Loading history...
2123
                    'survey_id' => $newSurveyId,
2124
                    'option_text' => $row['option_text'],
2125
                    'sort' => $row['sort'],
2126
                    'value' => $row['value'],
2127
                ];
2128
                $insertId = Database::insert($surveyOptionsTable, $params);
2129
                if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2130
                    $sql = "UPDATE $surveyOptionsTable SET question_option_id = $insertId WHERE iid = $insertId";
2131
                    Database::query($sql);
2132
                }
2133
            }
2134
2135
            return $newSurveyId;
2136
        }
2137
2138
        return false;
2139
    }
2140
2141
    /**
2142
     * @param array $surveyData
2143
     *
2144
     * @return bool
2145
     */
2146
    public static function removeMultiplicateQuestions($surveyData)
2147
    {
2148
        if (empty($surveyData)) {
2149
            return false;
2150
        }
2151
        $surveyId = $surveyData['survey_id'];
2152
        $courseId = $surveyData['c_id'];
2153
2154
        if (empty($surveyId) || empty($courseId)) {
2155
            return false;
2156
        }
2157
2158
        $questions = self::get_questions($surveyId);
2159
        foreach ($questions as $question) {
2160
            // Questions marked with "geneated" were created using the "multiplicate" feature.
2161
            if ($question['survey_question_comment'] === 'generated') {
2162
                self::delete_survey_question($surveyId, $question['question_id']);
2163
            }
2164
        }
2165
    }
2166
2167
    /**
2168
     * @param array $surveyData
2169
     *
2170
     * @return bool
2171
     */
2172
    public static function multiplicateQuestions($surveyData)
2173
    {
2174
        if (empty($surveyData)) {
2175
            return false;
2176
        }
2177
        $surveyId = $surveyData['survey_id'];
2178
        $courseId = $surveyData['c_id'];
2179
2180
        if (empty($surveyId) || empty($courseId)) {
2181
            return false;
2182
        }
2183
2184
        $questions = self::get_questions($surveyId);
2185
2186
        $obj = new UserGroup();
2187
2188
        $options['where'] = [' usergroup.course_id = ? ' => $courseId];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $options = array(); before regardless.
Loading history...
2189
        $classList = $obj->getUserGroupInCourse($options);
2190
2191
        $classToParse = [];
2192
        foreach ($classList as $class) {
2193
            $users = $obj->get_users_by_usergroup($class['id']);
2194
            if (empty($users)) {
2195
                continue;
2196
            }
2197
            $classToParse[] = [
2198
                'name' => $class['name'],
2199
                'users' => $users
2200
            ];
2201
        }
2202
2203
        self::parseMultiplicateUserList($classToParse, $questions, $courseId, $surveyData);
0 ignored issues
show
Bug Best Practice introduced by
The method SurveyManager::parseMultiplicateUserList() is not static, but was called statically. ( Ignorable by Annotation )

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

2203
        self::/** @scrutinizer ignore-call */ 
2204
              parseMultiplicateUserList($classToParse, $questions, $courseId, $surveyData);
Loading history...
2204
2205
        $extraFieldValue = new ExtraFieldValue('survey');
2206
        $groupData = $extraFieldValue->get_values_by_handler_and_field_variable($surveyId, 'group_id');
2207
        if ($groupData && !empty($groupData['value'])) {
2208
            $groupInfo = GroupManager::get_group_properties($groupData['value']);
2209
            if (!empty($groupInfo)) {
2210
                $users = GroupManager::getStudents($groupInfo['iid'], true);
2211
                if (!empty($users)) {
2212
                    $users = array_column($users, 'id');
2213
                    $classToParse = [
2214
                        [
2215
                            'name' =>  $groupInfo['name'],
2216
                            'users'=> $users
2217
                        ]
2218
                    ];
2219
                    self::parseMultiplicateUserList($classToParse, $questions, $courseId, $surveyData);
2220
                }
2221
            }
2222
        }
2223
    }
2224
2225
    public function parseMultiplicateUserList($itemList, $questions, $courseId, $surveyData)
2226
    {
2227
        $surveyId = $surveyData['survey_id'];
2228
        $classTag = '{{class_name}}';
2229
        $studentTag = '{{student_full_name}}';
2230
        $classCounter = 0;
2231
        foreach ($itemList as $class) {
2232
            $className = $class['name'];
2233
            $users = $class['users'];
2234
2235
            foreach ($questions as $question) {
2236
                $text = $question['question'];
2237
                if (strpos($text, $classTag) !== false) {
2238
                    $replacedText = str_replace($classTag, $className, $text);
2239
                    $values = [
2240
                        'c_id' => $courseId,
2241
                        'question_comment' => 'generated',
2242
                        'type' => $question['type'],
2243
                        'display' => $question['horizontalvertical'],
2244
                        'question' => $replacedText,
2245
                        'survey_id' => $surveyId,
2246
                        'question_id' => 0,
2247
                        'shared_question_id' => 0,
2248
                    ];
2249
                    self::save_question($surveyData, $values);
2250
                    $classCounter++;
2251
                    continue;
2252
                }
2253
2254
                foreach ($users as $userId) {
2255
                    $userInfo = api_get_user_info($userId);
2256
                    if (strpos($text, $studentTag) !== false) {
2257
                        $replacedText = str_replace($studentTag, $userInfo['complete_name'], $text);
2258
                        $values = [
2259
                            'c_id' => $courseId,
2260
                            'question_comment' => 'generated',
2261
                            'type' => $question['type'],
2262
                            'display' => $question['horizontalvertical'],
2263
                            'maximum_score' => $question['maximum_score'],
2264
                            'question' => $replacedText,
2265
                            'survey_id' => $surveyId,
2266
                            'question_id' => 0,
2267
                            'shared_question_id' => 0,
2268
                        ];
2269
2270
                        $answers = [];
2271
                        if (!empty($question['answers'])) {
2272
                            foreach ($question['answers'] as $answer) {
2273
                                $replacedText = str_replace($studentTag, $userInfo['complete_name'], $answer);
2274
                                $answers[] = $replacedText;
2275
                            }
2276
                        }
2277
                        $values['answers'] = $answers;
2278
                        self::save_question($surveyData, $values);
2279
                    }
2280
                }
2281
2282
                if ($classCounter < count($itemList)) {
2283
                    // Add end page
2284
                    $values = [
2285
                        'c_id' => $courseId,
2286
                        'question_comment' => 'generated',
2287
                        'type' => 'pagebreak',
2288
                        'display' => 'horizontal',
2289
                        'question' => get_lang('QuestionForNextClass'),
2290
                        'survey_id' => $surveyId,
2291
                        'question_id' => 0,
2292
                        'shared_question_id' => 0,
2293
                    ];
2294
                    self::save_question($surveyData, $values);
2295
                }
2296
            }
2297
        }
2298
    }
2299
2300
    /**
2301
     * @param array $survey
2302
     *
2303
     * @return int
2304
     */
2305
    public static function getCountPages($survey)
2306
    {
2307
        if (empty($survey) || !isset($survey['iid'])) {
2308
            return 0;
2309
        }
2310
2311
        $courseId = $survey['c_id'];
2312
        $surveyId = $survey['survey_id'];
2313
2314
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
2315
2316
        // pagebreak
2317
        $sql = "SELECT COUNT(iid) FROM $table
2318
                WHERE
2319
                    survey_question NOT LIKE '%{{%' AND
2320
                    type = 'pagebreak' AND
2321
                    c_id = $courseId AND
2322
                    survey_id = $surveyId";
2323
        $result = Database::query($sql);
2324
        $numberPageBreaks = Database::result($result, 0, 0);
2325
2326
        // No pagebreak
2327
        $sql = "SELECT COUNT(iid) FROM $table
2328
                WHERE
2329
                    survey_question NOT LIKE '%{{%' AND
2330
                    type != 'pagebreak' AND
2331
                    c_id = $courseId AND
2332
                    survey_id = $surveyId";
2333
        $result = Database::query($sql);
2334
        $countOfQuestions = Database::result($result, 0, 0);
2335
2336
        if ($survey['one_question_per_page'] == 1) {
2337
            if (!empty($countOfQuestions)) {
2338
                return $countOfQuestions;
2339
            }
2340
2341
            return 1;
2342
        }
2343
2344
        if (empty($numberPageBreaks)) {
2345
            return 1;
2346
        }
2347
2348
        return $numberPageBreaks + 1;
2349
    }
2350
2351
    /**
2352
     * Check whether this survey has ended. If so, display message and exit rhis script.
2353
     *
2354
     * @param array $surveyData Survey data
2355
     */
2356
    public static function checkTimeAvailability($surveyData)
2357
    {
2358
        if (empty($surveyData)) {
2359
            api_not_allowed(true);
2360
        }
2361
2362
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
2363
        $utcZone = new DateTimeZone('UTC');
2364
        $startDate = new DateTime($surveyData['start_date'], $utcZone);
2365
        $endDate = new DateTime($surveyData['end_date'], $utcZone);
2366
        $currentDate = new DateTime('now', $utcZone);
2367
        if (!$allowSurveyAvailabilityDatetime) {
2368
            $currentDate->modify('today');
2369
        }
2370
        if ($currentDate < $startDate) {
2371
            api_not_allowed(
2372
                true,
2373
                Display:: return_message(
2374
                    get_lang('SurveyNotAvailableYet'),
2375
                    'warning',
2376
                    false
2377
                )
2378
            );
2379
        }
2380
2381
        if ($currentDate > $endDate) {
2382
            api_not_allowed(
2383
                true,
2384
                Display:: return_message(
2385
                    get_lang('SurveyNotAvailableAnymore'),
2386
                    'warning',
2387
                    false
2388
                )
2389
            );
2390
        }
2391
    }
2392
2393
    /**
2394
     * @param int    $userId
2395
     * @param string $surveyCode
2396
     * @param int    $courseId
2397
     * @param int    $sessionId
2398
     * @param int    $groupId
2399
     *
2400
     * @return array|CSurveyInvitation[]
2401
     */
2402
    public static function getUserInvitationsForSurveyInCourse(
2403
        $userId,
2404
        $surveyCode,
2405
        $courseId,
2406
        $sessionId = 0,
2407
        $groupId = 0
2408
    ) {
2409
        $invitationRepo = Database::getManager()->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2410
        $invitations = $invitationRepo->findBy(
2411
            [
2412
                'user' => $userId,
2413
                'cId' => $courseId,
2414
                'sessionId' => $sessionId,
2415
                'groupId' => $groupId,
2416
                'surveyCode' => $surveyCode,
2417
            ],
2418
            ['invitationDate' => 'DESC']
2419
        );
2420
2421
        return $invitations;
2422
    }
2423
2424
    /**
2425
     * @param array $userInfo
2426
     * @param int   $answered (1 = answered 0 = not answered)
2427
     *
2428
     * @return string
2429
     */
2430
    public static function surveyReport($userInfo, $answered = 0)
2431
    {
2432
        $userId = isset($userInfo['user_id']) ? (int) $userInfo['user_id'] : 0;
2433
        $answered = (int) $answered;
2434
2435
        if (empty($userId)) {
2436
            return '';
2437
        }
2438
2439
        $em = Database::getManager();
2440
        $repo = $em->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2441
        $repoSurvey = $em->getRepository('ChamiloCourseBundle:CSurvey');
2442
        $invitations = $repo->findBy(['user' => $userId, 'answered' => $answered]);
2443
        $mainUrl = api_get_path(WEB_CODE_PATH).'survey/survey.php?';
2444
        $content = '';
2445
2446
        if (empty($answered)) {
2447
            $content .= Display::page_subheader(get_lang('Unanswered'));
2448
        } else {
2449
            $content .= Display::page_subheader(get_lang('Answered'));
2450
        }
2451
2452
        if (!empty($invitations)) {
2453
            $table = new HTML_Table(['class' => 'table']);
2454
            $table->setHeaderContents(0, 0, get_lang('SurveyName'));
2455
            $table->setHeaderContents(0, 1, get_lang('Course'));
2456
2457
            if (empty($answered)) {
2458
                $table->setHeaderContents(0, 2, get_lang('Survey').' - '.get_lang('EndDate'));
2459
            }
2460
2461
            // Not answered
2462
            /** @var CSurveyInvitation $invitation */
2463
            $row = 1;
2464
            foreach ($invitations as $invitation) {
2465
                $courseId = $invitation->getCId();
2466
                $courseInfo = api_get_course_info_by_id($courseId);
2467
2468
                $courseCode = $courseInfo['code'];
2469
                if (empty($courseInfo)) {
2470
                    continue;
2471
                }
2472
                $sessionId = $invitation->getSessionId();
2473
2474
                if (!empty($answered)) {
2475
                    // check if user is subscribed to the course/session
2476
                    if (empty($sessionId)) {
2477
                        $subscribe = CourseManager::is_user_subscribed_in_course($userId, $courseCode);
2478
                    } else {
2479
                        $subscribe = CourseManager::is_user_subscribed_in_course($userId, $courseCode, true, $sessionId);
2480
                    }
2481
2482
                    // User is not subscribe skip!
2483
                    if (empty($subscribe)) {
2484
                        continue;
2485
                    }
2486
                }
2487
2488
                $surveyCode = $invitation->getSurveyCode();
2489
2490
                $survey = $repoSurvey->findOneBy([
2491
                    'cId' => $courseId,
2492
                    'sessionId' => $sessionId,
2493
                    'code' => $surveyCode,
2494
                ]);
2495
2496
                if (empty($survey)) {
2497
                    continue;
2498
                }
2499
2500
                $url = $mainUrl.'survey_id='.$survey->getSurveyId().'&cidReq='.$courseCode.'&id_session='.$sessionId;
2501
                $title = $survey->getTitle();
2502
                $title = Display::url($title, $url);
2503
2504
                if (!empty($sessionId)) {
2505
                    $sessionInfo = api_get_session_info($sessionId);
2506
                    $courseInfo['name'] .= ' ('.$sessionInfo['name'].')';
2507
                }
2508
2509
                $surveyData = self::get_survey($survey->getSurveyId(), 0, $courseCode);
2510
                $table->setCellContents($row, 0, $title);
2511
                $table->setCellContents($row, 1, $courseInfo['name']);
2512
2513
                if (empty($answered)) {
2514
                    $table->setHeaderContents(
2515
                        $row,
2516
                        2,
2517
                        api_get_local_time(
2518
                            $survey->getAvailTill(),
2519
                            null,
2520
                            null,
2521
                            true,
2522
                            false
2523
                        )
2524
                    );
2525
                }
2526
2527
                if (!empty($answered) && $surveyData['anonymous'] == 0) {
2528
                    $answers = SurveyUtil::displayCompleteReport(
2529
                        $surveyData,
2530
                        $userId,
2531
                        false,
2532
                        false,
2533
                        false
2534
                    );
2535
                    $table->setCellContents(++$row, 0, $answers);
2536
                    $table->setCellContents(++$row, 1, '');
2537
                }
2538
2539
                $row++;
2540
            }
2541
            $content .= $table->toHtml();
2542
        } else {
2543
            $content .= Display::return_message(get_lang('NoData'));
2544
        }
2545
2546
        return $content;
2547
    }
2548
}
2549