Passed
Push — master ( d0b226...f5358a )
by Julito
10:41
created

main/survey/survey.lib.php (1 issue)

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CSurvey;
5
use Chamilo\CourseBundle\Entity\CSurveyInvitation;
6
use Chamilo\CourseBundle\Entity\CSurveyQuestion;
7
use Chamilo\CourseBundle\Entity\CSurveyQuestionOption;
8
9
/**
10
 * Class SurveyManager.
11
 *
12
 * @package chamilo.survey
13
 *
14
 * @author Patrick Cool <[email protected]>, Ghent University:
15
 * cleanup, refactoring and rewriting large parts (if not all) of the code
16
 * @author Julio Montoya <[email protected]>, Personality Test modification
17
 * and rewriting large parts of the code
18
 * @author cfasanando
19
 *
20
 * @todo move this file to inc/lib
21
 * @todo use consistent naming for the functions (save vs store for instance)
22
 */
23
class SurveyManager
24
{
25
    /**
26
     * @param $code
27
     *
28
     * @return string
29
     */
30
    public static function generate_unique_code($code)
31
    {
32
        if (empty($code)) {
33
            return false;
34
        }
35
        $course_id = api_get_course_int_id();
36
        $table = Database::get_course_table(TABLE_SURVEY);
37
        $code = Database::escape_string($code);
38
        $num = 0;
39
        $new_code = $code;
40
        while (true) {
41
            $sql = "SELECT * FROM $table
42
                    WHERE code = '$new_code' AND c_id = $course_id";
43
            $result = Database::query($sql);
44
            if (Database::num_rows($result)) {
45
                $num++;
46
                $new_code = $code.$num;
47
            } else {
48
                break;
49
            }
50
        }
51
52
        return $code.$num;
53
    }
54
55
    /**
56
     * Deletes all survey invitations of a user.
57
     *
58
     * @param int $user_id
59
     *
60
     * @return bool
61
     * @assert ('') === false
62
     */
63
    public static function delete_all_survey_invitations_by_user($user_id)
64
    {
65
        $user_id = (int) $user_id;
66
        if (empty($user_id)) {
67
            return false;
68
        }
69
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
70
        $table_survey = Database::get_course_table(TABLE_SURVEY);
71
72
        $sql = "SELECT survey_invitation_id, survey_code
73
                FROM $table_survey_invitation WHERE user = '$user_id' AND c_id <> 0 ";
74
        $result = Database::query($sql);
75
        while ($row = Database::fetch_array($result, 'ASSOC')) {
76
            $survey_invitation_id = $row['survey_invitation_id'];
77
            $survey_code = $row['survey_code'];
78
            $sql2 = "DELETE FROM $table_survey_invitation
79
                    WHERE survey_invitation_id = '$survey_invitation_id' AND c_id <> 0";
80
            if (Database::query($sql2)) {
81
                $sql3 = "UPDATE $table_survey SET
82
                            invited = invited-1
83
                        WHERE c_id <> 0 AND code ='$survey_code'";
84
                Database::query($sql3);
85
            }
86
        }
87
    }
88
89
    /**
90
     * @param string $course_code
91
     * @param int    $session_id
92
     *
93
     * @return array
94
     * @assert ('') === false
95
     */
96
    public static function get_surveys($course_code, $session_id = 0)
97
    {
98
        if (empty($course_code)) {
99
            return false;
100
        }
101
        $course_info = api_get_course_info($course_code);
102
103
        if (empty($course_info)) {
104
            return false;
105
        }
106
107
        $sessionCondition = api_get_session_condition($session_id, true, true);
108
109
        $table = Database::get_course_table(TABLE_SURVEY);
110
        $sql = "SELECT * FROM $table
111
                WHERE c_id = {$course_info['real_id']} $sessionCondition ";
112
        $result = Database::query($sql);
113
        $result = Database::store_result($result, 'ASSOC');
114
115
        return $result;
116
    }
117
118
    /**
119
     * Retrieves all the survey information.
120
     *
121
     * @param int  $survey_id the id of the survey
122
     * @param bool $shared    this parameter determines if
123
     *                        we have to get the information of a survey from the central (shared) database or from the
124
     *                        course database
125
     * @param string course code optional
126
     *
127
     * @author Patrick Cool <[email protected]>, Ghent University
128
     *
129
     * @version February 2007
130
     * @assert ('') === false
131
     *
132
     * @return array
133
     *
134
     * @todo this is the same function as in create_new_survey.php
135
     */
136
    public static function get_survey(
137
        $survey_id,
138
        $shared = 0,
139
        $course_code = '',
140
        $simple_return = false
141
    ) {
142
        $my_course_id = api_get_course_id();
143
144
        // Table definition
145
        if (!empty($course_code)) {
146
            $my_course_id = $course_code;
147
        } elseif (isset($_GET['course'])) {
148
            $my_course_id = Security::remove_XSS($_GET['course']);
149
        }
150
151
        $courseInfo = api_get_course_info($my_course_id);
152
        $survey_id = (int) $survey_id;
153
        $table_survey = Database::get_course_table(TABLE_SURVEY);
154
155
        if ($shared != 0) {
156
            $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
157
            $sql = "SELECT * FROM $table_survey
158
                    WHERE survey_id='".$survey_id."' ";
159
        } else {
160
            if (empty($courseInfo)) {
161
                return [];
162
            }
163
            $sql = "SELECT * FROM $table_survey
164
		            WHERE
165
		                survey_id='".$survey_id."' AND
166
		                c_id = ".$courseInfo['real_id'];
167
        }
168
169
        $result = Database::query($sql);
170
        $return = [];
171
172
        if (Database::num_rows($result) > 0) {
173
            $return = Database::fetch_array($result, 'ASSOC');
174
            if ($simple_return) {
175
                return $return;
176
            }
177
            // We do this (temporarily) to have the array match the quickform elements immediately
178
            // idealiter the fields in the db match the quickform fields
179
            $return['survey_code'] = $return['code'];
180
            $return['survey_title'] = $return['title'];
181
            $return['survey_subtitle'] = $return['subtitle'];
182
            $return['survey_language'] = $return['lang'];
183
            $return['start_date'] = $return['avail_from'];
184
            $return['end_date'] = $return['avail_till'];
185
            $return['survey_share'] = $return['is_shared'];
186
            $return['survey_introduction'] = $return['intro'];
187
            $return['survey_thanks'] = $return['surveythanks'];
188
            $return['survey_type'] = $return['survey_type'];
189
            $return['one_question_per_page'] = $return['one_question_per_page'];
190
            $return['show_form_profile'] = $return['show_form_profile'];
191
            $return['input_name_list'] = isset($return['input_name_list']) ? $return['input_name_list'] : null;
192
            $return['shuffle'] = $return['shuffle'];
193
            $return['parent_id'] = $return['parent_id'];
194
            $return['survey_version'] = $return['survey_version'];
195
            $return['anonymous'] = $return['anonymous'];
196
            $return['c_id'] = isset($return['c_id']) ? $return['c_id'] : 0;
197
            $return['session_id'] = isset($return['session_id']) ? $return['session_id'] : 0;
198
        }
199
200
        return $return;
201
    }
202
203
    /**
204
     * @param string $code
205
     *
206
     * @return string
207
     */
208
    public static function generateSurveyCode($code)
209
    {
210
        return strtolower(CourseManager::generate_course_code($code));
211
    }
212
213
    /**
214
     * This function stores a survey in the database.
215
     *
216
     * @param array $values
217
     *
218
     * @return array $return the type of return message that has to be displayed and the message in it
219
     *
220
     * @author Patrick Cool <[email protected]>, Ghent University
221
     *
222
     * @version February 2007
223
     */
224
    public static function store_survey($values)
225
    {
226
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
227
        $_user = api_get_user_info();
228
        $course_id = api_get_course_int_id();
229
        $session_id = api_get_session_id();
230
        $courseCode = api_get_course_id();
231
        $table_survey = Database::get_course_table(TABLE_SURVEY);
232
        $shared_survey_id = 0;
233
234
        if (!isset($values['survey_id'])) {
235
            // Check if the code doesn't soon exists in this language
236
            $sql = 'SELECT 1 FROM '.$table_survey.'
237
			        WHERE
238
			            c_id = '.$course_id.' AND
239
			            code = "'.Database::escape_string($values['survey_code']).'" AND
240
			            lang = "'.Database::escape_string($values['survey_language']).'"';
241
            $rs = Database::query($sql);
242
            if (Database::num_rows($rs) > 0) {
243
                Display::addFlash(
244
                    Display::return_message(
245
                        get_lang('ThisSurveyCodeSoonExistsInThisLanguage'),
246
                        'error'
247
                    )
248
                );
249
                $return['type'] = 'error';
250
                $return['id'] = isset($values['survey_id']) ? $values['survey_id'] : 0;
251
252
                return $return;
253
            }
254
255
            if (!isset($values['anonymous'])) {
256
                $values['anonymous'] = 0;
257
            }
258
259
            $values['anonymous'] = (int) $values['anonymous'];
260
261
            $survey = new CSurvey();
262
263
            $extraParams = [];
264
            if ($values['anonymous'] == 0) {
265
                // Input_name_list
266
                $values['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : 0;
267
                $survey->setShowFormProfile($values['show_form_profile']);
268
269
                if ($values['show_form_profile'] == 1) {
270
                    // Input_name_list
271
                    $fields = explode(',', $values['input_name_list']);
272
                    $field_values = '';
273
                    foreach ($fields as &$field) {
274
                        if ($field != '') {
275
                            if ($values[$field] == '') {
276
                                $values[$field] = 0;
277
                            }
278
                            $field_values .= $field.':'.$values[$field].'@';
279
                        }
280
                    }
281
                    $extraParams['form_fields'] = $field_values;
282
                } else {
283
                    $extraParams['form_fields'] = '';
284
                }
285
                $survey->setFormFields($extraParams['form_fields']);
286
            } else {
287
                $survey->setShowFormProfile(0);
288
                $survey->setFormFields(0);
289
            }
290
291
            $extraParams['one_question_per_page'] = isset($values['one_question_per_page']) ? $values['one_question_per_page'] : 0;
292
            $extraParams['shuffle'] = isset($values['shuffle']) ? $values['shuffle'] : 0;
293
294
            if ($values['survey_type'] == 1) {
295
                $survey
296
                    ->setSurveyType(1)
297
                    ->setShuffle($values['shuffle'])
298
                    ->setOneQuestionPerPage($values['one_question_per_page'])
299
                    ->setParentId($values['parent_id'])
300
                ;
301
                // Logic for versioning surveys
302
                if (!empty($values['parent_id'])) {
303
                    $versionValue = '';
304
                    $sql = 'SELECT survey_version
305
                            FROM '.$table_survey.'
306
					        WHERE
307
					            c_id = '.$course_id.' AND
308
					            parent_id = '.intval($values['parent_id']).'
309
                            ORDER BY survey_version DESC
310
                            LIMIT 1';
311
                    $rs = Database::query($sql);
312
                    if (Database::num_rows($rs) === 0) {
313
                        $sql = 'SELECT survey_version FROM '.$table_survey.'
314
						        WHERE
315
						            c_id = '.$course_id.' AND
316
						            survey_id = '.intval($values['parent_id']);
317
                        $rs = Database::query($sql);
318
                        $getversion = Database::fetch_array($rs, 'ASSOC');
319
                        if (empty($getversion['survey_version'])) {
320
                            $versionValue = ++$getversion['survey_version'];
321
                        } else {
322
                            $versionValue = $getversion['survey_version'];
323
                        }
324
                    } else {
325
                        $row = Database::fetch_array($rs, 'ASSOC');
326
                        $pos = api_strpos($row['survey_version']);
327
                        if ($pos === false) {
328
                            $row['survey_version'] = $row['survey_version'] + 1;
329
                            $versionValue = $row['survey_version'];
330
                        } else {
331
                            $getlast = explode('\.', $row['survey_version']);
332
                            $lastversion = array_pop($getlast);
333
                            $lastversion = $lastversion + 1;
334
                            $add = implode('.', $getlast);
335
                            if ($add != '') {
336
                                $insertnewversion = $add.'.'.$lastversion;
337
                            } else {
338
                                $insertnewversion = $lastversion;
339
                            }
340
                            $versionValue = $insertnewversion;
341
                        }
342
                    }
343
                    $survey->setSurveyVersion($versionValue);
344
                }
345
            }
346
347
            $from = api_get_utc_datetime($values['start_date'].'00:00:00', true, true);
348
            $until = api_get_utc_datetime($values['end_date'].'23:59:59', true, true);
349
            if ($allowSurveyAvailabilityDatetime) {
350
                $from = api_get_utc_datetime($values['start_date'].':00', true, true);
351
                $until = api_get_utc_datetime($values['end_date'].':59', true, true);
352
            }
353
354
            $survey
355
                ->setCId($course_id)
356
                ->setCode(self::generateSurveyCode($values['survey_code']))
357
                ->setTitle($values['survey_title'])
358
                ->setSubtitle($values['survey_title'])
359
                ->setAuthor($_user['user_id'])
360
                ->setLang($values['survey_language'])
361
                ->setAvailFrom($from)
362
                ->setAvailTill($until)
363
                ->setIsShared($shared_survey_id)
364
                ->setTemplate('template')
365
                ->setIntro($values['survey_introduction'])
366
                ->setSurveyThanks($values['survey_thanks'])
367
                ->setAnonymous($values['anonymous'])
368
                ->setSessionId(api_get_session_id())
369
                ->setVisibleResults($values['visible_results'])
370
            ;
371
372
            $em = Database::getManager();
373
            $em->persist($survey);
374
            $em->flush();
375
376
            $survey_id = $survey->getIid();
377
            if ($survey_id > 0) {
378
                $sql = "UPDATE $table_survey SET survey_id = $survey_id
379
                        WHERE iid = $survey_id";
380
                Database::query($sql);
381
382
                // Insert into item_property
383
                api_item_property_update(
384
                    api_get_course_info(),
385
                    TOOL_SURVEY,
386
                    $survey_id,
387
                    'SurveyAdded',
388
                    api_get_user_id()
389
                );
390
            }
391
392
            if ($values['survey_type'] == 1 && !empty($values['parent_id'])) {
393
                self::copy_survey($values['parent_id'], $survey_id);
394
            }
395
396
            Display::addFlash(
397
                Display::return_message(
398
                    get_lang('SurveyCreatedSuccesfully'),
399
                    'success'
400
                )
401
            );
402
            $return['id'] = $survey_id;
403
        } else {
404
            // Check whether the code doesn't soon exists in this language
405
            $sql = 'SELECT 1 FROM '.$table_survey.'
406
			        WHERE
407
			            c_id = '.$course_id.' AND
408
			            code = "'.Database::escape_string($values['survey_code']).'" AND
409
			            lang = "'.Database::escape_string($values['survey_language']).'" AND
410
			            survey_id !='.intval($values['survey_id']);
411
            $rs = Database::query($sql);
412
            if (Database::num_rows($rs) > 0) {
413
                Display::addFlash(
414
                    Display::return_message(
415
                        get_lang('ThisSurveyCodeSoonExistsInThisLanguage'),
416
                        'error'
417
                    )
418
                );
419
                $return['type'] = 'error';
420
                $return['id'] = isset($values['survey_id']) ? $values['survey_id'] : 0;
421
422
                return $return;
423
            }
424
425
            if (!isset($values['anonymous'])
426
                || (isset($values['anonymous']) && $values['anonymous'] == '')
427
            ) {
428
                $values['anonymous'] = 0;
429
            }
430
431
            $extraParams = [];
432
            $extraParams['one_question_per_page'] = isset($values['one_question_per_page']) ? $values['one_question_per_page'] : null;
433
            $extraParams['shuffle'] = isset($values['shuffle']) ? $values['shuffle'] : null;
434
435
            if ($values['anonymous'] == 0) {
436
                $extraParams['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : '';
437
                if ($extraParams['show_form_profile'] == 1) {
438
                    $fields = explode(',', $values['input_name_list']);
439
                    $field_values = '';
440
                    foreach ($fields as &$field) {
441
                        if ($field != '') {
442
                            if (!isset($values[$field]) ||
443
                                (isset($values[$field]) && $values[$field] == '')
444
                            ) {
445
                                $values[$field] = 0;
446
                            }
447
                            $field_values .= $field.':'.$values[$field].'@';
448
                        }
449
                    }
450
                    $extraParams['form_fields'] = $field_values;
451
                } else {
452
                    $extraParams['form_fields'] = '';
453
                }
454
            } else {
455
                $extraParams['show_form_profile'] = 0;
456
                $extraParams['form_fields'] = '';
457
            }
458
459
            $params = [
460
                'title' => $values['survey_title'],
461
                'subtitle' => $values['survey_subtitle'],
462
                'author' => $_user['user_id'],
463
                'lang' => $values['survey_language'],
464
                'avail_from' => $allowSurveyAvailabilityDatetime
465
                    ? api_get_utc_datetime($values['start_date'].':00')
466
                    : $values['start_date'],
467
                'avail_till' => $allowSurveyAvailabilityDatetime
468
                    ? api_get_utc_datetime($values['end_date'].':59')
469
                    : $values['end_date'],
470
                'is_shared' => $shared_survey_id,
471
                'template' => 'template',
472
                'intro' => $values['survey_introduction'],
473
                'surveythanks' => $values['survey_thanks'],
474
                'anonymous' => $values['anonymous'],
475
                'session_id' => api_get_session_id(),
476
                'visible_results' => $values['visible_results'],
477
            ];
478
479
            $params = array_merge($params, $extraParams);
480
            Database::update(
481
                $table_survey,
482
                $params,
483
                [
484
                    'c_id = ? AND survey_id = ?' => [
485
                        $course_id,
486
                        $values['survey_id'],
487
                    ],
488
                ]
489
            );
490
491
            // Update into item_property (update)
492
            api_item_property_update(
493
                api_get_course_info(),
494
                TOOL_SURVEY,
495
                $values['survey_id'],
496
                'SurveyUpdated',
497
                api_get_user_id()
498
            );
499
500
            Display::addFlash(
501
                Display::return_message(
502
                    get_lang('SurveyUpdatedSuccesfully'),
503
                    'confirmation'
504
                )
505
            );
506
507
            $return['id'] = $values['survey_id'];
508
        }
509
510
        $survey_id = (int) $return['id'];
511
512
        // Gradebook
513
        $gradebook_option = false;
514
        if (isset($values['survey_qualify_gradebook'])) {
515
            $gradebook_option = $values['survey_qualify_gradebook'] > 0;
516
        }
517
518
        $gradebook_link_type = 8;
519
        $link_info = GradebookUtils::isResourceInCourseGradebook(
520
            $courseCode,
521
            $gradebook_link_type,
522
            $survey_id,
523
            $session_id
524
        );
525
526
        $gradebook_link_id = isset($link_info['id']) ? $link_info['id'] : false;
527
528
        if ($gradebook_option) {
529
            if ($survey_id > 0) {
530
                $title_gradebook = ''; // Not needed here.
531
                $description_gradebook = ''; // Not needed here.
532
                $survey_weight = floatval($_POST['survey_weight']);
533
                $max_score = 1;
534
535
                if (!$gradebook_link_id) {
536
                    GradebookUtils::add_resource_to_course_gradebook(
537
                        $values['category_id'],
538
                        $courseCode,
539
                        $gradebook_link_type,
540
                        $survey_id,
541
                        $title_gradebook,
542
                        $survey_weight,
543
                        $max_score,
544
                        $description_gradebook,
545
                        1,
546
                        $session_id
547
                    );
548
                } else {
549
                    GradebookUtils::updateResourceFromCourseGradebook(
550
                        $gradebook_link_id,
551
                        $courseCode,
552
                        $survey_weight
553
                    );
554
                }
555
            }
556
        } else {
557
            // Delete everything of the gradebook for this $linkId
558
            GradebookUtils::remove_resource_from_course_gradebook($gradebook_link_id);
559
        }
560
561
        return $return;
562
    }
563
564
    /**
565
     * This function stores a shared survey in the central database.
566
     *
567
     * @param array $values
568
     *
569
     * @return array $return the type of return message that has to be displayed and the message in it
570
     *
571
     * @author Patrick Cool <[email protected]>, Ghent University
572
     *
573
     * @version February 2007
574
     */
575
    public function store_shared_survey($values)
576
    {
577
        $_user = api_get_user_info();
578
        $_course = api_get_course_info();
579
580
        // Table definitions
581
        $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
582
583
        if (!$values['survey_id'] ||
584
            !is_numeric($values['survey_id']) ||
585
            $values['survey_share']['survey_share'] == 'true'
586
        ) {
587
            $sql = "INSERT INTO $table_survey (code, title, subtitle, author, lang, template, intro, surveythanks, creation_date, course_code) VALUES (
588
                    '".Database::escape_string($values['survey_code'])."',
589
                    '".Database::escape_string($values['survey_title'])."',
590
                    '".Database::escape_string($values['survey_subtitle'])."',
591
                    '".intval($_user['user_id'])."',
592
                    '".Database::escape_string($values['survey_language'])."',
593
                    '".Database::escape_string('template')."',
594
                    '".Database::escape_string($values['survey_introduction'])."',
595
                    '".Database::escape_string($values['survey_thanks'])."',
596
                    '".api_get_utc_datetime()."',
597
                    '".$_course['id']."')";
598
            Database::query($sql);
599
            $return = Database::insert_id();
600
601
            $sql = "UPDATE $table_survey SET survey_id = $return WHERE iid = $return";
602
            Database::query($sql);
603
        } else {
604
            $sql = "UPDATE $table_survey SET
605
                        code 			= '".Database::escape_string($values['survey_code'])."',
606
                        title 			= '".Database::escape_string($values['survey_title'])."',
607
                        subtitle 		= '".Database::escape_string($values['survey_subtitle'])."',
608
                        author 			= '".intval($_user['user_id'])."',
609
                        lang 			= '".Database::escape_string($values['survey_language'])."',
610
                        template 		= '".Database::escape_string('template')."',
611
                        intro			= '".Database::escape_string($values['survey_introduction'])."',
612
                        surveythanks	= '".Database::escape_string($values['survey_thanks'])."'
613
					WHERE survey_id = '".Database::escape_string($values['survey_share']['survey_share'])."'";
614
            Database::query($sql);
615
            $return = $values['survey_share']['survey_share'];
616
        }
617
618
        return $return;
619
    }
620
621
    /**
622
     * This function deletes a survey (and also all the question in that survey.
623
     *
624
     * @param int  $survey_id id of the survey that has to be deleted
625
     * @param bool $shared
626
     * @param int  $course_id
627
     *
628
     * @return true
629
     *
630
     * @author Patrick Cool <[email protected]>, Ghent University
631
     *
632
     * @version January 2007
633
     */
634
    public static function delete_survey($survey_id, $shared = false, $course_id = 0)
635
    {
636
        // Database table definitions
637
        if (empty($course_id)) {
638
            $course_id = api_get_course_int_id();
639
        }
640
641
        $survey_id = (int) $survey_id;
642
643
        if (empty($survey_id)) {
644
            return false;
645
        }
646
647
        $course_info = api_get_course_info_by_id($course_id);
648
        $course_id = $course_info['real_id'];
649
650
        $table_survey = Database::get_course_table(TABLE_SURVEY);
651
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
652
653
        if ($shared) {
654
            $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
655
            // Deleting the survey
656
            $sql = "DELETE FROM $table_survey
657
                    WHERE survey_id='".$survey_id."'";
658
            Database::query($sql);
659
        } else {
660
            $sql = "DELETE FROM $table_survey
661
                    WHERE c_id = $course_id AND survey_id='".$survey_id."'";
662
            Database::query($sql);
663
        }
664
665
        // Deleting groups of this survey
666
        $sql = "DELETE FROM $table_survey_question_group
667
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
668
        Database::query($sql);
669
670
        // Deleting the questions of the survey
671
        self::delete_all_survey_questions($survey_id, $shared);
672
673
        // Update into item_property (delete)
674
        api_item_property_update(
675
            $course_info,
676
            TOOL_SURVEY,
677
            $survey_id,
678
            'SurveyDeleted',
679
            api_get_user_id()
680
        );
681
682
        Skill::deleteSkillsFromItem($survey_id, ITEM_TYPE_SURVEY);
683
684
        return true;
685
    }
686
687
    /**
688
     * @param int $survey_id
689
     * @param int $new_survey_id
690
     * @param int $targetCourseId
691
     *
692
     * @return bool
693
     */
694
    public static function copy_survey(
695
        $survey_id,
696
        $new_survey_id = null,
697
        $targetCourseId = null
698
    ) {
699
        $course_id = api_get_course_int_id();
700
        if (!$targetCourseId) {
701
            $targetCourseId = $course_id;
702
        }
703
704
        // Database table definitions
705
        $table_survey = Database::get_course_table(TABLE_SURVEY);
706
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
707
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
708
        $table_survey_options = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
709
        $survey_id = (int) $survey_id;
710
711
        // Get groups
712
        $survey_data = self::get_survey($survey_id, 0, null, true);
713
        if (empty($survey_data)) {
714
            return true;
715
        }
716
717
        if (empty($new_survey_id)) {
718
            $params = $survey_data;
719
            $params['code'] = self::generate_unique_code($params['code']);
720
            $params['c_id'] = $targetCourseId;
721
            unset($params['survey_id']);
722
            $params['session_id'] = api_get_session_id();
723
            $params['title'] = $params['title'].' '.get_lang('Copy');
724
            unset($params['iid']);
725
            $new_survey_id = Database::insert($table_survey, $params);
726
727
            if ($new_survey_id) {
728
                $sql = "UPDATE $table_survey SET survey_id = $new_survey_id
729
                        WHERE iid = $new_survey_id";
730
                Database::query($sql);
731
732
                // Insert into item_property
733
                api_item_property_update(
734
                    api_get_course_info(),
735
                    TOOL_SURVEY,
736
                    $new_survey_id,
737
                    'SurveyAdded',
738
                    api_get_user_id()
739
                );
740
            }
741
        } else {
742
            $new_survey_id = (int) $new_survey_id;
743
        }
744
745
        $sql = "SELECT * FROM $table_survey_question_group
746
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
747
        $res = Database::query($sql);
748
        while ($row = Database::fetch_array($res, 'ASSOC')) {
749
            $params = [
750
                'c_id' => $targetCourseId,
751
                'name' => $row['name'],
752
                'description' => $row['description'],
753
                'survey_id' => $new_survey_id,
754
            ];
755
            $insertId = Database::insert($table_survey_question_group, $params);
756
757
            $sql = "UPDATE $table_survey_question_group SET id = iid
758
                    WHERE iid = $insertId";
759
            Database::query($sql);
760
761
            $group_id[$row['id']] = $insertId;
762
        }
763
764
        // Get questions
765
        $sql = "SELECT * FROM $table_survey_question
766
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
767
        $res = Database::query($sql);
768
        while ($row = Database::fetch_array($res, 'ASSOC')) {
769
            $params = [
770
                'c_id' => $targetCourseId,
771
                'survey_id' => $new_survey_id,
772
                'survey_question' => $row['survey_question'],
773
                'survey_question_comment' => $row['survey_question_comment'],
774
                'type' => $row['type'],
775
                'display' => $row['display'],
776
                'sort' => $row['sort'],
777
                'shared_question_id' => $row['shared_question_id'],
778
                'max_value' => $row['max_value'],
779
                'survey_group_pri' => $row['survey_group_pri'],
780
                'survey_group_sec1' => $row['survey_group_sec1'],
781
                'survey_group_sec2' => $row['survey_group_sec2'],
782
            ];
783
784
            if (api_get_configuration_value('allow_required_survey_questions')) {
785
                if (isset($row['is_required'])) {
786
                    $params['is_required'] = $row['is_required'];
787
                }
788
            }
789
790
            $insertId = Database::insert($table_survey_question, $params);
791
            if ($insertId) {
792
                $sql = "UPDATE $table_survey_question SET question_id = iid WHERE iid = $insertId";
793
                Database::query($sql);
794
                $question_id[$row['question_id']] = $insertId;
795
            }
796
        }
797
798
        // Get questions options
799
        $sql = "SELECT * FROM $table_survey_options
800
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
801
802
        $res = Database::query($sql);
803
        while ($row = Database::fetch_array($res, 'ASSOC')) {
804
            $params = [
805
                'c_id' => $targetCourseId,
806
                'question_id' => $question_id[$row['question_id']],
807
                'survey_id' => $new_survey_id,
808
                'option_text' => $row['option_text'],
809
                'sort' => $row['sort'],
810
                'value' => $row['value'],
811
            ];
812
            $insertId = Database::insert($table_survey_options, $params);
813
            if ($insertId) {
814
                $sql = "UPDATE $table_survey_options SET question_option_id = $insertId
815
                        WHERE iid = $insertId";
816
                Database::query($sql);
817
            }
818
        }
819
820
        return $new_survey_id;
821
    }
822
823
    /**
824
     * This function duplicates a survey (and also all the question in that survey.
825
     *
826
     * @param int $surveyId id of the survey that has to be duplicated
827
     * @param int $courseId id of the course which survey has to be duplicated
828
     *
829
     * @return true
830
     *
831
     * @author Eric Marguin <[email protected]>, Elixir Interactive
832
     *
833
     * @version October 2007
834
     */
835
    public static function empty_survey($surveyId, $courseId = 0)
836
    {
837
        // Database table definitions
838
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
839
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
840
        $table_survey = Database::get_course_table(TABLE_SURVEY);
841
842
        $courseId = (int) $courseId;
843
        $courseId = empty($courseId) ? api_get_course_int_id() : $courseId;
844
        $surveyId = (int) $surveyId;
845
846
        $datas = self::get_survey($surveyId);
847
        $session_where = '';
848
        if (api_get_session_id() != 0) {
849
            $session_where = ' AND session_id = "'.api_get_session_id().'" ';
850
        }
851
852
        $sql = 'DELETE FROM '.$table_survey_invitation.'
853
		        WHERE
854
		            c_id = '.$courseId.' AND
855
		            survey_code = "'.Database::escape_string($datas['code']).'" '.$session_where.' ';
856
        Database::query($sql);
857
858
        $sql = 'DELETE FROM '.$table_survey_answer.'
859
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
860
        Database::query($sql);
861
862
        $sql = 'UPDATE '.$table_survey.' SET invited=0, answered=0
863
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
864
        Database::query($sql);
865
866
        return true;
867
    }
868
869
    /**
870
     * This function recalculates the number of people who have taken the survey (=filled at least one question).
871
     *
872
     * @param array  $survey_data
873
     * @param array  $user
874
     * @param string $survey_code
875
     *
876
     * @return bool
877
     *
878
     * @author Patrick Cool <[email protected]>, Ghent University
879
     *
880
     * @version February 2007
881
     */
882
    public static function update_survey_answered($survey_data, $user, $survey_code)
883
    {
884
        if (empty($survey_data)) {
885
            return false;
886
        }
887
888
        // Database table definitions
889
        $table_survey = Database::get_course_table(TABLE_SURVEY);
890
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
891
892
        $survey_id = (int) $survey_data['survey_id'];
893
        $course_id = (int) $survey_data['c_id'];
894
        $session_id = $survey_data['session_id'];
895
896
        // Getting a list with all the people who have filled the survey
897
        /*$people_filled = self::get_people_who_filled_survey($survey_id, false, $course_id);
898
        $number = count($people_filled);*/
899
900
        // Storing this value in the survey table
901
        $sql = "UPDATE $table_survey
902
		        SET answered = answered + 1
903
		        WHERE
904
                    c_id = $course_id AND
905
		            survey_id = ".$survey_id;
906
        Database::query($sql);
907
908
        $allow = api_get_configuration_value('survey_answered_at_field');
909
        // Requires DB change:
910
        // ALTER TABLE c_survey_invitation ADD answered_at DATETIME DEFAULT NULL;
911
        $answeredAt = '';
912
        if ($allow) {
913
            $answeredAt = "answered_at = '".api_get_utc_datetime()."',";
914
        }
915
916
        // Storing that the user has finished the survey.
917
        $sql = "UPDATE $table_survey_invitation
918
                SET $answeredAt answered = 1
919
                WHERE
920
                    c_id = $course_id AND
921
                    session_id = $session_id AND
922
                    user ='".Database::escape_string($user)."' AND
923
                    survey_code='".Database::escape_string($survey_code)."'";
924
        Database::query($sql);
925
    }
926
927
    /**
928
     * This function return the "icon" of the question type.
929
     *
930
     * @param string $type
931
     *
932
     * @author Patrick Cool <[email protected]>, Ghent University
933
     *
934
     * @version February 2007
935
     */
936
    public static function icon_question($type)
937
    {
938
        // the possible question types
939
        $possible_types = [
940
            'personality',
941
            'yesno',
942
            'multiplechoice',
943
            'multipleresponse',
944
            'open',
945
            'dropdown',
946
            'comment',
947
            'pagebreak',
948
            'percentage',
949
            'score',
950
        ];
951
952
        // the images array
953
        $icon_question = [
954
            'yesno' => 'yesno.png',
955
            'personality' => 'yesno.png',
956
            'multiplechoice' => 'mcua.png',
957
            'multipleresponse' => 'mcma.png',
958
            'open' => 'open_answer.png',
959
            'dropdown' => 'dropdown.png',
960
            'percentage' => 'percentagequestion.png',
961
            'score' => 'scorequestion.png',
962
            'comment' => 'commentquestion.png',
963
            'pagebreak' => 'page_end.png',
964
        ];
965
966
        if (in_array($type, $possible_types)) {
967
            return $icon_question[$type];
968
        } else {
969
            return false;
970
        }
971
    }
972
973
    /**
974
     * This function retrieves all the information of a question.
975
     *
976
     * @param int  $question_id the id of the question
977
     * @param bool $shared
978
     *
979
     * @return array
980
     *
981
     * @author Patrick Cool <[email protected]>, Ghent University
982
     *
983
     * @version January 2007
984
     *
985
     * @todo one sql call should do the trick
986
     */
987
    public static function get_question($question_id, $shared = false)
988
    {
989
        // Table definitions
990
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
991
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
992
        $course_id = api_get_course_int_id();
993
        $question_id = (int) $question_id;
994
995
        $sql = "SELECT * FROM $tbl_survey_question
996
                WHERE c_id = $course_id AND question_id='".$question_id."'
997
                ORDER BY `sort` ";
998
999
        $sqlOption = "  SELECT * FROM $table_survey_question_option
1000
                        WHERE c_id = $course_id AND question_id='".$question_id."'
1001
                        ORDER BY `sort` ";
1002
1003
        if ($shared) {
1004
            $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1005
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1006
1007
            $sql = "SELECT * FROM $tbl_survey_question
1008
                    WHERE question_id='".$question_id."'
1009
                    ORDER BY `sort` ";
1010
            $sqlOption = "SELECT * FROM $table_survey_question_option
1011
                          WHERE question_id='".$question_id."'
1012
                          ORDER BY `sort` ";
1013
        }
1014
1015
        // Getting the information of the question
1016
1017
        $result = Database::query($sql);
1018
        $row = Database::fetch_array($result, 'ASSOC');
1019
1020
        $return['survey_id'] = $row['survey_id'];
1021
        $return['question_id'] = $row['question_id'];
1022
        $return['type'] = $row['type'];
1023
        $return['question'] = $row['survey_question'];
1024
        $return['horizontalvertical'] = $row['display'];
1025
        $return['shared_question_id'] = $row['shared_question_id'];
1026
        $return['maximum_score'] = $row['max_value'];
1027
        $return['is_required'] = api_get_configuration_value('allow_required_survey_questions')
1028
            ? $row['is_required']
1029
            : false;
1030
1031
        if ($row['survey_group_pri'] != 0) {
1032
            $return['assigned'] = $row['survey_group_pri'];
1033
            $return['choose'] = 1;
1034
        } else {
1035
            $return['assigned1'] = $row['survey_group_sec1'];
1036
            $return['assigned2'] = $row['survey_group_sec2'];
1037
            $return['choose'] = 2;
1038
        }
1039
1040
        // Getting the information of the question options
1041
        $result = Database::query($sqlOption);
1042
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1043
            /** @todo this should be renamed to options instead of answers */
1044
            $return['answers'][] = $row['option_text'];
1045
            $return['values'][] = $row['value'];
1046
1047
            /** @todo this can be done more elegantly (used in reporting) */
1048
            $return['answersid'][] = $row['question_option_id'];
1049
        }
1050
1051
        return $return;
1052
    }
1053
1054
    /**
1055
     * This function gets all the question of any given survey.
1056
     *
1057
     * @param int $surveyId the id of the survey
1058
     * @param int $courseId
1059
     *
1060
     * @return array containing all the questions of the survey
1061
     *
1062
     * @author Patrick Cool <[email protected]>, Ghent University
1063
     *
1064
     * @version February 2007
1065
     *
1066
     * @todo one sql call should do the trick
1067
     */
1068
    public static function get_questions($surveyId, $courseId = 0)
1069
    {
1070
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1071
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1072
1073
        $courseId = (int) $courseId;
1074
        $surveyId = (int) $surveyId;
1075
1076
        if (empty($courseId)) {
1077
            $courseId = api_get_course_int_id();
1078
        }
1079
1080
        // Getting the information of the question
1081
        $sql = "SELECT * FROM $tbl_survey_question
1082
		        WHERE c_id = $courseId AND survey_id='".$surveyId."'";
1083
        $result = Database::query($sql);
1084
        $return = [];
1085
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1086
            $return[$row['question_id']]['survey_id'] = $row['survey_id'];
1087
            $return[$row['question_id']]['question_id'] = $row['question_id'];
1088
            $return[$row['question_id']]['type'] = $row['type'];
1089
            $return[$row['question_id']]['question'] = $row['survey_question'];
1090
            $return[$row['question_id']]['horizontalvertical'] = $row['display'];
1091
            $return[$row['question_id']]['maximum_score'] = $row['max_value'];
1092
            $return[$row['question_id']]['sort'] = $row['sort'];
1093
            $return[$row['question_id']]['survey_question_comment'] = $row['survey_question_comment'];
1094
        }
1095
1096
        // Getting the information of the question options
1097
        $sql = "SELECT * FROM $table_survey_question_option
1098
		        WHERE c_id = $courseId AND survey_id='".$surveyId."'";
1099
        $result = Database::query($sql);
1100
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1101
            $return[$row['question_id']]['answers'][] = $row['option_text'];
1102
        }
