Issues (2037)

main/survey/survey.lib.php (2 issues)

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CourseBundle\Entity\CSurveyInvitation;
6
7
/**
8
 * Class SurveyManager.
9
 *
10
 * @author Patrick Cool <[email protected]>, Ghent University:
11
 * cleanup, refactoring and rewriting large parts (if not all) of the code
12
 * @author Julio Montoya <[email protected]>, Personality Test modification
13
 * and rewriting large parts of the code
14
 * @author cfasanando
15
 *
16
 * @todo move this file to inc/lib
17
 * @todo use consistent naming for the functions (save vs store for instance)
18
 */
19
class SurveyManager
20
{
21
    /**
22
     * @param $code
23
     *
24
     * @return string
25
     */
26
    public static function generate_unique_code($code)
27
    {
28
        if (empty($code)) {
29
            return false;
30
        }
31
        $course_id = api_get_course_int_id();
32
        $table = Database::get_course_table(TABLE_SURVEY);
33
        $code = Database::escape_string($code);
34
        $num = 0;
35
        $new_code = $code;
36
        while (true) {
37
            $sql = "SELECT * FROM $table
38
                    WHERE code = '$new_code' AND c_id = $course_id";
39
            $result = Database::query($sql);
40
            if (Database::num_rows($result)) {
41
                $num++;
42
                $new_code = $code.$num;
43
            } else {
44
                break;
45
            }
46
        }
47
48
        return $code.$num;
49
    }
50
51
    /**
52
     * Deletes all survey invitations of a user.
53
     *
54
     * @param int $user_id
55
     *
56
     * @return bool
57
     * @assert ('') === false
58
     */
59
    public static function delete_all_survey_invitations_by_user($user_id)
60
    {
61
        $user_id = (int) $user_id;
62
        if (empty($user_id)) {
63
            return false;
64
        }
65
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
66
        $table_survey = Database::get_course_table(TABLE_SURVEY);
67
68
        $sql = "SELECT survey_invitation_id, survey_code
69
                FROM $table_survey_invitation WHERE user = '$user_id' AND c_id <> 0 ";
70
        $result = Database::query($sql);
71
        while ($row = Database::fetch_array($result, 'ASSOC')) {
72
            $survey_invitation_id = $row['survey_invitation_id'];
73
            $survey_code = $row['survey_code'];
74
            $sql2 = "DELETE FROM $table_survey_invitation
75
                    WHERE survey_invitation_id = '$survey_invitation_id' AND c_id <> 0";
76
            if (Database::query($sql2)) {
77
                $sql3 = "UPDATE $table_survey SET
78
                            invited = invited-1
79
                        WHERE c_id <> 0 AND code ='$survey_code'";
80
                Database::query($sql3);
81
            }
82
        }
83
    }
84
85
    /**
86
     * @param string $course_code
87
     * @param int    $session_id
88
     *
89
     * @return array
90
     * @assert ('') === false
91
     */
92
    public static function get_surveys($course_code, $session_id = 0)
93
    {
94
        if (empty($course_code)) {
95
            return false;
96
        }
97
        $course_info = api_get_course_info($course_code);
98
99
        if (empty($course_info)) {
100
            return false;
101
        }
102
103
        $sessionCondition = api_get_session_condition($session_id, true, true);
104
105
        $table = Database::get_course_table(TABLE_SURVEY);
106
        $sql = "SELECT * FROM $table
107
                WHERE c_id = {$course_info['real_id']} $sessionCondition ";
108
        $result = Database::query($sql);
109
110
        return Database::store_result($result, 'ASSOC');
111
    }
112
113
    /**
114
     * Retrieves all the survey information.
115
     *
116
     * @param int  $survey_id the id of the survey
117
     * @param bool $shared    this parameter determines if
118
     *                        we have to get the information of a survey from the central (shared) database or from the
119
     *                        course database
120
     * @param string course code optional
121
     *
122
     * @author Patrick Cool <[email protected]>, Ghent University
123
     *
124
     * @version February 2007
125
     * @assert ('') === false
126
     *
127
     * @return array
128
     *
129
     * @todo this is the same function as in create_new_survey.php
130
     */
131
    public static function get_survey(
132
        $survey_id,
133
        $shared = 0,
134
        $course_code = '',
135
        $simple_return = false
136
    ) {
137
        $my_course_id = api_get_course_id();
138
139
        // Table definition
140
        if (!empty($course_code)) {
141
            $my_course_id = $course_code;
142
        } elseif (isset($_GET['course'])) {
143
            $my_course_id = Security::remove_XSS($_GET['course']);
144
        }
145
146
        $courseInfo = api_get_course_info($my_course_id);
147
        $survey_id = (int) $survey_id;
148
        $table_survey = Database::get_course_table(TABLE_SURVEY);
149
150
        if (0 != $shared) {
151
            $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
152
            $sql = "SELECT * FROM $table_survey
153
                    WHERE survey_id='".$survey_id."' ";
154
        } else {
155
            if (empty($courseInfo)) {
156
                return [];
157
            }
158
            $sql = "SELECT * FROM $table_survey
159
		            WHERE
160
		                survey_id='".$survey_id."' AND
161
		                c_id = ".$courseInfo['real_id'];
162
        }
163
164
        $result = Database::query($sql);
165
        $return = [];
166
167
        if (Database::num_rows($result) > 0) {
168
            $return = Database::fetch_array($result, 'ASSOC');
169
            if ($simple_return) {
170
                return $return;
171
            }
172
            // We do this (temporarily) to have the array match the quickform elements immediately
173
            // idealiter the fields in the db match the quickform fields
174
            $return['survey_code'] = $return['code'];
175
            $return['survey_title'] = $return['title'];
176
            $return['survey_subtitle'] = $return['subtitle'];
177
            $return['survey_language'] = $return['lang'];
178
            $return['start_date'] = $return['avail_from'];
179
            $return['end_date'] = $return['avail_till'];
180
            $return['survey_share'] = $return['is_shared'];
181
            $return['survey_introduction'] = $return['intro'];
182
            $return['survey_thanks'] = $return['surveythanks'];
183
            $return['survey_type'] = $return['survey_type'];
184
            $return['one_question_per_page'] = $return['one_question_per_page'];
185
            $return['show_form_profile'] = $return['show_form_profile'];
186
            $return['input_name_list'] = isset($return['input_name_list']) ? $return['input_name_list'] : null;
187
            $return['shuffle'] = $return['shuffle'];
188
            $return['parent_id'] = $return['parent_id'];
189
            $return['survey_version'] = $return['survey_version'];
190
            $return['anonymous'] = $return['anonymous'];
191
            $return['c_id'] = isset($return['c_id']) ? $return['c_id'] : 0;
192
            $return['session_id'] = isset($return['session_id']) ? $return['session_id'] : 0;
193
        }
194
195
        return $return;
196
    }
197
198
    /**
199
     * @param string $code
200
     *
201
     * @return string
202
     */
203
    public static function generateSurveyCode($code)
204
    {
205
        return strtolower(CourseManager::generate_course_code($code));
206
    }
207
208
    /**
209
     * This function stores a survey in the database.
210
     *
211
     * @param array $values
212
     *
213
     * @return array $return the type of return message that has to be displayed and the message in it
214
     *
215
     * @author Patrick Cool <[email protected]>, Ghent University
216
     *
217
     * @version February 2007
218
     */
219
    public static function store_survey($values)
220
    {
221
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
222
        $_user = api_get_user_info();
223
        $course_id = api_get_course_int_id();
224
        $session_id = api_get_session_id();
225
        $courseCode = api_get_course_id();
226
        $table_survey = Database::get_course_table(TABLE_SURVEY);
227
        $shared_survey_id = 0;
228
229
        if (!isset($values['survey_id'])) {
230
            // Check if the code doesn't soon exists in this language
231
            $sql = 'SELECT 1 FROM '.$table_survey.'
232
			        WHERE
233
			            c_id = '.$course_id.' AND
234
			            code = "'.Database::escape_string($values['survey_code']).'" AND
235
			            lang = "'.Database::escape_string($values['survey_language']).'"';
236
            $rs = Database::query($sql);
237
            if (Database::num_rows($rs) > 0) {
238
                Display::addFlash(
239
                    Display::return_message(
240
                        get_lang('ThisSurveyCodeSoonExistsInThisLanguage'),
241
                        'error'
242
                    )
243
                );
244
                $return['type'] = 'error';
245
                $return['id'] = isset($values['survey_id']) ? $values['survey_id'] : 0;
246
247
                return $return;
248
            }
249
250
            if (!isset($values['anonymous'])) {
251
                $values['anonymous'] = 0;
252
            }
253
254
            $values['anonymous'] = (int) $values['anonymous'];
255
            $extraParams = [];
256
            if ($values['anonymous'] == 0) {
257
                // Input_name_list
258
                $values['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : 0;
259
                $extraParams['show_form_profile'] = $values['show_form_profile'];
260
261
                if ($values['show_form_profile'] == 1) {
262
                    // Input_name_list
263
                    $fields = explode(',', $values['input_name_list']);
264
                    $field_values = '';
265
                    foreach ($fields as &$field) {
266
                        if ($field != '') {
267
                            if ($values[$field] == '') {
268
                                $values[$field] = 0;
269
                            }
270
                            $field_values .= $field.':'.$values[$field].'@';
271
                        }
272
                    }
273
                    $extraParams['form_fields'] = $field_values;
274
                } else {
275
                    $extraParams['form_fields'] = '';
276
                }
277
            } else {
278
                // Input_name_list
279
                $extraParams['show_form_profile'] = 0;
280
                $extraParams['form_fields'] = '';
281
            }
282
283
            $extraParams['one_question_per_page'] = isset($values['one_question_per_page']) ? $values['one_question_per_page'] : 0;
284
            $extraParams['shuffle'] = isset($values['shuffle']) ? $values['shuffle'] : 0;
285
286
            if ($values['survey_type'] == 1) {
287
                $extraParams['survey_type'] = 1;
288
                $extraParams['parent_id'] = $values['parent_id'];
289
290
                // Logic for versioning surveys
291
                if (!empty($values['parent_id'])) {
292
                    $versionValue = '';
293
                    $sql = 'SELECT survey_version
294
                            FROM '.$table_survey.'
295
					        WHERE
296
					            c_id = '.$course_id.' AND
297
					            parent_id = '.intval($values['parent_id']).'
298
                            ORDER BY survey_version DESC
299
                            LIMIT 1';
300
                    $rs = Database::query($sql);
301
                    if (Database::num_rows($rs) === 0) {
302
                        $sql = 'SELECT survey_version FROM '.$table_survey.'
303
						        WHERE
304
						            c_id = '.$course_id.' AND
305
						            survey_id = '.intval($values['parent_id']);
306
                        $rs = Database::query($sql);
307
                        $getversion = Database::fetch_array($rs, 'ASSOC');
308
                        if (empty($getversion['survey_version'])) {
309
                            $versionValue = ++$getversion['survey_version'];
310
                        } else {
311
                            $versionValue = $getversion['survey_version'];
312
                        }
313
                    } else {
314
                        $row = Database::fetch_array($rs, 'ASSOC');
315
                        $pos = api_strpos($row['survey_version']);
316
                        if ($pos === false) {
317
                            $row['survey_version'] = $row['survey_version'] + 1;
318
                            $versionValue = $row['survey_version'];
319
                        } else {
320
                            $getlast = explode('\.', $row['survey_version']);
321
                            $lastversion = array_pop($getlast);
322
                            $lastversion = $lastversion + 1;
323
                            $add = implode('.', $getlast);
324
                            if ($add != '') {
325
                                $insertnewversion = $add.'.'.$lastversion;
326
                            } else {
327
                                $insertnewversion = $lastversion;
328
                            }
329
                            $versionValue = $insertnewversion;
330
                        }
331
                    }
332
                    $extraParams['survey_version'] = $versionValue;
333
                }
334
            }
335
336
            $params = [
337
                'c_id' => $course_id,
338
                'code' => self::generateSurveyCode($values['survey_code']),
339
                'title' => $values['survey_title'],
340
                'subtitle' => $values['survey_subtitle'],
341
                'author' => $_user['user_id'],
342
                'lang' => $values['survey_language'],
343
                'is_shared' => $shared_survey_id,
344
                'template' => 'template',
345
                'intro' => $values['survey_introduction'],
346
                'surveythanks' => $values['survey_thanks'],
347
                'creation_date' => api_get_utc_datetime(),
348
                'anonymous' => $values['anonymous'],
349
                'session_id' => api_get_session_id(),
350
                'visible_results' => $values['visible_results'],
351
            ];
352
353
            if (!empty($values['start_date'])) {
354
                if ($allowSurveyAvailabilityDatetime) {
355
                    $params['avail_from'] = api_get_utc_datetime($values['start_date'].':00');
356
                } else {
357
                    $params['avail_from'] = $values['start_date'];
358
                }
359
            }
360
361
            if (!empty($values['end_date'])) {
362
                if ($allowSurveyAvailabilityDatetime) {
363
                    $params['avail_till'] = api_get_utc_datetime($values['end_date'].':00');
364
                } else {
365
                    $params['avail_till'] = $values['end_date'];
366
                }
367
            }
368
369
            if (isset($values['survey_type']) && !empty($values['survey_type'])) {
370
                $params['survey_type'] = $values['survey_type'];
371
            }
372
373
            $params = array_merge($params, $extraParams);
374
375
            $survey_id = Database::insert($table_survey, $params);
376
            if ($survey_id > 0) {
377
                Event::addEvent(
378
                    LOG_SURVEY_CREATED,
379
                    LOG_SURVEY_ID,
380
                    $survey_id,
381
                    null,
382
                    api_get_user_id(),
383
                    api_get_course_int_id(),
384
                    api_get_session_id()
385
                );
386
387
                $sql = "UPDATE $table_survey SET survey_id = $survey_id
388
                        WHERE iid = $survey_id";
389
                Database::query($sql);
390
391
                // Insert into item_property
392
                api_item_property_update(
393
                    api_get_course_info(),
394
                    TOOL_SURVEY,
395
                    $survey_id,
396
                    'SurveyAdded',
397
                    api_get_user_id()
398
                );
399
            }
400
401
            if ($values['survey_type'] == 1 && !empty($values['parent_id'])) {
402
                self::copy_survey($values['parent_id'], $survey_id);
403
            }
404
405
            Display::addFlash(
406
                Display::return_message(
407
                    get_lang('SurveyCreatedSuccesfully'),
408
                    'success'
409
                )
410
            );
411
            $return['id'] = $survey_id;
412
        } else {
413
            // Check whether the code doesn't soon exists in this language
414
            $sql = 'SELECT 1 FROM '.$table_survey.'
415
			        WHERE
416
			            c_id = '.$course_id.' AND
417
			            code = "'.Database::escape_string($values['survey_code']).'" AND
418
			            lang = "'.Database::escape_string($values['survey_language']).'" AND
419
			            survey_id !='.intval($values['survey_id']);
420
            $rs = Database::query($sql);
421
            if (Database::num_rows($rs) > 0) {
422
                Display::addFlash(
423
                    Display::return_message(
424
                        get_lang('ThisSurveyCodeSoonExistsInThisLanguage'),
425
                        'error'
426
                    )
427
                );
428
                $return['type'] = 'error';
429
                $return['id'] = isset($values['survey_id']) ? $values['survey_id'] : 0;
430
431
                return $return;
432
            }
433
434
            if (!isset($values['anonymous'])
435
                || (isset($values['anonymous']) && $values['anonymous'] == '')
436
            ) {
437
                $values['anonymous'] = 0;
438
            }
439
440
            $extraParams = [];
441
            $extraParams['one_question_per_page'] = isset($values['one_question_per_page']) ? $values['one_question_per_page'] : 0;
442
            $extraParams['shuffle'] = isset($values['shuffle']) ? $values['shuffle'] : 0;
443
444
            if ($values['anonymous'] == 0) {
445
                $extraParams['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : 0;
446
                if ($extraParams['show_form_profile'] == 1) {
447
                    $fields = explode(',', $values['input_name_list']);
448
                    $field_values = '';
449
                    foreach ($fields as &$field) {
450
                        if ($field != '') {
451
                            if (!isset($values[$field]) ||
452
                                (isset($values[$field]) && $values[$field] == '')
453
                            ) {
454
                                $values[$field] = 0;
455
                            }
456
                            $field_values .= $field.':'.$values[$field].'@';
457
                        }
458
                    }
459
                    $extraParams['form_fields'] = $field_values;
460
                } else {
461
                    $extraParams['form_fields'] = '';
462
                }
463
            } else {
464
                $extraParams['show_form_profile'] = 0;
465
                $extraParams['form_fields'] = '';
466
            }
467
468
            if (!empty($values['end_date'])) {
469
                $availTill = $allowSurveyAvailabilityDatetime
470
                    ? api_get_utc_datetime($values['end_date'].':59')
471
                    : $values['end_date'];
472
            } else {
473
                $availTill = null;
474
            }
475
476
            $params = [
477
                'title' => $values['survey_title'],
478
                'subtitle' => $values['survey_subtitle'],
479
                'author' => $_user['user_id'],
480
                'lang' => $values['survey_language'],
481
                'avail_from' => $allowSurveyAvailabilityDatetime
482
                    ? api_get_utc_datetime($values['start_date'].':00')
483
                    : $values['start_date'],
484
                'avail_till' => $availTill,
485
                'is_shared' => $shared_survey_id,
486
                'template' => 'template',
487
                'intro' => $values['survey_introduction'],
488
                'surveythanks' => $values['survey_thanks'],
489
                'anonymous' => $values['anonymous'],
490
                'session_id' => api_get_session_id(),
491
                'visible_results' => $values['visible_results'],
492
            ];
493
494
            $params = array_merge($params, $extraParams);
495
            Database::update(
496
                $table_survey,
497
                $params,
498
                [
499
                    'c_id = ? AND survey_id = ?' => [
500
                        $course_id,
501
                        $values['survey_id'],
502
                    ],
503
                ]
504
            );
505
506
            // Update into item_property (update)
507
            api_item_property_update(
508
                api_get_course_info(),
509
                TOOL_SURVEY,
510
                $values['survey_id'],
511
                'SurveyUpdated',
512
                api_get_user_id()
513
            );
514
515
            Display::addFlash(
516
                Display::return_message(
517
                    get_lang('SurveyUpdatedSuccesfully'),
518
                    'confirmation'
519
                )
520
            );
521
522
            $return['id'] = $values['survey_id'];
523
        }
524
525
        $survey_id = (int) $return['id'];
526
527
        // Gradebook
528
        $gradebook_option = false;
529
        if (isset($values['survey_qualify_gradebook'])) {
530
            $gradebook_option = $values['survey_qualify_gradebook'] > 0;
531
        }
532
533
        $gradebook_link_type = 8;
534
        $link_info = GradebookUtils::isResourceInCourseGradebook(
535
            $courseCode,
536
            $gradebook_link_type,
537
            $survey_id,
538
            $session_id
539
        );
540
541
        $gradebook_link_id = isset($link_info['id']) ? $link_info['id'] : false;
542
543
        if ($gradebook_option) {
544
            if ($survey_id > 0) {
545
                $title_gradebook = ''; // Not needed here.
546
                $description_gradebook = ''; // Not needed here.
547
                $survey_weight = floatval($_POST['survey_weight']);
548
                $max_score = 1;
549
550
                if (!$gradebook_link_id) {
551
                    GradebookUtils::add_resource_to_course_gradebook(
552
                        $values['category_id'],
553
                        $courseCode,
554
                        $gradebook_link_type,
555
                        $survey_id,
556
                        $title_gradebook,
557
                        $survey_weight,
558
                        $max_score,
559
                        $description_gradebook,
560
                        1,
561
                        $session_id
562
                    );
563
                } else {
564
                    GradebookUtils::updateResourceFromCourseGradebook(
565
                        $gradebook_link_id,
566
                        $courseCode,
567
                        $survey_weight
568
                    );
569
                }
570
            }
571
        } else {
572
            // Delete everything of the gradebook for this $linkId
573
            GradebookUtils::remove_resource_from_course_gradebook($gradebook_link_id);
574
        }
575
576
        return $return;
577
    }
578
579
    /**
580
     * This function stores a shared survey in the central database.
581
     *
582
     * @param array $values
583
     *
584
     * @return array $return the type of return message that has to be displayed and the message in it
585
     *
586
     * @author Patrick Cool <[email protected]>, Ghent University
587
     *
588
     * @version February 2007
589
     */
590
    public function store_shared_survey($values)
591
    {
592
        $_user = api_get_user_info();
593
        $_course = api_get_course_info();
594
595
        // Table definitions
596
        $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
597
598
        if (!$values['survey_id'] ||
599
            !is_numeric($values['survey_id']) ||
600
            'true' == $values['survey_share']['survey_share']
601
        ) {
602
            $sql = "INSERT INTO $table_survey (code, title, subtitle, author, lang, template, intro, surveythanks, creation_date, course_code) VALUES (
603
                    '".Database::escape_string($values['survey_code'])."',
604
                    '".Database::escape_string($values['survey_title'])."',
605
                    '".Database::escape_string($values['survey_subtitle'])."',
606
                    '".intval($_user['user_id'])."',
607
                    '".Database::escape_string($values['survey_language'])."',
608
                    '".Database::escape_string('template')."',
609
                    '".Database::escape_string($values['survey_introduction'])."',
610
                    '".Database::escape_string($values['survey_thanks'])."',
611
                    '".api_get_utc_datetime()."',
612
                    '".$_course['id']."')";
613
            Database::query($sql);
614
            $return = Database::insert_id();
615
616
            $sql = "UPDATE $table_survey SET survey_id = $return WHERE iid = $return";
617
            Database::query($sql);
618
        } else {
619
            $sql = "UPDATE $table_survey SET
620
                        code 			= '".Database::escape_string($values['survey_code'])."',
621
                        title 			= '".Database::escape_string($values['survey_title'])."',
622
                        subtitle 		= '".Database::escape_string($values['survey_subtitle'])."',
623
                        author 			= '".intval($_user['user_id'])."',
624
                        lang 			= '".Database::escape_string($values['survey_language'])."',
625
                        template 		= '".Database::escape_string('template')."',
626
                        intro			= '".Database::escape_string($values['survey_introduction'])."',
627
                        surveythanks	= '".Database::escape_string($values['survey_thanks'])."'
628
					WHERE survey_id = '".Database::escape_string($values['survey_share']['survey_share'])."'";
629
            Database::query($sql);
630
            $return = $values['survey_share']['survey_share'];
631
        }
632
633
        return $return;
634
    }
635
636
    /**
637
     * This function deletes a survey (and also all the question in that survey.
638
     *
639
     * @param int  $survey_id id of the survey that has to be deleted
640
     * @param bool $shared
641
     * @param int  $course_id
642
     *
643
     * @return true
644
     *
645
     * @author Patrick Cool <[email protected]>, Ghent University
646
     *
647
     * @version January 2007
648
     */
649
    public static function delete_survey($survey_id, $shared = false, $course_id = 0)
650
    {
651
        // Database table definitions
652
        if (empty($course_id)) {
653
            $course_id = api_get_course_int_id();
654
        }
655
656
        $survey_id = (int) $survey_id;
657
658
        if (empty($survey_id)) {
659
            return false;
660
        }
661
662
        $course_info = api_get_course_info_by_id($course_id);
663
        $course_id = $course_info['real_id'];
664
665
        $table_survey = Database::get_course_table(TABLE_SURVEY);
666
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
667
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
668
669
        $sql = "SELECT code
670
                FROM $table_survey WHERE survey_id = $survey_id";
671
        $res = Database::query($sql);
672
        $row = Database::fetch_array($res);
673
        if ($row) {
674
            $survey_code = $row['code'];
675
        }
676
677
        if ($shared) {
678
            $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
679
            // Deleting the survey
680
            $sql = "DELETE FROM $table_survey
681
                    WHERE survey_id='".$survey_id."'";
682
            Database::query($sql);
683
        } else {
684
            $sql = "DELETE FROM $table_survey
685
                    WHERE c_id = $course_id AND survey_id='".$survey_id."'";
686
            Database::query($sql);
687
        }
688
689
        Event::addEvent(
690
            LOG_SURVEY_DELETED,
691
            LOG_SURVEY_ID,
692
            $survey_id,
693
            null,
694
            api_get_user_id(),
695
            api_get_course_int_id(),
696
            api_get_session_id()
697
        );
698
699
        // Deleting groups of this survey
700
        $sql = "DELETE FROM $table_survey_question_group
701
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
702
        Database::query($sql);
703
704
        // Deleting the questions of the survey
705
        self::delete_all_survey_questions($survey_id, $shared);
706
707
        // Deleting invitations of the survey
708
        $sql = "DELETE FROM $table_survey_invitation
709
                WHERE c_id = $course_id AND survey_code = '".$survey_code."'";
710
        Database::query($sql);
711
712
        // Update into item_property (delete)
713
        api_item_property_update(
714
            $course_info,
715
            TOOL_SURVEY,
716
            $survey_id,
717
            'SurveyDeleted',
718
            api_get_user_id()
719
        );
720
721
        Skill::deleteSkillsFromItem($survey_id, ITEM_TYPE_SURVEY);
722
723
        return true;
724
    }
725
726
    /**
727
     * Copy given survey to a new (optional) given survey ID.
728
     *
729
     * @param int $survey_id
730
     * @param int $new_survey_id
731
     * @param int $targetCourseId
732
     *
733
     * @return bool
734
     */
735
    public static function copy_survey(
736
        $survey_id,
737
        $new_survey_id = null,
738
        $targetCourseId = null
739
    ) {
740
        $course_id = api_get_course_int_id();
741
        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...
742
            $targetCourseId = $course_id;
743
        }
744
745
        // Database table definitions
746
        $table_survey = Database::get_course_table(TABLE_SURVEY);
747
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
748
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
749
        $table_survey_options = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
750
        $survey_id = (int) $survey_id;
751
752
        // Get groups
753
        $survey_data = self::get_survey($survey_id, 0, null, true);
754
        if (empty($survey_data)) {
755
            return true;
756
        }
757
758
        if (empty($new_survey_id)) {
759
            $params = $survey_data;
760
            $params['code'] = self::generate_unique_code($params['code']);
761
            $params['c_id'] = $targetCourseId;
762
            unset($params['survey_id']);
763
            $params['session_id'] = api_get_session_id();
764
            $params['title'] = $params['title'].' '.get_lang('Copy');
765
            unset($params['iid']);
766
            $params['invited'] = 0;
767
            $params['answered'] = 0;
768
            $new_survey_id = Database::insert($table_survey, $params);
769
770
            if ($new_survey_id) {
771
                $sql = "UPDATE $table_survey SET survey_id = $new_survey_id
772
                        WHERE iid = $new_survey_id";
773
                Database::query($sql);
774
775
                // Insert into item_property
776
                api_item_property_update(
777
                    api_get_course_info(),
778
                    TOOL_SURVEY,
779
                    $new_survey_id,
780
                    'SurveyAdded',
781
                    api_get_user_id()
782
                );
783
            }
784
        } else {
785
            $new_survey_id = (int) $new_survey_id;
786
        }
787
788
        $sql = "SELECT * FROM $table_survey_question_group
789
                WHERE c_id = $course_id AND survey_id = $survey_id";
790
        $res = Database::query($sql);
791
        while ($row = Database::fetch_array($res, 'ASSOC')) {
792
            $params = [
793
                'c_id' => $targetCourseId,
794
                'name' => $row['name'],
795
                'description' => $row['description'],
796
                'survey_id' => $new_survey_id,
797
            ];
798
            $insertId = Database::insert($table_survey_question_group, $params);
799
800
            $sql = "UPDATE $table_survey_question_group SET id = iid
801
                    WHERE iid = $insertId";
802
            Database::query($sql);
803
804
            $group_id[$row['id']] = $insertId;
805
        }
806
807
        // Get questions
808
        $sql = "SELECT * FROM $table_survey_question
809
                WHERE c_id = $course_id AND survey_id = $survey_id";
810
        $res = Database::query($sql);
811
        while ($row = Database::fetch_array($res, 'ASSOC')) {
812
            $params = [
813
                'c_id' => $targetCourseId,
814
                'survey_id' => $new_survey_id,
815
                'survey_question' => $row['survey_question'],
816
                'survey_question_comment' => $row['survey_question_comment'],
817
                'type' => $row['type'],
818
                'display' => $row['display'],
819
                'sort' => $row['sort'],
820
                'shared_question_id' => $row['shared_question_id'],
821
                'max_value' => $row['max_value'],
822
                'survey_group_pri' => $row['survey_group_pri'],
823
                'survey_group_sec1' => $row['survey_group_sec1'],
824
                'survey_group_sec2' => $row['survey_group_sec2'],
825
            ];
826
827
            if (api_get_configuration_value('allow_required_survey_questions')) {
828
                if (isset($row['is_required'])) {
829
                    $params['is_required'] = $row['is_required'];
830
                }
831
            }
832
833
            $insertId = Database::insert($table_survey_question, $params);
834
            if ($insertId) {
835
                $sql = "UPDATE $table_survey_question SET question_id = iid WHERE iid = $insertId";
836
                Database::query($sql);
837
                $question_id[$row['question_id']] = $insertId;
838
            }
839
        }
840
841
        // Get questions options
842
        $sql = "SELECT * FROM $table_survey_options
843
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
844
845
        $res = Database::query($sql);
846
        while ($row = Database::fetch_array($res, 'ASSOC')) {
847
            $params = [
848
                'c_id' => $targetCourseId,
849
                'question_id' => $question_id[$row['question_id']],
850
                'survey_id' => $new_survey_id,
851
                'option_text' => $row['option_text'],
852
                'sort' => $row['sort'],
853
                'value' => $row['value'],
854
            ];
855
            $insertId = Database::insert($table_survey_options, $params);
856
            if ($insertId) {
857
                $sql = "UPDATE $table_survey_options SET question_option_id = $insertId
858
                        WHERE iid = $insertId";
859
                Database::query($sql);
860
            }
861
        }
862
863
        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...
864
    }
865
866
    /**
867
     * This function duplicates a survey (and also all the question in that survey.
868
     *
869
     * @param int $surveyId id of the survey that has to be duplicated
870
     * @param int $courseId id of the course which survey has to be duplicated
871
     *
872
     * @return true
873
     *
874
     * @author Eric Marguin <[email protected]>, Elixir Interactive
875
     *
876
     * @version October 2007
877
     */
878
    public static function empty_survey($surveyId, $courseId = 0)
879
    {
880
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
881
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
882
        $table_survey = Database::get_course_table(TABLE_SURVEY);
883
884
        $courseId = (int) $courseId;
885
        $courseId = empty($courseId) ? api_get_course_int_id() : $courseId;
886
        $surveyId = (int) $surveyId;
887
888
        $datas = self::get_survey($surveyId);
889
        $session_where = '';
890
        if (0 != api_get_session_id()) {
891
            $session_where = ' AND session_id = "'.api_get_session_id().'" ';
892
        }
893
894
        $sql = 'DELETE FROM '.$table_survey_invitation.'
895
		        WHERE
896
		            c_id = '.$courseId.' AND
897
		            survey_code = "'.Database::escape_string($datas['code']).'" '.$session_where.' ';
898
        Database::query($sql);
899
900
        $sql = 'DELETE FROM '.$table_survey_answer.'
901
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
902
        Database::query($sql);
903
904
        $sql = 'UPDATE '.$table_survey.' SET invited=0, answered=0
905
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
906
        Database::query($sql);
907
908
        Event::addEvent(
909
            LOG_SURVEY_CLEAN_RESULTS,
910
            LOG_SURVEY_ID,
911
            $surveyId,
912
            null,
913
            api_get_user_id(),
914
            api_get_course_int_id(),
915
            api_get_session_id()
916
        );
917
918
        return true;
919
    }
920
921
    /**
922
     * This function recalculates the number of people who have taken the survey (=filled at least one question).
923
     *
924
     * @param array  $survey_data
925
     * @param array  $user
926
     * @param string $survey_code
927
     *
928
     * @return bool
929
     *
930
     * @author Patrick Cool <[email protected]>, Ghent University
931
     *
932
     * @version February 2007
933
     */
934
    public static function update_survey_answered($survey_data, $user, $survey_code, $lpItemId = 0)
935
    {
936
        if (empty($survey_data)) {
937
            return false;
938
        }
939
940
        // Database table definitions
941
        $table_survey = Database::get_course_table(TABLE_SURVEY);
942
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
943
944
        $survey_id = (int) $survey_data['survey_id'];
945
        $course_id = (int) $survey_data['c_id'];
946
        $sessionId = api_get_session_id();
947
948
        // Getting a list with all the people who have filled the survey
949
        /*$people_filled = self::get_people_who_filled_survey($survey_id, false, $course_id);
950
        $number = count($people_filled);*/
951
952
        // Storing this value in the survey table
953
        $sql = "UPDATE $table_survey
954
		        SET answered = answered + 1
955
		        WHERE
956
                    c_id = $course_id AND
957
		            survey_id = ".$survey_id;
958
        Database::query($sql);
959
960
        $allow = api_get_configuration_value('survey_answered_at_field');
961
        // Requires DB change:
962
        // ALTER TABLE c_survey_invitation ADD answered_at DATETIME DEFAULT NULL;
963
        $answeredAt = '';
964
        if ($allow) {
965
            $answeredAt = "answered_at = '".api_get_utc_datetime()."',";
966
        }
967
        // To select the answers by Lp Item
968
        $lpItemCondition = '';
969
        if (true === api_get_configuration_value('allow_survey_tool_in_lp')) {
970
            $lpItemCondition = " AND c_lp_item_id = $lpItemId";
971
        }
972
        // To select the answers by session
973
        $sessionCondition = '';
974
        if (true === api_get_configuration_value('show_surveys_base_in_sessions')) {
975
            $sessionCondition = api_get_session_condition($sessionId);
976
        }
977
978
        // Storing that the user has finished the survey.
979
        $sql = "UPDATE $table_survey_invitation
980
                SET $answeredAt answered = 1
981
                WHERE
982
                    c_id = $course_id AND
983
                    user ='".Database::escape_string($user)."' AND
984
                    survey_code='".Database::escape_string($survey_code)."'
985
                    $sessionCondition
986
                    $lpItemCondition";
987
        Database::query($sql);
988
    }
989
990
    /**
991
     * This function return the "icon" of the question type.
992
     *
993
     * @param string $type
994
     *
995
     * @author Patrick Cool <[email protected]>, Ghent University
996
     *
997
     * @version February 2007
998
     */
999
    public static function icon_question($type)
1000
    {
1001
        // the possible question types
1002
        $possible_types = [
1003
            'personality',
1004
            'yesno',
1005
            'multiplechoice',
1006
            'multiplechoiceother',
1007
            'multipleresponse',
1008
            'open',
1009
            'dropdown',
1010
            'comment',
1011
            'pagebreak',
1012
            'percentage',
1013
            'score',
1014
            'selectivedisplay',
1015
        ];
1016
1017
        // the images array
1018
        $icon_question = [
1019
            'yesno' => 'yesno.png',
1020
            'personality' => 'yesno.png',
1021
            'multiplechoice' => 'mcua.png',
1022
            'multiplechoiceother' => 'mcma.png',
1023
            'multipleresponse' => 'mcma.png',
1024
            'open' => 'open_answer.png',
1025
            'dropdown' => 'dropdown.png',
1026
            'percentage' => 'percentagequestion.png',
1027
            'score' => 'scorequestion.png',
1028
            'comment' => 'commentquestion.png',
1029
            'pagebreak' => 'page_end.png',
1030
            'selectivedisplay' => 'yesno.png',
1031
        ];
1032
1033
        if (in_array($type, $possible_types)) {
1034
            return $icon_question[$type];
1035
        }
1036
1037
        return false;
1038
    }
1039
1040
    /**
1041
     * This function retrieves all the information of a question.
1042
     *
1043
     * @param int  $question_id the id of the question
1044
     * @param bool $shared
1045
     *
1046
     * @return array
1047
     *
1048
     * @author Patrick Cool <[email protected]>, Ghent University
1049
     *
1050
     * @version January 2007
1051
     *
1052
     * @todo one sql call should do the trick
1053
     */
1054
    public static function get_question($question_id, $shared = false)
1055
    {
1056
        // Table definitions
1057
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1058
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1059
        $course_id = api_get_course_int_id();
1060
        $question_id = (int) $question_id;
1061
1062
        if (empty($question_id)) {
1063
            return [];
1064
        }
1065
1066
        $sql = "SELECT * FROM $tbl_survey_question
1067
                WHERE c_id = $course_id AND question_id = $question_id
1068
                ORDER BY `sort` ";
1069
1070
        $sqlOption = "  SELECT * FROM $table_survey_question_option
1071
                        WHERE c_id = $course_id AND question_id='".$question_id."'
1072
                        ORDER BY `sort` ";
1073
1074
        if ($shared) {
1075
            $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1076
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1077
1078
            $sql = "SELECT * FROM $tbl_survey_question
1079
                    WHERE question_id = $question_id
1080
                    ORDER BY `sort` ";
1081
            $sqlOption = "SELECT * FROM $table_survey_question_option
1082
                          WHERE question_id = $question_id
1083
                          ORDER BY `sort` ";
1084
        }
1085
1086
        // Getting the information of the question
1087
        $result = Database::query($sql);
1088
        $row = Database::fetch_array($result, 'ASSOC');
1089
1090
        $return['survey_id'] = $row['survey_id'];
1091
        $return['parent_id'] = isset($row['parent_id']) ? $row['parent_id'] : 0;
1092
        $return['parent_option_id'] = isset($row['parent_option_id']) ? $row['parent_option_id'] : 0;
1093
        $return['question_id'] = $row['question_id'];
1094
        $return['type'] = $row['type'];
1095
        $return['question'] = $row['survey_question'];
1096
        $return['horizontalvertical'] = $row['display'];
1097
        $return['shared_question_id'] = $row['shared_question_id'];
1098
        $return['maximum_score'] = $row['max_value'];
1099
        $return['is_required'] = api_get_configuration_value('allow_required_survey_questions')
1100
            ? $row['is_required']
1101
            : false;
1102
1103
        if (0 != $row['survey_group_pri']) {
1104
            $return['assigned'] = $row['survey_group_pri'];
1105
            $return['choose'] = 1;
1106
        } else {
1107
            $return['assigned1'] = $row['survey_group_sec1'];
1108
            $return['assigned2'] = $row['survey_group_sec2'];
1109
            $return['choose'] = 2;
1110
        }
1111
1112
        // Getting the information of the question options
1113
        $result = Database::query($sqlOption);
1114
        $counter = 0;
1115
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1116
            /** @todo this should be renamed to options instead of answers */
1117
            $return['answers'][] = $row['option_text'];
1118
            $return['values'][] = $row['value'];
1119
            $return['answer_data'][$counter]['data'] = $row['option_text'];
1120
            $return['answer_data'][$counter]['iid'] = $row['iid'];
1121
            /** @todo this can be done more elegantly (used in reporting) */
1122
            $return['answersid'][] = $row['question_option_id'];
1123
            $counter++;
1124
        }
1125
1126
        return $return;
1127
    }
