Passed
Push — master ( 1cdc43...510ee8 )
by Julito
09:15
created

SurveyManager   F

Complexity

Total Complexity 243

Size/Duplication

Total Lines 2441
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 1264
dl 0
loc 2441
rs 0.8
c 0
b 0
f 0
wmc 243

40 Methods

Rating   Name   Duplication   Size   Complexity  
A delete_all_survey_invitations_by_user() 0 22 4
A generate_unique_code() 0 23 4
A get_surveys() 0 20 3
A store_shared_survey() 0 44 4
A delete_survey() 0 51 4
A save_shared_question_options() 0 22 4
A is_user_filled_survey() 0 19 2
F save_question() 0 175 30
A delete_all_survey_questions() 0 26 2
A save_shared_question() 0 45 3
A get_questions() 0 37 4
B get_question() 0 65 5
B move_survey_question() 0 46 6
F store_survey() 0 338 45
A delete_shared_survey_question() 0 18 1
A delete_survey_question() 0 22 2
A delete_all_survey_answers() 0 10 1
A generateSurveyCode() 0 3 1
A empty_survey() 0 32 3
B save_question_options() 0 50 11
A icon_question() 0 34 2
B get_survey() 0 65 10
A update_survey_answered() 0 43 3
D copy_survey() 0 127 12
A delete_all_survey_questions_options() 0 18 2
A delete_survey_question_option() 0 23 2
A generate_survey_hash() 0 5 1
A emptySurveyFromId() 0 30 2
B get_people_who_filled_survey() 0 64 7
C copySurveySession() 0 116 13
A validate_survey_hash() 0 8 2
A checkTimeAvailability() 0 32 5
A survey_generation_hash_available() 0 7 2
C multiplicateQuestions() 0 90 13
A removeMultiplicateQuestions() 0 17 6
B getCountPages() 0 44 6
A generate_survey_link() 0 15 1
B protectByMandatory() 0 67 6
B surveyReport() 0 64 8
A getUserInvitationsForSurveyInCourse() 0 20 1

How to fix   Complexity   

Complex Class

Complex classes like SurveyManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SurveyManager, and based on these observations, apply Extract Interface, too.

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

326
                        $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...
327
                        if ($pos === false) {
328
                            $row['survey_version'] = $row['survey_version'] + 1;
329
                            $versionValue = $row['survey_version'];
330
                        } else {
331
                            $getlast = explode('\.', $row['survey_version']);
332
                            $lastversion = array_pop($getlast);
333
                            $lastversion = $lastversion + 1;
334
                            $add = implode('.', $getlast);
335
                            if ($add != '') {
336
                                $insertnewversion = $add.'.'.$lastversion;
337
                            } else {
338
                                $insertnewversion = $lastversion;
339
                            }
340
                            $versionValue = $insertnewversion;
341
                        }
342
                    }
343
                    $survey->setSurveyVersion($versionValue);
344
                }
345
            }
346
347
            $from = api_get_utc_datetime($values['start_date'].'00:00:00', true, true);
348
            $until = api_get_utc_datetime($values['end_date'].'23:59:59', true, true);
349
            if ($allowSurveyAvailabilityDatetime) {
350
                $from = api_get_utc_datetime($values['start_date'].':00', true, true);
351
                $until = api_get_utc_datetime($values['end_date'].':59', true, true);
352
            }
353
354
            $survey
355
                ->setCId($course_id)
356
                ->setCode(self::generateSurveyCode($values['survey_code']))
357
                ->setTitle($values['survey_title'])
358
                ->setSubtitle($values['survey_title'])
359
                ->setAuthor($_user['user_id'])
360
                ->setLang($values['survey_language'])
361
                ->setAvailFrom($from)
362
                ->setAvailTill($until)
363
                ->setIsShared($shared_survey_id)
364
                ->setTemplate('template')
365
                ->setIntro($values['survey_introduction'])
366
                ->setSurveyThanks($values['survey_thanks'])
367
                ->setAnonymous($values['anonymous'])
368
                ->setSessionId(api_get_session_id())
369
                ->setVisibleResults($values['visible_results'])
370
            ;
371
372
            $em = Database::getManager();
373
            $em->persist($survey);
374
            $em->flush();
375
376
            $survey_id = $survey->getIid();
377
            if ($survey_id > 0) {
378
                $sql = "UPDATE $table_survey SET survey_id = $survey_id
379
                        WHERE iid = $survey_id";
380
                Database::query($sql);
381
382
                // Insert into item_property
383
                api_item_property_update(
384
                    api_get_course_info(),
385
                    TOOL_SURVEY,
386
                    $survey_id,
387
                    'SurveyAdded',
388
                    api_get_user_id()
389
                );
390
            }
391
392
            if ($values['survey_type'] == 1 && !empty($values['parent_id'])) {
393
                self::copy_survey($values['parent_id'], $survey_id);
394
            }
395
396
            Display::addFlash(
397
                Display::return_message(
398
                    get_lang('SurveyCreatedSuccesfully'),
399
                    'success'
400
                )
401
            );
402
            $return['id'] = $survey_id;