1103
1104
        return $return;
1105
    }
1106
1107
    /**
1108
     * This function saves a question in the database.
1109
     * This can be either an update of an existing survey or storing a new survey.
1110
     *
1111
     * @param array $survey_data
1112
     * @param array $form_content all the information of the form
1113
     *
1114
     * @return string
1115
     *
1116
     * @author Patrick Cool <[email protected]>, Ghent University
1117
     *
1118
     * @version January 2007
1119
     */
1120
    public static function save_question($survey_data, $form_content)
1121
    {
1122
        $return_message = '';
1123
        if (strlen($form_content['question']) > 1) {
1124
            // Checks length of the question
1125
            $empty_answer = false;
1126
1127
            if ($survey_data['survey_type'] == 1) {
1128
                if (empty($form_content['choose'])) {
1129
                    $return_message = 'PleaseChooseACondition';
1130
1131
                    return $return_message;
1132
                }
1133
1134
                if (($form_content['choose'] == 2) &&
1135
                    ($form_content['assigned1'] == $form_content['assigned2'])
1136
                ) {
1137
                    $return_message = 'ChooseDifferentCategories';
1138
1139
                    return $return_message;
1140
                }
1141
            }
1142
1143
            if ($form_content['type'] != 'percentage') {
1144
                if (isset($form_content['answers'])) {
1145
                    for ($i = 0; $i < count($form_content['answers']); $i++) {
1146
                        if (strlen($form_content['answers'][$i]) < 1) {
1147
                            $empty_answer = true;
1148
                            break;
1149
                        }
1150
                    }
1151
                }
1152
            }
1153
1154
            if ($form_content['type'] == 'score') {
1155
                if (strlen($form_content['maximum_score']) < 1) {
1156
                    $empty_answer = true;
1157
                }
1158
            }
1159
            $course_id = api_get_course_int_id();
1160
            if (!$empty_answer) {
1161
                // Table definitions
1162
                $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1163
1164
                // Getting all the information of the survey
1165
                $survey_data = self::get_survey($form_content['survey_id']);
1166
1167
                // Storing the question in the shared database
1168
                if (is_numeric($survey_data['survey_share']) && $survey_data['survey_share'] != 0) {
1169
                    $shared_question_id = self::save_shared_question($form_content, $survey_data);
1170
                    $form_content['shared_question_id'] = $shared_question_id;
1171
                }
1172
1173
                // Storing a new question
1174
                if ($form_content['question_id'] == '' || !is_numeric($form_content['question_id'])) {
1175
                    // Finding the max sort order of the questions in the given survey
1176
                    $sql = "SELECT max(sort) AS max_sort
1177
					        FROM $tbl_survey_question
1178
                            WHERE c_id = $course_id AND survey_id='".intval($form_content['survey_id'])."'";
1179
                    $result = Database::query($sql);
1180
                    $row = Database::fetch_array($result, 'ASSOC');
1181
                    $max_sort = $row['max_sort'];
1182
1183
                    $question = new CSurveyQuestion();
1184
1185
                    // Some variables defined for survey-test type
1186
                    $extraParams = [];
1187
                    if (isset($_POST['choose'])) {
1188
                        if ($_POST['choose'] == 1) {
1189
                            $question->setSurveyGroupPri($_POST['assigned']);
1190
                        } elseif ($_POST['choose'] == 2) {
1191
                            $question->setSurveyGroupSec1($_POST['assigned1']);
1192
                            $question->setSurveyGroupSec2($_POST['assigned2']);
1193
                        }
1194
                    }
1195
1196
                    $question
1197
                        ->setSurveyQuestionComment($form_content['question_comment'] ?? '')
1198
                        ->setMaxValue($form_content['maximum_score'] ?? 0)
1199
                        ->setDisplay($form_content['horizontalvertical'] ?? '')
1200
                        ->setCId($course_id)
1201
                        ->setSurveyId($form_content['survey_id'])
1202
                        ->setSurveyQuestion($form_content['question'])
1203
                        ->setType($form_content['type'])
1204
                        ->setSort($max_sort + 1)
1205
                        ->setSharedQuestionId($form_content['shared_question_id'])
1206
                    ;
1207
1208
                    if (api_get_configuration_value('allow_required_survey_questions')) {
1209
                        $question->setIsMandatory(isset($form_content['is_required']));
1210
                    }
1211
1212
                    $em = Database::getManager();
1213
                    $em->persist($question);
1214
                    $em->flush();
1215
1216
                    $question_id = $question->getIid();
1217
                    if ($question_id) {
1218
                        $sql = "UPDATE $tbl_survey_question SET question_id = $question_id
1219
                                WHERE iid = $question_id";
1220
                        Database::query($sql);
1221
1222
                        $form_content['question_id'] = $question_id;
1223
                        $return_message = 'QuestionAdded';
1224
                    }
1225
                } else {
1226
                    // Updating an existing question
1227
                    $extraParams = [];
1228
                    if (isset($_POST['choose'])) {
1229
                        if ($_POST['choose'] == 1) {
1230
                            $extraParams['survey_group_pri'] = $_POST['assigned'];
1231
                            $extraParams['survey_group_sec1'] = 0;
1232
                            $extraParams['survey_group_sec2'] = 0;
1233
                        } elseif ($_POST['choose'] == 2) {
1234
                            $extraParams['survey_group_pri'] = 0;
1235
                            $extraParams['survey_group_sec1'] = $_POST['assigned1'];
1236
                            $extraParams['survey_group_sec2'] = $_POST['assigned2'];
1237
                        }
1238
                    }
1239
1240
                    $maxScore = isset($form_content['maximum_score']) ? $form_content['maximum_score'] : null;
1241
                    $questionComment = isset($form_content['question_comment'])
1242
                        ? $form_content['question_comment']
1243
                        : null;
1244
1245
                    // Adding the question to the survey_question table
1246
                    $params = [
1247
                        'survey_question' => $form_content['question'],
1248
                        'survey_question_comment' => $questionComment,
1249
                        'display' => $form_content['horizontalvertical'],
1250
                    ];
1251
1252
                    if (api_get_configuration_value('allow_required_survey_questions')) {
1253
                        $params['is_required'] = isset($form_content['is_required']);
1254
                    }
1255
1256
                    $params = array_merge($params, $extraParams);
1257
                    Database::update(
1258
                        $tbl_survey_question,
1259
                        $params,
1260
                        [
1261
                            'c_id = ? AND question_id = ?' => [
1262
                                $course_id,
1263
                                $form_content['question_id'],
1264
                            ],
1265
                        ]
1266
                    );
1267
                    $return_message = 'QuestionUpdated';
1268
                }
1269
1270
                if (!empty($form_content['survey_id'])) {
1271
                    //Updating survey
1272
                    api_item_property_update(
1273
                        api_get_course_info(),
1274
                        TOOL_SURVEY,
1275
                        $form_content['survey_id'],
1276
                        'SurveyUpdated',
1277
                        api_get_user_id()
1278
                    );
1279
                }
1280
1281
                // Storing the options of the question
1282
                self::save_question_options($form_content, $survey_data);
1283
            } else {
1284
                $return_message = 'PleasFillAllAnswer';
1285
            }
1286
        } else {
1287
            $return_message = 'PleaseEnterAQuestion';
1288
        }
1289
1290
        if (!empty($return_message)) {
1291
            Display::addFlash(Display::return_message(get_lang($return_message)));
1292
        }
1293
1294
        return $return_message;
1295
    }