1128
1129
    /**
1130
     * This function gets all the question of any given survey.
1131
     *
1132
     * @param int $surveyId the id of the survey
1133
     * @param int $courseId
1134
     *
1135
     * @return array containing all the questions of the survey
1136
     *
1137
     * @author Patrick Cool <[email protected]>, Ghent University
1138
     *
1139
     * @version February 2007
1140
     *
1141
     * @todo one sql call should do the trick
1142
     */
1143
    public static function get_questions($surveyId, $courseId = 0)
1144
    {
1145
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1146
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1147
1148
        $courseId = (int) $courseId;
1149
        $surveyId = (int) $surveyId;
1150
1151
        if (empty($courseId)) {
1152
            $courseId = api_get_course_int_id();
1153
        }
1154
1155
        // Getting the information of the question
1156
        $sql = "SELECT * FROM $tbl_survey_question
1157
		        WHERE c_id = $courseId AND survey_id= $surveyId ";
1158
        $result = Database::query($sql);
1159
        $questions = [];
1160
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1161
            $questionId = $row['question_id'];
1162
            $questions[$questionId]['survey_id'] = $surveyId;
1163
            $questions[$questionId]['question_id'] = $questionId;
1164
            $questions[$questionId]['type'] = $row['type'];
1165
            $questions[$questionId]['question'] = $row['survey_question'];
1166
            $questions[$questionId]['horizontalvertical'] = $row['display'];
1167
            $questions[$questionId]['maximum_score'] = $row['max_value'];
1168
            $questions[$questionId]['sort'] = $row['sort'];
1169
            $questions[$questionId]['survey_question_comment'] = $row['survey_question_comment'];
1170
1171
            // Getting the information of the question options
1172
            $sql = "SELECT * FROM $table_survey_question_option
1173
		             WHERE c_id = $courseId AND survey_id= $surveyId  AND question_id = $questionId";
1174
            $resultOptions = Database::query($sql);
1175
            while ($rowOption = Database::fetch_array($resultOptions, 'ASSOC')) {
1176
                $questions[$questionId]['answers'][] = $rowOption['option_text'];
1177
            }
1178
        }
