SurveyManager::save_question_options()   F
last analyzed

Complexity

Conditions 23
Paths 128

Size

Total Lines 116
Code Lines 80

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 80
nc 128
nop 3
dl 0
loc 116
rs 3.9333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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

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

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

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

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

Loading history...
343
                        if ($pos === false) {
344
                            $row['survey_version'] = $row['survey_version'] + 1;
345
                            $versionValue = $row['survey_version'];
346
                        } else {
347
                            $getlast = explode('\.', $row['survey_version']);
348
                            $lastversion = array_pop($getlast);
349
                            $lastversion = $lastversion + 1;
350
                            $add = implode('.', $getlast);
351
                            if ($add != '') {
352
                                $insertnewversion = $add.'.'.$lastversion;
353
                            } else {
354
                                $insertnewversion = $lastversion;
355
                            }
356
                            $versionValue = $insertnewversion;
357
                        }
358
                    }
359
                    $extraParams['survey_version'] = $versionValue;
360
                }
361
            }
362
363
            $params = [
364
                'c_id' => $course_id,
365
                'code' => self::generateSurveyCode($values['survey_code']),
366
                'title' => $values['survey_title'],
367
                'subtitle' => $values['survey_subtitle'],
368
                'author' => $_user['user_id'],
369
                'lang' => $values['survey_language'],
370
                'is_shared' => $shared_survey_id,
371
                'template' => 'template',
372
                'intro' => $values['survey_introduction'],
373
                'surveythanks' => $values['survey_thanks'],
374
                'creation_date' => api_get_utc_datetime(),
375
                'anonymous' => $values['anonymous'],
376
                'session_id' => api_get_session_id(),
377
                'visible_results' => $values['visible_results'],
378
            ];
379
380
            if (!empty($values['start_date'])) {
381
                if ($allowSurveyAvailabilityDatetime) {
382
                    $params['avail_from'] = api_get_utc_datetime($values['start_date'].':00');
383
                } else {
384
                    $params['avail_from'] = $values['start_date'];
385
                }
386
            }
387
388
            if (!empty($values['end_date'])) {
389
                if ($allowSurveyAvailabilityDatetime) {
390
                    $params['avail_till'] = api_get_utc_datetime($values['end_date'].':00');
391
                } else {
392
                    $params['avail_till'] = $values['end_date'];
393
                }
394
            }
395
396
            if (isset($values['survey_type']) && !empty($values['survey_type'])) {
397
                $params['survey_type'] = $values['survey_type'];
398
            }
399
400
            $params = array_merge($params, $extraParams);
401
402
            $survey_id = Database::insert($table_survey, $params);
403
            if ($survey_id > 0) {
404
                Event::addEvent(
0 ignored issues
show
Bug introduced by
The method addEvent() does not exist on Event. ( Ignorable by Annotation )

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

404
                Event::/** @scrutinizer ignore-call */ 
405
                       addEvent(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

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

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
770
            $targetCourseId = $course_id;
771
        }
772
773
        // Database table definitions
774
        $table_survey = Database::get_course_table(TABLE_SURVEY);
775
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
776
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
777
        $table_survey_options = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
778
        $survey_id = (int) $survey_id;
779
780
        // Get groups
781
        $survey_data = self::get_survey($survey_id, 0, null, true);
782
        if (empty($survey_data)) {
783
            return true;
784
        }
785
786
        if (empty($new_survey_id)) {
787
            $params = $survey_data;
788
789
            if (!empty($surveyCode)) {
790
                $surveyCode = preg_replace('/\s+/', '', $surveyCode);
791
                $params['code'] = $surveyCode;
792
            } else {
793
                $params['code'] = self::generate_unique_code($params['code']);
794
            }
795
796
            $params['c_id'] = $targetCourseId;
797
            unset($params['survey_id']);
798
            $params['session_id'] = api_get_session_id();
799
            $params['title'] = $params['title'].' '.get_lang('Copy');
800
            unset($params['iid']);
801
            $params['invited'] = 0;
802
            $params['answered'] = 0;
803
            $new_survey_id = Database::insert($table_survey, $params);
804
805
            if ($new_survey_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $new_survey_id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
806
                $sql = "UPDATE $table_survey SET survey_id = $new_survey_id
807
                        WHERE iid = $new_survey_id";
808
                Database::query($sql);
809
810
                // Insert into item_property
811
                api_item_property_update(
812
                    api_get_course_info(),
813
                    TOOL_SURVEY,
814
                    $new_survey_id,
815
                    'SurveyAdded',
816
                    api_get_user_id()
817
                );
818
            }
819
        } else {
820
            $new_survey_id = (int) $new_survey_id;
821
        }
822
823
        $sql = "SELECT * FROM $table_survey_question_group
824
                WHERE c_id = $course_id AND survey_id = $survey_id";
825
        $res = Database::query($sql);
826
        while ($row = Database::fetch_array($res, 'ASSOC')) {
827
            $params = [
828
                'c_id' => $targetCourseId,
829
                'name' => $row['name'],
830
                'description' => $row['description'],
831
                'survey_id' => $new_survey_id,
832
            ];
833
            $insertId = Database::insert($table_survey_question_group, $params);
834
835
            $sql = "UPDATE $table_survey_question_group SET id = iid
836
                    WHERE iid = $insertId";
837
            Database::query($sql);
838
839
            $group_id[$row['id']] = $insertId;
840
        }
841
842
        // Get questions
843
        $sql = "SELECT * FROM $table_survey_question
844
                WHERE c_id = $course_id AND survey_id = $survey_id";
845
        $res = Database::query($sql);
846
        while ($row = Database::fetch_array($res, 'ASSOC')) {
847
            $params = [
848
                'c_id' => $targetCourseId,
849
                'survey_id' => $new_survey_id,
850
                'survey_question' => $row['survey_question'],
851
                'survey_question_comment' => $row['survey_question_comment'],
852
                'type' => $row['type'],
853
                'display' => $row['display'],
854
                'sort' => $row['sort'],
855
                'shared_question_id' => $row['shared_question_id'],
856
                'max_value' => $row['max_value'],
857
                'survey_group_pri' => $row['survey_group_pri'],
858
                'survey_group_sec1' => $row['survey_group_sec1'],
859
                'survey_group_sec2' => $row['survey_group_sec2'],
860
            ];
861
862
            if (api_get_configuration_value('allow_required_survey_questions')) {
863
                if (isset($row['is_required'])) {
864
                    $params['is_required'] = $row['is_required'];
865
                }
866
            }
867
868
            $insertId = Database::insert($table_survey_question, $params);
869
            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...
870
                $sql = "UPDATE $table_survey_question SET question_id = iid WHERE iid = $insertId";
871
                Database::query($sql);
872
                $question_id[$row['question_id']] = $insertId;
873
            }
874
        }
875
876
        // Get questions options
877
        $sql = "SELECT * FROM $table_survey_options
878
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
879
880
        $res = Database::query($sql);
881
        while ($row = Database::fetch_array($res, 'ASSOC')) {
882
            $params = [
883
                'c_id' => $targetCourseId,
884
                'question_id' => $question_id[$row['question_id']],
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_id does not seem to be defined for all execution paths leading up to this point.
Loading history...
885
                'survey_id' => $new_survey_id,
886
                'option_text' => $row['option_text'],
887
                'sort' => $row['sort'],
888
                'value' => $row['value'],
889
            ];
890
            $insertId = Database::insert($table_survey_options, $params);
891
            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...
892
                $sql = "UPDATE $table_survey_options SET question_option_id = $insertId
893
                        WHERE iid = $insertId";
894
                Database::query($sql);
895
            }
896
        }
897
898
        return $new_survey_id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $new_survey_id also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
899
    }
900
901
    /**
902
     * This function duplicates a survey (and also all the question in that survey.
903
     *
904
     * @param int $surveyId id of the survey that has to be duplicated
905
     * @param int $courseId id of the course which survey has to be duplicated
906
     *
907
     * @return true
908
     *
909
     * @author Eric Marguin <[email protected]>, Elixir Interactive
910
     *
911
     * @version October 2007
912
     */
913
    public static function empty_survey($surveyId, $courseId = 0)
914
    {
915
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
916
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
917
        $table_survey = Database::get_course_table(TABLE_SURVEY);
918
919
        $courseId = (int) $courseId;
920
        $courseId = empty($courseId) ? api_get_course_int_id() : $courseId;
921
        $surveyId = (int) $surveyId;
922
923
        $datas = self::get_survey($surveyId);
924
        $session_where = '';
925
        if (0 != api_get_session_id()) {
926
            $session_where = ' AND session_id = "'.api_get_session_id().'" ';
927
        }
928
929
        $sql = 'DELETE FROM '.$table_survey_invitation.'
930
		        WHERE
931
		            c_id = '.$courseId.' AND
932
		            survey_code = "'.Database::escape_string($datas['code']).'" '.$session_where.' ';
933
        Database::query($sql);
934
935
        $sql = 'DELETE FROM '.$table_survey_answer.'
936
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
937
        Database::query($sql);
938
939
        $sql = 'UPDATE '.$table_survey.' SET invited=0, answered=0
940
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
941
        Database::query($sql);
942
943
        Event::addEvent(
944
            LOG_SURVEY_CLEAN_RESULTS,
945
            LOG_SURVEY_ID,
946
            $surveyId,
947
            null,
948
            api_get_user_id(),
949
            api_get_course_int_id(),
950
            api_get_session_id()
951
        );
952
953
        return true;
954
    }
955
956
    /**
957
     * This function recalculates the number of people who have taken the survey (=filled at least one question).
958
     *
959
     * @param array  $survey_data
960
     * @param array  $user
961
     * @param string $survey_code
962
     *
963
     * @return bool
964
     *
965
     * @author Patrick Cool <[email protected]>, Ghent University
966
     *
967
     * @version February 2007
968
     */
969
    public static function update_survey_answered($survey_data, $user, $survey_code, $lpItemId = 0)
970
    {
971
        if (empty($survey_data)) {
972
            return false;
973
        }
974
975
        // Database table definitions
976
        $table_survey = Database::get_course_table(TABLE_SURVEY);
977
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
978
979
        $survey_id = (int) $survey_data['survey_id'];
980
        $course_id = (int) $survey_data['c_id'];
981
        $sessionId = api_get_session_id();
982
983
        // Getting a list with all the people who have filled the survey
984
        /*$people_filled = self::get_people_who_filled_survey($survey_id, false, $course_id);
985
        $number = count($people_filled);*/
986
987
        // Storing this value in the survey table
988
        $sql = "UPDATE $table_survey
989
		        SET answered = answered + 1
990
		        WHERE
991
                    c_id = $course_id AND
992
		            survey_id = ".$survey_id;
993
        Database::query($sql);
994
995
        $allow = api_get_configuration_value('survey_answered_at_field');
996
        // Requires DB change:
997
        // ALTER TABLE c_survey_invitation ADD answered_at DATETIME DEFAULT NULL;
998
        $answeredAt = '';
999
        if ($allow) {
1000
            $answeredAt = "answered_at = '".api_get_utc_datetime()."',";
1001
        }
1002
        // To select the answers by Lp Item
1003
        $lpItemCondition = '';
1004
        if (true === api_get_configuration_value('allow_survey_tool_in_lp')) {
1005
            $lpItemCondition = " AND c_lp_item_id = $lpItemId";
1006
        }
1007
        // To select the answers by session
1008
        $sessionCondition = '';
1009
        if (true === api_get_configuration_value('show_surveys_base_in_sessions')) {
1010
            $sessionCondition = api_get_session_condition($sessionId);
1011
        }
1012
1013
        // Storing that the user has finished the survey.
1014
        $sql = "UPDATE $table_survey_invitation
1015
                SET $answeredAt answered = 1
1016
                WHERE
1017
                    c_id = $course_id AND
1018
                    user ='".Database::escape_string($user)."' AND
1019
                    survey_code='".Database::escape_string($survey_code)."'
1020
                    $sessionCondition
1021
                    $lpItemCondition";
1022
        Database::query($sql);
1023
    }