403
        } else {
404
            // Check whether the code doesn't soon exists in this language
405
            $sql = 'SELECT 1 FROM '.$table_survey.'
406
			        WHERE
407
			            c_id = '.$course_id.' AND
408
			            code = "'.Database::escape_string($values['survey_code']).'" AND
409
			            lang = "'.Database::escape_string($values['survey_language']).'" AND
410
			            survey_id !='.intval($values['survey_id']);
411
            $rs = Database::query($sql);
412
            if (Database::num_rows($rs) > 0) {
413
                Display::addFlash(
414
                    Display::return_message(
415
                        get_lang('ThisSurveyCodeSoonExistsInThisLanguage'),
416
                        'error'
417
                    )
418
                );
419
                $return['type'] = 'error';
420
                $return['id'] = isset($values['survey_id']) ? $values['survey_id'] : 0;
421
422
                return $return;
423
            }
424
425
            if (!isset($values['anonymous'])
426
                || (isset($values['anonymous']) && $values['anonymous'] == '')
427
            ) {
428
                $values['anonymous'] = 0;
429
            }
430
431
            $extraParams = [];
432
            $extraParams['one_question_per_page'] = isset($values['one_question_per_page']) ? $values['one_question_per_page'] : null;
433
            $extraParams['shuffle'] = isset($values['shuffle']) ? $values['shuffle'] : null;
434
435
            if ($values['anonymous'] == 0) {
436
                $extraParams['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : '';
437
                if ($extraParams['show_form_profile'] == 1) {
438
                    $fields = explode(',', $values['input_name_list']);
439
                    $field_values = '';
440
                    foreach ($fields as &$field) {
441
                        if ($field != '') {
442
                            if (!isset($values[$field]) ||
443
                                (isset($values[$field]) && $values[$field] == '')
444
                            ) {
445
                                $values[$field] = 0;
446
                            }
447
                            $field_values .= $field.':'.$values[$field].'@';
448
                        }
449
                    }
450
                    $extraParams['form_fields'] = $field_values;
451
                } else {
452
                    $extraParams['form_fields'] = '';
453
                }
454
            } else {
455
                $extraParams['show_form_profile'] = 0;
456
                $extraParams['form_fields'] = '';
457
            }
458
459
            $params = [
460
                'title' => $values['survey_title'],
461
                'subtitle' => $values['survey_subtitle'],
462
                'author' => $_user['user_id'],
463
                'lang' => $values['survey_language'],
464
                'avail_from' => $allowSurveyAvailabilityDatetime
465
                    ? api_get_utc_datetime($values['start_date'].':00')
466
                    : $values['start_date'],
467
                'avail_till' => $allowSurveyAvailabilityDatetime
468
                    ? api_get_utc_datetime($values['end_date'].':59')
469
                    : $values['end_date'],
470
                'is_shared' => $shared_survey_id,
471
                'template' => 'template',
472
                'intro' => $values['survey_introduction'],
473
                'surveythanks' => $values['survey_thanks'],
474
                'anonymous' => $values['anonymous'],
475
                'session_id' => api_get_session_id(),
476
                'visible_results' => $values['visible_results'],
477
            ];
478
479
            $params = array_merge($params, $extraParams);
480
            Database::update(
481
                $table_survey,
482
                $params,
483
                [
484
                    'c_id = ? AND survey_id = ?' => [
485
                        $course_id,
486
                        $values['survey_id'],
487
                    ],
488
                ]
489
            );
490
491
            // Update into item_property (update)
492
            api_item_property_update(
493
                api_get_course_info(),
494
                TOOL_SURVEY,
495
                $values['survey_id'],
496
                'SurveyUpdated',
497
                api_get_user_id()
498
            );
499
500
            Display::addFlash(
501
                Display::return_message(
502
                    get_lang('SurveyUpdatedSuccesfully'),
503
                    'confirmation'
504
                )
505
            );
506
507
            $return['id'] = $values['survey_id'];
508
        }
509
510
        $survey_id = (int) $return['id'];
511
512
        // Gradebook
513
        $gradebook_option = false;
514
        if (isset($values['survey_qualify_gradebook'])) {
515
            $gradebook_option = $values['survey_qualify_gradebook'] > 0;
516
        }
517
518
        $gradebook_link_type = 8;
519
        $link_info = GradebookUtils::isResourceInCourseGradebook(
520
            $courseCode,
521
            $gradebook_link_type,
522
            $survey_id,
523
            $session_id
524
        );
525
526
        $gradebook_link_id = isset($link_info['id']) ? $link_info['id'] : false;
527
528
        if ($gradebook_option) {
529
            if ($survey_id > 0) {
530
                $title_gradebook = ''; // Not needed here.
531
                $description_gradebook = ''; // Not needed here.
532
                $survey_weight = floatval($_POST['survey_weight']);
533
                $max_score = 1;
534
535
                if (!$gradebook_link_id) {
536
                    GradebookUtils::add_resource_to_course_gradebook(
537
                        $values['category_id'],
538
                        $courseCode,
539
                        $gradebook_link_type,
540
                        $survey_id,
541
                        $title_gradebook,
542
                        $survey_weight,
543
                        $max_score,
544
                        $description_gradebook,
545
                        1,
546
                        $session_id
547
                    );
548
                } else {
549
                    GradebookUtils::updateResourceFromCourseGradebook(
550
                        $gradebook_link_id,
551
                        $courseCode,
552
                        $survey_weight
553
                    );
554
                }
555
            }
556
        } else {
557
            // Delete everything of the gradebook for this $linkId
558
            GradebookUtils::remove_resource_from_course_gradebook($gradebook_link_id);
559
        }
560
561
        return $return;
562
    }
563
564
    /**
565
     * This function stores a shared survey in the central database.
566
     *
567
     * @param array $values
568
     *
569
     * @return array $return the type of return message that has to be displayed and the message in it
570
     *
571
     * @author Patrick Cool <[email protected]>, Ghent University
572
     *
573
     * @version February 2007
574
     */
575
    public function store_shared_survey($values)
