Passed
Push — 1.11.x ( bce6cd...c146d9 )
by Angel Fernando Quiroz
12:25
created

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