1024
1025
    /**
1026
     * This function return the "icon" of the question type.
1027
     *
1028
     * @param string $type
1029
     *
1030
     * @author Patrick Cool <[email protected]>, Ghent University
1031
     *
1032
     * @version February 2007
1033
     */
1034
    public static function icon_question($type)
1035
    {
1036
        // the possible question types
1037
        $possible_types = [
1038
            'personality',
1039
            'yesno',
1040
            'multiplechoice',
1041
            'multiplechoiceother',
1042
            'multipleresponse',
1043
            'open',
1044
            'dropdown',
1045
            'comment',
1046
            'pagebreak',
1047
            'percentage',
1048
            'score',
1049
            'selectivedisplay',
1050
        ];
1051
1052
        // the images array
1053
        $icon_question = [
1054
            'yesno' => 'yesno.png',
1055
            'personality' => 'yesno.png',
1056
            'multiplechoice' => 'mcua.png',
1057
            'multiplechoiceother' => 'mcma.png',
1058
            'multipleresponse' => 'mcma.png',
1059
            'open' => 'open_answer.png',
1060
            'dropdown' => 'dropdown.png',
1061
            'percentage' => 'percentagequestion.png',
1062
            'score' => 'scorequestion.png',
1063
            'comment' => 'commentquestion.png',
1064
            'pagebreak' => 'page_end.png',
1065
            'selectivedisplay' => 'yesno.png',
1066
        ];
1067
1068
        if (in_array($type, $possible_types)) {
1069
            return $icon_question[$type];
1070
        }
1071
1072
        return false;
1073
    }
1074
1075
    /**
1076
     * This function retrieves all the information of a question.
1077
     *
1078
     * @param int  $question_id the id of the question
1079
     * @param bool $shared
1080
     *
1081
     * @return array
1082
     *
1083
     * @author Patrick Cool <[email protected]>, Ghent University
1084
     *
1085
     * @version January 2007
1086
     *
1087
     * @todo one sql call should do the trick
1088
     */
1089
    public static function get_question($question_id, $shared = false)
1090
    {
1091
        // Table definitions
1092
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1093
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1094
        $course_id = api_get_course_int_id();
1095
        $question_id = (int) $question_id;
1096
1097
        if (empty($question_id)) {
1098
            return [];
1099
        }
1100
1101
        $sql = "SELECT * FROM $tbl_survey_question
1102
                WHERE c_id = $course_id AND question_id = $question_id
1103
                ORDER BY `sort` ";
1104
1105
        $sqlOption = "  SELECT * FROM $table_survey_question_option
1106
                        WHERE c_id = $course_id AND question_id='".$question_id."'
1107
                        ORDER BY `sort` ";
1108
1109
        if ($shared) {
1110
            $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1111
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1112
1113
            $sql = "SELECT * FROM $tbl_survey_question
1114
                    WHERE question_id = $question_id
1115
                    ORDER BY `sort` ";
1116
            $sqlOption = "SELECT * FROM $table_survey_question_option
1117
                          WHERE question_id = $question_id
1118
                          ORDER BY `sort` ";
1119
        }
1120
1121
        // Getting the information of the question
1122
        $result = Database::query($sql);
1123
        $row = Database::fetch_array($result, 'ASSOC');
1124
1125
        $return['survey_id'] = $row['survey_id'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.
Loading history...
1126
        $return['parent_id'] = isset($row['parent_id']) ? $row['parent_id'] : 0;
1127
        $return['parent_option_id'] = isset($row['parent_option_id']) ? $row['parent_option_id'] : 0;
1128
        $return['question_id'] = $row['question_id'];
1129
        $return['type'] = $row['type'];
1130
        $return['question'] = $row['survey_question'];
1131
        $return['horizontalvertical'] = $row['display'];
1132
        $return['shared_question_id'] = $row['shared_question_id'];
1133
        $return['maximum_score'] = $row['max_value'];
1134
        $return['is_required'] = api_get_configuration_value('allow_required_survey_questions')
1135
            ? $row['is_required']
1136
            : false;
1137
1138
        if (0 != $row['survey_group_pri']) {
1139
            $return['assigned'] = $row['survey_group_pri'];
1140
            $return['choose'] = 1;
1141
        } else {
1142
            $return['assigned1'] = $row['survey_group_sec1'];
1143
            $return['assigned2'] = $row['survey_group_sec2'];
1144
            $return['choose'] = 2;
1145
        }
1146
1147
        // Getting the information of the question options
1148
        $result = Database::query($sqlOption);
1149
        $counter = 0;
1150
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1151
            /** @todo this should be renamed to options instead of answers */
1152
            $return['answers'][] = $row['option_text'];
1153
            $return['values'][] = $row['value'];
1154
            $return['answer_data'][$counter]['data'] = $row['option_text'];
1155
            $return['answer_data'][$counter]['iid'] = $row['iid'];
1156
            /** @todo this can be done more elegantly (used in reporting) */
1157
            $return['answersid'][] = $row['question_option_id'];
1158
            $counter++;
1159
        }
1160
1161
        return $return;
1162
    }
1163
1164
    /**
1165
     * This function gets all the question of any given survey.
1166
     *
1167
     * @param int $surveyId the id of the survey
1168
     * @param int $courseId
1169
     *
1170
     * @return array containing all the questions of the survey
1171
     *
1172
     * @author Patrick Cool <[email protected]>, Ghent University
1173
     *
1174
     * @version February 2007
1175
     *
1176
     * @todo one sql call should do the trick
1177
     */
1178
    public static function get_questions($surveyId, $courseId = 0)
1179
    {
1180
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1181
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1182
1183
        $courseId = (int) $courseId;
1184
        $surveyId = (int) $surveyId;
1185
1186
        if (empty($courseId)) {
1187
            $courseId = api_get_course_int_id();
1188
        }
1189
1190
        // Getting the information of the question
1191
        $sql = "SELECT * FROM $tbl_survey_question
1192
		        WHERE c_id = $courseId AND survey_id= $surveyId ";
1193
        $result = Database::query($sql);
1194
        $questions = [];
1195
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1196
            $questionId = $row['question_id'];
1197
            $questions[$questionId]['survey_id'] = $surveyId;
1198
            $questions[$questionId]['question_id'] = $questionId;
1199
            $questions[$questionId]['type'] = $row['type'];
1200
            $questions[$questionId]['question'] = $row['survey_question'];
1201
            $questions[$questionId]['horizontalvertical'] = $row['display'];
1202
            $questions[$questionId]['maximum_score'] = $row['max_value'];
1203
            $questions[$questionId]['sort'] = $row['sort'];
1204
            $questions[$questionId]['survey_question_comment'] = $row['survey_question_comment'];
1205
1206
            // Getting the information of the question options
1207
            $sql = "SELECT * FROM $table_survey_question_option
1208
		             WHERE c_id = $courseId AND survey_id= $surveyId  AND question_id = $questionId";
1209
            $resultOptions = Database::query($sql);
1210
            while ($rowOption = Database::fetch_array($resultOptions, 'ASSOC')) {
1211
                $questions[$questionId]['answers'][] = $rowOption['option_text'];
1212
            }
1213
        }
1214
1215
        return $questions;
1216
    }
1217
1218
    /**
1219
     * This function saves a question in the database.
1220
     * This can be either an update of an existing survey or storing a new survey.
1221
     *
1222
     * @param array $survey_data
1223
     * @param array $form_content all the information of the form
1224
     *
1225
     * @return string
1226
     *
1227
     * @author Patrick Cool <[email protected]>, Ghent University
1228
     *
1229
     * @version January 2007
1230
     */
1231
    public static function save_question($survey_data, $form_content, $showMessage = true, $dataFromDatabase = [])