576
    {
577
        $_user = api_get_user_info();
578
        $_course = api_get_course_info();
579
580
        // Table definitions
581
        $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
582
583
        if (!$values['survey_id'] ||
584
            !is_numeric($values['survey_id']) ||
585
            $values['survey_share']['survey_share'] == 'true'
586
        ) {
587
            $sql = "INSERT INTO $table_survey (code, title, subtitle, author, lang, template, intro, surveythanks, creation_date, course_code) VALUES (
588
                    '".Database::escape_string($values['survey_code'])."',
589
                    '".Database::escape_string($values['survey_title'])."',
590
                    '".Database::escape_string($values['survey_subtitle'])."',
591
                    '".intval($_user['user_id'])."',
592
                    '".Database::escape_string($values['survey_language'])."',
593
                    '".Database::escape_string('template')."',
594
                    '".Database::escape_string($values['survey_introduction'])."',
595
                    '".Database::escape_string($values['survey_thanks'])."',
596
                    '".api_get_utc_datetime()."',
597
                    '".$_course['id']."')";
598
            Database::query($sql);
599
            $return = Database::insert_id();
600
601
            $sql = "UPDATE $table_survey SET survey_id = $return WHERE iid = $return";
602
            Database::query($sql);
603
        } else {
604
            $sql = "UPDATE $table_survey SET
605
                        code 			= '".Database::escape_string($values['survey_code'])."',
606
                        title 			= '".Database::escape_string($values['survey_title'])."',
607
                        subtitle 		= '".Database::escape_string($values['survey_subtitle'])."',
608
                        author 			= '".intval($_user['user_id'])."',
609
                        lang 			= '".Database::escape_string($values['survey_language'])."',
610
                        template 		= '".Database::escape_string('template')."',
611
                        intro			= '".Database::escape_string($values['survey_introduction'])."',
612
                        surveythanks	= '".Database::escape_string($values['survey_thanks'])."'
613
					WHERE survey_id = '".Database::escape_string($values['survey_share']['survey_share'])."'";
614
            Database::query($sql);
615
            $return = $values['survey_share']['survey_share'];
616
        }
617
618
        return $return;
619
    }
620
621
    /**
622
     * This function deletes a survey (and also all the question in that survey.
623
     *
624
     * @param int  $survey_id id of the survey that has to be deleted
625
     * @param bool $shared
626
     * @param int  $course_id
627
     *
628
     * @return true
629
     *
630
     * @author Patrick Cool <[email protected]>, Ghent University
631
     *
632
     * @version January 2007
633
     */
634
    public static function delete_survey($survey_id, $shared = false, $course_id = 0)
635
    {
636
        // Database table definitions
637
        if (empty($course_id)) {
638
            $course_id = api_get_course_int_id();
639
        }
640
641
        $survey_id = (int) $survey_id;
642
643
        if (empty($survey_id)) {
644
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type true.
Loading history...
645
        }
646
647
        $course_info = api_get_course_info_by_id($course_id);
648
        $course_id = $course_info['real_id'];
649
650
        $table_survey = Database::get_course_table(TABLE_SURVEY);
651
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
652
653
        if ($shared) {
654
            $table_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
655
            // Deleting the survey
656
            $sql = "DELETE FROM $table_survey
657
                    WHERE survey_id='".$survey_id."'";
658
            Database::query($sql);
659
        } else {
660
            $sql = "DELETE FROM $table_survey
661
                    WHERE c_id = $course_id AND survey_id='".$survey_id."'";
662
            Database::query($sql);
663
        }
664
665
        // Deleting groups of this survey
666
        $sql = "DELETE FROM $table_survey_question_group
667
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
668
        Database::query($sql);
669
670
        // Deleting the questions of the survey
671
        self::delete_all_survey_questions($survey_id, $shared);
672
673
        // Update into item_property (delete)
674
        api_item_property_update(
675
            $course_info,
676
            TOOL_SURVEY,
677
            $survey_id,
678
            'SurveyDeleted',
679
            api_get_user_id()
680
        );
681
682
        Skill::deleteSkillsFromItem($survey_id, ITEM_TYPE_SURVEY);
683
684
        return true;
685
    }
686
687
    /**
688
     * @param int $survey_id
689
     * @param int $new_survey_id
690
     * @param int $targetCourseId
691
     *
692
     * @return bool
693
     */