1296
1297
    /**
1298
     * This function saves the question in the shared database.
1299
     *
1300
     * @param array $form_content all the information of the form
1301
     * @param array $survey_data  all the information of the survey
1302
     *
1303
     * @author Patrick Cool <[email protected]>, Ghent University
1304
     *
1305
     * @version February 2007
1306
     *
1307
     * @return int
1308
     *
1309
     * @todo editing of a shared question
1310
     */
1311
    public function save_shared_question($form_content, $survey_data)
1312
    {
1313
        $_course = api_get_course_info();
1314
1315
        // Table definitions
1316
        $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1317
1318
        // Storing a new question
1319
        if ($form_content['shared_question_id'] == '' ||
1320
            !is_numeric($form_content['shared_question_id'])
1321
        ) {
1322
            // Finding the max sort order of the questions in the given survey
1323
            $sql = "SELECT max(sort) AS max_sort FROM $tbl_survey_question
1324
                    WHERE survey_id='".intval($survey_data['survey_share'])."'
1325
                    AND code='".Database::escape_string($_course['id'])."'";
1326
            $result = Database::query($sql);
1327
            $row = Database::fetch_array($result, 'ASSOC');
1328
            $max_sort = $row['max_sort'];
1329
1330
            // Adding the question to the survey_question table
1331
            $sql = "INSERT INTO $tbl_survey_question (survey_id, survey_question, survey_question_comment, type, display, sort, code) VALUES (
1332
                    '".Database::escape_string($survey_data['survey_share'])."',
1333
                    '".Database::escape_string($form_content['question'])."',
1334
                    '".Database::escape_string($form_content['question_comment'])."',
1335
                    '".Database::escape_string($form_content['type'])."',
1336
                    '".Database::escape_string($form_content['horizontalvertical'])."',
1337
                    '".Database::escape_string($max_sort + 1)."',
1338
                    '".Database::escape_string($_course['id'])."')";
1339
            Database::query($sql);
1340
            $shared_question_id = Database::insert_id();
1341
        } else {
1342
            // Updating an existing question
1343
            // adding the question to the survey_question table
1344
            $sql = "UPDATE $tbl_survey_question SET
1345
                        survey_question = '".Database::escape_string($form_content['question'])."',
1346
                        survey_question_comment = '".Database::escape_string($form_content['question_comment'])."',
1347
                        display = '".Database::escape_string($form_content['horizontalvertical'])."'
1348
                    WHERE
1349
                        question_id = '".intval($form_content['shared_question_id'])."' AND
1350
                        code = '".Database::escape_string($_course['id'])."'";
1351
            Database::query($sql);
1352
            $shared_question_id = $form_content['shared_question_id'];
1353
        }