1232
    {
1233
        $return_message = '';
1234
        if (strlen($form_content['question']) > 1) {
1235
            // Checks length of the question
1236
            $empty_answer = false;
1237
            if (1 == $survey_data['survey_type']) {
1238
                if (empty($form_content['choose'])) {
1239
                    return 'PleaseChooseACondition';
1240
                }
1241
1242
                if ((2 == $form_content['choose']) &&
1243
                    ($form_content['assigned1'] == $form_content['assigned2'])
1244
                ) {
1245
                    return 'ChooseDifferentCategories';
1246
                }
1247
            }
1248
1249
            if ('percentage' !== $form_content['type']) {
1250
                if (isset($form_content['answers'])) {
1251
                    for ($i = 0; $i < count($form_content['answers']); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1252
                        if (strlen($form_content['answers'][$i]) < 1) {
1253
                            $empty_answer = true;
1254
                            break;
1255
                        }
1256
                    }
1257
                }
1258
            }
1259
1260
            if ('score' == $form_content['type']) {
1261
                if (strlen($form_content['maximum_score']) < 1) {
1262
                    $empty_answer = true;
1263
                }
1264
            }
1265
1266
            $course_id = api_get_course_int_id();
1267
1268
            if (!$empty_answer) {
1269
                // Table definitions
1270
                $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1271
                $surveyId = (int) $form_content['survey_id'];
1272
1273
                // Getting all the information of the survey
1274
                $survey_data = self::get_survey($surveyId);
1275
1276
                // Storing the question in the shared database
1277
                if (is_numeric($survey_data['survey_share']) && $survey_data['survey_share'] != 0) {
1278
                    $shared_question_id = self::save_shared_question($form_content, $survey_data);
0 ignored issues
show
Bug Best Practice introduced by
The method SurveyManager::save_shared_question() is not static, but was called statically. ( Ignorable by Annotation )

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

1278
                    /** @scrutinizer ignore-call */ 
1279
                    $shared_question_id = self::save_shared_question($form_content, $survey_data);
Loading history...
1279
                    $form_content['shared_question_id'] = $shared_question_id;
1280
                }
1281
1282
                // Storing a new question
1283
                if ($form_content['question_id'] == '' || !is_numeric($form_content['question_id'])) {
1284
                    // Finding the max sort order of the questions in the given survey
1285
                    $sql = "SELECT max(sort) AS max_sort
1286
					        FROM $tbl_survey_question
1287
                            WHERE c_id = $course_id AND survey_id = $surveyId ";
1288
                    $result = Database::query($sql);
1289
                    $row = Database::fetch_array($result, 'ASSOC');
1290
                    $max_sort = $row['max_sort'];
1291
1292
                    // Some variables defined for survey-test type
1293
                    $extraParams = [];
1294
                    if (isset($_POST['choose'])) {
1295
                        if ($_POST['choose'] == 1) {
1296
                            $extraParams['survey_group_pri'] = $_POST['assigned'];
1297
                        } elseif ($_POST['choose'] == 2) {
1298
                            $extraParams['survey_group_sec1'] = $_POST['assigned1'];
1299
                            $extraParams['survey_group_sec2'] = $_POST['assigned2'];
1300
                        }
1301
                    }
1302
1303
                    $questionComment = isset($form_content['question_comment']) ? $form_content['question_comment'] : '';
1304
                    $maxScore = isset($form_content['maximum_score']) ? $form_content['maximum_score'] : '';
1305
                    $display = isset($form_content['horizontalvertical']) ? $form_content['horizontalvertical'] : '';
1306
1307
                    $params = [
1308
                        'c_id' => $course_id,
1309
                        'survey_id' => $surveyId,
1310
                        'survey_question' => $form_content['question'],
1311
                        'survey_question_comment' => $questionComment,
1312
                        'type' => $form_content['type'],
1313
                        'display' => $display,
1314
                        'sort' => $max_sort + 1,
1315
                        'shared_question_id' => $form_content['shared_question_id'],
1316
                        'max_value' => $maxScore,
1317
                    ];
1318
1319
                    if (api_get_configuration_value('survey_question_dependency')) {
1320
                        $params['parent_id'] = 0;
1321
                        $params['parent_option_id'] = 0;
1322
                        if (isset($form_content['parent_id']) &&
1323
                            isset($form_content['parent_option_id']) &&
1324
                            !empty($form_content['parent_id']) &&
1325
                            !empty($form_content['parent_option_id'])
1326
                        ) {
1327
                            $params['parent_id'] = $form_content['parent_id'];
1328
                            $params['parent_option_id'] = $form_content['parent_option_id'];
1329
                        }
1330
                    }
1331
1332
                    if (api_get_configuration_value('allow_required_survey_questions')) {
1333
                        $params['is_required'] = isset($form_content['is_required']);
1334
                    }
1335
1336
                    $params = array_merge($params, $extraParams);
1337
                    $question_id = Database::insert($tbl_survey_question, $params);
1338
                    if ($question_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $question_id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1339
                        $sql = "UPDATE $tbl_survey_question SET question_id = $question_id
1340
                                WHERE iid = $question_id";
1341
                        Database::query($sql);
1342
1343
                        $form_content['question_id'] = $question_id;
1344
                        $return_message = 'QuestionAdded';
1345
                    }
1346
                } else {
1347
                    // Updating an existing question
1348
                    $extraParams = [];
1349
                    if (isset($_POST['choose'])) {
1350
                        if (1 == $_POST['choose']) {
1351
                            $extraParams['survey_group_pri'] = $_POST['assigned'];
1352
                            $extraParams['survey_group_sec1'] = 0;
1353
                            $extraParams['survey_group_sec2'] = 0;
1354
                        } elseif (2 == $_POST['choose']) {
1355
                            $extraParams['survey_group_pri'] = 0;
1356
                            $extraParams['survey_group_sec1'] = $_POST['assigned1'];
1357
                            $extraParams['survey_group_sec2'] = $_POST['assigned2'];
1358
                        }
1359
                    }
1360
1361
                    $maxScore = isset($form_content['maximum_score']) ? $form_content['maximum_score'] : null;
1362
                    $questionComment = isset($form_content['question_comment'])
1363
                        ? $form_content['question_comment']
1364
                        : null;
1365
1366
                    // Adding the question to the survey_question table
1367
                    $params = [
1368
                        'survey_question' => $form_content['question'],
1369
                        'survey_question_comment' => $questionComment,
1370
                        'display' => $form_content['horizontalvertical'] ?? '',
1371
                        'max_value' => $maxScore,
1372
                    ];
1373
1374
                    if (api_get_configuration_value('allow_required_survey_questions')) {
1375
                        $params['is_required'] = isset($form_content['is_required']);
1376
                    }
1377
1378
                    if (api_get_configuration_value('survey_question_dependency')) {
1379
                        $params['parent_id'] = 0;
1380
                        $params['parent_option_id'] = 0;
1381
                        if (isset($form_content['parent_id']) &&
1382
                            isset($form_content['parent_option_id']) &&
1383
                            !empty($form_content['parent_id']) &&
1384
                            !empty($form_content['parent_option_id'])
1385
                        ) {
1386
                            $params['parent_id'] = $form_content['parent_id'];
1387
                            $params['parent_option_id'] = $form_content['parent_option_id'];
1388
                        }
1389
                    }
1390
1391
                    $params = array_merge($params, $extraParams);
1392
                    Database::update(
1393
                        $tbl_survey_question,
1394
                        $params,
1395
                        [
1396
                            'c_id = ? AND question_id = ?' => [
1397
                                $course_id,
1398
                                $form_content['question_id'],
1399
                            ],
1400
                        ]
1401
                    );
1402
                    $return_message = 'QuestionUpdated';
1403
                }
1404
1405
                if (!empty($form_content['survey_id'])) {
1406
                    // Updating survey
1407
                    api_item_property_update(
1408
                        api_get_course_info(),
1409
                        TOOL_SURVEY,
1410
                        $form_content['survey_id'],
1411
                        'SurveyUpdated',
1412
                        api_get_user_id()
1413
                    );
1414
                }
1415
1416
                // Storing the options of the question
1417
                self::save_question_options($form_content, $survey_data, $dataFromDatabase);
1418
            } else {
1419
                $return_message = 'PleasFillAllAnswer';
1420
            }
1421
        } else {
1422
            $return_message = 'PleaseEnterAQuestion';
1423
        }
1424
1425
        if ($showMessage) {
1426
            if (!empty($return_message)) {
1427
                Display::addFlash(Display::return_message(get_lang($return_message)));
1428
            }
1429
        }
1430
1431
        return $return_message;
1432
    }
1433
1434
    /**
1435
     * This function saves the question in the shared database.
1436
     *
1437
     * @param array $form_content all the information of the form
1438
     * @param array $survey_data  all the information of the survey
1439
     *
1440
     * @author Patrick Cool <[email protected]>, Ghent University
1441
     *
1442
     * @version February 2007
1443
     *
1444
     * @return int
1445
     *
1446
     * @todo editing of a shared question
1447
     */
1448
    public function save_shared_question($form_content, $survey_data)
1449
    {
1450
        $_course = api_get_course_info();
1451
1452
        // Table definitions
1453
        $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1454
1455
        // Storing a new question
1456
        if ('' == $form_content['shared_question_id'] ||
1457
            !is_numeric($form_content['shared_question_id'])
1458
        ) {
1459
            // Finding the max sort order of the questions in the given survey
1460
            $sql = "SELECT max(sort) AS max_sort FROM $tbl_survey_question
1461
                    WHERE survey_id='".intval($survey_data['survey_share'])."'
1462
                    AND code='".Database::escape_string($_course['id'])."'";
1463
            $result = Database::query($sql);
1464
            $row = Database::fetch_array($result, 'ASSOC');
1465
            $max_sort = $row['max_sort'];
1466
1467
            // Adding the question to the survey_question table
1468
            $sql = "INSERT INTO $tbl_survey_question (survey_id, survey_question, survey_question_comment, type, display, sort, code) VALUES (
1469
                    '".Database::escape_string($survey_data['survey_share'])."',
1470
                    '".Database::escape_string($form_content['question'])."',
1471
                    '".Database::escape_string($form_content['question_comment'])."',
1472
                    '".Database::escape_string($form_content['type'])."',
1473
                    '".Database::escape_string($form_content['horizontalvertical'])."',
1474
                    '".Database::escape_string($max_sort + 1)."',
1475
                    '".Database::escape_string($_course['id'])."')";
1476
            Database::query($sql);
1477
            $shared_question_id = Database::insert_id();
1478
        } else {
1479
            // Updating an existing question
1480
            // adding the question to the survey_question table
1481
            $sql = "UPDATE $tbl_survey_question SET
1482
                        survey_question = '".Database::escape_string($form_content['question'])."',
1483
                        survey_question_comment = '".Database::escape_string($form_content['question_comment'])."',
1484
                        display = '".Database::escape_string($form_content['horizontalvertical'])."'
1485
                    WHERE
1486
                        question_id = '".intval($form_content['shared_question_id'])."' AND
1487
                        code = '".Database::escape_string($_course['id'])."'";
1488
            Database::query($sql);
1489
            $shared_question_id = $form_content['shared_question_id'];
1490
        }
1491
1492
        return $shared_question_id;
1493
    }
1494
1495
    /**
1496
     * This functions moves a question of a survey up or down.
1497
     *
1498
     * @param string $direction
1499
     * @param int    $survey_question_id
1500
     * @param int    $survey_id
1501
     *
1502
     * @author Patrick Cool <[email protected]>, Ghent University
1503
     *
1504
     * @version January 2007
1505
     */
1506
    public static function move_survey_question(
1507
        $direction,
1508
        $survey_question_id,
1509
        $survey_id
1510
    ) {
1511
        // Table definition
1512
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1513
        $course_id = api_get_course_int_id();
1514
1515
        if ('moveup' == $direction) {
1516
            $sort = 'DESC';
1517
        }
1518
        if ('movedown' == $direction) {
1519
            $sort = 'ASC';
1520
        }
1521
1522
        $survey_id = (int) $survey_id;
1523
1524
        // Finding the two questions that needs to be swapped
1525
        $sql = "SELECT * FROM $table_survey_question
1526
		        WHERE c_id = $course_id AND survey_id='".$survey_id."'
1527
		        ORDER BY sort $sort";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sort does not seem to be defined for all execution paths leading up to this point.
Loading history...
1528
        $result = Database::query($sql);
1529
        $found = false;
1530
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1531
            if ($found) {
1532
                $question_id_two = $row['question_id'];
1533
                $question_sort_two = $row['sort'];
1534
                $found = false;
1535
            }
1536
            if ($row['question_id'] == $survey_question_id) {
1537
                $found = true;
1538
                $question_id_one = $row['question_id'];
1539
                $question_sort_one = $row['sort'];
1540
            }
1541
        }
1542
1543
        $sql = "UPDATE $table_survey_question
1544
                SET sort = '".Database::escape_string($question_sort_two)."'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_sort_two does not seem to be defined for all execution paths leading up to this point.
Loading history...
1545
		        WHERE c_id = $course_id AND question_id='".intval($question_id_one)."'";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_id_one does not seem to be defined for all execution paths leading up to this point.
Loading history...
1546
        Database::query($sql);
1547
1548
        $sql = "UPDATE $table_survey_question
1549
                SET sort = '".Database::escape_string($question_sort_one)."'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_sort_one does not seem to be defined for all execution paths leading up to this point.
Loading history...
1550
		        WHERE c_id = $course_id AND question_id='".intval($question_id_two)."'";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_id_two does not seem to be defined for all execution paths leading up to this point.
Loading history...
1551
        Database::query($sql);
1552
    }
1553
1554
    /**
1555
     * This function deletes all the questions of a given survey
1556
     * This function is normally only called when a survey is deleted.
1557
     *
1558
     * @param int $survey_id the id of the survey that has to be deleted
1559
     *
1560
     * @return bool
1561
     *
1562
     * @author Patrick Cool <[email protected]>, Ghent University
1563
     *
1564
     * @version January 2007
1565
     */