694
    public static function copy_survey(
695
        $survey_id,
696
        $new_survey_id = null,
697
        $targetCourseId = null
698
    ) {
699
        $course_id = api_get_course_int_id();
700
        if (!$targetCourseId) {
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...
701
            $targetCourseId = $course_id;
702
        }
703
704
        // Database table definitions
705
        $table_survey = Database::get_course_table(TABLE_SURVEY);
706
        $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
707
        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
708
        $table_survey_options = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
709
        $survey_id = (int) $survey_id;
710
711
        // Get groups
712
        $survey_data = self::get_survey($survey_id, 0, null, true);
713
        if (empty($survey_data)) {
714
            return true;
715
        }
716
717
        if (empty($new_survey_id)) {
718
            $params = $survey_data;
719
            $params['code'] = self::generate_unique_code($params['code']);
720
            $params['c_id'] = $targetCourseId;
721
            unset($params['survey_id']);
722
            $params['session_id'] = api_get_session_id();
723
            $params['title'] = $params['title'].' '.get_lang('Copy');
724
            unset($params['iid']);
725
            $new_survey_id = Database::insert($table_survey, $params);
726
727
            if ($new_survey_id) {
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...
728
                $sql = "UPDATE $table_survey SET survey_id = $new_survey_id
729
                        WHERE iid = $new_survey_id";
730
                Database::query($sql);
731
732
                // Insert into item_property
733
                api_item_property_update(
734
                    api_get_course_info(),
735
                    TOOL_SURVEY,
736
                    $new_survey_id,
737
                    'SurveyAdded',
738
                    api_get_user_id()
739
                );
740
            }
741
        } else {
742
            $new_survey_id = (int) $new_survey_id;
743
        }
744
745
        $sql = "SELECT * FROM $table_survey_question_group
746
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
747
        $res = Database::query($sql);
748
        while ($row = Database::fetch_array($res, 'ASSOC')) {
749
            $params = [
750
                'c_id' => $targetCourseId,
751
                'name' => $row['name'],
752
                'description' => $row['description'],
753
                'survey_id' => $new_survey_id,
754
            ];
755
            $insertId = Database::insert($table_survey_question_group, $params);
756
757
            $sql = "UPDATE $table_survey_question_group SET id = iid
758
                    WHERE iid = $insertId";
759
            Database::query($sql);
760
761
            $group_id[$row['id']] = $insertId;
762
        }
763
764
        // Get questions
765
        $sql = "SELECT * FROM $table_survey_question
766
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
767
        $res = Database::query($sql);
768
        while ($row = Database::fetch_array($res, 'ASSOC')) {
769
            $params = [
770
                'c_id' => $targetCourseId,
771
                'survey_id' => $new_survey_id,
772
                'survey_question' => $row['survey_question'],
773
                'survey_question_comment' => $row['survey_question_comment'],
774
                'type' => $row['type'],
775
                'display' => $row['display'],
776
                'sort' => $row['sort'],
777
                'shared_question_id' => $row['shared_question_id'],
778
                'max_value' => $row['max_value'],
779
                'survey_group_pri' => $row['survey_group_pri'],
780
                'survey_group_sec1' => $row['survey_group_sec1'],
781
                'survey_group_sec2' => $row['survey_group_sec2'],
782
            ];
783
784
            if (api_get_configuration_value('allow_required_survey_questions')) {
785
                if (isset($row['is_required'])) {
786
                    $params['is_required'] = $row['is_required'];
787
                }
788
            }
789
790
            $insertId = Database::insert($table_survey_question, $params);
791
            if ($insertId) {
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...
792
                $sql = "UPDATE $table_survey_question SET question_id = iid WHERE iid = $insertId";
793
                Database::query($sql);
794
                $question_id[$row['question_id']] = $insertId;
795
            }
796
        }
797
798
        // Get questions options
799
        $sql = "SELECT * FROM $table_survey_options
800
                WHERE c_id = $course_id AND survey_id='".$survey_id."'";
801
802
        $res = Database::query($sql);
803
        while ($row = Database::fetch_array($res, 'ASSOC')) {
804
            $params = [
805
                'c_id' => $targetCourseId,
806
                'question_id' => $question_id[$row['question_id']],
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...
807
                'survey_id' => $new_survey_id,
808
                'option_text' => $row['option_text'],
809
                'sort' => $row['sort'],
810
                'value' => $row['value'],
811
            ];
812
            $insertId = Database::insert($table_survey_options, $params);
813
            if ($insertId) {
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...
814
                $sql = "UPDATE $table_survey_options SET question_option_id = $insertId
815
                        WHERE iid = $insertId";
816
                Database::query($sql);
817
            }
818
        }
819
820
        return $new_survey_id;
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...
821
    }
822
823
    /**
824
     * This function duplicates a survey (and also all the question in that survey.
825
     *
826
     * @param int $surveyId id of the survey that has to be duplicated
827
     * @param int $courseId id of the course which survey has to be duplicated
828
     *
829
     * @return true
830
     *
831
     * @author Eric Marguin <[email protected]>, Elixir Interactive
832
     *
833
     * @version October 2007
834
     */
835
    public static function empty_survey($surveyId, $courseId = 0)
836
    {
837
        // Database table definitions
838
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
839
        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
840
        $table_survey = Database::get_course_table(TABLE_SURVEY);
841
842
        $courseId = (int) $courseId;
843
        $courseId = empty($courseId) ? api_get_course_int_id() : $courseId;
844
        $surveyId = (int) $surveyId;
845
846
        $datas = self::get_survey($surveyId);
847
        $session_where = '';
848
        if (api_get_session_id() != 0) {
849
            $session_where = ' AND session_id = "'.api_get_session_id().'" ';
850
        }
851
852
        $sql = 'DELETE FROM '.$table_survey_invitation.'
853
		        WHERE
854
		            c_id = '.$courseId.' AND
855
		            survey_code = "'.Database::escape_string($datas['code']).'" '.$session_where.' ';
856
        Database::query($sql);
857
858
        $sql = 'DELETE FROM '.$table_survey_answer.'
859
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
860
        Database::query($sql);
861
862
        $sql = 'UPDATE '.$table_survey.' SET invited=0, answered=0
863
		        WHERE c_id = '.$courseId.' AND survey_id='.$surveyId;
864
        Database::query($sql);
865
866
        return true;
867
    }
868
869
    /**
870
     * This function recalculates the number of people who have taken the survey (=filled at least one question).
871
     *
872
     * @param array  $survey_data
873
     * @param array  $user
874
     * @param string $survey_code
875
     *
876
     * @return bool
877
     *
878
     * @author Patrick Cool <[email protected]>, Ghent University
879
     *
880
     * @version February 2007
881
     */
882
    public static function update_survey_answered($survey_data, $user, $survey_code)
883
    {
884
        if (empty($survey_data)) {
885
            return false;
886
        }
887
888
        // Database table definitions
889
        $table_survey = Database::get_course_table(TABLE_SURVEY);
890
        $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
891
892
        $survey_id = (int) $survey_data['survey_id'];
893
        $course_id = (int) $survey_data['c_id'];
894
        $session_id = $survey_data['session_id'];
895
896
        // Getting a list with all the people who have filled the survey
897
        /*$people_filled = self::get_people_who_filled_survey($survey_id, false, $course_id);
898
        $number = count($people_filled);*/
899
900
        // Storing this value in the survey table
901
        $sql = "UPDATE $table_survey
902
		        SET answered = answered + 1
903
		        WHERE
904
                    c_id = $course_id AND
905
		            survey_id = ".$survey_id;
906
        Database::query($sql);
907
908
        $allow = api_get_configuration_value('survey_answered_at_field');
909
        // Requires DB change:
910
        // ALTER TABLE c_survey_invitation ADD answered_at DATETIME DEFAULT NULL;
911
        $answeredAt = '';
912
        if ($allow) {
913
            $answeredAt = "answered_at = '".api_get_utc_datetime()."',";
914
        }
915
916
        // Storing that the user has finished the survey.
917
        $sql = "UPDATE $table_survey_invitation
918
                SET $answeredAt answered = 1
919
                WHERE
920
                    c_id = $course_id AND
921
                    session_id = $session_id AND
922
                    user ='".Database::escape_string($user)."' AND
923
                    survey_code='".Database::escape_string($survey_code)."'";
924
        Database::query($sql);
925
    }