1354
1355
        return $shared_question_id;
1356
    }
1357
1358
    /**
1359
     * This functions moves a question of a survey up or down.
1360
     *
1361
     * @param string $direction
1362
     * @param int    $survey_question_id
1363
     * @param int    $survey_id
1364
     *
1365
     * @author Patrick Cool <[email protected]>, Ghent University
1366
     *
1367
     * @version January 2007
1368
     */
1369
    public static function move_survey_question(
1370
        $direction,
1371
        $survey_question_id,
1372
        $survey_id
1373
    ) {
1374
        // Table definition
1375
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1376
        $course_id = api_get_course_int_id();
1377
1378
        if ($direction == 'moveup') {
1379
            $sort = 'DESC';
1380
        }
1381
        if ($direction == 'movedown') {
1382
            $sort = 'ASC';
1383
        }
1384
1385
        $survey_id = (int) $survey_id;
1386
1387
        // Finding the two questions that needs to be swapped
1388
        $sql = "SELECT * FROM $table_survey_question
1389
		        WHERE c_id = $course_id AND survey_id='".$survey_id."'
1390
		        ORDER BY sort $sort";
1391
        $result = Database::query($sql);
1392
        $found = false;
1393
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1394
            if ($found) {
1395
                $question_id_two = $row['question_id'];
1396
                $question_sort_two = $row['sort'];
1397
                $found = false;
1398
            }
1399
            if ($row['question_id'] == $survey_question_id) {
1400
                $found = true;
1401
                $question_id_one = $row['question_id'];
1402
                $question_sort_one = $row['sort'];
1403
            }
1404
        }