1566
    public static function delete_all_survey_questions($survey_id, $shared = false)
1567
    {
1568
        $course_id = api_get_course_int_id();
1569
        $survey_id = (int) $survey_id;
1570
1571
        // Table definitions
1572
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1573
        $course_condition = " c_id = $course_id AND ";
1574
        if ($shared) {
1575
            $course_condition = '';
1576
            $table_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1577
        }
1578
1579
        $sql = "DELETE FROM $table_survey_question
1580
		        WHERE $course_condition survey_id = '".$survey_id."'";
1581
1582
        // Deleting the survey questions
1583
        Database::query($sql);
1584
1585
        // Deleting all the options of the questions of the survey
1586
        self::delete_all_survey_questions_options($survey_id, $shared);
1587
1588
        // Deleting all the answers on this survey
1589
        self::delete_all_survey_answers($survey_id);
1590
1591
        return true;
1592
    }
1593
1594
    /**
1595
     * This function deletes a survey question and all its options.
1596
     *
1597
     * @param int  $survey_id   the id of the survey
1598
     * @param int  $question_id the id of the question
1599
     * @param bool $shared
1600
     *
1601
     * @return mixed False on error, true if the question could be deleted
1602
     *
1603
     * @todo also delete the answers to this question
1604
     *
1605
     * @author Patrick Cool <[email protected]>, Ghent University
1606
     *
1607
     * @version March 2007
1608
     */
1609
    public static function delete_survey_question($survey_id, $question_id, $shared = false)
1610
    {
1611
        $survey_id = (int) $survey_id;
1612
        $question_id = (int) $question_id;
1613
        $course_id = api_get_course_int_id();
1614
1615
        if ($shared) {
1616
            self::delete_shared_survey_question($survey_id, $question_id);
1617
        }
1618
1619
        // Table definitions
1620
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
1621
        // Deleting the survey questions
1622
        $sql = "DELETE FROM $table
1623
		        WHERE
1624
		            c_id = $course_id AND
1625
		            survey_id = $survey_id AND
1626
		            question_id = $question_id";
1627
        $result = Database::query($sql);
1628
        if (false == $result) {
1629
            return false;
1630
        }
1631
        // Deleting the options of the question of the survey
1632
        self::delete_survey_question_option($survey_id, $question_id, $shared);
1633
1634
        return true;
1635
    }
1636
1637
    /**
1638
     * This function deletes a shared survey question from the main database and all its options.
1639
     *
1640
     * @param int $question_id the id of the question
1641
     *
1642
     * @todo delete all the options of this question
1643
     *
1644
     * @author Patrick Cool <[email protected]>, Ghent University
1645
     *
1646
     * @version March 2007
1647
     */
1648
    public static function delete_shared_survey_question($survey_id, $question_id)
1649
    {
1650
        // Table definitions
1651
        $table_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1652
        $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1653
1654
        // First we have to get the shared_question_id
1655
        $question_data = self::get_question($question_id);
1656
1657
        // Deleting the survey questions
1658
        $sql = "DELETE FROM $table_survey_question
1659
		        WHERE question_id='".intval($question_data['shared_question_id'])."'";
1660
        Database::query($sql);
1661
1662
        // Deleting the options of the question of the survey question
1663
        $sql = "DELETE FROM $table_survey_question_option
1664
		        WHERE question_id='".intval($question_data['shared_question_id'])."'";
1665
        Database::query($sql);
1666
    }
1667
1668
    /**
1669
     * This function stores the options of the questions in the table.
1670
     *
1671
     * @param array $form_content
1672
     *
1673
     * @author Patrick Cool <[email protected]>, Ghent University
1674
     *
1675
     * @version January 2007
1676
     *
1677
     * @todo writing the update statement when editing a question
1678
     */
1679
    public static function save_question_options($form_content, $survey_data, $dataFromDatabase = [])
1680
    {
1681
        $course_id = api_get_course_int_id();
1682
        $type = $form_content['type'];
1683
1684
        // A percentage question type has options 1 -> 100
1685
        if ('percentage' === $type) {
1686
            for ($i = 1; $i < 101; $i++) {
1687
                $form_content['answers'][] = $i;
1688
            }
1689
        }
1690
1691
        if (is_numeric($survey_data['survey_share']) && 0 != $survey_data['survey_share']) {
1692
            self::save_shared_question_options($form_content, $survey_data);
0 ignored issues
show
Bug Best Practice introduced by
The method SurveyManager::save_shared_question_options() is not static, but was called statically. ( Ignorable by Annotation )

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

1692
            self::/** @scrutinizer ignore-call */ 
1693
                  save_shared_question_options($form_content, $survey_data);
Loading history...
1693
        }
1694
1695
        // Table definition
1696
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1697
1698
        // We are editing a question so we first have to remove all the existing options from the database
1699
        $optionsToDelete = [];
1700
        if (isset($dataFromDatabase['answer_data'])) {
1701
            foreach ($dataFromDatabase['answer_data'] as $data) {
1702
                if ('other' === $data['data'] && 'multiplechoiceother' === $type) {
1703
                    continue;
1704
                }
1705
1706
                if (!in_array($data['iid'], $form_content['answersid'])) {
1707
                    $optionsToDelete[] = $data['iid'];
1708
                }
1709
            }
1710
        }
1711
1712
        if (!empty($optionsToDelete)) {
1713
            foreach ($optionsToDelete as $iid) {
1714
                $iid = (int) $iid;
1715
                $sql = "DELETE FROM $table
1716
			            WHERE
1717
			                iid = $iid AND
1718
			                c_id = $course_id AND
1719
                            question_id = '".intval($form_content['question_id'])."'
1720
                            ";
1721
                Database::query($sql);
1722
            }
1723
        }
1724
1725
        $counter = 1;
1726
        if (isset($form_content['answers']) && is_array($form_content['answers'])) {
1727
            for ($i = 0; $i < count($form_content['answers']); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1728
                $values = isset($form_content['values']) ? $form_content['values'][$i] : '';
1729
                $answerId = 0;
1730
                if (isset($form_content['answersid']) && isset($form_content['answersid'][$i])) {
1731
                    $answerId = $form_content['answersid'][$i];
1732
                }
1733
                if (empty($answerId)) {
1734
                    $params = [
1735
                        'c_id' => $course_id,
1736
                        'question_id' => $form_content['question_id'],
1737
                        'survey_id' => $form_content['survey_id'],
1738
                        'option_text' => $form_content['answers'][$i],
1739
                        'value' => $values,
1740
                        'sort' => $counter,
1741
                    ];
1742
                    $insertId = Database::insert($table, $params);
1743
                    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...
1744
                        $sql = "UPDATE $table
1745
                                SET question_option_id = $insertId
1746
                                WHERE iid = $insertId";
1747
                        Database::query($sql);
1748
                        $counter++;
1749
                    }
1750
                } else {
1751
                    $params = [
1752
                        'option_text' => $form_content['answers'][$i],
1753
                        'value' => $values,
1754
                        'sort' => $counter,
1755
                    ];
1756
                    Database::update($table, $params, ['iid = ?' => [$answerId]]);
1757
                    $counter++;
1758
                }
1759
            }
1760
        }
1761
1762
        if ('multiplechoiceother' === $type) {
1763
            // First time creation
1764
            if (empty($dataFromDatabase['answer_data'])) {
1765
                $params = [
1766
                    'c_id' => $course_id,
1767
                    'question_id' => $form_content['question_id'],
1768
                    'survey_id' => $form_content['survey_id'],
1769
                    'option_text' => 'other',
1770
                    'value' => 0,
1771
                    'sort' => $counter,
1772
                ];
1773
                $insertId = Database::insert($table, $params);
1774
                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...
1775
                    $sql = "UPDATE $table
1776
                            SET question_option_id = $insertId
1777
                            WHERE iid = $insertId";
1778
                    Database::query($sql);
1779
                }
1780
            } else {
1781
                $params = [
1782
                    'option_text' => 'other',
1783
                    'value' => 0,
1784
                    'sort' => $counter,
1785
                ];
1786
                Database::update(
1787
                    $table,
1788
                    $params,
1789
                    [
1790
                        'c_id = ? AND question_id = ? AND survey_id = ? AND option_text = ?' => [
1791
                            $course_id,
1792
                            $form_content['question_id'],
1793
                            $form_content['survey_id'],
1794
                            'other',
1795
                        ],
1796
                    ]
1797
                );
1798
            }
1799
        }
1800
    }
1801
1802
    /**
1803
     * This function stores the options of the questions in the shared table.
1804
     *
1805
     * @param array $form_content
1806
     *
1807
     * @author Patrick Cool <[email protected]>, Ghent University
1808
     *
1809
     * @version February 2007
1810
     *
1811
     * @todo writing the update statement when editing a question
1812
     */
1813
    public function save_shared_question_options($form_content, $survey_data)
1814
    {
1815
        if (is_array($form_content) && is_array($form_content['answers'])) {
1816
            // Table definition
1817
            $table = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1818
1819
            // We are editing a question so we first have to remove all the existing options from the database
1820
            $sql = "DELETE FROM $table
1821
                    WHERE question_id = '".Database::escape_string($form_content['shared_question_id'])."'";
1822
            Database::query($sql);
1823
1824
            $counter = 1;
1825
            foreach ($form_content['answers'] as &$answer) {
1826
                $params = [
1827
                    'question_id' => $form_content['shared_question_id'],
1828
                    'survey_id' => $survey_data['is_shared'],
1829
                    'option_text' => $answer,
1830
                    'sort' => $counter,
1831
                ];
1832
                Database::insert($table, $params);
1833
1834
                $counter++;
1835
            }
1836
        }
1837
    }
1838
1839
    /**
1840
     * This function deletes all the options of the questions of a given survey
1841
     * This function is normally only called when a survey is deleted.
1842
     *
1843
     * @param int $survey_id the id of the survey that has to be deleted
1844
     *
1845
     * @return true
1846
     *
1847
     * @author Patrick Cool <[email protected]>, Ghent University
1848
     *
1849
     * @version January 2007
1850
     */
1851
    public static function delete_all_survey_questions_options($survey_id, $shared = false)
1852
    {
1853
        // Table definitions
1854
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1855
        $course_id = api_get_course_int_id();
1856
        $course_condition = " c_id = $course_id AND ";
1857
        if ($shared) {
1858
            $course_condition = '';
1859
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1860
        }
1861
1862
        $sql = "DELETE FROM $table_survey_question_option
1863
                WHERE $course_condition survey_id='".intval($survey_id)."'";
1864
1865
        // Deleting the options of the survey questions
1866
        Database::query($sql);
1867
1868
        return true;
1869
    }
1870
1871
    /**
1872
     * This function deletes the options of a given question.
1873
     *
1874
     * @param int  $survey_id
1875
     * @param int  $question_id
1876
     * @param bool $shared
1877
     *
1878
     * @return bool
1879
     *
1880
     * @author Patrick Cool <[email protected]>, Ghent University
1881
     * @author Julio Montoya
1882
     *
1883
     * @version March 2007
1884
     */