1179
1180
        return $questions;
1181
    }
1182
1183
    /**
1184
     * This function saves a question in the database.
1185
     * This can be either an update of an existing survey or storing a new survey.
1186
     *
1187
     * @param array $survey_data
1188
     * @param array $form_content all the information of the form
1189
     *
1190
     * @return string
1191
     *
1192
     * @author Patrick Cool <[email protected]>, Ghent University
1193
     *
1194
     * @version January 2007
1195
     */
1196
    public static function save_question($survey_data, $form_content, $showMessage = true, $dataFromDatabase = [])
1197
    {
1198
        $return_message = '';
1199
        if (strlen($form_content['question']) > 1) {
1200
            // Checks length of the question
1201
            $empty_answer = false;
1202
            if (1 == $survey_data['survey_type']) {
1203
                if (empty($form_content['choose'])) {
1204
                    return 'PleaseChooseACondition';
1205
                }
1206
1207
                if ((2 == $form_content['choose']) &&
1208
                    ($form_content['assigned1'] == $form_content['assigned2'])
1209
                ) {
1210
                    return 'ChooseDifferentCategories';
1211
                }
1212
            }
1213
1214
            if ('percentage' !== $form_content['type']) {
1215
                if (isset($form_content['answers'])) {
1216
                    for ($i = 0; $i < count($form_content['answers']); $i++) {
1217
                        if (strlen($form_content['answers'][$i]) < 1) {
1218
                            $empty_answer = true;
1219
                            break;
1220
                        }
1221
                    }
1222
                }
1223
            }
1224
1225
            if ('score' == $form_content['type']) {
1226
                if (strlen($form_content['maximum_score']) < 1) {
1227
                    $empty_answer = true;
1228
                }
1229
            }
1230
1231
            $course_id = api_get_course_int_id();
1232
1233
            if (!$empty_answer) {
1234
                // Table definitions
1235
                $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1236
                $surveyId = (int) $form_content['survey_id'];
1237
1238
                // Getting all the information of the survey
1239
                $survey_data = self::get_survey($surveyId);
1240
1241
                // Storing the question in the shared database
1242
                if (is_numeric($survey_data['survey_share']) && $survey_data['survey_share'] != 0) {
1243
                    $shared_question_id = self::save_shared_question($form_content, $survey_data);
1244
                    $form_content['shared_question_id'] = $shared_question_id;
1245
                }
1246
1247
                // Storing a new question
1248
                if ($form_content['question_id'] == '' || !is_numeric($form_content['question_id'])) {
1249
                    // Finding the max sort order of the questions in the given survey
1250
                    $sql = "SELECT max(sort) AS max_sort
1251
					        FROM $tbl_survey_question
1252
                            WHERE c_id = $course_id AND survey_id = $surveyId ";
1253
                    $result = Database::query($sql);
1254
                    $row = Database::fetch_array($result, 'ASSOC');
1255
                    $max_sort = $row['max_sort'];
1256
1257
                    // Some variables defined for survey-test type
1258
                    $extraParams = [];
1259
                    if (isset($_POST['choose'])) {
1260
                        if ($_POST['choose'] == 1) {
1261
                            $extraParams['survey_group_pri'] = $_POST['assigned'];
1262
                        } elseif ($_POST['choose'] == 2) {
1263
                            $extraParams['survey_group_sec1'] = $_POST['assigned1'];
1264
                            $extraParams['survey_group_sec2'] = $_POST['assigned2'];
1265
                        }
1266
                    }
1267
1268
                    $questionComment = isset($form_content['question_comment']) ? $form_content['question_comment'] : '';
1269
                    $maxScore = isset($form_content['maximum_score']) ? $form_content['maximum_score'] : '';
1270
                    $display = isset($form_content['horizontalvertical']) ? $form_content['horizontalvertical'] : '';
1271
1272
                    $params = [
1273
                        'c_id' => $course_id,
1274
                        'survey_id' => $surveyId,
1275
                        'survey_question' => $form_content['question'],
1276
                        'survey_question_comment' => $questionComment,
1277
                        'type' => $form_content['type'],
1278
                        'display' => $display,
1279
                        'sort' => $max_sort + 1,
1280
                        'shared_question_id' => $form_content['shared_question_id'],
1281
                        'max_value' => $maxScore,
1282
                    ];
1283
1284
                    if (api_get_configuration_value('survey_question_dependency')) {
1285
                        $params['parent_id'] = 0;
1286
                        $params['parent_option_id'] = 0;
1287
                        if (isset($form_content['parent_id']) &&
1288
                            isset($form_content['parent_option_id']) &&
1289
                            !empty($form_content['parent_id']) &&
1290
                            !empty($form_content['parent_option_id'])
1291
                        ) {
1292
                            $params['parent_id'] = $form_content['parent_id'];
1293
                            $params['parent_option_id'] = $form_content['parent_option_id'];
1294
                        }
1295
                    }
1296
1297
                    if (api_get_configuration_value('allow_required_survey_questions')) {
1298
                        $params['is_required'] = isset($form_content['is_required']);
1299
                    }
1300
1301
                    $params = array_merge($params, $extraParams);
1302
                    $question_id = Database::insert($tbl_survey_question, $params);
1303
                    if ($question_id) {
1304
                        $sql = "UPDATE $tbl_survey_question SET question_id = $question_id
1305
                                WHERE iid = $question_id";
1306
                        Database::query($sql);
1307
1308
                        $form_content['question_id'] = $question_id;
1309
                        $return_message = 'QuestionAdded';
1310
                    }
1311
                } else {
1312
                    // Updating an existing question
1313
                    $extraParams = [];
1314
                    if (isset($_POST['choose'])) {
1315
                        if (1 == $_POST['choose']) {
1316
                            $extraParams['survey_group_pri'] = $_POST['assigned'];
1317
                            $extraParams['survey_group_sec1'] = 0;
1318
                            $extraParams['survey_group_sec2'] = 0;
1319
                        } elseif (2 == $_POST['choose']) {
1320
                            $extraParams['survey_group_pri'] = 0;
1321
                            $extraParams['survey_group_sec1'] = $_POST['assigned1'];
1322
                            $extraParams['survey_group_sec2'] = $_POST['assigned2'];
1323
                        }
1324
                    }
1325
1326
                    $maxScore = isset($form_content['maximum_score']) ? $form_content['maximum_score'] : null;
1327
                    $questionComment = isset($form_content['question_comment'])
1328
                        ? $form_content['question_comment']
1329
                        : null;
1330
1331
                    // Adding the question to the survey_question table
1332
                    $params = [
1333
                        'survey_question' => $form_content['question'],
1334
                        'survey_question_comment' => $questionComment,
1335
                        'display' => $form_content['horizontalvertical'] ?? '',
1336
                        'max_value' => $maxScore,
1337
                    ];
1338
1339
                    if (api_get_configuration_value('allow_required_survey_questions')) {
1340
                        $params['is_required'] = isset($form_content['is_required']);
1341
                    }
1342
1343
                    if (api_get_configuration_value('survey_question_dependency')) {
1344
                        $params['parent_id'] = 0;
1345
                        $params['parent_option_id'] = 0;
1346
                        if (isset($form_content['parent_id']) &&
1347
                            isset($form_content['parent_option_id']) &&
1348
                            !empty($form_content['parent_id']) &&
1349
                            !empty($form_content['parent_option_id'])
1350
                        ) {
1351
                            $params['parent_id'] = $form_content['parent_id'];
1352
                            $params['parent_option_id'] = $form_content['parent_option_id'];
1353
                        }
1354
                    }
1355
1356
                    $params = array_merge($params, $extraParams);
1357
                    Database::update(
1358
                        $tbl_survey_question,
1359
                        $params,
1360
                        [
1361
                            'c_id = ? AND question_id = ?' => [
1362
                                $course_id,
1363
                                $form_content['question_id'],
1364
                            ],
1365
                        ]
1366
                    );
1367
                    $return_message = 'QuestionUpdated';
1368
                }
1369
1370
                if (!empty($form_content['survey_id'])) {
1371
                    // Updating survey
1372
                    api_item_property_update(
1373
                        api_get_course_info(),
1374
                        TOOL_SURVEY,
1375
                        $form_content['survey_id'],
1376
                        'SurveyUpdated',
1377
                        api_get_user_id()
1378
                    );
1379
                }
1380
1381
                // Storing the options of the question
1382
                self::save_question_options($form_content, $survey_data, $dataFromDatabase);
1383
            } else {
1384
                $return_message = 'PleasFillAllAnswer';
1385
            }
1386
        } else {
1387
            $return_message = 'PleaseEnterAQuestion';
1388
        }
1389
1390
        if ($showMessage) {
1391
            if (!empty($return_message)) {
1392
                Display::addFlash(Display::return_message(get_lang($return_message)));
1393
            }
1394
        }
1395
1396
        return $return_message;
1397
    }