1405
1406
        $sql = "UPDATE $table_survey_question 
1407
                SET sort = '".Database::escape_string($question_sort_two)."'
1408
		        WHERE c_id = $course_id AND question_id='".intval($question_id_one)."'";
1409
        Database::query($sql);
1410
1411
        $sql = "UPDATE $table_survey_question 
1412
                SET sort = '".Database::escape_string($question_sort_one)."'
1413
		        WHERE c_id = $course_id AND question_id='".intval($question_id_two)."'";
1414
        Database::query($sql);
1415
    }
1416
1417
    /**
1418
     * This function deletes all the questions of a given survey
1419
     * This function is normally only called when a survey is deleted.
1420
     *
1421
     * @param int $survey_id the id of the survey that has to be deleted
1422
     *
1423
     * @return bool
1424
     *
1425
     * @author Patrick Cool <[email protected]>, Ghent University
1426
     *
1427
     * @version January 2007
1428
     */
1429
    public static function delete_all_survey_questions($survey_id, $shared = false)
1430
    {
1431
        $course_id = api_get_course_int_id();
1432
        $survey_id = (int) $survey_id;
1433
1434
        // Table definitions
1435
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1436
        $course_condition = " c_id = $course_id AND ";
1437
        if ($shared) {
1438
            $course_condition = '';
1439
            $table_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1440
        }
1441
1442
        $sql = "DELETE FROM $table_survey_question
1443
		        WHERE $course_condition survey_id = '".$survey_id."'";
1444
1445
        // Deleting the survey questions
1446
        Database::query($sql);
1447
1448
        // Deleting all the options of the questions of the survey
1449
        self::delete_all_survey_questions_options($survey_id, $shared);
1450
1451
        // Deleting all the answers on this survey
1452
        self::delete_all_survey_answers($survey_id);
1453
1454
        return true;
1455
    }