1885
    public static function delete_survey_question_option(
1886
        $survey_id,
1887
        $question_id,
1888
        $shared = false
1889
    ) {
1890
        $course_id = api_get_course_int_id();
1891
        $course_condition = " c_id = $course_id AND ";
1892
1893
        // Table definitions
1894
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1895
        if ($shared) {
1896
            $course_condition = '';
1897
            $table = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1898
        }
1899
1900
        // Deleting the options of the survey questions
1901
        $sql = "DELETE FROM $table
1902
		        WHERE
1903
		            $course_condition survey_id='".intval($survey_id)."' AND
1904
		            question_id='".intval($question_id)."'";
1905
        Database::query($sql);
1906
1907
        return true;
1908
    }
1909
1910
    /**
1911
     * SURVEY ANSWERS FUNCTIONS.
1912
     */
1913
1914
    /**
1915
     * This function deletes all the answers anyone has given on this survey
1916
     * This function is normally only called when a survey is deleted.
1917
     *
1918
     * @param $survey_id the id of the survey that has to be deleted
1919
     *
1920
     * @return true
1921
     *
1922
     * @todo write the function
1923
     *
1924
     * @author Patrick Cool <[email protected]>, Ghent University
1925
     *
1926
     * @version January 2007,december 2008
1927
     */
1928
    public static function delete_all_survey_answers($survey_id)
1929
    {
1930
        $course_id = api_get_course_int_id();
1931
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
1932
        $survey_id = (int) $survey_id;
1933
        $sql = "DELETE FROM $table
1934
                WHERE c_id = $course_id AND survey_id = $survey_id";
1935
        Database::query($sql);
1936
1937
        return true;
1938
    }
1939
1940
    /**
1941
     * @param int $user_id
1942
     * @param int $survey_id
1943
     * @param int $course_id
1944
     *
1945
     * @return bool
1946
     */
1947
    public static function is_user_filled_survey($user_id, $survey_id, $course_id)
1948
    {
1949
        $table = Database::get_course_table(TABLE_SURVEY_ANSWER);
1950
        $user_id = (int) $user_id;
1951
        $course_id = (int) $course_id;
1952
        $survey_id = (int) $survey_id;
1953
1954
        $sql = "SELECT DISTINCT user
1955
                FROM $table
1956
                WHERE
1957
                    c_id		= $course_id AND
1958
                    user		= $user_id AND
1959
                    survey_id	= $survey_id";
1960
        $result = Database::query($sql);
1961
        if (Database::num_rows($result)) {
1962
            return true;
1963
        }
1964
1965
        return false;
1966
    }
1967
1968
    /**
1969
     * This function gets all the persons who have filled the survey.
1970
     *
1971
     * @param int $survey_id
1972
     *
1973
     * @return array
1974
     *
1975
     * @author Patrick Cool <[email protected]>, Ghent University
1976
     *
1977
     * @version February 2007
1978
     */
1979
    public static function get_people_who_filled_survey(
1980
        $survey_id,
1981
        $all_user_info = false,
1982
        $course_id = null
1983
    ) {
1984
        // Database table definition
1985
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1986
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
1987
1988
        // Variable initialisation
1989
        $return = [];
1990
1991
        if (empty($course_id)) {
1992
            $course_id = api_get_course_int_id();
1993
        } else {
1994
            $course_id = (int) $course_id;
1995
        }
1996
1997
        $survey_id = (int) $survey_id;
1998
1999
        if ($all_user_info) {
2000
            $order_clause = api_sort_by_first_name()
2001
                ? ' ORDER BY user.firstname, user.lastname'
2002
                : ' ORDER BY user.lastname, user.firstname';
2003
            $sql = "SELECT DISTINCT
2004
			            answered_user.user as invited_user,
2005
			            user.firstname,
2006
			            user.lastname,
2007
			            user.id as user_id
2008
                    FROM $table_survey_answer answered_user
2009
                    LEFT JOIN $table_user as user ON answered_user.user = user.id
2010
                    WHERE
2011
                        answered_user.c_id = $course_id AND
2012
                        survey_id= '".$survey_id."' ".
2013
                $order_clause;
2014
        } else {
2015
            $sql = "SELECT DISTINCT user FROM $table_survey_answer
2016
			        WHERE c_id = $course_id AND survey_id= '".$survey_id."'  ";
2017
2018
            if (api_get_configuration_value('survey_anonymous_show_answered')) {
2019
                $tblInvitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
2020
                $tblSurvey = Database::get_course_table(TABLE_SURVEY);
2021
2022
                $sql = "SELECT i.user FROM $tblInvitation i
2023
                    INNER JOIN $tblSurvey s
2024
                    ON i.survey_code = s.code
2025
                        AND i.c_id = s.c_id
2026
                        AND i.session_id = s.session_id
2027
                    WHERE i.answered IS TRUE AND s.iid = $survey_id";
2028
            }
2029
        }
2030
2031
        $res = Database::query($sql);
2032
        while ($row = Database::fetch_array($res, 'ASSOC')) {
2033
            if ($all_user_info) {
2034
                $userInfo = api_get_user_info($row['user_id']);
2035
                $row['user_info'] = $userInfo;
2036
                $return[] = $row;
2037
            } else {
2038
                $return[] = $row['user'];
2039
            }
2040
        }
2041
2042
        return $return;
2043
    }
2044
2045
    /**
2046
     * @return bool
2047
     */
2048
    public static function survey_generation_hash_available()
2049
    {
2050
        if (extension_loaded('mcrypt')) {
2051
            return true;
2052
        }
2053
2054
        return false;
2055
    }
2056
2057
    /**
2058
     * @param int $survey_id
2059
     * @param int $course_id
2060
     * @param int $session_id
2061
     * @param int $group_id
2062
     *
2063
     * @return string
2064
     */
2065
    public static function generate_survey_hash($survey_id, $course_id, $session_id, $group_id)
2066
    {
2067
        return hash('sha512', api_get_security_key().'_'.$course_id.'_'.$session_id.'_'.$group_id.'_'.$survey_id);
2068
    }
2069
2070
    /**
2071
     * @param int    $survey_id
2072
     * @param int    $course_id
2073
     * @param int    $session_id
2074
     * @param int    $group_id
2075
     * @param string $hash
2076
     *
2077
     * @return bool
2078
     */
2079
    public static function validate_survey_hash($survey_id, $course_id, $session_id, $group_id, $hash)
2080
    {
2081
        $generatedHash = self::generate_survey_hash($survey_id, $course_id, $session_id, $group_id);
2082
        if ($generatedHash == $hash) {
2083
            return true;
2084
        }
2085
2086
        return false;
2087
    }
2088
2089
    /**
2090
     * @param int $survey_id
2091
     * @param int $course_id
2092
     * @param int $session_id
2093
     * @param int $group_id
2094
     *
2095
     * @return string
2096
     */
2097
    public static function generate_survey_link(
2098
        $survey_id,
2099
        $course_id,
2100
        $session_id,
2101
        $group_id
2102
    ) {
2103
        $code = self::generate_survey_hash(
2104
            $survey_id,
2105
            $course_id,
2106
            $session_id,
2107
            $group_id
2108
        );
2109
2110
        return api_get_path(WEB_CODE_PATH).'survey/link.php?h='.$code.'&i='.$survey_id.'&c='.intval($course_id).'&s='
2111
            .intval($session_id).'&g='.$group_id;
2112
    }
2113
2114
    /**
2115
     * Check if the current user has mandatory surveys no-answered
2116
     * and redirect to fill the first found survey.
2117
     */
2118
    public static function protectByMandatory()