1398
1399
    /**
1400
     * This function saves the question in the shared database.
1401
     *
1402
     * @param array $form_content all the information of the form
1403
     * @param array $survey_data  all the information of the survey
1404
     *
1405
     * @author Patrick Cool <[email protected]>, Ghent University
1406
     *
1407
     * @version February 2007
1408
     *
1409
     * @return int
1410
     *
1411
     * @todo editing of a shared question
1412
     */
1413
    public function save_shared_question($form_content, $survey_data)
1414
    {
1415
        $_course = api_get_course_info();
1416
1417
        // Table definitions
1418
        $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1419
1420
        // Storing a new question
1421
        if ('' == $form_content['shared_question_id'] ||
1422
            !is_numeric($form_content['shared_question_id'])
1423
        ) {
1424
            // Finding the max sort order of the questions in the given survey
1425
            $sql = "SELECT max(sort) AS max_sort FROM $tbl_survey_question
1426
                    WHERE survey_id='".intval($survey_data['survey_share'])."'
1427
                    AND code='".Database::escape_string($_course['id'])."'";
1428
            $result = Database::query($sql);
1429
            $row = Database::fetch_array($result, 'ASSOC');
1430
            $max_sort = $row['max_sort'];
1431
1432
            // Adding the question to the survey_question table
1433
            $sql = "INSERT INTO $tbl_survey_question (survey_id, survey_question, survey_question_comment, type, display, sort, code) VALUES (
1434
                    '".Database::escape_string($survey_data['survey_share'])."',
1435
                    '".Database::escape_string($form_content['question'])."',
1436
                    '".Database::escape_string($form_content['question_comment'])."',
1437
                    '".Database::escape_string($form_content['type'])."',
1438
                    '".Database::escape_string($form_content['horizontalvertical'])."',
1439
                    '".Database::escape_string($max_sort + 1)."',
1440
                    '".Database::escape_string($_course['id'])."')";
1441
            Database::query($sql);
1442
            $shared_question_id = Database::insert_id();
1443
        } else {
1444
            // Updating an existing question
1445
            // adding the question to the survey_question table
1446
            $sql = "UPDATE $tbl_survey_question SET
1447
                        survey_question = '".Database::escape_string($form_content['question'])."',
1448
                        survey_question_comment = '".Database::escape_string($form_content['question_comment'])."',
1449
                        display = '".Database::escape_string($form_content['horizontalvertical'])."'
1450
                    WHERE
1451
                        question_id = '".intval($form_content['shared_question_id'])."' AND
1452
                        code = '".Database::escape_string($_course['id'])."'";
1453
            Database::query($sql);
1454
            $shared_question_id = $form_content['shared_question_id'];
1455
        }
1456
1457
        return $shared_question_id;
1458
    }
1459
1460
    /**
1461
     * This functions moves a question of a survey up or down.
1462
     *
1463
     * @param string $direction
1464
     * @param int    $survey_question_id
1465
     * @param int    $survey_id
1466
     *
1467
     * @author Patrick Cool <[email protected]>, Ghent University
1468
     *
1469
     * @version January 2007
1470
     */
1471
    public static function move_survey_question(
1472
        $direction,
1473
        $survey_question_id,
1474
        $survey_id
1475
    ) {
1476
        // Table definition
1477
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1478
        $course_id = api_get_course_int_id();
1479
1480
        if ('moveup' == $direction) {
1481
            $sort = 'DESC';
1482
        }
1483
        if ('movedown' == $direction) {
1484
            $sort = 'ASC';
1485
        }
1486
1487
        $survey_id = (int) $survey_id;
1488
1489
        // Finding the two questions that needs to be swapped
1490
        $sql = "SELECT * FROM $table_survey_question
1491
		        WHERE c_id = $course_id AND survey_id='".$survey_id."'
1492
		        ORDER BY sort $sort";
1493
        $result = Database::query($sql);
1494
        $found = false;
1495
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1496
            if ($found) {
1497
                $question_id_two = $row['question_id'];
1498
                $question_sort_two = $row['sort'];
1499
                $found = false;
1500
            }
1501
            if ($row['question_id'] == $survey_question_id) {
1502
                $found = true;
1503
                $question_id_one = $row['question_id'];
1504
                $question_sort_one = $row['sort'];
1505
            }
1506
        }
1507
1508
        $sql = "UPDATE $table_survey_question
1509
                SET sort = '".Database::escape_string($question_sort_two)."'
1510
		        WHERE c_id = $course_id AND question_id='".intval($question_id_one)."'";
1511
        Database::query($sql);
1512
1513
        $sql = "UPDATE $table_survey_question
1514
                SET sort = '".Database::escape_string($question_sort_one)."'
1515
		        WHERE c_id = $course_id AND question_id='".intval($question_id_two)."'";
1516
        Database::query($sql);
1517
    }
1518
1519
    /**
1520
     * This function deletes all the questions of a given survey
1521
     * This function is normally only called when a survey is deleted.
1522
     *
1523
     * @param int $survey_id the id of the survey that has to be deleted
1524
     *
1525
     * @return bool
1526
     *
1527
     * @author Patrick Cool <[email protected]>, Ghent University
1528
     *
1529
     * @version January 2007
1530
     */