926
927
    /**
928
     * This function return the "icon" of the question type.
929
     *
930
     * @param string $type
931
     *
932
     * @author Patrick Cool <[email protected]>, Ghent University
933
     *
934
     * @version February 2007
935
     */
936
    public static function icon_question($type)
937
    {
938
        // the possible question types
939
        $possible_types = [
940
            'personality',
941
            'yesno',
942
            'multiplechoice',
943
            'multipleresponse',
944
            'open',
945
            'dropdown',
946
            'comment',
947
            'pagebreak',
948
            'percentage',
949
            'score',
950
        ];
951
952
        // the images array
953
        $icon_question = [
954
            'yesno' => 'yesno.png',
955
            'personality' => 'yesno.png',
956
            'multiplechoice' => 'mcua.png',
957
            'multipleresponse' => 'mcma.png',
958
            'open' => 'open_answer.png',
959
            'dropdown' => 'dropdown.png',
960
            'percentage' => 'percentagequestion.png',
961
            'score' => 'scorequestion.png',
962
            'comment' => 'commentquestion.png',
963
            'pagebreak' => 'page_end.png',
964
        ];
965
966
        if (in_array($type, $possible_types)) {
967
            return $icon_question[$type];
968
        } else {
969
            return false;
970
        }
971
    }
972
973
    /**
974
     * This function retrieves all the information of a question.
975
     *
976
     * @param int  $question_id the id of the question
977
     * @param bool $shared
978
     *
979
     * @return array
980
     *
981
     * @author Patrick Cool <[email protected]>, Ghent University
982
     *
983
     * @version January 2007
984
     *
985
     * @todo one sql call should do the trick
986
     */
987
    public static function get_question($question_id, $shared = false)
988
    {
989
        // Table definitions
990
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
991
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
992
        $course_id = api_get_course_int_id();
993
        $question_id = (int) $question_id;
994
995
        $sql = "SELECT * FROM $tbl_survey_question
996
                WHERE c_id = $course_id AND question_id='".$question_id."'
997
                ORDER BY `sort` ";
998
999
        $sqlOption = "  SELECT * FROM $table_survey_question_option
1000
                        WHERE c_id = $course_id AND question_id='".$question_id."'
1001
                        ORDER BY `sort` ";
1002
1003
        if ($shared) {
1004
            $tbl_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
1005
            $table_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
1006
1007
            $sql = "SELECT * FROM $tbl_survey_question
1008
                    WHERE question_id='".$question_id."'
1009
                    ORDER BY `sort` ";
1010
            $sqlOption = "SELECT * FROM $table_survey_question_option
1011
                          WHERE question_id='".$question_id."'
1012
                          ORDER BY `sort` ";
1013
        }
1014
1015
        // Getting the information of the question
1016
1017
        $result = Database::query($sql);
1018
        $row = Database::fetch_array($result, 'ASSOC');
1019
1020
        $return['survey_id'] = $row['survey_id'];
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...
1021
        $return['question_id'] = $row['question_id'];
1022
        $return['type'] = $row['type'];
1023
        $return['question'] = $row['survey_question'];
1024
        $return['horizontalvertical'] = $row['display'];
1025
        $return['shared_question_id'] = $row['shared_question_id'];
1026
        $return['maximum_score'] = $row['max_value'];
1027
        $return['is_required'] = api_get_configuration_value('allow_required_survey_questions')
1028
            ? $row['is_required']
1029
            : false;
1030
1031
        if ($row['survey_group_pri'] != 0) {
1032
            $return['assigned'] = $row['survey_group_pri'];
1033
            $return['choose'] = 1;
1034
        } else {
1035
            $return['assigned1'] = $row['survey_group_sec1'];
1036
            $return['assigned2'] = $row['survey_group_sec2'];
1037
            $return['choose'] = 2;
1038
        }
1039
1040
        // Getting the information of the question options
1041
        $result = Database::query($sqlOption);
1042
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1043
            /** @todo this should be renamed to options instead of answers */
1044
            $return['answers'][] = $row['option_text'];
1045
            $return['values'][] = $row['value'];
1046
1047
            /** @todo this can be done more elegantly (used in reporting) */
1048
            $return['answersid'][] = $row['question_option_id'];
1049
        }
1050
1051
        return $return;
1052
    }
1053
1054
    /**
1055
     * This function gets all the question of any given survey.
1056
     *
1057
     * @param int $surveyId the id of the survey
1058
     * @param int $courseId
1059
     *
1060
     * @return array containing all the questions of the survey
1061
     *
1062
     * @author Patrick Cool <[email protected]>, Ghent University
1063
     *
1064
     * @version February 2007
1065
     *
1066
     * @todo one sql call should do the trick
1067
     */
1068
    public static function get_questions($surveyId, $courseId = 0)
1069
    {
1070
        $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1071
        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1072
1073
        $courseId = (int) $courseId;
1074
        $surveyId = (int) $surveyId;
1075
1076
        if (empty($courseId)) {
1077
            $courseId = api_get_course_int_id();
1078
        }
1079
1080
        // Getting the information of the question
1081
        $sql = "SELECT * FROM $tbl_survey_question
1082
		        WHERE c_id = $courseId AND survey_id='".$surveyId."'";
1083
        $result = Database::query($sql);
1084
        $return = [];
1085
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1086
            $return[$row['question_id']]['survey_id'] = $row['survey_id'];
1087
            $return[$row['question_id']]['question_id'] = $row['question_id'];
1088
            $return[$row['question_id']]['type'] = $row['type'];
1089
            $return[$row['question_id']]['question'] = $row['survey_question'];
1090
            $return[$row['question_id']]['horizontalvertical'] = $row['display'];
1091
            $return[$row['question_id']]['maximum_score'] = $row['max_value'];
1092
            $return[$row['question_id']]['sort'] = $row['sort'];
1093
            $return[$row['question_id']]['survey_question_comment'] = $row['survey_question_comment'];
1094
        }