2119
    {
2120
        if (false !== strpos($_SERVER['SCRIPT_NAME'], 'fillsurvey.php')) {
2121
            return;
2122
        }
2123
2124
        $userId = api_get_user_id();
2125
        $courseId = api_get_course_int_id();
2126
        $sessionId = api_get_session_id();
2127
2128
        if (!$userId) {
2129
            return;
2130
        }
2131
2132
        if (!$courseId) {
2133
            return;
2134
        }
2135
2136
        try {
2137
            /** @var CSurveyInvitation $invitation */
2138
            $invitation = Database::getManager()
2139
                ->createQuery("
2140
                    SELECT i FROM ChamiloCourseBundle:CSurveyInvitation i
2141
                    INNER JOIN ChamiloCourseBundle:CSurvey s
2142
                        WITH (s.code = i.surveyCode AND s.cId = i.cId AND s.sessionId = i.sessionId)
2143
                    INNER JOIN ChamiloCoreBundle:ExtraFieldValues efv WITH efv.itemId = s.iid
2144
                    INNER JOIN ChamiloCoreBundle:ExtraField ef WITH efv.field = ef.id
2145
                    WHERE
2146
                        i.answered = 0 AND
2147
                        i.cId = :course AND
2148
                        i.user = :user AND
2149
                        i.sessionId = :session AND
2150
                        :now BETWEEN s.availFrom AND s.availTill AND
2151
                        ef.variable = :variable AND
2152
                        efv.value = 1 AND
2153
                        s.surveyType != 3
2154
                    ORDER BY s.availTill ASC
2155
                ")
2156
                ->setMaxResults(1)
2157
                ->setParameters([
2158
                    'course' => $courseId,
2159
                    'user' => $userId,
2160
                    'session' => $sessionId,
2161
                    'now' => new DateTime('UTC', new DateTimeZone('UTC')),
2162
                    'variable' => 'is_mandatory',
2163
                ])
2164
                ->getSingleResult();
2165
        } catch (Exception $e) {
2166
            $invitation = null;
2167
        }
2168
2169
        if (!$invitation) {
2170
            return;
2171
        }
2172
2173
        Display::addFlash(
2174
            Display::return_message(get_lang('MandatorySurveyNoAnswered'), 'warning')
2175
        );
2176
2177
        $url = SurveyUtil::generateFillSurveyLink(
2178
            $invitation->getInvitationCode(),
2179
            api_get_course_info(),
2180
            api_get_session_id()
2181
        );
2182
2183
        header('Location: '.$url);
2184
        exit;
2185
    }
2186
2187
    /**
2188
     * This function empty surveys (invitations and answers).
2189
     *
2190
     * @param int $surveyId id of the survey to empty
2191
     *
2192
     * @return bool
2193
     */
2194
    public static function emptySurveyFromId($surveyId)
2195
    {
2196
        // Database table definitions
2197
        $surveyInvitationTable = Database::get_course_table(TABLE_SURVEY_INVITATION);
2198
        $surveyAnswerTable = Database::get_course_table(TABLE_SURVEY_ANSWER);
2199
        $surveyTable = Database::get_course_table(TABLE_SURVEY);
2200
        $surveyId = (int) $surveyId;
2201
        $surveyData = self::get_survey($surveyId);
2202
        if (empty($surveyData)) {
2203
            return false;
2204
        }
2205
2206
        $surveyCode = $surveyData['survey_code'];
2207
        $courseId = (int) $surveyData['c_id'];
2208
        $sessionId = (int) $surveyData['session_id'];
2209
2210
        $sql = "DELETE FROM $surveyInvitationTable
2211
                WHERE session_id = $sessionId AND c_id = $courseId AND survey_code = '$surveyCode' ";
2212
        Database::query($sql);
2213
2214
        $sql = "DELETE FROM $surveyAnswerTable
2215
               WHERE survey_id = $surveyId AND c_id = $courseId ";
2216
        Database::query($sql);
2217
2218
        $sql = "UPDATE $surveyTable
2219
                SET invited = 0, answered = 0
2220
                WHERE survey_id = $surveyId AND c_id = $courseId AND session_id = $sessionId ";
2221
        Database::query($sql);
2222
2223
        return true;
2224
    }
2225
2226
    /**
2227
     * Copy survey specifying course ID and session ID where will be copied.
2228
     *
2229
     * @param int $surveyId
2230
     * @param int $targetCourseId  target course id
2231
     * @param int $targetSessionId target session id
2232
     *
2233
     * @return bool|int when fails or return the new survey id
2234
     */
2235
    public static function copySurveySession(
2236
        $surveyId,
2237
        $targetCourseId,
2238
        $targetSessionId
2239
    ) {
2240
        // Database table definitions
2241
        $surveyTable = Database::get_course_table(TABLE_SURVEY);
2242
        $surveyQuestionGroupTable = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
2243
        $surveyQuestionTable = Database::get_course_table(TABLE_SURVEY_QUESTION);
2244
        $surveyOptionsTable = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2245
        $surveyId = (int) $surveyId;
2246
        $targetCourseId = (int) $targetCourseId;
2247
        $targetSessionId = (int) $targetSessionId;
2248
2249
        $surveyData = self::get_survey($surveyId, 0, '', true);
2250
        if (empty($surveyData) || empty($targetCourseId)) {
2251
            return false;
2252
        }
2253
2254
        $originalCourseId = $surveyData['c_id'];
2255
        $originalSessionId = $surveyData['session_id'];
2256
2257
        $surveyData['code'] = self::generate_unique_code($surveyData['code']);
2258
        $surveyData['c_id'] = $targetCourseId;
2259
        $surveyData['session_id'] = $targetSessionId;
2260
        // Add a "Copy" suffix if copied inside the same course
2261
        if ($targetCourseId == $originalCourseId) {
2262
            $surveyData['title'] = $surveyData['title'].' '.get_lang('Copy');
2263
        }
2264
        unset($surveyData['iid']);
2265
        unset($surveyData['id']);
2266
2267
        $newSurveyId = Database::insert($surveyTable, $surveyData);
2268
2269
        if ($newSurveyId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $newSurveyId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2270
            $sql = "UPDATE $surveyTable SET survey_id = $newSurveyId
2271
                    WHERE iid = $newSurveyId";
2272
            Database::query($sql);
2273
2274
            $sql = "SELECT * FROM $surveyQuestionGroupTable
2275
                    WHERE c_id = $originalCourseId AND survey_id = $surveyId";
2276
            $res = Database::query($sql);
2277
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2278
                $params = [
2279
                    'c_id' => $targetCourseId,
2280
                    'name' => $row['name'],
2281
                    'description' => $row['description'],
2282
                    'survey_id' => $newSurveyId,
2283
                ];
2284
                $insertId = Database::insert($surveyQuestionGroupTable, $params);
2285
                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...
2286
                    $sql = "UPDATE $surveyQuestionGroupTable SET id = iid WHERE iid = $insertId";
2287
                    Database::query($sql);
2288
                    $group_id[$row['id']] = $insertId;
2289
                }
2290
            }
2291
2292
            // Get questions
2293
            $sql = "SELECT * FROM $surveyQuestionTable
2294
                    WHERE c_id = $originalCourseId AND survey_id = $surveyId";
2295
            $res = Database::query($sql);
2296
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2297
                $params = [
2298
                    'c_id' => $targetCourseId,
2299
                    'survey_id' => $newSurveyId,
2300
                    'survey_question' => $row['survey_question'],
2301
                    'survey_question_comment' => $row['survey_question_comment'],
2302
                    'type' => $row['type'],
2303
                    'display' => $row['display'],
2304
                    'sort' => $row['sort'],
2305
                    'shared_question_id' => $row['shared_question_id'],
2306
                    'max_value' => $row['max_value'],
2307
                    'survey_group_pri' => $row['survey_group_pri'],
2308
                    'survey_group_sec1' => $row['survey_group_sec1'],
2309
                    'survey_group_sec2' => $row['survey_group_sec2'],
2310
                ];
2311
2312
                if (api_get_configuration_value('allow_required_survey_questions')) {
2313
                    if (isset($row['is_required'])) {
2314
                        $params['is_required'] = $row['is_required'];
2315
                    }
2316
                }
2317
2318
                $insertId = Database::insert($surveyQuestionTable, $params);
2319
                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...
2320
                    $sql = "UPDATE $surveyQuestionTable
2321
                            SET question_id = iid
2322
                            WHERE iid = $insertId";
2323
                    Database::query($sql);
2324
2325
                    $question_id[$row['question_id']] = $insertId;
2326
                }
2327
            }
2328
2329
            // Get questions options
2330
            $sql = "SELECT * FROM $surveyOptionsTable
2331
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId";
2332
2333
            $res = Database::query($sql);
2334
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2335
                $params = [
2336
                    'c_id' => $targetCourseId,
2337
                    'question_id' => $question_id[$row['question_id']],
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question_id does not seem to be defined for all execution paths leading up to this point.
Loading history...
2338
                    'survey_id' => $newSurveyId,
2339
                    'option_text' => $row['option_text'],
2340
                    'sort' => $row['sort'],
2341
                    'value' => $row['value'],
2342
                ];
2343
                $insertId = Database::insert($surveyOptionsTable, $params);
2344
                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...
2345
                    $sql = "UPDATE $surveyOptionsTable SET question_option_id = $insertId WHERE iid = $insertId";
2346
                    Database::query($sql);
2347
                }
2348
            }
2349
2350
            return $newSurveyId;
2351
        }
2352
2353
        return false;
2354
    }
2355
2356
    /**
2357
     * Copy/duplicate one question (into the same survey).
2358
     * Note: Relies on the question iid to find all necessary info.
2359
     *
2360
     * @param int $questionId
2361
     *
2362
     * @return int The new question's iid, or 0 on error
2363
     */
2364
    public static function copyQuestion($questionId)
2365
    {
2366
        if (empty($questionId)) {
2367
            return 0;
2368
        }
2369
        $questionId = (int) $questionId;
2370
        $questionTable = Database::get_course_table(TABLE_SURVEY_QUESTION);
2371
        $optionsTable = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2372
2373
        // Get questions
2374
        $sql = "SELECT * FROM $questionTable WHERE iid = $questionId";
2375
        $res = Database::query($sql);
2376
        if (false == $res) {
2377
            // Could not find this question
2378
            return 0;
2379
        }
2380
        $row = Database::fetch_array($res, 'ASSOC');
2381
        $params = [
2382
            'c_id' => $row['c_id'],
2383
            'survey_id' => $row['survey_id'],
2384
            'survey_question' => trim($row['survey_question']),
2385
            'survey_question_comment' => $row['survey_question_comment'],
2386
            'type' => $row['type'],
2387
            'display' => $row['display'],
2388
            'shared_question_id' => $row['shared_question_id'],
2389
            'max_value' => $row['max_value'],
2390
            'survey_group_pri' => $row['survey_group_pri'],
2391
            'survey_group_sec1' => $row['survey_group_sec1'],
2392
            'survey_group_sec2' => $row['survey_group_sec2'],
2393
        ];
2394
        if (api_get_configuration_value('allow_required_survey_questions')) {
2395
            if (isset($row['is_required'])) {
2396
                $params['is_required'] = $row['is_required'];
2397
            }
2398
        }
2399
        // Get question position
2400
        $sqlSort = "SELECT max(sort) as sort FROM $questionTable
2401
                    WHERE survey_id = ".$row['survey_id'];
2402
        $resSort = Database::query($sqlSort);
2403
        $rowSort = Database::fetch_assoc($resSort);
2404
        $params['sort'] = $rowSort['sort'] + 1;
2405
        // Insert the new question
2406
        $insertId = Database::insert($questionTable, $params);
2407
        if (false == $insertId) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $insertId of type false|integer against false; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
2408
            return 0;
2409
        }
2410
        // Normalize question_id with iid
2411
        $sql = "UPDATE $questionTable
2412
                SET question_id = iid
2413
                WHERE iid = $insertId";
2414
        Database::query($sql);
2415
2416
        // Get questions options
2417
        $sql = "SELECT * FROM $optionsTable WHERE question_id = $questionId";
2418
        $res = Database::query($sql);
2419
        while ($row = Database::fetch_assoc($res)) {
2420
            $params = [
2421
                'c_id' => $row['c_id'],
2422
                'question_id' => $insertId,
2423
                'survey_id' => $row['survey_id'],
2424
                'option_text' => $row['option_text'],
2425
                'sort' => $row['sort'],
2426
                'value' => $row['value'],
2427
            ];
2428
            $optionId = Database::insert($optionsTable, $params);
2429
            if ($optionId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $optionId 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...
2430
                $sql = "UPDATE $optionsTable SET question_option_id = $optionId WHERE iid = $optionId";
2431
                Database::query($sql);
2432
            }
2433
        }
2434
2435
        return $insertId;
2436
    }
2437
2438
    /**
2439
     * @param array $surveyData
2440
     *
2441
     * @return bool
2442
     */
2443
    public static function removeMultiplicateQuestions($surveyData)
2444
    {
2445
        if (empty($surveyData)) {
2446
            return false;
2447
        }
2448
        $surveyId = $surveyData['survey_id'];
2449
        $courseId = $surveyData['c_id'];
2450
2451
        if (empty($surveyId) || empty($courseId)) {
2452
            return false;
2453
        }
2454
2455
        $questions = self::get_questions($surveyId);
2456
        foreach ($questions as $question) {
2457
            // Questions marked with "geneated" were created using the "multiplicate" feature.
2458
            if ($question['survey_question_comment'] === 'generated') {
2459
                self::delete_survey_question($surveyId, $question['question_id']);
2460
            }
2461
        }
2462
    }
2463
2464
    /**
2465
     * @param array  $surveyData
2466
     * @param string $type       by_class or by_user
2467
     *
2468
     * @return bool
2469
     */
2470
    public static function multiplicateQuestions($surveyData, $type)