1456
1457
    /**
1458
     * This function deletes a survey question and all its options.
1459
     *
1460
     * @param int  $survey_id   the id of the survey
1461
     * @param int  $question_id the id of the question
1462
     * @param bool $shared
1463
     *
1464
     * @todo also delete the answers to this question
1465
     *
1466
     * @author Patrick Cool <[email protected]>, Ghent University
1467
     *
1468
     * @version March 2007
1469
     */
1470
    public static function delete_survey_question($survey_id, $question_id, $shared = false)
1471
    {
1472
        $survey_id = (int) $survey_id;
1473
        $question_id = (int) $question_id;
1474
        $course_id = api_get_course_int_id();
1475
1476
        if ($shared) {
1477
            self::delete_shared_survey_question($survey_id, $question_id);
1478
        }
1479
1480
        // Table definitions
1481
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
1482
        // Deleting the survey questions
1483
        $sql = "DELETE FROM $table
1484
		        WHERE
1485
		            c_id = $course_id AND
1486
		            survey_id='".$survey_id."' AND
1487
		            question_id='".$question_id."'";
1488
        Database::query($sql);
1489
1490
        // Deleting the options of the question of the survey
1491
        self::delete_survey_question_option($survey_id, $question_id, $shared);
1492
    }
1493
1494
    /**
1495
     * This function deletes a shared survey question from the main database and all its options.
1496
     *
1497
     * @param int $question_id the id of the question
1498
     *
1499
     * @todo delete all the options of this question
1500
     *
1501
     * @author Patrick Cool <[email protected]>, Ghent University
1502
     *
1503
     * @version March 2007
1504
     */
1505
    public static function delete_shared_survey_question($survey_id, $question_id)
1506
    {
1507
        // Table definitions
1508
        $table_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1509
        $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1510
1511
        // First we have to get the shared_question_id
1512
        $question_data = self::get_question($question_id);
1513
1514
        // Deleting the survey questions
1515
        $sql = "DELETE FROM $table_survey_question
1516
		        WHERE question_id='".intval($question_data['shared_question_id'])."'";
1517
        Database::query($sql);
1518
1519
        // Deleting the options of the question of the survey question
1520
        $sql = "DELETE FROM $table_survey_question_option
1521
		        WHERE question_id='".intval($question_data['shared_question_id'])."'";
1522
        Database::query($sql);
1523
    }
1524
1525
    /**
1526
     * This function stores the options of the questions in the table.
1527
     *
1528
     * @param array $form_content
1529
     *
1530
     * @author Patrick Cool <[email protected]>, Ghent University
1531
     *
1532
     * @version January 2007
1533
     *
1534
     * @todo writing the update statement when editing a question
1535
     */
1536
    public static function save_question_options($form_content, $survey_data)
1537
    {
1538
        $course_id = api_get_course_int_id();
1539
        // A percentage question type has options 1 -> 100
1540
        if ($form_content['type'] === 'percentage') {
1541
            for ($i = 1; $i < 101; $i++) {
1542
                $form_content['answers'][] = $i;
1543
            }
1544
        }
1545
1546
        if (is_numeric($survey_data['survey_share']) && $survey_data['survey_share'] != 0) {
1547
            self::save_shared_question_options($form_content, $survey_data);
1548
        }
1549
1550
        // Table definition
1551
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1552
1553
        // We are editing a question so we first have to remove all the existing options from the database
1554
        if (is_numeric($form_content['question_id'])) {
1555
            $sql = "DELETE FROM $table_survey_question_option
1556
			        WHERE c_id = $course_id AND question_id = '".intval($form_content['question_id'])."'";
1557
            Database::query($sql);
1558
        }
1559
1560
        $counter = 1;
1561
        $em = Database::getManager();
1562
        if (isset($form_content['answers']) && is_array($form_content['answers'])) {
1563
            for ($i = 0; $i < count($form_content['answers']); $i++) {
1564
                $values = isset($form_content['values']) ? $form_content['values'][$i] : 0;
1565
                $option = new CSurveyQuestionOption();
1566
                $option
1567
                    ->setCId($course_id)
1568
                    ->setQuestionId($form_content['question_id'])
1569
                    ->setSurveyId($form_content['survey_id'])
1570
                    ->setOptionText($form_content['answers'][$i])
1571
                    ->setValue($values)
1572
                    ->setSort($counter)
1573
                ;
1574
1575
                $em->persist($option);
1576
                $em->flush();
1577
1578
                $insertId = $option->getIid();
1579
                if ($insertId) {
1580
                    $sql = "UPDATE $table_survey_question_option
1581
                            SET question_option_id = $insertId
1582
                            WHERE iid = $insertId";
1583
                    Database::query($sql);
1584
1585
                    $counter++;
1586
                }
1587
            }
1588
        }
1589
    }
1590
1591
    /**
1592
     * This function stores the options of the questions in the shared table.
1593
     *
1594
     * @param array $form_content
1595
     *
1596
     * @author Patrick Cool <[email protected]>, Ghent University
1597
     *
1598
     * @version February 2007
1599
     *
1600
     * @todo writing the update statement when editing a question
1601
     */
1602
    public function save_shared_question_options($form_content, $survey_data)
1603
    {
1604
        if (is_array($form_content) && is_array($form_content['answers'])) {
1605
            // Table definition
1606
            $table = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1607
1608
            // We are editing a question so we first have to remove all the existing options from the database
1609
            $sql = "DELETE FROM $table
1610
                    WHERE question_id = '".Database::escape_string($form_content['shared_question_id'])."'";
1611
            Database::query($sql);
1612
1613
            $counter = 1;
1614
            foreach ($form_content['answers'] as &$answer) {
1615
                $params = [
1616
                    'question_id' => $form_content['shared_question_id'],
1617
                    'survey_id' => $survey_data['is_shared'],
1618
                    'option_text' => $answer,
1619
                    'sort' => $counter,
1620
                ];
1621
                Database::insert($table, $params);
1622
1623
                $counter++;
1624
            }
1625
        }
1626
    }
1627
1628
    /**
1629
     * This function deletes all the options of the questions of a given survey
1630
     * This function is normally only called when a survey is deleted.
1631
     *
1632
     * @param int $survey_id the id of the survey that has to be deleted
1633
     *
1634
     * @return true
1635
     *
1636
     * @author Patrick Cool <[email protected]>, Ghent University
1637
     *
1638
     * @version January 2007
1639
     */
1640
    public static function delete_all_survey_questions_options($survey_id, $shared = false)
1641
    {
1642
        // Table definitions
1643
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1644
        $course_id = api_get_course_int_id();
1645
        $course_condition = " c_id = $course_id AND ";
1646
        if ($shared) {
1647
            $course_condition = '';
1648
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1649
        }
1650
1651
        $sql = "DELETE FROM $table_survey_question_option
1652
                WHERE $course_condition survey_id='".intval($survey_id)."'";
1653
1654
        // Deleting the options of the survey questions
1655
        Database::query($sql);
1656
1657
        return true;
1658
    }
1659
1660
    /**
1661
     * This function deletes the options of a given question.
1662
     *
1663
     * @param int  $survey_id
1664
     * @param int  $question_id
1665
     * @param bool $shared
1666
     *
1667
     * @return bool
1668
     *
1669
     * @author Patrick Cool <[email protected]>, Ghent University
1670
     * @author Julio Montoya
1671
     *
1672
     * @version March 2007
1673
     */
1674
    public static function delete_survey_question_option(
1675
        $survey_id,
1676
        $question_id,
1677
        $shared = false
1678
    ) {
1679
        $course_id = api_get_course_int_id();
1680
        $course_condition = " c_id = $course_id AND ";
1681
1682
        // Table definitions
1683
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1684
        if ($shared) {
1685
            $course_condition = '';
1686
            $table = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1687
        }
1688
1689
        // Deleting the options of the survey questions
1690
        $sql = "DELETE FROM $table
1691
		        WHERE
1692
		            $course_condition survey_id='".intval($survey_id)."' AND
1693
		            question_id='".intval($question_id)."'";
1694
        Database::query($sql);
1695
1696
        return true;
1697
    }
1698
1699
    /**
1700
     * SURVEY ANSWERS FUNCTIONS.
1701
     */
1702
1703
    /**
1704
     * This function deletes all the answers anyone has given on this survey
1705
     * This function is normally only called when a survey is deleted.
1706
     *
1707
     * @param $survey_id the id of the survey that has to be deleted
1708
     *
1709
     * @return true
1710
     *
1711
     * @todo write the function
1712
     *
1713
     * @author Patrick Cool <[email protected]>, Ghent University
1714
     *
1715
     * @version January 2007,december 2008
1716
     */
1717
    public static function delete_all_survey_answers($survey_id)
1718
    {
1719
        $course_id = api_get_course_int_id();
1720
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
1721
        $survey_id = (int) $survey_id;
1722
        $sql = "DELETE FROM $table 
1723
                WHERE c_id = $course_id AND survey_id = $survey_id";
1724
        Database::query($sql);
1725
1726
        return true;
1727
    }
1728
1729
    /**
1730
     * @param int $user_id
1731
     * @param int $survey_id
1732
     * @param int $course_id
1733
     *
1734
     * @return bool
1735
     */
1736
    public static function is_user_filled_survey($user_id, $survey_id, $course_id)
1737
    {
1738
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
1739
        $user_id = (int) $user_id;
1740
        $course_id = (int) $course_id;
1741
        $survey_id = (int) $survey_id;
1742
1743
        $sql = "SELECT DISTINCT user 
1744
                FROM $table
1745
                WHERE
1746
                    c_id		= $course_id AND
1747
                    user		= $user_id AND
1748
                    survey_id	= $survey_id";
1749
        $result = Database::query($sql);
1750
        if (Database::num_rows($result)) {
1751
            return true;
1752
        }
1753
1754
        return false;
1755
    }
1756
1757
    /**
1758
     * This function gets all the persons who have filled the survey.
1759
     *
1760
     * @param int $survey_id
1761
     *
1762
     * @return array
1763
     *
1764
     * @author Patrick Cool <[email protected]>, Ghent University
1765
     *
1766
     * @version February 2007
1767
     */