1095
1096
        // Getting the information of the question options
1097
        $sql = "SELECT * FROM $table_survey_question_option
1098
		        WHERE c_id = $courseId AND survey_id='".$surveyId."'";
1099
        $result = Database::query($sql);
1100
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1101
            $return[$row['question_id']]['answers'][] = $row['option_text'];
1102
        }
1103
1104
        return $return;
1105
    }
1106
1107
    /**
1108
     * This function saves a question in the database.
1109
     * This can be either an update of an existing survey or storing a new survey.
1110
     *
1111
     * @param array $survey_data
1112
     * @param array $form_content all the information of the form
1113
     *
1114
     * @return string
1115
     *
1116
     * @author Patrick Cool <[email protected]>, Ghent University
1117
     *
1118
     * @version January 2007
1119
     */
1120
    public static function save_question($survey_data, $form_content)
1121
    {
1122
        $return_message = '';
1123
        if (strlen($form_content['question']) > 1) {
1124
            // Checks length of the question
1125
            $empty_answer = false;
1126
1127
            if ($survey_data['survey_type'] == 1) {
1128
                if (empty($form_content['choose'])) {
1129
                    $return_message = 'PleaseChooseACondition';
1130
1131
                    return $return_message;
1132
                }
1133
1134
                if (($form_content['choose'] == 2) &&
1135
                    ($form_content['assigned1'] == $form_content['assigned2'])
1136
                ) {
1137
                    $return_message = 'ChooseDifferentCategories';
1138
1139
                    return $return_message;
1140
                }
1141
            }
1142
1143
            if ($form_content['type'] != 'percentage') {
1144
                if (isset($form_content['answers'])) {
1145
                    for ($i = 0; $i < count($form_content['answers']); $i++) {
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...
1146
                        if (strlen($form_content['answers'][$i]) < 1) {
1147
                            $empty_answer = true;
1148
                            break;
1149
                        }
1150
                    }
1151
                }
1152
            }
1153
1154
            if ($form_content['type'] == 'score') {
1155
                if (strlen($form_content['maximum_score']) < 1) {
1156
                    $empty_answer = true;
1157
                }
1158
            }
1159
            $course_id = api_get_course_int_id();
1160
            if (!$empty_answer) {
1161
                // Table definitions
1162
                $tbl_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1163
1164
                // Getting all the information of the survey
1165
                $survey_data = self::get_survey($form_content['survey_id']);
1166
1167
                // Storing the question in the shared database
1168
                if (is_numeric($survey_data['survey_share']) && $survey_data['survey_share'] != 0) {
1169
                    $shared_question_id = self::save_shared_question($form_content, $survey_data);
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

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

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

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

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

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

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

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2074
                    $sql = "UPDATE $surveyQuestionGroupTable SET id = iid WHERE iid = $insertId";
2075
                    Database::query($sql);
2076
                    $group_id[$row['id']] = $insertId;
2077
                }
2078
            }
2079
2080
            // Get questions
2081
            $sql = "SELECT * FROM $surveyQuestionTable 
2082
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId";
2083
            $res = Database::query($sql);
2084
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2085
                $params = [
2086
                    'c_id' => $targetCourseId,
2087
                    'survey_id' => $newSurveyId,
2088
                    'survey_question' => $row['survey_question'],
2089
                    'survey_question_comment' => $row['survey_question_comment'],
2090
                    'type' => $row['type'],
2091
                    'display' => $row['display'],
2092
                    'sort' => $row['sort'],
2093
                    'shared_question_id' => $row['shared_question_id'],
2094
                    'max_value' => $row['max_value'],
2095
                    'survey_group_pri' => $row['survey_group_pri'],
2096
                    'survey_group_sec1' => $row['survey_group_sec1'],
2097
                    'survey_group_sec2' => $row['survey_group_sec2'],
2098
                ];
2099
2100
                if (api_get_configuration_value('allow_required_survey_questions')) {
2101
                    if (isset($row['is_required'])) {
2102
                        $params['is_required'] = $row['is_required'];
2103
                    }
2104
                }
2105
2106
                $insertId = Database::insert($surveyQuestionTable, $params);
2107
                if ($insertId) {
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...
2108
                    $sql = "UPDATE $surveyQuestionTable 
2109
                            SET question_id = iid
2110
                            WHERE iid = $insertId";
2111
                    Database::query($sql);
2112
2113
                    $question_id[$row['question_id']] = $insertId;
2114
                }
2115
            }
2116
2117
            // Get questions options
2118
            $sql = "SELECT * FROM $surveyOptionsTable 
2119
                    WHERE survey_id = $surveyId AND c_id = $originalCourseId";
2120
2121
            $res = Database::query($sql);
2122
            while ($row = Database::fetch_array($res, 'ASSOC')) {
2123
                $params = [
2124
                    'c_id' => $targetCourseId,
2125
                    'question_id' => $question_id[$row['question_id']],
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...
2126
                    'survey_id' => $newSurveyId,
2127
                    'option_text' => $row['option_text'],
2128
                    'sort' => $row['sort'],
2129
                    'value' => $row['value'],
2130
                ];
2131
                $insertId = Database::insert($surveyOptionsTable, $params);
2132
                if ($insertId) {
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...
2133
                    $sql = "UPDATE $surveyOptionsTable SET question_option_id = $insertId WHERE iid = $insertId";
2134
                    Database::query($sql);
2135
                }
2136
            }
2137
2138
            return $newSurveyId;
2139
        }