2471
    {
2472
        if (empty($surveyData)) {
2473
            return false;
2474
        }
2475
        $surveyId = $surveyData['survey_id'];
2476
        $courseId = $surveyData['c_id'];
2477
2478
        if (empty($surveyId) || empty($courseId)) {
2479
            return false;
2480
        }
2481
2482
        $questions = self::get_questions($surveyId);
2483
2484
        if (empty($questions)) {
2485
            return false;
2486
        }
2487
2488
        $extraFieldValue = new ExtraFieldValue('survey');
2489
        $groupData = $extraFieldValue->get_values_by_handler_and_field_variable($surveyId, 'group_id');
2490
        $groupId = null;
2491
        if ($groupData && !empty($groupData['value'])) {
2492
            $groupId = (int) $groupData['value'];
2493
        }
2494
        switch ($type) {
2495
            case 'by_class':
2496
                if (null === $groupId) {
2497
                    $obj = new UserGroup();
2498
                    $options['where'] = [' usergroup.course_id = ? ' => $courseId];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $options = array(); before regardless.
Loading history...
2499
                    $classList = $obj->getUserGroupInCourse($options);
2500
                    $classToParse = [];
2501
                    foreach ($classList as $class) {
2502
                        $users = $obj->get_users_by_usergroup($class['id']);
2503
                        if (empty($users)) {
2504
                            continue;
2505
                        }
2506
                        $classToParse[] = [
2507
                            'name' => $class['name'],
2508
                            'users' => $users,
2509
                        ];
2510
                    }
2511
                    self::parseMultiplicateUserList($classToParse, $questions, $courseId, $surveyData, true);
2512
                } else {
2513
                    $groupInfo = GroupManager::get_group_properties($groupId);
2514
                    if (!empty($groupInfo)) {
2515
                        $users = GroupManager::getStudents($groupInfo['iid'], true);
2516
                        if (!empty($users)) {
2517
                            $users = array_column($users, 'id');
2518
                            self::parseMultiplicateUserList(
2519
                                [
2520
                                    [
2521
                                        'name' => $groupInfo['name'],
2522
                                        'users' => $users,
2523
                                    ],
2524
                                ],
2525
                                $questions,
2526
                                $courseId,
2527
                                $surveyData,
2528
                                false
2529
                            );
2530
                        }
2531
                    }
2532
                }
2533
                break;
2534
            case 'by_user':
2535
                if (null === $groupId) {
2536
                    $sessionId = api_get_session_id();
2537
                    $users = CourseManager::get_student_list_from_course_code(
2538
                        api_get_course_id(),
2539
                        !empty($sessionId),
2540
                        $sessionId
2541
                    );
2542
                    if (!empty($users)) {
2543
                        $users = array_column($users, 'id');
2544
                        self::parseMultiplicateUserListPerUser(
2545
                            [
2546
                                [
2547
                                    'name' => '',
2548
                                    'users' => $users,
2549
                                ],
2550
                            ],
2551
                            $questions,
2552
                            $courseId,
2553
                            $surveyData,
2554
                            false
2555
                        );
2556
                    }
2557
                } else {
2558
                    $groupInfo = GroupManager::get_group_properties($groupId);
2559
                    if (!empty($groupInfo)) {
2560
                        $users = GroupManager::getStudents($groupInfo['iid'], true);
2561
                        if (!empty($users)) {
2562
                            $users = array_column($users, 'id');
2563
                            self::parseMultiplicateUserListPerUser(
2564
                                [
2565
                                    [
2566
                                        'name' => $groupInfo['name'],
2567
                                        'users' => $users,
2568
                                    ],
2569
                                ],
2570
                                $questions,
2571
                                $courseId,
2572
                                $surveyData,
2573
                                false
2574
                            );
2575
                        }
2576
                    }
2577
                }
2578
                break;
2579
        }
2580
2581
        return true;
2582
    }
2583
2584
    public static function parseMultiplicateUserList($itemList, $questions, $courseId, $surveyData, $addClassNewPage = false)
2585
    {
2586
        if (empty($itemList) || empty($questions)) {
2587
            return false;
2588
        }
2589
2590
        $surveyId = $surveyData['survey_id'];
2591
        $classTag = '{{class_name}}';
2592
        $studentTag = '{{student_full_name}}';
2593
        $classCounter = 0;
2594
        $newQuestionList = [];
2595
        foreach ($questions as $question) {
2596
            $newQuestionList[$question['sort']] = $question;
2597
        }
2598
        ksort($newQuestionList);
2599
2600
        $order = api_get_configuration_value('survey_duplicate_order_by_name');
2601
        foreach ($itemList as $class) {
2602
            $className = $class['name'];
2603
            $users = $class['users'];
2604
            $userInfoList = [];
2605
            foreach ($users as $userId) {
2606
                $userInfoList[] = api_get_user_info($userId);
2607
            }
2608
2609
            if ($order) {
2610
                usort(
2611
                    $userInfoList,
2612
                    function ($a, $b) {
2613
                        return $a['lastname'] > $b['lastname'];
2614
                    }
2615
                );
2616
            }
2617
2618
            foreach ($newQuestionList as $question) {
2619
                $text = $question['question'];
2620
                if (false !== strpos($text, $classTag)) {
2621
                    $replacedText = str_replace($classTag, $className, $text);
2622
                    $values = [
2623
                        'c_id' => $courseId,
2624
                        'question_comment' => 'generated',
2625
                        'type' => $question['type'],
2626
                        'display' => $question['horizontalvertical'],
2627
                        'horizontalvertical' => $question['horizontalvertical'],
2628
                        'question' => $replacedText,
2629
                        'survey_id' => $surveyId,
2630
                        'question_id' => 0,
2631
                        'shared_question_id' => 0,
2632
                        'answers' => $question['answers'] ?? null,
2633
                    ];
2634
                    self::save_question($surveyData, $values, false);
2635
                    $classCounter++;
2636
                    continue;
2637
                }
2638
2639
                foreach ($userInfoList as $userInfo) {
2640
                    if (false !== strpos($text, $studentTag)) {
2641
                        $replacedText = str_replace($studentTag, $userInfo['complete_name'], $text);
2642
                        $values = [
2643
                            'c_id' => $courseId,
2644
                            'question_comment' => 'generated',
2645
                            'type' => $question['type'],
2646
                            'display' => $question['horizontalvertical'],
2647
                            'maximum_score' => $question['maximum_score'],
2648
                            'question' => $replacedText,
2649
                            'survey_id' => $surveyId,
2650
                            'question_id' => 0,
2651
                            'shared_question_id' => 0,
2652
                        ];
2653
2654
                        $answers = [];
2655
                        if (!empty($question['answers'])) {
2656
                            foreach ($question['answers'] as $answer) {
2657
                                $replacedText = str_replace($studentTag, $userInfo['complete_name'], $answer);
2658
                                $answers[] = $replacedText;
2659
                            }
2660
                        }
2661
                        $values['answers'] = $answers;
2662
                        self::save_question($surveyData, $values, false);
2663
                    }
2664
                }
2665
2666
                if ($addClassNewPage && $classCounter < count($itemList)) {
2667
                    self::addGeneratedNewPage($courseId, $surveyId, $surveyData, get_lang('QuestionForNextClass'));
2668
                }
2669
            }
2670
        }
2671
2672
        return true;
2673
    }
2674
2675
    public static function parseMultiplicateUserListPerUser(
2676
        $itemList,
2677
        $questions,
2678
        $courseId,
2679
        $surveyData,
2680
        $addClassNewPage = false
2681
    ) {
2682
        if (empty($itemList) || empty($questions)) {
2683
            return false;
2684
        }
2685
2686
        $surveyId = $surveyData['survey_id'];
2687
        $classTag = '{{class_name}}';
2688
        $studentTag = '{{student_full_name}}';
2689
        $classCounter = 0;
2690
        $newQuestionList = [];
2691
        foreach ($questions as $question) {
2692
            $newQuestionList[$question['sort']] = $question;
2693
        }
2694
        ksort($newQuestionList);
2695
2696
        $order = api_get_configuration_value('survey_duplicate_order_by_name');
2697
        foreach ($itemList as $class) {
2698
            $className = $class['name'];
2699
            $users = $class['users'];
2700
            $userInfoList = [];
2701
            foreach ($users as $userId) {
2702
                $userInfoList[] = api_get_user_info($userId);
2703
            }
2704
2705
            if ($order) {
2706
                usort(
2707
                    $userInfoList,
2708
                    function ($a, $b) {
2709
                        return $a['lastname'] > $b['lastname'];
2710
                    }
2711
                );
2712
            }
2713
2714
            /*foreach ($newQuestionList as $question) {
2715
                $text = $question['question'];
2716
                if (false === strpos($text, $studentTag)) {
2717
                    $values = [
2718
                        'c_id' => $courseId,
2719
                        'question_comment' => 'generated',
2720
                        'type' => $question['type'],
2721
                        'display' => $question['horizontalvertical'],
2722
                        'horizontalvertical' => $question['horizontalvertical'],
2723
                        'question' => $text,
2724
                        'survey_id' => $surveyId,
2725
                        'question_id' => 0,
2726
                        'shared_question_id' => 0,
2727
                        'answers' => $question['answers'] ?? null,
2728
                    ];
2729
                    self::save_question($surveyData, $values, false);
2730
                } else {
2731
                    break;
2732
                }
2733
            }*/
2734
2735
            self::addGeneratedNewPage($courseId, $surveyId, $surveyData, get_lang('QuestionForNextUser'));
2736
2737
            $counter = 0;
2738
            foreach ($userInfoList as $userInfo) {
2739
                foreach ($newQuestionList as $question) {
2740
                    $text = $question['question'];
2741
                    if (false !== strpos($text, $studentTag)) {
2742
                        $replacedText = str_replace($studentTag, $userInfo['complete_name'], $text);
2743
                        $values = [
2744
                            'c_id' => $courseId,
2745
                            'question_comment' => 'generated',
2746
                            'type' => $question['type'],
2747
                            'display' => $question['horizontalvertical'],
2748
                            'maximum_score' => $question['maximum_score'],
2749
                            'question' => $replacedText,
2750
                            'survey_id' => $surveyId,
2751
                            'question_id' => 0,
2752
                            'shared_question_id' => 0,
2753
                        ];
2754
2755
                        $answers = [];
2756
                        if (!empty($question['answers'])) {
2757
                            foreach ($question['answers'] as $answer) {
2758
                                $replacedText = str_replace($studentTag, $userInfo['complete_name'], $answer);
2759
                                $answers[] = $replacedText;
2760
                            }
2761
                        }
2762
                        $values['answers'] = $answers;
2763
                        self::save_question($surveyData, $values, false);
2764
                    }
2765
                }
2766
                $counter++;
2767
                if ($counter < count($userInfoList)) {
2768
                    self::addGeneratedNewPage($courseId, $surveyId, $surveyData, get_lang('QuestionForNextUser'));
2769
                }
2770
            }
2771
        }
2772
2773
        return true;
2774
    }
2775
2776
    public static function addGeneratedNewPage($courseId, $surveyId, $surveyData, $label)
2777
    {
2778
        // Add end page
2779
        $values = [
2780
            'c_id' => $courseId,
2781
            'question_comment' => 'generated',
2782
            'type' => 'pagebreak',
2783
            'display' => 'horizontal',
2784
            'question' => $label,
2785
            'survey_id' => $surveyId,
2786
            'question_id' => 0,
2787
            'shared_question_id' => 0,
2788
        ];
2789
        self::save_question($surveyData, $values, false);
2790
    }
2791
2792
    public static function hasDependency($survey)
2793
    {
2794
        if (false === api_get_configuration_value('survey_question_dependency')) {
2795
            return false;
2796
        }
2797
2798
        if (empty($survey)) {
2799
            return false;
2800
        }
2801
2802
        if (!isset($survey['survey_id'])) {
2803
            return false;
2804
        }
2805
2806
        $courseId = (int) $survey['c_id'];
2807
        $surveyId = (int) $survey['survey_id'];
2808
2809
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
2810
2811
        $sql = "SELECT COUNT(iid) count FROM $table
2812
                WHERE
2813
                    c_id = $courseId AND
2814
                    survey_id = $surveyId AND
2815
                    parent_option_id <> 0
2816
                LIMIT 1
2817
                ";
2818
        $result = Database::query($sql);
2819
        $row = Database::fetch_array($result);
2820
2821
        if ($row) {
2822
            return $row['count'] > 0;
2823
        }
2824
2825
        return false;
2826
    }