1768
    public static function get_people_who_filled_survey(
1769
        $survey_id,
1770
        $all_user_info = false,
1771
        $course_id = null
1772
    ) {
1773
        // Database table definition
1774
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1775
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1776
1777
        // Variable initialisation
1778
        $return = [];
1779
1780
        if (empty($course_id)) {
1781
            $course_id = api_get_course_int_id();
1782
        } else {
1783
            $course_id = (int) $course_id;
1784
        }
1785
1786
        $survey_id = (int) $survey_id;
1787
1788
        if ($all_user_info) {
1789
            $order_clause = api_sort_by_first_name()
1790
                ? ' ORDER BY user.firstname, user.lastname'
1791
                : ' ORDER BY user.lastname, user.firstname';
1792
            $sql = "SELECT DISTINCT
1793
			            answered_user.user as invited_user, 
1794
			            user.firstname, 
1795
			            user.lastname, 
1796
			            user.user_id
1797
                    FROM $table_survey_answer answered_user
1798
                    LEFT JOIN $table_user as user ON answered_user.user = user.user_id
1799
                    WHERE
1800
                        answered_user.c_id = $course_id AND
1801
                        survey_id= '".$survey_id."' ".
1802
                $order_clause;
1803
        } else {
1804
            $sql = "SELECT DISTINCT user FROM $table_survey_answer
1805
			        WHERE c_id = $course_id AND survey_id= '".$survey_id."'  ";
1806
1807
            if (api_get_configuration_value('survey_anonymous_show_answered')) {
1808
                $tblInvitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
1809
                $tblSurvey = Database::get_course_table(TABLE_SURVEY);
1810
1811
                $sql = "SELECT i.user FROM $tblInvitation i
1812
                    INNER JOIN $tblSurvey s 
1813
                    ON i.survey_code = s.code
1814
                        AND i.c_id = s.c_id
1815
                        AND i.session_id = s.session_id
1816
                    WHERE i.answered IS TRUE AND s.iid = $survey_id";
1817
            }
1818
        }
1819
1820
        $res = Database::query($sql);
1821
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1822
            if ($all_user_info) {
1823
                $userInfo = api_get_user_info($row['user_id']);
1824
                $row['user_info'] = $userInfo;
1825
                $return[] = $row;
1826
            } else {
1827
                $return[] = $row['user'];
1828
            }
1829
        }
1830
1831
        return $return;
1832
    }
1833
1834
    /**
1835
     * @return bool
1836
     */
1837
    public static function survey_generation_hash_available()
1838
    {
1839
        if (extension_loaded('mcrypt')) {
1840
            return true;
1841
        }
1842
1843
        return false;
1844
    }
1845
1846
    /**
1847
     * @param int $survey_id
1848
     * @param int $course_id
1849
     * @param int $session_id
1850
     * @param int $group_id
1851
     *
1852
     * @return string
1853
     */
1854
    public static function generate_survey_hash($survey_id, $course_id, $session_id, $group_id)
1855
    {
1856
        $hash = hash('sha512', api_get_security_key().'_'.$course_id.'_'.$session_id.'_'.$group_id.'_'.$survey_id);
1857
1858
        return $hash;
1859
    }
1860
1861
    /**
1862
     * @param int    $survey_id
1863
     * @param int    $course_id
1864
     * @param int    $session_id
1865
     * @param int    $group_id
1866
     * @param string $hash
1867
     *
1868
     * @return bool
1869
     */
1870
    public static function validate_survey_hash($survey_id, $course_id, $session_id, $group_id, $hash)
1871
    {
1872
        $generatedHash = self::generate_survey_hash($survey_id, $course_id, $session_id, $group_id);
1873
        if ($generatedHash == $hash) {
1874
            return true;
1875
        }
1876
1877
        return false;
1878
    }
1879
1880
    /**
1881
     * @param int $survey_id
1882
     * @param int $course_id
1883
     * @param int $session_id
1884
     * @param int $group_id
1885
     *
1886
     * @return string
1887
     */
1888
    public static function generate_survey_link(
1889
        $survey_id,
1890
        $course_id,
1891
        $session_id,
1892
        $group_id
1893
    ) {
1894
        $code = self::generate_survey_hash(
1895
            $survey_id,
1896
            $course_id,
1897
            $session_id,
1898
            $group_id
1899
        );
1900
1901
        return api_get_path(WEB_CODE_PATH).'survey/link.php?h='.$code.'&i='.$survey_id.'&c='.intval($course_id).'&s='
1902
            .intval($session_id).'&g='.$group_id;
1903
    }
1904
1905
    /**
1906
     * Check if the current user has mandatory surveys no-answered
1907
     * and redirect to fill the first found survey.
1908
     */
1909
    public static function protectByMandatory()
1910
    {
1911
        if (strpos($_SERVER['SCRIPT_NAME'], 'fillsurvey.php') !== false) {
1912
            return;
1913
        }
1914
1915
        $userId = api_get_user_id();
1916
        $courseId = api_get_course_int_id();
1917
        $sessionId = api_get_session_id();
1918
1919
        if (!$userId) {
1920
            return;
1921
        }
1922
1923
        if (!$courseId) {
1924
            return;
1925
        }
1926
1927
        try {
1928
            /** @var CSurveyInvitation $invitation */
1929
            $invitation = Database::getManager()
1930
                ->createQuery("
1931
                    SELECT i FROM ChamiloCourseBundle:CSurveyInvitation i
1932
                    INNER JOIN ChamiloCourseBundle:CSurvey s
1933
                        WITH (s.code = i.surveyCode AND s.cId = i.cId AND s.sessionId = i.sessionId)
1934
                    INNER JOIN ChamiloCoreBundle:ExtraFieldValues efv WITH efv.itemId = s.iid
1935
                    INNER JOIN ChamiloCoreBundle:ExtraField ef WITH efv.field = ef.id
1936
                    WHERE 
1937
                        i.answered = 0 AND 
1938
                        i.cId = :course AND 
1939
                        i.user = :user AND 
1940
                        i.sessionId = :session AND 
1941
                        :now BETWEEN s.availFrom AND s.availTill AND 
1942
                        ef.variable = :variable AND 
1943
                        efv.value = 1 AND 
1944
                        s.surveyType != 3
1945
                    ORDER BY s.availTill ASC
1946
                ")
1947
                ->setMaxResults(1)
1948
                ->setParameters([
1949
                    'course' => $courseId,
1950
                    'user' => $userId,
1951
                    'session' => $sessionId,
1952
                    'now' => new DateTime('UTC', new DateTimeZone('UTC')),
1953
                    'variable' => 'is_mandatory',
1954
                ])
1955
                ->getSingleResult();
1956
        } catch (Exception $e) {
1957
            $invitation = null;
1958
        }
1959
1960
        if (!$invitation) {
1961
            return;
1962
        }
1963
1964
        Display::addFlash(
1965
            Display::return_message(get_lang('MandatorySurveyNoAnswered'), 'warning')
1966
        );
1967
1968
        $url = SurveyUtil::generateFillSurveyLink(
1969
            $invitation->getInvitationCode(),
1970
            api_get_course_info(),
1971
            api_get_session_id()
1972
        );
1973
1974
        header('Location: '.$url);
1975
        exit;
1976
    }
1977
1978
    /**
1979
     * This function empty surveys (invitations and answers).
1980
     *
1981
     * @param int $surveyId id of the survey to empty
1982
     *
1983
     * @return bool
1984
     */
1985
    public static function emptySurveyFromId($surveyId)
1986
    {
1987
        // Database table definitions
1988
        $surveyInvitationTable = Database:: get_course_table(TABLE_SURVEY_INVITATION);
1989
        $surveyAnswerTable = Database:: get_course_table(TABLE_SURVEY_ANSWER);
1990
        $surveyTable = Database:: get_course_table(TABLE_SURVEY);
1991
        $surveyId = (int) $surveyId;
1992
        $surveyData = self::get_survey($surveyId);
1993
        if (empty($surveyData)) {
1994
            return false;
1995
        }
1996
1997
        $surveyCode = $surveyData['survey_code'];
1998
        $courseId = (int) $surveyData['c_id'];
1999
        $sessionId = (int) $surveyData['session_id'];
2000
2001
        $sql = "DELETE FROM $surveyInvitationTable 
2002
                WHERE session_id = $sessionId AND c_id = $courseId AND survey_code = '$surveyCode' ";
2003
        Database::query($sql);
2004
2005
        $sql = "DELETE FROM $surveyAnswerTable 
2006
               WHERE survey_id = $surveyId AND c_id = $courseId ";
2007
        Database::query($sql);
2008
2009
        $sql = "UPDATE $surveyTable 
2010
                SET invited = 0, answered = 0 
2011
                WHERE survey_id = $surveyId AND c_id = $courseId AND session_id = $sessionId ";
2012
        Database::query($sql);
2013
2014
        return true;
2015
    }
2016
2017
    /**
2018
     * This function copy survey specifying course id and session id where will be copied.
2019
     *
2020
     * @param int $surveyId
2021
     * @param int $targetCourseId  target course id
2022
     * @param int $targetSessionId target session id
2023
     *
2024
     * @return bool|int when fails or return the new survey id
2025
     */
2026
    public static function copySurveySession($surveyId, $targetCourseId, $targetSessionId)
2027
    {
2028
        // Database table definitions
2029
        $surveyTable = Database::get_course_table(TABLE_SURVEY);
2030
        $surveyQuestionGroupTable = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
2031
        $surveyQuestionTable = Database::get_course_table(TABLE_SURVEY_QUESTION);
2032
        $surveyOptionsTable = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2033
        $surveyId = (int) $surveyId;
2034
        $targetCourseId = (int) $targetCourseId;
2035
        $targetSessionId = (int) $targetSessionId;
2036
2037
        $surveyData = self::get_survey($surveyId, 0, '', true);
2038
        if (empty($surveyData) || empty($targetCourseId)) {
2039
            return false;
2040
        }
2041
2042
        $originalCourseId = $surveyData['c_id'];
2043
        $originalSessionId = $surveyData['session_id'];
2044
2045
        $surveyData['code'] = self::generate_unique_code($surveyData['code']);
2046
        $surveyData['c_id'] = $targetCourseId;
2047
        $surveyData['session_id'] = $targetSessionId;
2048
        // Add a "Copy" suffix if copied inside the same course
2049
        if ($targetCourseId == $originalCourseId) {
2050
            $surveyData['title'] = $surveyData['title'].' '.get_lang('Copy');
2051
        }
2052
        unset($surveyData['iid']);
2053
        unset($surveyData['id']);
2054
2055
        $newSurveyId = Database::insert($surveyTable, $surveyData);
2056
2057
        if ($newSurveyId) {
2058
            $sql = "UPDATE $surveyTable SET survey_id = $newSurveyId 
2059
                    WHERE iid = $newSurveyId";
2060
            Database::query($sql);
2061
2062
            $sql = "SELECT * FROM $surveyQuestionGroupTable 
2063
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId ";
2064
            $res = Database::query($sql);
2065
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2066
                $params = [
2067
                    'c_id' => $targetCourseId,
2068
                    'name' => $row['name'],
2069
                    'description' => $row['description'],
2070
                    'survey_id' => $newSurveyId,
2071
                ];
2072
                $insertId = Database::insert($surveyQuestionGroupTable, $params);
2073
                if ($insertId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $insertId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2074
                    $sql = "UPDATE $surveyQuestionGroupTable SET id = iid WHERE iid = $insertId";
2075
                    Database::query($sql);
2076
                    $group_id[$row['id']] = $insertId;
2077
                }
2078
            }
2079
2080
            // Get questions
2081
            $sql = "SELECT * FROM $surveyQuestionTable 
2082
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId";
2083
            $res = Database::query($sql);
2084
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2085
                $params = [
2086
                    'c_id' => $targetCourseId,
2087
                    'survey_id' => $newSurveyId,
2088
                    'survey_question' => $row['survey_question'],
2089
                    'survey_question_comment' => $row['survey_question_comment'],
2090
                    'type' => $row['type'],
2091
                    'display' => $row['display'],
2092
                    'sort' => $row['sort'],
2093
                    'shared_question_id' => $row['shared_question_id'],
2094
                    'max_value' => $row['max_value'],
2095
                    'survey_group_pri' => $row['survey_group_pri'],
2096
                    'survey_group_sec1' => $row['survey_group_sec1'],
2097
                    'survey_group_sec2' => $row['survey_group_sec2'],
2098
                ];
2099
2100
                if (api_get_configuration_value('allow_required_survey_questions')) {
2101
                    if (isset($row['is_required'])) {
2102
                        $params['is_required'] = $row['is_required'];
2103
                    }
2104
                }
2105
2106
                $insertId = Database::insert($surveyQuestionTable, $params);
2107
                if ($insertId) {
2108
                    $sql = "UPDATE $surveyQuestionTable 
2109
                            SET question_id = iid
2110
                            WHERE iid = $insertId";
2111
                    Database::query($sql);
2112
2113
                    $question_id[$row['question_id']] = $insertId;
2114
                }
2115
            }
2116
2117
            // Get questions options
2118
            $sql = "SELECT * FROM $surveyOptionsTable 
2119
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId";
2120
2121
            $res = Database::query($sql);
2122
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2123
                $params = [
2124
                    'c_id' => $targetCourseId,
2125
                    'question_id' => $question_id[$row['question_id']],
2126
                    'survey_id' => $newSurveyId,
2127
                    'option_text' => $row['option_text'],
2128
                    'sort' => $row['sort'],
2129
                    'value' => $row['value'],
2130
                ];
2131
                $insertId = Database::insert($surveyOptionsTable, $params);
2132
                if ($insertId) {
2133
                    $sql = "UPDATE $surveyOptionsTable SET question_option_id = $insertId WHERE iid = $insertId";
2134
                    Database::query($sql);
2135
                }
2136
            }