2140
2141
        return false;
2142
    }
2143
2144
    /**
2145
     * @param array $surveyData
2146
     *
2147
     * @return bool
2148
     */
2149
    public static function removeMultiplicateQuestions($surveyData)
2150
    {
2151
        if (empty($surveyData)) {
2152
            return false;
2153
        }
2154
        $surveyId = $surveyData['survey_id'];
2155
        $courseId = $surveyData['c_id'];
2156
2157
        if (empty($surveyId) || empty($courseId)) {
2158
            return false;
2159
        }
2160
2161
        $questions = self::get_questions($surveyId);
2162
        foreach ($questions as $question) {
2163
            // Questions marked with "geneated" were created using the "multiplicate" feature.
2164
            if ($question['survey_question_comment'] === 'generated') {
2165
                self::delete_survey_question($surveyId, $question['question_id']);
2166
            }
2167
        }
2168
    }
2169
2170
    /**
2171
     * @param array $surveyData
2172
     *
2173
     * @return bool
2174
     */
2175
    public static function multiplicateQuestions($surveyData)
2176
    {
2177
        if (empty($surveyData)) {
2178
            return false;
2179
        }
2180
        $surveyId = $surveyData['survey_id'];
2181
        $courseId = $surveyData['c_id'];
2182
2183
        if (empty($surveyId) || empty($courseId)) {
2184
            return false;
2185
        }
2186
2187
        $questions = self::get_questions($surveyId);
2188
2189
        $obj = new UserGroup();
2190
2191
        $options['where'] = [' usergroup.course_id = ? ' => $courseId];
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...
2192
        $classList = $obj->getUserGroupInCourse($options);
2193
2194
        $classTag = '{{class_name}}';
2195
        $studentTag = '{{student_full_name}}';
2196
        $classCounter = 0;
2197
        foreach ($classList as $class) {
2198
            $className = $class['name'];
2199
            foreach ($questions as $question) {
2200
                $users = $obj->get_users_by_usergroup($class['id']);
2201
                if (empty($users)) {
2202
                    continue;
2203
                }
2204
2205
                $text = $question['question'];
2206
                if (strpos($text, $classTag) !== false) {
2207
                    $replacedText = str_replace($classTag, $className, $text);
2208
                    $values = [
2209
                        'c_id' => $courseId,
2210
                        'question_comment' => 'generated',
2211
                        'type' => $question['type'],
2212
                        'display' => $question['horizontalvertical'],
2213
                        'question' => $replacedText,
2214
                        'survey_id' => $surveyId,
2215
                        'question_id' => 0,
2216
                        'shared_question_id' => 0,
2217
                    ];
2218
                    self::save_question($surveyData, $values);
2219
                    $classCounter++;
2220
                    continue;
2221
                }
2222
2223
                foreach ($users as $userId) {
2224
                    $userInfo = api_get_user_info($userId);
2225
2226
                    if (strpos($text, $studentTag) !== false) {
2227
                        $replacedText = str_replace($studentTag, $userInfo['complete_name'], $text);
2228
                        $values = [
2229
                            'c_id' => $courseId,
2230
                            'question_comment' => 'generated',
2231
                            'type' => $question['type'],
2232
                            'display' => $question['horizontalvertical'],
2233
                            'maximum_score' => $question['maximum_score'],
2234
                            'question' => $replacedText,
2235
                            'survey_id' => $surveyId,
2236
                            'question_id' => 0,
2237
                            'shared_question_id' => 0,
2238
                        ];
2239
2240
                        $answers = [];
2241
                        if (!empty($question['answers'])) {
2242
                            foreach ($question['answers'] as $answer) {
2243
                                $replacedText = str_replace($studentTag, $userInfo['complete_name'], $answer);
2244
                                $answers[] = $replacedText;
2245
                            }
2246
                        }
2247
                        $values['answers'] = $answers;
2248
                        self::save_question($surveyData, $values);
2249
                    }
2250
                }
2251
2252
                if ($classCounter < count($classList)) {
2253
                    // Add end page
2254
                    $values = [
2255
                        'c_id' => $courseId,
2256
                        'question_comment' => 'generated',
2257
                        'type' => 'pagebreak',
2258
                        'display' => 'horizontal',
2259
                        'question' => get_lang('QuestionForNextClass'),
2260
                        'survey_id' => $surveyId,
2261
                        'question_id' => 0,
2262
                        'shared_question_id' => 0,
2263
                    ];
2264
                    self::save_question($surveyData, $values);
2265
                }
2266
            }
2267
        }
2268
    }
2269
2270
    /**
2271
     * @param array $survey
2272
     *
2273
     * @return int
2274
     */
2275
    public static function getCountPages($survey)
2276
    {
2277
        if (empty($survey) || !isset($survey['iid'])) {
2278
            return 0;
2279
        }
2280
2281
        $courseId = $survey['c_id'];
2282
        $surveyId = $survey['survey_id'];
2283
2284
        $table = Database::get_course_table(TABLE_SURVEY_QUESTION);
2285
2286
        // pagebreak
2287
        $sql = "SELECT COUNT(iid) FROM $table
2288
                WHERE
2289
                    survey_question NOT LIKE '%{{%' AND
2290
                    type = 'pagebreak' AND
2291
                    c_id = $courseId AND
2292
                    survey_id = $surveyId";
2293
        $result = Database::query($sql);
2294
        $numberPageBreaks = Database::result($result, 0, 0);
2295
2296
        // No pagebreak
2297
        $sql = "SELECT COUNT(iid) FROM $table
2298
                WHERE
2299
                    survey_question NOT LIKE '%{{%' AND
2300
                    type != 'pagebreak' AND
2301
                    c_id = $courseId AND
2302
                    survey_id = $surveyId";
2303
        $result = Database::query($sql);
2304
        $countOfQuestions = Database::result($result, 0, 0);
2305
2306
        if ($survey['one_question_per_page'] == 1) {
2307
            if (!empty($countOfQuestions)) {
2308
                return $countOfQuestions;
2309
            }
2310
2311
            return 1;
2312
        }
2313
2314
        if (empty($numberPageBreaks)) {
2315
            return 1;
2316
        }
2317
2318
        return $numberPageBreaks + 1;
2319
    }