2827
2828
    /**
2829
     * @param array $survey
2830
     *
2831
     * @return int
2832
     */
2833
    public static function getCountPages($survey)
2834
    {
2835
        if (empty($survey) || !isset($survey['iid'])) {
2836
            return 0;
2837
        }
2838
2839
        $courseId = (int) $survey['c_id'];
2840
        $surveyId = (int) $survey['survey_id'];
2841
2842
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
2843
2844
        // pagebreak
2845
        $sql = "SELECT COUNT(iid) FROM $table
2846
                WHERE
2847
                    survey_question NOT LIKE '%{{%' AND
2848
                    type = 'pagebreak' AND
2849
                    c_id = $courseId AND
2850
                    survey_id = $surveyId";
2851
        $result = Database::query($sql);
2852
        $numberPageBreaks = Database::result($result, 0, 0);
2853
2854
        // No pagebreak
2855
        $sql = "SELECT COUNT(iid) FROM $table
2856
                WHERE
2857
                    survey_question NOT LIKE '%{{%' AND
2858
                    type != 'pagebreak' AND
2859
                    c_id = $courseId AND
2860
                    survey_id = $surveyId";
2861
        $result = Database::query($sql);
2862
        $countOfQuestions = Database::result($result, 0, 0);
2863
2864
        if (1 == $survey['one_question_per_page']) {
2865
            if (!empty($countOfQuestions)) {
2866
                return $countOfQuestions;
2867
            }
2868
2869
            return 1;
2870
        }
2871
2872
        if (empty($numberPageBreaks)) {
2873
            return 1;
2874
        }
2875
2876
        return $numberPageBreaks + 1;
2877
    }
2878
2879
    /**
2880
     * Check whether this survey has ended. If so, display message and exit rhis script.
2881
     *
2882
     * @param array $surveyData Survey data
2883
     */
2884
    public static function checkTimeAvailability($surveyData)
2885
    {
2886
        if (empty($surveyData)) {
2887
            api_not_allowed(true);
2888
        }
2889
2890
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
2891
        $utcZone = new DateTimeZone('UTC');
2892
        $startDate = new DateTime($surveyData['start_date'], $utcZone);
2893
        $endDate = new DateTime($surveyData['end_date'], $utcZone);
2894
        $currentDate = new DateTime('now', $utcZone);
2895
        if (!$allowSurveyAvailabilityDatetime) {
2896
            $currentDate->modify('today');
2897
        }
2898
        if ($currentDate < $startDate) {
2899
            api_not_allowed(
2900
                true,
2901
                Display::return_message(
2902
                    get_lang('SurveyNotAvailableYet'),
2903
                    'warning',
2904
                    false
2905
                )
2906
            );
2907
        }
2908
2909
        if ($currentDate > $endDate) {
2910
            api_not_allowed(
2911
                true,
2912
                Display::return_message(
2913
                    get_lang('SurveyNotAvailableAnymore'),
2914
                    'warning',
2915
                    false
2916
                )
2917
            );
2918
        }
2919
    }
2920
2921
    /**
2922
     * @param int    $userId
2923
     * @param string $surveyCode
2924
     * @param int    $courseId
2925
     * @param int    $sessionId
2926
     * @param int    $groupId
2927
     *
2928
     * @return array|CSurveyInvitation[]
2929
     */
2930
    public static function getUserInvitationsForSurveyInCourse(
2931
        $userId,
2932
        $surveyCode,
2933
        $courseId,
2934
        $sessionId = 0,
2935
        $groupId = 0,
2936
        $lpItemId = 0
2937
    ) {
2938
        $invitationRepo = Database::getManager()->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2939
2940
        $params = [
2941
            'user' => $userId,
2942
            'cId' => $courseId,
2943
            'sessionId' => $sessionId,
2944
            'groupId' => $groupId,
2945
            'surveyCode' => $surveyCode,
2946
        ];
2947
2948
        if (true === api_get_configuration_value('allow_survey_tool_in_lp')) {
2949
            $params['lpItemId'] = $lpItemId;
2950
        }
2951
2952
        return $invitationRepo->findBy(
2953
            $params,
2954
            ['invitationDate' => 'DESC']
2955
        );
2956
    }
2957
2958
    public static function getInvitationsAnswered(
2959
        $surveyCode,
2960
        $courseId,
2961
        $sessionId = 0
2962
    ) {
2963
        $invitationRepo = Database::getManager()->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2964
2965
        return $invitationRepo->findBy(
2966
            [
2967
                'cId' => $courseId,
2968
                'sessionId' => $sessionId,
2969
                'answered' => true,
2970
                'surveyCode' => $surveyCode,
2971
            ],
2972
            ['invitationDate' => 'DESC']
2973
        );
2974
    }
2975
2976
    /**
2977
     * @param array $userInfo
2978
     * @param int   $answered (1 = answered 0 = not answered)
2979
     *
2980
     * @return string
2981
     */
2982
    public static function surveyReport($userInfo, $answered = 0)
2983
    {
2984
        $userId = isset($userInfo['user_id']) ? (int) $userInfo['user_id'] : 0;
2985
        $answered = (int) $answered;
2986
2987
        if (empty($userId)) {
2988
            return '';
2989
        }
2990
2991
        $em = Database::getManager();
2992
        $repo = $em->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2993
        $repoSurvey = $em->getRepository('ChamiloCourseBundle:CSurvey');
2994
        $invitations = $repo->findBy(['user' => $userId, 'answered' => $answered]);
2995
        $mainUrl = api_get_path(WEB_CODE_PATH).'survey/survey.php?';
2996
        $content = '';
2997
2998
        if (empty($answered)) {
2999
            $content .= Display::page_subheader(get_lang('Unanswered'));
3000
        } else {
3001
            $content .= Display::page_subheader(get_lang('Answered'));
3002
        }
3003
3004
        if (!empty($invitations)) {
3005
            $table = new HTML_Table(['class' => 'table']);
3006
            $table->setHeaderContents(0, 0, get_lang('SurveyName'));
3007
            $table->setHeaderContents(0, 1, get_lang('Course'));
3008
3009
            if (empty($answered)) {
3010
                $table->setHeaderContents(0, 2, get_lang('Survey').' - '.get_lang('EndDate'));
3011
            }
3012
3013
            // Not answered
3014
            /** @var CSurveyInvitation $invitation */
3015
            $row = 1;
3016
            foreach ($invitations as $invitation) {
3017
                $courseId = $invitation->getCId();
3018
                $courseInfo = api_get_course_info_by_id($courseId);
3019
3020
                $courseCode = $courseInfo['code'];
3021
                if (empty($courseInfo)) {
3022
                    continue;
3023
                }
3024
                $sessionId = $invitation->getSessionId();
3025
3026
                if (!empty($answered)) {
3027
                    // check if user is subscribed to the course/session
3028
                    if (empty($sessionId)) {
3029
                        $subscribe = CourseManager::is_user_subscribed_in_course($userId, $courseCode);
3030
                    } else {
3031
                        $subscribe = CourseManager::is_user_subscribed_in_course(
3032
                            $userId,
3033
                            $courseCode,
3034
                            true,
3035
                            $sessionId
3036
                        );
3037
                    }
3038
3039
                    // User is not subscribe skip!
3040
                    if (empty($subscribe)) {
3041
                        continue;
3042
                    }
3043
                }
3044
3045
                $surveyCode = $invitation->getSurveyCode();
3046
3047
                $survey = $repoSurvey->findOneBy([
3048
                    'cId' => $courseId,
3049
                    'sessionId' => $sessionId,
3050
                    'code' => $surveyCode,
3051
                ]);
3052
3053
                if (empty($survey)) {
3054
                    continue;
3055
                }
3056
3057
                $url = $mainUrl.'survey_id='.$survey->getSurveyId().'&cidReq='.$courseCode.'&id_session='.$sessionId;
3058
                $title = $survey->getTitle();
3059
                $title = Display::url($title, $url);
3060
3061
                if (!empty($sessionId)) {
3062
                    $sessionInfo = api_get_session_info($sessionId);
3063
                    $courseInfo['name'] .= ' ('.$sessionInfo['name'].')';
3064
                }
3065
3066
                $surveyData = self::get_survey($survey->getSurveyId(), 0, $courseCode);
3067
                $table->setCellContents($row, 0, $title);
3068
                $table->setCellContents($row, 1, $courseInfo['name']);
3069
3070
                if (empty($answered)) {
3071
                    $table->setHeaderContents(
3072
                        $row,
3073
                        2,
3074
                        api_get_local_time(
3075
                            $survey->getAvailTill(),
3076
                            null,
3077
                            null,
3078
                            true,
3079
                            false
3080
                        )
3081
                    );
3082
                }
3083
3084
                if (!empty($answered) && $surveyData['anonymous'] == 0) {
3085
                    $answers = SurveyUtil::displayCompleteReport(
3086
                        $surveyData,
3087
                        $userId,
3088
                        false,
3089
                        false,
3090
                        false
3091
                    );
3092
                    $table->setCellContents(++$row, 0, $answers);
3093
                    $table->setCellContents(++$row, 1, '');
3094
                }
3095
3096
                $row++;
3097
            }
3098
            $content .= $table->toHtml();
3099
        } else {
3100
            $content .= Display::return_message(get_lang('NoData'));
3101
        }
3102
3103
        return $content;
3104
    }
3105
3106
    public static function sendToTutors($surveyId)
3107
    {
3108
        $survey = Database::getManager()->getRepository('ChamiloCourseBundle:CSurvey')->find($surveyId);
3109
        if (null === $survey) {
3110
            return false;
3111
        }
3112
3113
        $extraFieldValue = new ExtraFieldValue('survey');
3114
        $groupData = $extraFieldValue->get_values_by_handler_and_field_variable($surveyId, 'group_id');
3115
        if ($groupData && !empty($groupData['value'])) {
3116
            $groupInfo = GroupManager::get_group_properties($groupData['value']);
3117
            if ($groupInfo) {
3118
                $tutors = GroupManager::getTutors($groupInfo);
3119
                if (!empty($tutors)) {
3120
                    SurveyUtil::saveInviteMail(
3121
                        $survey,
3122
                        ' ',
3123
                        ' ',
3124
                        false
3125
                    );
3126
3127
                    foreach ($tutors as $tutor) {
3128
                        $subject = sprintf(get_lang('GroupSurveyX'), $groupInfo['name']);
3129
                        $content = sprintf(
3130
                            get_lang('HelloXGroupX'),
3131
                            $tutor['complete_name'],
3132
                            $groupInfo['name']
3133
                        );
3134
3135
                        SurveyUtil::saveInvitations(
3136
                            $surveyId,
3137
                            ['users' => $tutor['user_id']],
3138
                            $subject,
3139
                            $content,
3140
                            false,
3141
                            true,
3142
                            false,
3143
                            true
3144
                        );
3145
                    }
3146
                    Display::addFlash(Display::return_message(get_lang('Updated'), 'confirmation', false));
3147
                }
3148
                SurveyUtil::update_count_invited($survey->getCode());
3149
3150
                return true;
3151
            }
3152
        }
3153
3154
        return false;
3155
    }
3156
}
3157