2137
2138
            return $newSurveyId;
2139
        }
2140
2141
        return false;
2142
    }
2143
2144
    /**
2145
     * @param array $surveyData
2146
     *
2147
     * @return bool
2148
     */
2149
    public static function removeMultiplicateQuestions($surveyData)
2150
    {
2151
        if (empty($surveyData)) {
2152
            return false;
2153
        }
2154
        $surveyId = $surveyData['survey_id'];
2155
        $courseId = $surveyData['c_id'];
2156
2157
        if (empty($surveyId) || empty($courseId)) {
2158
            return false;
2159
        }
2160
2161
        $questions = self::get_questions($surveyId);
2162
        foreach ($questions as $question) {
2163
            // Questions marked with "geneated" were created using the "multiplicate" feature.
2164
            if ($question['survey_question_comment'] === 'generated') {
2165
                self::delete_survey_question($surveyId, $question['question_id']);
2166
            }
2167
        }
2168
    }
2169
2170
    /**
2171
     * @param array $surveyData
2172
     *
2173
     * @return bool
2174
     */
2175
    public static function multiplicateQuestions($surveyData)
2176
    {
2177
        if (empty($surveyData)) {
2178
            return false;
2179
        }
2180
        $surveyId = $surveyData['survey_id'];
2181
        $courseId = $surveyData['c_id'];
2182
2183
        if (empty($surveyId) || empty($courseId)) {
2184
            return false;
2185
        }
2186
2187
        $questions = self::get_questions($surveyId);
2188
2189
        $obj = new UserGroup();
2190
2191
        $options['where'] = [' usergroup.course_id = ? ' => $courseId];
2192
        $classList = $obj->getUserGroupInCourse($options);
2193
2194
        $classTag = '{{class_name}}';
2195
        $studentTag = '{{student_full_name}}';
2196
        $classCounter = 0;
2197
        foreach ($classList as $class) {
2198
            $className = $class['name'];
2199
            foreach ($questions as $question) {
2200
                $users = $obj->get_users_by_usergroup($class['id']);
2201
                if (empty($users)) {
2202
                    continue;
2203
                }
2204
2205
                $text = $question['question'];
2206
                if (strpos($text, $classTag) !== false) {
2207
                    $replacedText = str_replace($classTag, $className, $text);
2208
                    $values = [
2209
                        'c_id' => $courseId,
2210
                        'question_comment' => 'generated',
2211
                        'type' => $question['type'],
2212
                        'display' => $question['horizontalvertical'],
2213
                        'question' => $replacedText,
2214
                        'survey_id' => $surveyId,
2215
                        'question_id' => 0,
2216
                        'shared_question_id' => 0,
2217
                    ];
2218
                    self::save_question($surveyData, $values);
2219
                    $classCounter++;
2220
                    continue;
2221
                }
2222
2223
                foreach ($users as $userId) {
2224
                    $userInfo = api_get_user_info($userId);
2225
2226
                    if (strpos($text, $studentTag) !== false) {
2227
                        $replacedText = str_replace($studentTag, $userInfo['complete_name'], $text);
2228
                        $values = [
2229
                            'c_id' => $courseId,
2230
                            'question_comment' => 'generated',
2231
                            'type' => $question['type'],
2232
                            'display' => $question['horizontalvertical'],
2233
                            'maximum_score' => $question['maximum_score'],
2234
                            'question' => $replacedText,
2235
                            'survey_id' => $surveyId,
2236
                            'question_id' => 0,
2237
                            'shared_question_id' => 0,
2238
                        ];
2239
2240
                        $answers = [];
2241
                        if (!empty($question['answers'])) {
2242
                            foreach ($question['answers'] as $answer) {
2243
                                $replacedText = str_replace($studentTag, $userInfo['complete_name'], $answer);
2244
                                $answers[] = $replacedText;
2245
                            }
2246
                        }
2247
                        $values['answers'] = $answers;
2248
                        self::save_question($surveyData, $values);
2249
                    }
2250
                }
2251
2252
                if ($classCounter < count($classList)) {
2253
                    // Add end page
2254
                    $values = [
2255
                        'c_id' => $courseId,
2256
                        'question_comment' => 'generated',
2257
                        'type' => 'pagebreak',
2258
                        'display' => 'horizontal',
2259
                        'question' => get_lang('QuestionForNextClass'),
2260
                        'survey_id' => $surveyId,
2261
                        'question_id' => 0,
2262
                        'shared_question_id' => 0,
2263
                    ];
2264
                    self::save_question($surveyData, $values);
2265
                }
2266
            }
2267
        }
2268
    }
2269
2270
    /**
2271
     * @param array $survey
2272
     *
2273
     * @return int
2274
     */
2275
    public static function getCountPages($survey)
2276
    {
2277
        if (empty($survey) || !isset($survey['iid'])) {
2278
            return 0;
2279
        }
2280
2281
        $courseId = $survey['c_id'];
2282
        $surveyId = $survey['survey_id'];
2283
2284
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
2285
2286
        // pagebreak
2287
        $sql = "SELECT COUNT(iid) FROM $table
2288
                WHERE
2289
                    survey_question NOT LIKE '%{{%' AND
2290
                    type = 'pagebreak' AND
2291
                    c_id = $courseId AND
2292
                    survey_id = $surveyId";
2293
        $result = Database::query($sql);
2294
        $numberPageBreaks = Database::result($result, 0, 0);
2295
2296
        // No pagebreak
2297
        $sql = "SELECT COUNT(iid) FROM $table
2298
                WHERE
2299
                    survey_question NOT LIKE '%{{%' AND
2300
                    type != 'pagebreak' AND
2301
                    c_id = $courseId AND
2302
                    survey_id = $surveyId";
2303
        $result = Database::query($sql);
2304
        $countOfQuestions = Database::result($result, 0, 0);
2305
2306
        if ($survey['one_question_per_page'] == 1) {
2307
            if (!empty($countOfQuestions)) {
2308
                return $countOfQuestions;
2309
            }
2310
2311
            return 1;
2312
        }
2313
2314
        if (empty($numberPageBreaks)) {
2315
            return 1;
2316
        }
2317
2318
        return $numberPageBreaks + 1;
2319
    }
2320
2321
    /**
2322
     * Check whether this survey has ended. If so, display message and exit rhis script.
2323
     *
2324
     * @param array $surveyData Survey data
2325
     */
2326
    public static function checkTimeAvailability($surveyData)
2327
    {
2328
        if (empty($surveyData)) {
2329
            api_not_allowed(true);
2330
        }
2331
2332
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
2333
        $utcZone = new DateTimeZone('UTC');
2334
        $startDate = new DateTime($surveyData['start_date'], $utcZone);
2335
        $endDate = new DateTime($surveyData['end_date'], $utcZone);
2336
        $currentDate = new DateTime('now', $utcZone);
2337
        if (!$allowSurveyAvailabilityDatetime) {
2338
            $currentDate->modify('today');
2339
        }
2340
        if ($currentDate < $startDate) {
2341
            api_not_allowed(
2342
                true,
2343
                Display:: return_message(
2344
                    get_lang('SurveyNotAvailableYet'),
2345
                    'warning',
2346
                    false
2347
                )
2348
            );
2349
        }
2350
2351
        if ($currentDate > $endDate) {
2352
            api_not_allowed(
2353
                true,
2354
                Display:: return_message(
2355
                    get_lang('SurveyNotAvailableAnymore'),
2356
                    'warning',
2357
                    false
2358
                )
2359
            );
2360
        }
2361
    }
2362
}
2363