1531
    public static function delete_all_survey_questions($survey_id, $shared = false)
1532
    {
1533
        $course_id = api_get_course_int_id();
1534
        $survey_id = (int) $survey_id;
1535
1536
        // Table definitions
1537
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1538
        $course_condition = " c_id = $course_id AND ";
1539
        if ($shared) {
1540
            $course_condition = '';
1541
            $table_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1542
        }
1543
1544
        $sql = "DELETE FROM $table_survey_question
1545
		        WHERE $course_condition survey_id = '".$survey_id."'";
1546
1547
        // Deleting the survey questions
1548
        Database::query($sql);
1549
1550
        // Deleting all the options of the questions of the survey
1551
        self::delete_all_survey_questions_options($survey_id, $shared);
1552
1553
        // Deleting all the answers on this survey
1554
        self::delete_all_survey_answers($survey_id);
1555
1556
        return true;
1557
    }
1558
1559
    /**
1560
     * This function deletes a survey question and all its options.
1561
     *
1562
     * @param int  $survey_id   the id of the survey
1563
     * @param int  $question_id the id of the question
1564
     * @param bool $shared
1565
     *
1566
     * @return mixed False on error, true if the question could be deleted
1567
     *
1568
     * @todo also delete the answers to this question
1569
     *
1570
     * @author Patrick Cool <[email protected]>, Ghent University
1571
     *
1572
     * @version March 2007
1573
     */
1574
    public static function delete_survey_question($survey_id, $question_id, $shared = false)
1575
    {
1576
        $survey_id = (int) $survey_id;
1577
        $question_id = (int) $question_id;
1578
        $course_id = api_get_course_int_id();
1579
1580
        if ($shared) {
1581
            self::delete_shared_survey_question($survey_id, $question_id);
1582
        }
1583
1584
        // Table definitions
1585
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
1586
        // Deleting the survey questions
1587
        $sql = "DELETE FROM $table
1588
		        WHERE
1589
		            c_id = $course_id AND
1590
		            survey_id = $survey_id AND
1591
		            question_id = $question_id";
1592
        $result = Database::query($sql);
1593
        if (false == $result) {
1594
            return false;
1595
        }
1596
        // Deleting the options of the question of the survey
1597
        self::delete_survey_question_option($survey_id, $question_id, $shared);
1598
1599
        return true;
1600
    }
1601
1602
    /**
1603
     * This function deletes a shared survey question from the main database and all its options.
1604
     *
1605
     * @param int $question_id the id of the question
1606
     *
1607
     * @todo delete all the options of this question
1608
     *
1609
     * @author Patrick Cool <[email protected]>, Ghent University
1610
     *
1611
     * @version March 2007
1612
     */
1613
    public static function delete_shared_survey_question($survey_id, $question_id)
1614
    {
1615
        // Table definitions
1616
        $table_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1617
        $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1618
1619
        // First we have to get the shared_question_id
1620
        $question_data = self::get_question($question_id);
1621
1622
        // Deleting the survey questions
1623
        $sql = "DELETE FROM $table_survey_question
1624
		        WHERE question_id='".intval($question_data['shared_question_id'])."'";
1625
        Database::query($sql);
1626
1627
        // Deleting the options of the question of the survey question
1628
        $sql = "DELETE FROM $table_survey_question_option
1629
		        WHERE question_id='".intval($question_data['shared_question_id'])."'";
1630
        Database::query($sql);
1631
    }
1632
1633
    /**
1634
     * This function stores the options of the questions in the table.
1635
     *
1636
     * @param array $form_content
1637
     *
1638
     * @author Patrick Cool <[email protected]>, Ghent University
1639
     *
1640
     * @version January 2007
1641
     *
1642
     * @todo writing the update statement when editing a question
1643
     */
1644
    public static function save_question_options($form_content, $survey_data, $dataFromDatabase = [])
1645
    {
1646
        $course_id = api_get_course_int_id();
1647
        $type = $form_content['type'];
1648
1649
        // A percentage question type has options 1 -> 100
1650
        if ('percentage' === $type) {
1651
            for ($i = 1; $i < 101; $i++) {
1652
                $form_content['answers'][] = $i;
1653
            }
1654
        }
1655
1656
        if (is_numeric($survey_data['survey_share']) && 0 != $survey_data['survey_share']) {
1657
            self::save_shared_question_options($form_content, $survey_data);
1658
        }
1659
1660
        // Table definition
1661
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1662
1663
        // We are editing a question so we first have to remove all the existing options from the database
1664
        $optionsToDelete = [];
1665
        if (isset($dataFromDatabase['answer_data'])) {
1666
            foreach ($dataFromDatabase['answer_data'] as $data) {
1667
                if ('other' === $data['data'] && 'multiplechoiceother' === $type) {
1668
                    continue;
1669
                }
1670
1671
                if (!in_array($data['iid'], $form_content['answersid'])) {
1672
                    $optionsToDelete[] = $data['iid'];
1673
                }
1674
            }
1675
        }
1676
1677
        if (!empty($optionsToDelete)) {
1678
            foreach ($optionsToDelete as $iid) {
1679
                $iid = (int) $iid;
1680
                $sql = "DELETE FROM $table
1681
			            WHERE
1682
			                iid = $iid AND
1683
			                c_id = $course_id AND
1684
                            question_id = '".intval($form_content['question_id'])."'
1685
                            ";
1686
                Database::query($sql);
1687
            }
1688
        }
1689
1690
        $counter = 1;
1691
        if (isset($form_content['answers']) && is_array($form_content['answers'])) {
1692
            for ($i = 0; $i < count($form_content['answers']); $i++) {
1693
                $values = isset($form_content['values']) ? $form_content['values'][$i] : '';
1694
                $answerId = 0;
1695
                if (isset($form_content['answersid']) && isset($form_content['answersid'][$i])) {
1696
                    $answerId = $form_content['answersid'][$i];
1697
                }
1698
                if (empty($answerId)) {
1699
                    $params = [
1700
                        'c_id' => $course_id,
1701
                        'question_id' => $form_content['question_id'],
1702
                        'survey_id' => $form_content['survey_id'],
1703
                        'option_text' => $form_content['answers'][$i],
1704
                        'value' => $values,
1705
                        'sort' => $counter,
1706
                    ];
1707
                    $insertId = Database::insert($table, $params);
1708
                    if ($insertId) {
1709
                        $sql = "UPDATE $table
1710
                                SET question_option_id = $insertId
1711
                                WHERE iid = $insertId";
1712
                        Database::query($sql);
1713
                        $counter++;
1714
                    }
1715
                } else {
1716
                    $params = [
1717
                        'option_text' => $form_content['answers'][$i],
1718
                        'value' => $values,
1719
                        'sort' => $counter,
1720
                    ];
1721
                    Database::update($table, $params, ['iid = ?' => [$answerId]]);
1722
                    $counter++;
1723
                }
1724
            }
1725
        }
1726
1727
        if ('multiplechoiceother' === $type) {
1728
            // First time creation
1729
            if (empty($dataFromDatabase['answer_data'])) {
1730
                $params = [
1731
                    'c_id' => $course_id,
1732
                    'question_id' => $form_content['question_id'],
1733
                    'survey_id' => $form_content['survey_id'],
1734
                    'option_text' => 'other',
1735
                    'value' => 0,
1736
                    'sort' => $counter,
1737
                ];
1738
                $insertId = Database::insert($table, $params);
1739
                if ($insertId) {
1740
                    $sql = "UPDATE $table
1741
                            SET question_option_id = $insertId
1742
                            WHERE iid = $insertId";
1743
                    Database::query($sql);
1744
                }
1745
            } else {
1746
                $params = [
1747
                    'option_text' => 'other',
1748
                    'value' => 0,
1749
                    'sort' => $counter,
1750
                ];
1751
                Database::update(
1752
                    $table,
1753
                    $params,
1754
                    [
1755
                        'c_id = ? AND question_id = ? AND survey_id = ? AND option_text = ?' => [
1756
                            $course_id,
1757
                            $form_content['question_id'],
1758
                            $form_content['survey_id'],
1759
                            'other',
1760
                        ],
1761
                    ]
1762
                );
1763
            }
1764
        }
1765
    }
1766
1767
    /**
1768
     * This function stores the options of the questions in the shared table.
1769
     *
1770
     * @param array $form_content
1771
     *
1772
     * @author Patrick Cool <[email protected]>, Ghent University
1773
     *
1774
     * @version February 2007
1775
     *
1776
     * @todo writing the update statement when editing a question
1777
     */
1778
    public function save_shared_question_options($form_content, $survey_data)
1779
    {
1780
        if (is_array($form_content) && is_array($form_content['answers'])) {
1781
            // Table definition
1782
            $table = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1783
1784
            // We are editing a question so we first have to remove all the existing options from the database
1785
            $sql = "DELETE FROM $table
1786
                    WHERE question_id = '".Database::escape_string($form_content['shared_question_id'])."'";
1787
            Database::query($sql);
1788
1789
            $counter = 1;
1790
            foreach ($form_content['answers'] as &$answer) {
1791
                $params = [
1792
                    'question_id' => $form_content['shared_question_id'],
1793
                    'survey_id' => $survey_data['is_shared'],
1794
                    'option_text' => $answer,
1795
                    'sort' => $counter,
1796
                ];
1797
                Database::insert($table, $params);
1798
1799
                $counter++;
1800
            }
1801
        }
1802
    }
1803
1804
    /**
1805
     * This function deletes all the options of the questions of a given survey
1806
     * This function is normally only called when a survey is deleted.
1807
     *
1808
     * @param int $survey_id the id of the survey that has to be deleted
1809
     *
1810
     * @return true
1811
     *
1812
     * @author Patrick Cool <[email protected]>, Ghent University
1813
     *
1814
     * @version January 2007
1815
     */
1816
    public static function delete_all_survey_questions_options($survey_id, $shared = false)
1817
    {
1818
        // Table definitions
1819
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1820
        $course_id = api_get_course_int_id();
1821
        $course_condition = " c_id = $course_id AND ";
1822
        if ($shared) {
1823
            $course_condition = '';
1824
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1825
        }
1826
1827
        $sql = "DELETE FROM $table_survey_question_option
1828
                WHERE $course_condition survey_id='".intval($survey_id)."'";
1829
1830
        // Deleting the options of the survey questions
1831
        Database::query($sql);
1832
1833
        return true;
1834
    }
1835
1836
    /**
1837
     * This function deletes the options of a given question.
1838
     *
1839
     * @param int  $survey_id
1840
     * @param int  $question_id
1841
     * @param bool $shared
1842
     *
1843
     * @return bool
1844
     *
1845
     * @author Patrick Cool <[email protected]>, Ghent University
1846
     * @author Julio Montoya
1847
     *
1848
     * @version March 2007
1849
     */
1850
    public static function delete_survey_question_option(
1851
        $survey_id,
1852
        $question_id,
1853
        $shared = false
1854
    ) {
1855
        $course_id = api_get_course_int_id();
1856
        $course_condition = " c_id = $course_id AND ";
1857
1858
        // Table definitions
1859
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1860
        if ($shared) {
1861
            $course_condition = '';
1862
            $table = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1863
        }
1864
1865
        // Deleting the options of the survey questions
1866
        $sql = "DELETE FROM $table
1867
		        WHERE
1868
		            $course_condition survey_id='".intval($survey_id)."' AND
1869
		            question_id='".intval($question_id)."'";
1870
        Database::query($sql);
1871
1872
        return true;
1873
    }
1874
1875
    /**
1876
     * SURVEY ANSWERS FUNCTIONS.
1877
     */
1878
1879
    /**
1880
     * This function deletes all the answers anyone has given on this survey
1881
     * This function is normally only called when a survey is deleted.
1882
     *
1883
     * @param $survey_id the id of the survey that has to be deleted
1884
     *
1885
     * @return true
1886
     *
1887
     * @todo write the function
1888
     *
1889
     * @author Patrick Cool <[email protected]>, Ghent University
1890
     *
1891
     * @version January 2007,december 2008
1892
     */
1893
    public static function delete_all_survey_answers($survey_id)
1894
    {
1895
        $course_id = api_get_course_int_id();
1896
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
1897
        $survey_id = (int) $survey_id;
1898
        $sql = "DELETE FROM $table
1899
                WHERE c_id = $course_id AND survey_id = $survey_id";
1900
        Database::query($sql);
1901
1902
        return true;
1903
    }
1904
1905
    /**
1906
     * @param int $user_id
1907
     * @param int $survey_id
1908
     * @param int $course_id
1909
     *
1910
     * @return bool
1911
     */
1912
    public static function is_user_filled_survey($user_id, $survey_id, $course_id)
1913
    {
1914
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
1915
        $user_id = (int) $user_id;
1916
        $course_id = (int) $course_id;
1917
        $survey_id = (int) $survey_id;
1918
1919
        $sql = "SELECT DISTINCT user
1920
                FROM $table
1921
                WHERE
1922
                    c_id		= $course_id AND
1923
                    user		= $user_id AND
1924
                    survey_id	= $survey_id";
1925
        $result = Database::query($sql);
1926
        if (Database::num_rows($result)) {
1927
            return true;
1928
        }
1929
1930
        return false;
1931
    }
1932
1933
    /**
1934
     * This function gets all the persons who have filled the survey.
1935
     *
1936
     * @param int $survey_id
1937
     *
1938
     * @return array
1939
     *
1940
     * @author Patrick Cool <[email protected]>, Ghent University
1941
     *
1942
     * @version February 2007
1943
     */