2320
2321
    /**
2322
     * Check whether this survey has ended. If so, display message and exit rhis script.
2323
     *
2324
     * @param array $surveyData Survey data
2325
     */
2326
    public static function checkTimeAvailability($surveyData)
2327
    {
2328
        if (empty($surveyData)) {
2329
            api_not_allowed(true);
2330
        }
2331
2332
        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
2333
        $utcZone = new DateTimeZone('UTC');
2334
        $startDate = new DateTime($surveyData['start_date'], $utcZone);
2335
        $endDate = new DateTime($surveyData['end_date'], $utcZone);
2336
        $currentDate = new DateTime('now', $utcZone);
2337
        if (!$allowSurveyAvailabilityDatetime) {
2338
            $currentDate->modify('today');
2339
        }
2340
        if ($currentDate < $startDate) {
2341
            api_not_allowed(
2342
                true,
2343
                Display:: return_message(
2344
                    get_lang('SurveyNotAvailableYet'),
2345
                    'warning',
2346
                    false
2347
                )
2348
            );
2349
        }
2350
2351
        if ($currentDate > $endDate) {
2352
            api_not_allowed(
2353
                true,
2354
                Display:: return_message(
2355
                    get_lang('SurveyNotAvailableAnymore'),
2356
                    'warning',
2357
                    false
2358
                )
2359
            );
2360
        }
2361
    }
2362
2363
    /**
2364
     * @param int    $userId
2365
     * @param string $surveyCode
2366
     * @param int    $courseId
2367
     * @param int    $sessionId
2368
     * @param int    $groupId
2369
     *
2370
     * @return array|CSurveyInvitation[]
2371
     */
2372
    public static function getUserInvitationsForSurveyInCourse(
2373
        $userId,
2374
        $surveyCode,
2375
        $courseId,
2376
        $sessionId = 0,
2377
        $groupId = 0
2378
    ) {
2379
        $invitationRepo = Database::getManager()->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2380
        $invitations = $invitationRepo->findBy(
2381
            [
2382
                'user' => $userId,
2383
                'cId' => $courseId,
2384
                'sessionId' => $sessionId,
2385
                'groupId' => $groupId,
2386
                'surveyCode' => $surveyCode,
2387
            ],
2388
            ['invitationDate' => 'DESC']
2389
        );
2390
2391
        return $invitations;
2392
    }
2393
2394
    /**
2395
     * @param array $userInfo
2396
     * @param int   $answered
2397
     *
2398
     * @return string
2399
     */
2400
    public static function surveyReport($userInfo, $answered = 0)
2401
    {
2402
        $userId = isset($userInfo['user_id']) ? (int) $userInfo['user_id'] : 0;
2403
        $answered = (int) $answered;
2404
2405
        if (empty($userId)) {
2406
            return '';
2407
        }
2408
2409
        $em = Database::getManager();
2410
        $repo = $em->getRepository('ChamiloCourseBundle:CSurveyInvitation');
2411
        $repoSurvey = $em->getRepository('ChamiloCourseBundle:CSurvey');
2412
        $invitations = $repo->findBy(['user' => $userId, 'answered' => $answered]);
2413
        $mainUrl = api_get_path(WEB_CODE_PATH).'survey/survey.php?';
2414
        $content = '';
2415
2416
        if (empty($answered)) {
2417
            $content .= Display::page_subheader(get_lang('Answered'));
2418
        } else {
2419
            $content .= Display::page_subheader(get_lang('Unanswered'));
2420
        }
2421
2422
        if (!empty($invitations)) {
2423
            $table = new HTML_Table(['class' => 'table']);
2424
            $table->setHeaderContents(0, 0, get_lang('SurveyName'));
2425
            $table->setHeaderContents(0, 1, get_lang('Course'));
2426
2427
            // Not answered
2428
            /** @var CSurveyInvitation $invitation */
2429
            $row = 1;
2430
            foreach ($invitations as $invitation) {
2431
                $courseId = $invitation->getCId();
2432
                $courseInfo = api_get_course_info_by_id($courseId);
2433
                $sessionId = $invitation->getSessionId();
2434
                $surveyCode = $invitation->getSurveyCode();
2435
2436
                $survey = $repoSurvey->findOneBy([
2437
                    'cId' => $courseId,
2438
                    'sessionId' => $sessionId,
2439
                    'code' => $surveyCode
2440
                ]);
2441
2442
                if (empty($survey)) {
2443
                    continue;
2444
                }
2445
2446
                $url = $mainUrl.'survey_id='.$survey->getSurveyId().'&cidReq='.$courseInfo['code'].'&id_session='.$sessionId;
2447
                $title = $survey->getTitle();
2448
                $title = Display::url($title, $url);
2449
2450
                if (!empty($sessionId)) {
2451
                    $sessionInfo = api_get_session_info($sessionId);
2452
                    $courseInfo['name'] .= ' ('.$sessionInfo['name'].')';
2453
                }
2454
                $table->setCellContents($row, 0, $title);
2455
                $table->setCellContents($row, 1, $courseInfo['name']);
2456
                $row++;
2457
            }
2458
            $content .= $table->toHtml();
2459
        } else {
2460
            $content .= Display::return_message(get_lang('NoData'));
2461
        }
2462
2463
        return $content;
2464
    }
2465
}
2466