1944
    public static function get_people_who_filled_survey(
1945
        $survey_id,
1946
        $all_user_info = false,
1947
        $course_id = null
1948
    ) {
1949
        // Database table definition
1950
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1951
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1952
1953
        // Variable initialisation
1954
        $return = [];
1955
1956
        if (empty($course_id)) {
1957
            $course_id = api_get_course_int_id();
1958
        } else {
1959
            $course_id = (int) $course_id;
1960
        }
1961
1962
        $survey_id = (int) $survey_id;
1963
1964
        if ($all_user_info) {
1965
            $order_clause = api_sort_by_first_name()
1966
                ? ' ORDER BY user.firstname, user.lastname'
1967
                : ' ORDER BY user.lastname, user.firstname';
1968
            $sql = "SELECT DISTINCT
1969
			            answered_user.user as invited_user,
1970
			            user.firstname,
1971
			            user.lastname,
1972
			            user.id as user_id
1973
                    FROM $table_survey_answer answered_user
1974
                    LEFT JOIN $table_user as user ON answered_user.user = user.id
1975
                    WHERE
1976
                        answered_user.c_id = $course_id AND
1977
                        survey_id= '".$survey_id."' ".
1978
                $order_clause;
1979
        } else {
1980
            $sql = "SELECT DISTINCT user FROM $table_survey_answer
1981
			        WHERE c_id = $course_id AND survey_id= '".$survey_id."'  ";
1982
1983
            if (api_get_configuration_value('survey_anonymous_show_answered')) {
1984
                $tblInvitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
1985
                $tblSurvey = Database::get_course_table(TABLE_SURVEY);
1986
1987
                $sql = "SELECT i.user FROM $tblInvitation i
1988
                    INNER JOIN $tblSurvey s
1989
                    ON i.survey_code = s.code
1990
                        AND i.c_id = s.c_id
1991
                        AND i.session_id = s.session_id
1992
                    WHERE i.answered IS TRUE AND s.iid = $survey_id";
1993
            }
1994
        }
1995
1996
        $res = Database::query($sql);
1997
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1998
            if ($all_user_info) {
1999
                $userInfo = api_get_user_info($row['user_id']);
2000
                $row['user_info'] = $userInfo;
2001
                $return[] = $row;
2002
            } else {
2003
                $return[] = $row['user'];
2004
            }
2005
        }
2006
2007
        return $return;
2008
    }
2009
2010
    /**
2011
     * @return bool
2012
     */
2013
    public static function survey_generation_hash_available()
2014
    {
2015
        if (extension_loaded('mcrypt')) {
2016
            return true;
2017
        }
2018
2019
        return false;
2020
    }
2021
2022
    /**
2023
     * @param int $survey_id
2024
     * @param int $course_id
2025
     * @param int $session_id
2026
     * @param int $group_id
2027
     *
2028
     * @return string
2029
     */
2030
    public static function generate_survey_hash($survey_id, $course_id, $session_id, $group_id)
2031
    {
2032
        return hash('sha512', api_get_security_key().'_'.$course_id.'_'.$session_id.'_'.$group_id.'_'.$survey_id);
2033
    }
2034
2035
    /**
2036
     * @param int    $survey_id
2037
     * @param int    $course_id
2038
     * @param int    $session_id
2039
     * @param int    $group_id
2040
     * @param string $hash
2041
     *
2042
     * @return bool
2043
     */
2044
    public static function validate_survey_hash($survey_id, $course_id, $session_id, $group_id, $hash)
2045
    {
2046
        $generatedHash = self::generate_survey_hash($survey_id, $course_id, $session_id, $group_id);
2047
        if ($generatedHash == $hash) {
2048
            return true;
2049
        }
2050
2051
        return false;
2052
    }
2053
2054
    /**
2055
     * @param int $survey_id
2056
     * @param int $course_id
2057
     * @param int $session_id
2058
     * @param int $group_id
2059
     *
2060
     * @return string
2061
     */
2062
    public static function generate_survey_link(
2063
        $survey_id,
2064
        $course_id,
2065
        $session_id,
2066
        $group_id
2067
    ) {
2068
        $code = self::generate_survey_hash(
2069
            $survey_id,
2070
            $course_id,
2071
            $session_id,
2072
            $group_id
2073
        );
2074
2075
        return api_get_path(WEB_CODE_PATH).'survey/link.php?h='.$code.'&i='.$survey_id.'&c='.intval($course_id).'&s='
2076
            .intval($session_id).'&g='.$group_id;
2077
    }
2078
2079
    /**
2080
     * Check if the current user has mandatory surveys no-answered
2081
     * and redirect to fill the first found survey.
2082
     */
2083
    public static function protectByMandatory()
2084
    {
2085
        if (false !== strpos($_SERVER['SCRIPT_NAME'], 'fillsurvey.php')) {
2086
            return;
2087
        }
2088
2089
        $userId = api_get_user_id();
2090
        $courseId = api_get_course_int_id();
2091
        $sessionId = api_get_session_id();
2092
2093
        if (!$userId) {
2094
            return;
2095
        }
2096
2097
        if (!$courseId) {
2098
            return;
2099
        }
2100
2101
        try {
2102
            /** @var CSurveyInvitation $invitation */
2103
            $invitation = Database::getManager()
2104
                ->createQuery("
2105
                    SELECT i FROM ChamiloCourseBundle:CSurveyInvitation i
2106
                    INNER JOIN ChamiloCourseBundle:CSurvey s
2107
                        WITH (s.code = i.surveyCode AND s.cId = i.cId AND s.sessionId = i.sessionId)
2108
                    INNER JOIN ChamiloCoreBundle:ExtraFieldValues efv WITH efv.itemId = s.iid
2109
                    INNER JOIN ChamiloCoreBundle:ExtraField ef WITH efv.field = ef.id
2110
                    WHERE
2111
                        i.answered = 0 AND
2112
                        i.cId = :course AND
2113
                        i.user = :user AND
2114
                        i.sessionId = :session AND
2115
                        :now BETWEEN s.availFrom AND s.availTill AND
2116
                        ef.variable = :variable AND
2117
                        efv.value = 1 AND
2118
                        s.surveyType != 3
2119
                    ORDER BY s.availTill ASC
2120
                ")
2121
                ->setMaxResults(1)
2122
                ->setParameters([
2123
                    'course' => $courseId,
2124
                    'user' => $userId,
2125
                    'session' => $sessionId,
2126
                    'now' => new DateTime('UTC', new DateTimeZone('UTC')),
2127
                    'variable' => 'is_mandatory',
2128
                ])
2129
                ->getSingleResult();
2130
        } catch (Exception $e) {
2131
            $invitation = null;
2132
        }
2133
2134
        if (!$invitation) {
2135
            return;
2136
        }
2137
2138
        Display::addFlash(
2139
            Display::return_message(get_lang('MandatorySurveyNoAnswered'), 'warning')
2140
        );
2141
2142
        $url = SurveyUtil::generateFillSurveyLink(
2143
            $invitation->getInvitationCode(),
2144
            api_get_course_info(),
2145
            api_get_session_id()
2146
        );
2147
2148
        header('Location: '.$url);
2149
        exit;
2150
    }
2151
2152
    /**
2153
     * This function empty surveys (invitations and answers).
2154
     *
2155
     * @param int $surveyId id of the survey to empty
2156
     *
2157
     * @return bool
2158
     */
2159
    public static function emptySurveyFromId($surveyId)
2160
    {
2161
        // Database table definitions
2162
        $surveyInvitationTable = Database::get_course_table(TABLE_SURVEY_INVITATION);
2163
        $surveyAnswerTable = Database::get_course_table(TABLE_SURVEY_ANSWER);
2164
        $surveyTable = Database::get_course_table(TABLE_SURVEY);
2165
        $surveyId = (int) $surveyId;
2166
        $surveyData = self::get_survey($surveyId);
2167
        if (empty($surveyData)) {
2168
            return false;
2169
        }
2170
2171
        $surveyCode = $surveyData['survey_code'];
2172
        $courseId = (int) $surveyData['c_id'];
2173
        $sessionId = (int) $surveyData['session_id'];
2174
2175
        $sql = "DELETE FROM $surveyInvitationTable
2176
                WHERE session_id = $sessionId AND c_id = $courseId AND survey_code = '$surveyCode' ";
2177
        Database::query($sql);
2178
2179
        $sql = "DELETE FROM $surveyAnswerTable
2180
               WHERE survey_id = $surveyId AND c_id = $courseId ";
2181
        Database::query($sql);
2182
2183
        $sql = "UPDATE $surveyTable
2184
                SET invited = 0, answered = 0
2185
                WHERE survey_id = $surveyId AND c_id = $courseId AND session_id = $sessionId ";
2186
        Database::query($sql);
2187
2188
        return true;
2189
    }
2190
2191
    /**
2192
     * Copy survey specifying course ID and session ID where will be copied.
2193
     *
2194
     * @param int $surveyId
2195
     * @param int $targetCourseId  target course id
2196
     * @param int $targetSessionId target session id
2197
     *
2198
     * @return bool|int when fails or return the new survey id
2199
     */
2200
    public static function copySurveySession(
2201
        $surveyId,
2202
        $targetCourseId,
2203
        $targetSessionId
2204
    ) {
2205
        // Database table definitions
2206
        $surveyTable = Database::get_course_table(TABLE_SURVEY);
2207
        $surveyQuestionGroupTable = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
2208
        $surveyQuestionTable = Database::get_course_table(TABLE_SURVEY_QUESTION);
2209
        $surveyOptionsTable = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2210
        $surveyId = (int) $surveyId;
2211
        $targetCourseId = (int) $targetCourseId;
2212
        $targetSessionId = (int) $targetSessionId;
2213
2214
        $surveyData = self::get_survey($surveyId, 0, '', true);
2215
        if (empty($surveyData) || empty($targetCourseId)) {
2216
            return false;
2217
        }
2218
2219
        $originalCourseId = $surveyData['c_id'];
2220
        $originalSessionId = $surveyData['session_id'];
2221
2222
        $surveyData['code'] = self::generate_unique_code($surveyData['code']);
2223
        $surveyData['c_id'] = $targetCourseId;
2224
        $surveyData['session_id'] = $targetSessionId;
2225
        // Add a "Copy" suffix if copied inside the same course
2226
        if ($targetCourseId == $originalCourseId) {
2227
            $surveyData['title'] = $surveyData['title'].' '.get_lang('Copy');
2228
        }
2229
        unset($surveyData['iid']);
2230
        unset($surveyData['id']);
2231
2232
        $newSurveyId = Database::insert($surveyTable, $surveyData);
2233
2234
        if ($newSurveyId) {
2235
            $sql = "UPDATE $surveyTable SET survey_id = $newSurveyId
2236
                    WHERE iid = $newSurveyId";
2237
            Database::query($sql);
2238
2239
            $sql = "SELECT * FROM $surveyQuestionGroupTable
2240
                    WHERE c_id = $originalCourseId AND survey_id = $surveyId";
2241
            $res = Database::query($sql);
2242
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2243
                $params = [
2244
                    'c_id' => $targetCourseId,
2245
                    'name' => $row['name'],
2246
                    'description' => $row['description'],
2247
                    'survey_id' => $newSurveyId,
2248
                ];
2249
                $insertId = Database::insert($surveyQuestionGroupTable, $params);
2250
                if ($insertId) {
2251
                    $sql = "UPDATE $surveyQuestionGroupTable SET id = iid WHERE iid = $insertId";
2252
                    Database::query($sql);
2253
                    $group_id[$row['id']] = $insertId;
2254
                }
2255
            }
2256
2257
            // Get questions
2258
            $sql = "SELECT * FROM $surveyQuestionTable
2259
                    WHERE c_id = $originalCourseId AND survey_id = $surveyId";
2260
            $res = Database::query($sql);
2261
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2262
                $params = [
2263
                    'c_id' => $targetCourseId,
2264
                    'survey_id' => $newSurveyId,
2265
                    'survey_question' => $row['survey_question'],
2266
                    'survey_question_comment' => $row['survey_question_comment'],
2267
                    'type' => $row['type'],
2268
                    'display' => $row['display'],
2269
                    'sort' => $row['sort'],
2270
                    'shared_question_id' => $row['shared_question_id'],
2271
                    'max_value' => $row['max_value'],
2272
                    'survey_group_pri' => $row['survey_group_pri'],
2273
                    'survey_group_sec1' => $row['survey_group_sec1'],
2274
                    'survey_group_sec2' => $row['survey_group_sec2'],
2275
                ];
2276
2277
                if (api_get_configuration_value('allow_required_survey_questions')) {
2278
                    if (isset($row['is_required'])) {
2279
                        $params['is_required'] = $row['is_required'];
2280
                    }
2281
                }
2282
2283
                $insertId = Database::insert($surveyQuestionTable, $params);
2284
                if ($insertId) {
2285
                    $sql = "UPDATE $surveyQuestionTable
2286
                            SET question_id = iid
2287
                            WHERE iid = $insertId";
2288
                    Database::query($sql);
2289
2290
                    $question_id[$row['question_id']] = $insertId;
2291
                }
2292
            }
2293
2294
            // Get questions options
2295
            $sql = "SELECT * FROM $surveyOptionsTable
2296
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId";
2297
2298
            $res = Database::query($sql);
2299
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2300
                $params = [
2301
                    'c_id' => $targetCourseId,
2302
                    'question_id' => $question_id[$row['question_id']],
2303
                    'survey_id' => $newSurveyId,
2304
                    'option_text' => $row['option_text'],
2305
                    'sort' => $row['sort'],
2306
                    'value' => $row['value'],
2307
                ];
2308
                $insertId = Database::insert($surveyOptionsTable, $params);
2309
                if ($insertId) {
2310
                    $sql = "UPDATE $surveyOptionsTable SET question_option_id = $insertId WHERE iid = $insertId";
2311
                    Database::query($sql);
2312
                }
2313
            }
2314
2315
            return $newSurveyId;
2316
        }
2317
2318
        return false;
2319
    }
2320
2321
    /**
2322
     * Copy/duplicate one question (into the same survey).
2323
     * Note: Relies on the question iid to find all necessary info.
2324
     *
2325
     * @param int $questionId
2326
     *
2327
     * @return int The new question's iid, or 0 on error
2328
     */
2329
    public static function copyQuestion($questionId)
2330
    {
2331
        if (empty($questionId)) {
2332
            return 0;
2333
        }
2334
        $questionId = (int) $questionId;
2335
        $questionTable = Database::get_course_table(TABLE_SURVEY_QUESTION);
2336
        $optionsTable = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2337
2338
        // Get questions
2339
        $sql = "SELECT * FROM $questionTable WHERE iid = $questionId";
2340
        $res = Database::query($sql);
2341
        if (false == $res) {
2342
            // Could not find this question
2343
            return 0;
2344
        }
2345
        $row = Database::fetch_array($res, 'ASSOC');
2346
        $params = [
2347
            'c_id' => $row['c_id'],
2348
            'survey_id' => $row['survey_id'],
2349
            'survey_question' => trim($row['survey_question']),
2350
            'survey_question_comment' => $row['survey_question_comment'],
2351
            'type' => $row['type'],
2352
            'display' => $row['display'],
2353
            'shared_question_id' => $row['shared_question_id'],
2354
            'max_value' => $row['max_value'],
2355
            'survey_group_pri' => $row['survey_group_pri'],
2356
            'survey_group_sec1' => $row['survey_group_sec1'],
2357
            'survey_group_sec2' => $row['survey_group_sec2'],
2358
        ];
2359
        if (api_get_configuration_value('allow_required_survey_questions')) {
2360
            if (isset($row['is_required'])) {
2361
                $params['is_required'] = $row['is_required'];
2362
            }
2363
        }
2364
        // Get question position
2365
        $sqlSort = "SELECT max(sort) as sort FROM $questionTable
2366
                    WHERE survey_id = ".$row['survey_id'];
2367
        $resSort = Database::query($sqlSort);
2368
        $rowSort = Database::fetch_assoc($resSort);
2369
        $params['sort'] = $rowSort['sort'] + 1;
2370
        // Insert the new question
2371
        $insertId = Database::insert($questionTable, $params);
2372
        if (false == $insertId) {
2373
            return 0;
2374
        }
2375
        // Normalize question_id with iid
2376
        $sql = "UPDATE $questionTable
2377
                SET question_id = iid
2378
                WHERE iid = $insertId";
2379
        Database::query($sql);
2380
2381
        // Get questions options
2382
        $sql = "SELECT * FROM $optionsTable WHERE question_id = $questionId";
2383
        $res = Database::query($sql);
2384
        while ($row = Database::fetch_assoc($res)) {
2385
            $params = [
2386
                'c_id' => $row['c_id'],
2387
                'question_id' => $insertId,
2388
                'survey_id' => $row['survey_id'],
2389
                'option_text' => $row['option_text'],
2390
                'sort' => $row['sort'],
2391
                'value' => $row['value'],
2392
            ];
2393
            $optionId = Database::insert($optionsTable, $params);
2394
            if ($optionId) {
2395
                $sql = "UPDATE $optionsTable SET question_option_id = $optionId WHERE iid = $optionId";
2396
                Database::query($sql);
2397
            }
2398
        }
2399
2400
        return $insertId;
2401
    }
2402
2403
    /**
2404
     * @param array $surveyData
2405
     *
2406
     * @return bool
2407
     */
2408
    public static function removeMultiplicateQuestions($surveyData)
2409
    {
2410
        if (empty($surveyData)) {
2411
            return false;
2412
        }
2413
        $surveyId = $surveyData['survey_id'];
2414
        $courseId = $surveyData['c_id'];
2415
2416
        if (empty($surveyId) || empty($courseId)) {
2417
            return false;
2418
        }
2419
2420
        $questions = self::get_questions($surveyId);
2421
        foreach ($questions as $question) {
2422
            // Questions marked with "geneated" were created using the "multiplicate" feature.
2423
            if ($question['survey_question_comment'] === 'generated') {
2424
                self::delete_survey_question($surveyId, $question['question_id']);
2425
            }
2426
        }
2427
    }
2428
2429
    /**
2430
     * @param array  $surveyData
2431
     * @param string $type       by_class or by_user
2432
     *
2433
     * @return bool
2434
     */
2435
    public static function multiplicateQuestions($surveyData, $type)
2436
    {
2437
        if (empty($surveyData)) {
2438
            return false;
2439
        }
2440
        $surveyId = $surveyData['survey_id'];
2441
        $courseId = $surveyData['c_id'];
2442
2443
        if (empty($surveyId) || empty($courseId)) {
2444
            return false;
2445
        }
2446
2447
        $questions = self::get_questions($surveyId);
2448
2449
        if (empty($questions)) {
2450
            return false;
2451
        }
2452
2453
        $extraFieldValue = new ExtraFieldValue('survey');
2454
        $groupData = $extraFieldValue->get_values_by_handler_and_field_variable($surveyId, 'group_id');
2455
        $groupId = null;
2456
        if ($groupData && !empty($groupData['value'])) {
2457
            $groupId = (int) $groupData['value'];
2458
        }
2459
        switch ($type) {
2460
            case 'by_class':
2461
                if (null === $groupId) {
2462
                    $obj = new UserGroup();
2463
                    $options['where'] = [' usergroup.course_id = ? ' => $courseId];
2464
                    $classList = $obj->getUserGroupInCourse($options);
2465
                    $classToParse = [];
2466
                    foreach ($classList as $class) {
2467
                        $users = $obj->get_users_by_usergroup($class['id']);
2468
                        if (empty($users)) {
2469
                            continue;
2470
                        }
2471
                        $classToParse[] = [
2472
                            'name' => $class['name'],
2473
                            'users' => $users,
2474
                        ];
2475
                    }
2476
                    self::parseMultiplicateUserList($classToParse, $questions, $courseId, $surveyData, true);
2477
                } else {
2478
                    $groupInfo = GroupManager::get_group_properties($groupId);
2479
                    if (!empty($groupInfo)) {
2480
                        $users = GroupManager::getStudents($groupInfo['iid'], true);
2481
                        if (!empty($users)) {
2482
                            $users = array_column($users, 'id');
2483
                            self::parseMultiplicateUserList(
2484
                                [
2485
                                    [
2486
                                        'name' => $groupInfo['name'],
2487
                                        'users' => $users,
2488
                                    ],
2489
                                ],
2490
                                $questions,
2491
                                $courseId,
2492
                                $surveyData,
2493
                                false
2494
                            );
2495
                        }
2496
                    }
2497
                }
2498
                break;
2499
            case 'by_user':
2500
                if (null === $groupId) {
2501
                    $sessionId = api_get_session_id();
2502
                    $users = CourseManager::get_student_list_from_course_code(
2503
                        api_get_course_id(),
2504
                        !empty($sessionId),
2505
                        $sessionId
2506
                    );
2507
                    if (!empty($users)) {
2508
                        $users = array_column($users, 'id');
2509
                        self::parseMultiplicateUserListPerUser(
2510
                            [
2511
                                [
2512
                                    'name' => '',
2513
                                    'users' => $users,
2514
                                ],
2515
                            ],
2516
                            $questions,
2517
                            $courseId,
2518
                            $surveyData,
2519
                            false
2520
                        );
2521
                    }
2522
                } else {
2523
                    $groupInfo = GroupManager::get_group_properties($groupId);
2524
                    if (!empty($groupInfo)) {
2525
                        $users = GroupManager::getStudents($groupInfo['iid'], true);
2526
                        if (!empty($users)) {
2527
                            $users = array_column($users, 'id');
2528
                            self::parseMultiplicateUserListPerUser(
2529
                                [
2530
                                    [
2531
                                        'name' => $groupInfo['name'],
2532
                                        'users' => $users,
2533
                                    ],
2534
                                ],
2535
                                $questions,
2536
                                $courseId,
2537
                                $surveyData,
2538
                                false
2539
                            );
2540
                        }
2541
                    }
2542
                }
2543
                break;
2544
        }
2545
2546
        return true;
2547
    }
2548
2549
    public static function parseMultiplicateUserList($itemList, $questions, $courseId, $surveyData, $addClassNewPage = false)
2550
    {
2551
        if (empty($itemList) || empty($questions)) {
2552
            return false;
2553
        }
2554
2555
        $surveyId = $surveyData['survey_id'];
2556
        $classTag = '{{class_name}}';
2557
        $studentTag = '{{student_full_name}}';
2558
        $classCounter = 0;
2559
        $newQuestionList = [];
2560
        foreach ($questions as $question) {
2561
            $newQuestionList[$question['sort']] = $question;
2562
        }
2563
        ksort($newQuestionList);
2564
2565
        $order = api_get_configuration_value('survey_duplicate_order_by_name');
2566
        foreach ($itemList as $class) {
2567
            $className = $class['name'];
2568
            $users = $class['users'];
2569
            $userInfoList = [];
2570
            foreach ($users as $userId) {
2571
                $userInfoList[] = api_get_user_info($userId);
2572
            }
2573
2574
            if ($order) {
2575
                usort(
2576
                    $userInfoList,
2577
                    function ($a, $b) {
2578
                        return $a['lastname'] > $b['lastname'];
2579
                    }
2580
                );
2581
            }
2582
2583
            foreach ($newQuestionList as $question) {
2584
                $text = $question['question'];
2585
                if (false !== strpos($text, $classTag)) {
2586
                    $replacedText = str_replace($classTag, $className, $text);
2587
                    $values = [
2588
                        'c_id' => $courseId,
2589
                        'question_comment' => 'generated',
2590
                        'type' => $question['type'],
2591
                        'display' => $question['horizontalvertical'],
2592
                        'horizontalvertical' => $question['horizontalvertical'],
2593
                        'question' => $replacedText,
2594
                        'survey_id' => $surveyId,
2595
                        'question_id' => 0,
2596
                        'shared_question_id' => 0,
2597
                        'answers' => $question['answers'] ?? null,
2598
                    ];
2599
                    self::save_question($surveyData, $values, false);
2600
                    $classCounter++;
2601
                    continue;
2602
                }
2603
2604
                foreach ($userInfoList as $userInfo) {
2605
                    if (false !== strpos($text, $studentTag)) {
2606
                        $replacedText = str_replace($studentTag, $userInfo['complete_name'], $text);
2607
                        $values = [
2608
                            'c_id' => $courseId,
2609
                            'question_comment' => 'generated',
2610
                            'type' => $question['type'],
2611
                            'display' => $question['horizontalvertical'],
2612
                            'maximum_score' => $question['maximum_score'],
2613
                            'question' => $replacedText,
2614
                            'survey_id' => $surveyId,
2615
                            'question_id' => 0,
2616
                            'shared_question_id' => 0,
2617
                        ];
2618
2619
                        $answers = [];
2620
                        if (!empty($question['answers'])) {
2621
                            foreach ($question['answers'] as $answer) {
2622
                                $replacedText = str_replace($studentTag, $userInfo['complete_name'], $answer);
2623
                                $answers[] = $replacedText;
2624
                            }
2625
                        }
2626
                        $values['answers'] = $answers;
2627
                        self::save_question($surveyData, $values, false);
2628
                    }
2629
                }
2630
2631
                if ($addClassNewPage && $classCounter < count($itemList)) {
2632
                    self::addGeneratedNewPage($courseId, $surveyId, $surveyData, get_lang('QuestionForNextClass'));
2633
                }
2634
            }
2635
        }
2636
2637
        return true;
2638
    }
2639
2640
    public static function parseMultiplicateUserListPerUser(
2641
        $itemList,
2642
        $questions,
2643
        $courseId,
2644
        $surveyData,
2645
        $addClassNewPage = false
2646
    ) {
2647
        if (empty($itemList) || empty($questions)) {
2648
            return false;
2649
        }
2650
2651
        $surveyId = $surveyData['survey_id'];
2652
        $classTag = '{{class_name}}';
2653
        $studentTag = '{{student_full_name}}';
2654
        $classCounter = 0;
2655
        $newQuestionList = [];
2656
        foreach ($questions as $question) {
2657
            $newQuestionList[$question['sort']] = $question;
2658
        }
2659
        ksort($newQuestionList);
2660
2661
        $order = api_get_configuration_value('survey_duplicate_order_by_name');
2662
        foreach ($itemList as $class) {
2663
            $className = $class['name'];
2664
            $users = $class['users'];
2665
            $userInfoList = [];
2666
            foreach ($users as $userId) {
2667
                $userInfoList[] = api_get_user_info($userId);
2668
            }
2669
2670
            if ($order) {
2671
                usort(
2672
                    $userInfoList,
2673
                    function ($a, $b) {
2674
                        return $a['lastname'] > $b['lastname'];
2675
                    }
2676
                );
2677
            }
2678
2679
            /*foreach ($newQuestionList as $question) {
2680
                $text = $question['question'];
2681
                if (false === strpos($text, $studentTag)) {
2682
                    $values = [
2683
                        'c_id' => $courseId,
2684
                        'question_comment' => 'generated',
2685
                        'type' => $question['type'],
2686
                        'display' => $question['horizontalvertical'],
2687
                        'horizontalvertical' => $question['horizontalvertical'],
2688
                        'question' => $text,
2689
                        'survey_id' => $surveyId,
2690
                        'question_id' => 0,
2691
                        'shared_question_id' => 0,
2692
                        'answers' => $question['answers'] ?? null,
2693
                    ];
2694
                    self::save_question($surveyData, $values, false);
2695
                } else {
2696
                    break;
2697
                }
2698
            }*/
2699
2700
            self::addGeneratedNewPage($courseId, $surveyId, $surveyData, get_lang('QuestionForNextUser'));
2701
2702
            $counter = 0;
2703
            foreach ($userInfoList as $userInfo) {
2704
                foreach ($newQuestionList as $question) {
2705
                    $text = $question['question'];
2706
                    if (false !== strpos($text, $studentTag)) {
2707
                        $replacedText = str_replace($studentTag, $userInfo['complete_name'], $text);
2708
                        $values = [
2709
                            'c_id' => $courseId,
2710
                            'question_comment' => 'generated',
2711
                            'type' => $question['type'],
2712
                            'display' => $question['horizontalvertical'],
2713
                            'maximum_score' => $question['maximum_score'],
2714
                            'question' => $replacedText,
2715
                            'survey_id' => $surveyId,
2716
                            'question_id' => 0,
2717
                            'shared_question_id' => 0,
2718
                        ];
2719
2720
                        $answers = [];
2721
                        if (!empty($question['answers'])) {
2722
                            foreach ($question['answers'] as $answer) {
2723
                                $replacedText = str_replace($studentTag, $userInfo['complete_name'], $answer);
2724
                                $answers[] = $replacedText;
2725
                            }
2726
                        }
2727
                        $values['answers'] = $answers;
2728
                        self::save_question($surveyData, $values, false);
2729
                    }
2730
                }
2731
                $counter++;
2732
                if ($counter < count($userInfoList)) {
2733
                    self::addGeneratedNewPage($courseId, $surveyId, $surveyData, get_lang('QuestionForNextUser'));
2734
                }
2735
            }
2736
        }
2737
2738
        return true;
2739
    }
2740
2741
    public static function addGeneratedNewPage($courseId, $surveyId, $surveyData, $label)
2742
    {
2743
        // Add end page
2744
        $values = [
2745
            'c_id' => $courseId,
2746
            'question_comment' => 'generated',
2747
            'type' => 'pagebreak',
2748
            'display' => 'horizontal',
2749
            'question' => $label,
2750
            'survey_id' => $surveyId,
2751
            'question_id' => 0,
2752
            'shared_question_id' => 0,
2753
        ];
2754
        self::save_question($surveyData, $values, false);
2755
    }
2756
2757
    public static function hasDependency($survey)
2758
    {
2759
        if (false === api_get_configuration_value('survey_question_dependency')) {
2760
            return false;
2761
        }
2762
2763
        if (empty($survey)) {
2764
            return false;
2765
        }
2766
2767
        if (!isset($survey['survey_id'])) {
2768
            return false;
2769
        }
2770
2771
        $courseId = (int) $survey['c_id'];
2772
        $surveyId = (int) $survey['survey_id'];
2773
2774
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
2775
2776
        $sql = "SELECT COUNT(iid) count FROM $table
2777
                WHERE
2778
                    c_id = $courseId AND
2779
                    survey_id = $surveyId AND
2780
                    parent_option_id <> 0
2781
                LIMIT 1
2782
                ";
2783
        $result = Database::query($sql);
2784
        $row = Database::fetch_array($result);
2785
2786
        if ($row) {
2787
            return $row['count'] > 0;
2788
        }
2789
2790
        return false;
2791
    }
2792
2793
    /**
2794
     * @param array $survey
2795
     *
2796
     * @return int
2797
     */
2798
    public static function getCountPages($survey)
2799
    {
2800
        if (empty($survey) || !isset($survey['iid'])) {
2801
            return 0;
2802
        }
2803
2804
        $courseId = (int) $survey['c_id'];
2805
        $surveyId = (int) $survey['survey_id'];
2806
2807
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
2808
2809
        // pagebreak
2810
        $sql = "SELECT COUNT(iid) FROM $table
2811
                WHERE
2812
                    survey_question NOT LIKE '%{{%' AND
2813
                    type = 'pagebreak' AND
2814
                    c_id = $courseId AND
2815
                    survey_id = $surveyId";
2816
        $result = Database::query($sql);
2817
        $numberPageBreaks = Database::result($result, 0, 0);
2818
2819
        // No pagebreak
2820
        $sql = "SELECT COUNT(iid) FROM $table
2821
                WHERE
2822
                    survey_question NOT LIKE '%{{%' AND
2823
                    type != 'pagebreak' AND
2824
                    c_id = $courseId AND
2825
                    survey_id = $surveyId";
2826
        $result = Database::query($sql);
2827
        $countOfQuestions = Database::result($result, 0, 0);
2828
2829
        if (1 == $survey['one_question_per_page']) {
2830
            if (!empty($countOfQuestions)) {
2831
                return $countOfQuestions;
2832
            }
2833
2834
            return 1;
2835
        }
2836
2837
        if (empty($numberPageBreaks)) {
2838
            return 1;
2839
        }
2840
2841
        return $numberPageBreaks + 1;
2842
    }
2843
2844
    /**
2845
     * Check whether this survey has ended. If so, display message and exit rhis script.
2846
     *
2847
     * @param array $surveyData Survey data
2848
     */
2849
    public static function checkTimeAvailability($surveyData)
2850
    {
2851
        if (empty($surveyData)) {
2852
            api_not_allowed(true);
2853
        }
2854
2855
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
2856
        $utcZone = new DateTimeZone('UTC');
2857
        $startDate = new DateTime($surveyData['start_date'], $utcZone);
2858
        $endDate = new DateTime($surveyData['end_date'], $utcZone);
2859
        $currentDate = new DateTime('now', $utcZone);
2860
        if (!$allowSurveyAvailabilityDatetime) {
2861
            $currentDate->modify('today');
2862
        }
2863
        if ($currentDate < $startDate) {
2864
            api_not_allowed(
2865
                true,
2866
                Display::return_message(
2867
                    get_lang('SurveyNotAvailableYet'),
2868
                    'warning',
2869
                    false
2870
                )
2871
            );
2872
        }
2873
2874
        if ($currentDate > $endDate) {
2875
            api_not_allowed(
2876
                true,
2877
                Display::return_message(
2878
                    get_lang('SurveyNotAvailableAnymore'),
2879
                    'warning',
2880
                    false
2881
                )
2882
            );
2883
        }
2884
    }
2885
2886
    /**
2887
     * @param int    $userId
2888
     * @param string $surveyCode
2889
     * @param int    $courseId
2890
     * @param int    $sessionId
2891
     * @param int    $groupId
2892
     *
2893
     * @return array|CSurveyInvitation[]
2894
     */
2895
    public static function getUserInvitationsForSurveyInCourse(
2896
        $userId,
2897
        $surveyCode,
2898
        $courseId,
2899
        $sessionId = 0,
2900
        $groupId = 0,
2901
        $lpItemId = 0
2902
    ) {
2903
        $invitationRepo = Database::getManager()->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2904
2905
        $params = [
2906
            'user' => $userId,
2907
            'cId' => $courseId,
2908
            'sessionId' => $sessionId,
2909
            'groupId' => $groupId,
2910
            'surveyCode' => $surveyCode,
2911
        ];
2912
2913
        if (true === api_get_configuration_value('allow_survey_tool_in_lp')) {
2914
            $params['lpItemId'] = $lpItemId;
2915
        }
2916
2917
        return $invitationRepo->findBy(
2918
            $params,
2919
            ['invitationDate' => 'DESC']
2920
        );
2921
    }
2922
2923
    public static function getInvitationsAnswered(
2924
        $surveyCode,
2925
        $courseId,
2926
        $sessionId = 0
2927
    ) {
2928
        $invitationRepo = Database::getManager()->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2929
2930
        return $invitationRepo->findBy(
2931
            [
2932
                'cId' => $courseId,
2933
                'sessionId' => $sessionId,
2934
                'answered' => true,
2935
                'surveyCode' => $surveyCode,
2936
            ],
2937
            ['invitationDate' => 'DESC']
2938
        );
2939
    }
2940
2941
    /**
2942
     * @param array $userInfo
2943
     * @param int   $answered (1 = answered 0 = not answered)
2944
     *
2945
     * @return string
2946
     */
2947
    public static function surveyReport($userInfo, $answered = 0)
2948
    {
2949
        $userId = isset($userInfo['user_id']) ? (int) $userInfo['user_id'] : 0;
2950
        $answered = (int) $answered;
2951
2952
        if (empty($userId)) {
2953
            return '';
2954
        }
2955
2956
        $em = Database::getManager();
2957
        $repo = $em->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2958
        $repoSurvey = $em->getRepository('ChamiloCourseBundle:CSurvey');
2959
        $invitations = $repo->findBy(['user' => $userId, 'answered' => $answered]);
2960
        $mainUrl = api_get_path(WEB_CODE_PATH).'survey/survey.php?';
2961
        $content = '';
2962
2963
        if (empty($answered)) {
2964
            $content .= Display::page_subheader(get_lang('Unanswered'));
2965
        } else {
2966
            $content .= Display::page_subheader(get_lang('Answered'));
2967
        }
2968
2969
        if (!empty($invitations)) {
2970
            $table = new HTML_Table(['class' => 'table']);
2971
            $table->setHeaderContents(0, 0, get_lang('SurveyName'));
2972
            $table->setHeaderContents(0, 1, get_lang('Course'));
2973
2974
            if (empty($answered)) {
2975
                $table->setHeaderContents(0, 2, get_lang('Survey').' - '.get_lang('EndDate'));
2976
            }
2977
2978
            // Not answered
2979
            /** @var CSurveyInvitation $invitation */
2980
            $row = 1;
2981
            foreach ($invitations as $invitation) {
2982
                $courseId = $invitation->getCId();
2983
                $courseInfo = api_get_course_info_by_id($courseId);
2984
2985
                $courseCode = $courseInfo['code'];
2986
                if (empty($courseInfo)) {
2987
                    continue;
2988
                }
2989
                $sessionId = $invitation->getSessionId();
2990
2991
                if (!empty($answered)) {
2992
                    // check if user is subscribed to the course/session
2993
                    if (empty($sessionId)) {
2994
                        $subscribe = CourseManager::is_user_subscribed_in_course($userId, $courseCode);
2995
                    } else {
2996
                        $subscribe = CourseManager::is_user_subscribed_in_course(
2997
                            $userId,
2998
                            $courseCode,
2999
                            true,
3000
                            $sessionId
3001
                        );
3002
                    }
3003
3004
                    // User is not subscribe skip!
3005
                    if (empty($subscribe)) {
3006
                        continue;
3007
                    }
3008
                }
3009
3010
                $surveyCode = $invitation->getSurveyCode();
3011
3012
                $survey = $repoSurvey->findOneBy([
3013
                    'cId' => $courseId,
3014
                    'sessionId' => $sessionId,
3015
                    'code' => $surveyCode,
3016
                ]);
3017
3018
                if (empty($survey)) {
3019
                    continue;
3020
                }
3021
3022
                $url = $mainUrl.'survey_id='.$survey->getSurveyId().'&cidReq='.$courseCode.'&id_session='.$sessionId;
3023
                $title = $survey->getTitle();
3024
                $title = Display::url($title, $url);
3025
3026
                if (!empty($sessionId)) {
3027
                    $sessionInfo = api_get_session_info($sessionId);
3028
                    $courseInfo['name'] .= ' ('.$sessionInfo['name'].')';
3029
                }
3030
3031
                $surveyData = self::get_survey($survey->getSurveyId(), 0, $courseCode);
3032
                $table->setCellContents($row, 0, $title);
3033
                $table->setCellContents($row, 1, $courseInfo['name']);
3034
3035
                if (empty($answered)) {
3036
                    $table->setHeaderContents(
3037
                        $row,
3038
                        2,
3039
                        api_get_local_time(
3040
                            $survey->getAvailTill(),
3041
                            null,
3042
                            null,
3043
                            true,
3044
                            false
3045
                        )
3046
                    );
3047
                }
3048
3049
                if (!empty($answered) && $surveyData['anonymous'] == 0) {
3050
                    $answers = SurveyUtil::displayCompleteReport(
3051
                        $surveyData,
3052
                        $userId,
3053
                        false,
3054
                        false,
3055
                        false
3056
                    );
3057
                    $table->setCellContents(++$row, 0, $answers);
3058
                    $table->setCellContents(++$row, 1, '');
3059
                }
3060
3061
                $row++;
3062
            }
3063
            $content .= $table->toHtml();
3064
        } else {
3065
            $content .= Display::return_message(get_lang('NoData'));
3066
        }
3067
3068
        return $content;
3069
    }
3070
3071
    public static function sendToTutors($surveyId)
3072
    {
3073
        $survey = Database::getManager()->getRepository('ChamiloCourseBundle:CSurvey')->find($surveyId);
3074
        if (null === $survey) {
3075
            return false;
3076
        }
3077
3078
        $extraFieldValue = new ExtraFieldValue('survey');
3079
        $groupData = $extraFieldValue->get_values_by_handler_and_field_variable($surveyId, 'group_id');
3080
        if ($groupData && !empty($groupData['value'])) {
3081
            $groupInfo = GroupManager::get_group_properties($groupData['value']);
3082
            if ($groupInfo) {
3083
                $tutors = GroupManager::getTutors($groupInfo);
3084
                if (!empty($tutors)) {
3085
                    SurveyUtil::saveInviteMail(
3086
                        $survey,
3087
                        ' ',
3088
                        ' ',
3089
                        false
3090
                    );
3091
3092
                    foreach ($tutors as $tutor) {
3093
                        $subject = sprintf(get_lang('GroupSurveyX'), $groupInfo['name']);
3094
                        $content = sprintf(
3095
                            get_lang('HelloXGroupX'),
3096
                            $tutor['complete_name'],
3097
                            $groupInfo['name']
3098
                        );
3099
3100
                        SurveyUtil::saveInvitations(
3101
                            $surveyId,
3102
                            ['users' => $tutor['user_id']],
3103
                            $subject,
3104
                            $content,
3105
                            false,
3106
                            true,
3107
                            false,
3108
                            true
3109
                        );
3110
                    }
3111
                    Display::addFlash(Display::return_message(get_lang('Updated'), 'confirmation', false));
3112
                }
3113
                SurveyUtil::update_count_invited($survey->getCode());
3114
3115
                return true;
3116
            }
3117
        }
3118
3119
        return false;
3120
    }
3121
}
3122