Completed
Pull Request — 1.10.x (#1499)
by
unknown
52:23 queued 20:38
created

Event::eventAddVirtualCourseTime()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 78
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 46
nc 3
nop 5
dl 0
loc 78
rs 8.9019
c 0
b 0
f 0

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* See license terms in /license.txt */
3
4
//use Chamilo\UserBundle\Entity\User;
5
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
6
7
/**
8
 * Class Event
9
 * Functions of this library are used to record informations when some kind
10
 * of event occur. Each event has his own types of informations then each event
11
 * use its own function.
12
 */
13
class Event
14
{
15
    /**
16
     * @author Sebastien Piraux <[email protected]>
17
     * @desc Record information for open event (when homepage is opened)
18
     */
19
    public static function event_open()
20
    {
21
        global $_configuration;
22
        global $TABLETRACK_OPEN;
23
24
        // @getHostByAddr($_SERVER['REMOTE_ADDR']) : will provide host and country information
25
        // $_SERVER['HTTP_USER_AGENT'] :  will provide browser and os information
26
        // $_SERVER['HTTP_REFERER'] : provide information about refering url
27
        if (isset($_SERVER['HTT_REFERER'])) {
28
            $referer = Database::escape_string($_SERVER['HTTP_REFERER']);
29
        } else {
30
            $referer = '';
31
        }
32
        // record informations only if user comes from another site
33
        //if(!eregi($_configuration['root_web'],$referer))
34
        $pos = strpos($referer, $_configuration['root_web']);
35
        if ($pos === false && $referer != '') {
36
            $ip = api_get_real_ip();
37
            $remhost = @ getHostByAddr($ip);
38
            if ($remhost == $ip) {
39
                $remhost = "Unknown";
40
            } // don't change this
41
            $reallyNow = api_get_utc_datetime();
42
            $params = [
43
                'open_remote_host' => $remhost,
44
                'open_agent' => $_SERVER['HTTP_USER_AGENT'],
45
                'open_referer' => $referer,
46
                'open_date' => $reallyNow,
47
            ];
48
            Database::insert($TABLETRACK_OPEN, $params);
49
        }
50
51
        return 1;
52
    }
53
54
    /**
55
     * @author Sebastien Piraux <[email protected]> old code
56
     * @author Julio Montoya 2013
57
     * @desc Record information for login event when an user identifies himself with username & password
58
     */
59
    public static function event_login($userId)
60
    {
61
        $userInfo = api_get_user_info($userId);
62
63
        $userId = intval($userId);
64
65
        if (empty($userInfo)) {
66
            return false;
67
        }
68
69
        $TABLETRACK_LOGIN = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
70
71
        $reallyNow = api_get_utc_datetime();
72
73
        $sql = "INSERT INTO ".$TABLETRACK_LOGIN." (login_user_id, user_ip, login_date, logout_date) VALUES
74
                    ('".$userId."',
75
                    '".Database::escape_string(api_get_real_ip())."',
76
                    '".$reallyNow."',
77
                    '".$reallyNow."'
78
                    )";
79
        Database::query($sql);
80
81
        // Auto subscribe
82
        $user_status = $userInfo['status']  == SESSIONADMIN ? 'sessionadmin' :
83
            $userInfo['status'] == COURSEMANAGER ? 'teacher' :
84
                $userInfo['status'] == DRH ? 'DRH' : 'student';
85
        $autoSubscribe = api_get_setting($user_status.'_autosubscribe');
86
        if ($autoSubscribe) {
87
            $autoSubscribe = explode('|', $autoSubscribe);
88
            foreach ($autoSubscribe as $code) {
89
                if (CourseManager::course_exists($code)) {
90
                    CourseManager::subscribe_user($userId, $code);
91
                }
92
            }
93
        }
94
    }
95
96
    /**
97
     * @param tool name of the tool (name in mainDb.accueil table)
98
     * @author Sebastien Piraux <[email protected]>
99
     * @desc Record information for access event for courses
100
     */
101
    public static function accessCourse()
102
    {
103
        $TABLETRACK_ACCESS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
104
        //for "what's new" notification
105
        $TABLETRACK_LASTACCESS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
106
107
        $id_session = api_get_session_id();
108
        $now = api_get_utc_datetime();
109
        $courseId = api_get_course_int_id();
110
        $user_id = api_get_user_id();
111
        $ip = api_get_real_ip();
112
113
        if ($user_id) {
114
            $user_id = "'".$user_id."'";
115
        } else {
116
            $user_id = "0"; // no one
117
        }
118
        $sql = "INSERT INTO ".$TABLETRACK_ACCESS."  (user_ip, access_user_id, c_id, access_date, access_session_id) VALUES
119
                ('".$ip."', ".$user_id.", '".$courseId."', '".$now."','".$id_session."')";
120
121
        Database::query($sql);
122
123
        // added for "what's new" notification
124
        $sql = "UPDATE $TABLETRACK_LASTACCESS  SET access_date = '$now'
125
                WHERE access_user_id = $user_id AND c_id = '$courseId' AND access_tool IS NULL AND access_session_id=".$id_session;
126
        $result = Database::query($sql);
127
128 View Code Duplication
        if (Database::affected_rows($result) == 0) {
129
            $sql = "INSERT INTO $TABLETRACK_LASTACCESS (access_user_id, c_id, access_date, access_session_id)
130
                    VALUES (".$user_id.", '".$courseId."', '$now', '".$id_session."')";
131
            Database::query($sql);
132
        }
133
134
        return 1;
135
    }
136
137
    /**
138
     * @param tool name of the tool (name in mainDb.accueil table)
139
     * @author Sebastien Piraux <[email protected]>
140
     * @desc Record information for access event for tools
141
     *
142
     *  $tool can take this values :
143
     *  Links, Calendar, Document, Announcements,
144
     *  Group, Video, Works, Users, Exercices, Course Desc
145
     *  ...
146
     *  Values can be added if new modules are created (15char max)
147
     *  I encourage to use $nameTool as $tool when calling this function
148
     *
149
     * 	Functionality for "what's new" notification is added by Toon Van Hoecke
150
     */
151
    public static function event_access_tool($tool, $id_session = 0)
152
    {
153
        if (empty($tool)) {
154
            return false;
155
        }
156
        $TABLETRACK_ACCESS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
157
        //for "what's new" notification
158
        $TABLETRACK_LASTACCESS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
159
160
        $_course = api_get_course_info();
161
        $courseId = api_get_course_int_id();
162
        $id_session = api_get_session_id();
163
        $tool = Database::escape_string($tool);
164
        $reallyNow = api_get_utc_datetime();
165
        $user_id = api_get_user_id();
166
167
        // record information
168
        // only if user comes from the course $_cid
169
        //if( eregi($_configuration['root_web'].$_cid,$_SERVER['HTTP_REFERER'] ) )
170
        //$pos = strpos($_SERVER['HTTP_REFERER'],$_configuration['root_web'].$_cid);
171
        $coursePath = isset($_course['path']) ? $_course['path'] : null;
172
173
        $pos = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower(api_get_path(WEB_COURSE_PATH).$coursePath)) : false;
174
        // added for "what's new" notification
175
        $pos2 = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower(api_get_path(WEB_PATH)."index")) : false;
176
        // end "what's new" notification
177
        if ($pos !== false || $pos2 !== false) {
178
            $params = [
179
                'access_user_id' => $user_id,
180
                'c_id' => $courseId,
181
                'access_tool' => $tool,
182
                'access_date' => $reallyNow,
183
                'access_session_id' => $id_session,
184
                'user_ip' => api_get_real_ip()
185
            ];
186
            Database::insert($TABLETRACK_ACCESS, $params);
187
        }
188
189
        // "what's new" notification
190
        $sql = "UPDATE $TABLETRACK_LASTACCESS
191
                SET access_date = '$reallyNow'
192
                WHERE access_user_id = ".$user_id." AND c_id = '".$courseId."' AND access_tool = '".$tool."' AND access_session_id=".$id_session;
193
        $result = Database::query($sql);
194 View Code Duplication
        if (Database::affected_rows($result) == 0) {
195
            $sql = "INSERT INTO $TABLETRACK_LASTACCESS (access_user_id, c_id, access_tool, access_date, access_session_id)
196
                    VALUES (".$user_id.", '".$courseId."' , '$tool', '$reallyNow', $id_session)";
197
            Database::query($sql);
198
        }
199
        return 1;
200
    }
201
202
    /**
203
     * @param doc_id id of document (id in mainDb.document table)
204
     * @author Sebastien Piraux <[email protected]>
205
     * @desc Record information for download event
206
     * (when an user click to d/l a document)
207
     * it will be used in a redirection page
208
     * bug fixed: Roan Embrechts
209
     * Roan:
210
     * The user id is put in single quotes,
211
     * (why? perhaps to prevent sql insertion hacks?)
212
     * and later again.
213
     * Doing this twice causes an error, I remove one of them.
214
     */
215 View Code Duplication
    public static function event_download($doc_url)
216
    {
217
        $tbl_stats_downloads = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS);
218
        $doc_url = Database::escape_string($doc_url);
219
220
        $reallyNow = api_get_utc_datetime();
221
        $user_id = "'".api_get_user_id()."'";
222
        $_cid = api_get_course_int_id();
223
224
        $sql = "INSERT INTO $tbl_stats_downloads (
225
                     down_user_id,
226
                     c_id,
227
                     down_doc_path,
228
                     down_date,
229
                     down_session_id
230
                    )
231
                    VALUES (
232
                     ".$user_id.",
233
                     '".$_cid."',
234
                     '".$doc_url."',
235
                     '".$reallyNow."',
236
                     '".api_get_session_id()."'
237
                    )";
238
        Database::query($sql);
239
        return 1;
240
    }
241
242
    /**
243
     * @param doc_id id of document (id in mainDb.document table)
244
     * @author Sebastien Piraux <[email protected]>
245
     * @desc Record information for upload event
246
     * used in the works tool to record informations when
247
     * an user upload 1 work
248
     */
249 View Code Duplication
    public static function event_upload($doc_id)
250
    {
251
        $TABLETRACK_UPLOADS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS);
252
        $courseId = api_get_course_int_id();
253
        $reallyNow = api_get_utc_datetime();
254
        $user_id = api_get_user_id();
255
        $doc_id = intval($doc_id);
256
257
        $sql = "INSERT INTO ".$TABLETRACK_UPLOADS."
258
                    ( upload_user_id,
259
                      c_id,
260
                      upload_cours_id,
261
                      upload_work_id,
262
                      upload_date,
263
                      upload_session_id
264
                    )
265
                    VALUES (
266
                     ".$user_id.",
267
                     '".$courseId."',
268
                     '',
269
                     '".$doc_id."',
270
                     '".$reallyNow."',
271
                     '".api_get_session_id()."'
272
                    )";
273
        Database::query($sql);
274
275
        return 1;
276
    }
277
278
    /**
279
     * @param link_id (id in coursDb liens table)
280
     * @author Sebastien Piraux <[email protected]>
281
     * @desc Record information for link event (when an user click on an added link)
282
     * it will be used in a redirection page
283
     */
284
    public static function event_link($link_id)
285
    {
286
        $TABLETRACK_LINKS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LINKS);
287
        $reallyNow = api_get_utc_datetime();
288
        $user_id = api_get_user_id();
289
        $sql = "INSERT INTO ".$TABLETRACK_LINKS."
290
                    ( links_user_id,
291
                     c_id,
292
                     links_link_id,
293
                     links_date,
294
                     links_session_id
295
                    ) VALUES (
296
                     ".$user_id.",
297
                     '".api_get_course_int_id()."',
298
                     '".Database::escape_string($link_id)."',
299
                     '".$reallyNow."',
300
                     '".api_get_session_id()."'
301
                    )";
302
        Database::query($sql);
303
        return 1;
304
    }
305
306
    /**
307
     * Update the TRACK_E_EXERCICES exercises
308
     *
309
     * @param   int     exeid id of the attempt
310
     * @param   int     exo_id 	exercise id
311
     * @param   mixed   result 	score
312
     * @param   int     weighting ( higher score )
313
     * @param   int     duration ( duration of the attempt in seconds )
314
     * @param   int     session_id
315
     * @param   int     learnpath_id (id of the learnpath)
316
     * @param   int     learnpath_item_id (id of the learnpath_item)
317
     *
318
     * @author Sebastien Piraux <[email protected]>
319
     * @author Julio Montoya Armas <[email protected]> Reworked 2010
320
     * @desc Record result of user when an exercice was done
321
     */
322
    public static function update_event_exercice(
323
        $exeid,
324
        $exo_id,
325
        $score,
326
        $weighting,
327
        $session_id,
328
        $learnpath_id = 0,
329
        $learnpath_item_id = 0,
330
        $learnpath_item_view_id = 0,
331
        $duration = 0,
332
        $question_list = array(),
333
        $status = '',
334
        $remind_list = array(),
335
        $end_date = null
336
    ) {
337
        global $debug;
338
339
        if ($debug) error_log('Called to update_event_exercice');
340
        if ($debug) error_log('duration:' . $duration);
341
342
        if ($exeid != '') {
343
            /*
344
             * Code commented due BT#8423 do not change the score to 0.
345
             *
346
             * Validation in case of fraud with actived control time
347
            if (!ExerciseLib::exercise_time_control_is_valid($exo_id, $learnpath_id, $learnpath_item_id)) {
348
                $score = 0;
349
            }
350
            */
351
            if (!isset($status) || empty($status)) {
352
                $status = '';
353
            } else {
354
                $status = Database::escape_string($status);
355
            }
356
357
            $TABLETRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
358
359
            if (!empty($question_list)) {
360
                $question_list = array_map('intval', $question_list);
361
            }
362
363
            if (!empty($remind_list)) {
364
                $remind_list = array_map('intval', $remind_list);
365
                $remind_list = array_filter($remind_list);
366
                $remind_list = implode(",", $remind_list);
367
            } else {
368
                $remind_list = '';
369
            }
370
371
            if (empty($end_date)) {
372
                $end_date = api_get_utc_datetime();
373
            }
374
375
            $sql = "UPDATE $TABLETRACK_EXERCICES SET
376
        		   exe_exo_id 			= '".Database::escape_string($exo_id)."',
377
        		   exe_result			= '".Database::escape_string($score)."',
378
        		   exe_weighting 		= '".Database::escape_string($weighting)."',
379
        		   session_id			= '".Database::escape_string($session_id)."',
380
        		   orig_lp_id 			= '".Database::escape_string($learnpath_id)."',
381
        		   orig_lp_item_id 		= '".Database::escape_string($learnpath_item_id)."',
382
                   orig_lp_item_view_id = '".Database::escape_string($learnpath_item_view_id)."',
383
        		   exe_duration = '".Database::escape_string($duration)."',
384
        		   exe_date = '".$end_date."',
385
        		   status = '".$status."',
386
        		   questions_to_check = '".$remind_list."',
387
        		   data_tracking = '".implode(',', $question_list)."',
388
                   user_ip = '" . Database::escape_string(api_get_real_ip()) . "'
389
        		 WHERE exe_id = '".Database::escape_string($exeid)."'";
390
            $res = Database::query($sql);
391
392
            if ($debug) error_log('update_event_exercice called');
393
            if ($debug) error_log("$sql");
394
395
            //Deleting control time session track
396
            //ExerciseLib::exercise_time_control_delete($exo_id);
397
            return $res;
398
        } else {
399
            return false;
400
        }
401
    }
402
403
    /**
404
     * Record an event for this attempt at answering an exercise
405
     * @param	float	Score achieved
406
     * @param	string	Answer given
407
     * @param	integer	Question ID
408
     * @param	integer Exercise attempt ID a.k.a exe_id (from track_e_exercise)
409
     * @param	integer	Position
410
     * @param	integer Exercise ID (from c_quiz)
411
     * @param	bool update results?
412
     * @param	string  Filename (for audio answers - using nanogong)
413
     * @param	integer User ID The user who's going to get this score. Default value of null means "get from context".
414
     * @param	integer	Course ID (from the "id" column of course table). Default value of null means "get from context".
415
     * @param	integer	Session ID (from the session table). Default value of null means "get from context".
416
     * @param	integer	Learnpath ID (from c_lp table). Default value of null means "get from context".
417
     * @param	integer	Learnpath item ID (from the c_lp_item table). Default value of null means "get from context".
418
     * @return	boolean	Result of the insert query
419
     */
420
    public static function saveQuestionAttempt(
421
        $score,
422
        $answer,
423
        $question_id,
424
        $exe_id,
425
        $position,
426
        $exercise_id = 0,
427
        $updateResults = false,
428
        $nano = null,
429
        $user_id = null,
430
        $course_id = null,
431
        $session_id = null,
432
        $learnpath_id = null,
433
        $learnpath_item_id = null
434
    ) {
435
        global $debug;
436
        $question_id = Database::escape_string($question_id);
437
        $exe_id = Database::escape_string($exe_id);
438
        $position = Database::escape_string($position);
439
        $now = api_get_utc_datetime();
440
441
        // check user_id or get from context
442
        if (empty($user_id)) {
443
            $user_id = api_get_user_id();
444
            // anonymous
445
            if (empty($user_id)) {
446
                $user_id = api_get_anonymous_id();
447
            }
448
        }
449
        // check course_id or get from context
450
        if (empty($course_id) or intval($course_id) != $course_id) {
451
            $course_id = api_get_course_int_id();
452
        }
453
        // check session_id or get from context
454
        if (empty($session_id)) {
455
            $session_id = api_get_session_id();
456
        }
457
        // check learnpath_id or get from context
458
        if (empty($learnpath_id)) {
459
            global $learnpath_id;
460
        }
461
        // check learnpath_item_id or get from context
462
        if (empty($learnpath_item_id)) {
463
            global $learnpath_item_id;
464
        }
465
466
        $TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
467
468
        if ($debug) {
469
            error_log("----- entering saveQuestionAttempt() function ------");
470
            error_log("answer: $answer");
471
            error_log("score: $score");
472
            error_log("question_id : $question_id");
473
            error_log("position: $position");
474
        }
475
476
        //Validation in case of fraud with active control time
477
        if (!ExerciseLib::exercise_time_control_is_valid($exercise_id, $learnpath_id, $learnpath_item_id)) {
478
            if ($debug) {
479
                error_log("exercise_time_control_is_valid is false");
480
            }
481
            $score = 0;
482
            $answer = 0;
483
        }
484
485
        $file = '';
486
        if (isset($nano)) {
487
            $file = Database::escape_string(basename($nano->load_filename_if_exists(false)));
488
        }
489
490
        $session_id = api_get_session_id();
491
492
        if (!empty($question_id) && !empty($exe_id) && !empty($user_id)) {
493
            $attempt = array(
494
                'user_id' => $user_id,
495
                'question_id' => $question_id,
496
                'answer' => $answer,
497
                'marks' => $score,
498
                'c_id' => $course_id,
499
                'session_id' => $session_id,
500
                'position' => $position,
501
                'tms' => $now,
502
                'filename' => $file,
503
            );
504
505
            // Check if attempt exists.
506
507
            $sql = "SELECT exe_id FROM $TBL_TRACK_ATTEMPT
508
                    WHERE
509
                        c_id = $course_id AND
510
                        session_id = $session_id AND
511
                        exe_id = $exe_id AND
512
                        user_id = $user_id AND
513
                        question_id = $question_id AND
514
                        position = $position";
515
            $result = Database::query($sql);
516
            if (Database::num_rows($result)) {
517
                if ($debug) {
518
                    error_log("Attempt already exist: exe_id: $exe_id - user_id:$user_id - question_id:$question_id");
519
                }
520
                if ($updateResults == false) {
521
                    //The attempt already exist do not update use  update_event_exercise() instead
522
                    return false;
523
                }
524
            } else {
525
                $attempt['exe_id'] = $exe_id;
526
            }
527
528
            if ($debug) {
529
                error_log("updateResults : $updateResults");
530
                error_log("Saving question attempt: ");
531
                error_log($sql);
532
            }
533
534
            $recording_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
535
536
            if ($updateResults == false) {
537
                $attempt_id = Database::insert($TBL_TRACK_ATTEMPT, $attempt);
538
539
                if (defined('ENABLED_LIVE_EXERCISE_TRACKING')) {
540
                    if ($debug) {
541
                        error_log("Saving e attempt recording ");
542
                    }
543
                    $attempt_recording = array(
544
                        'exe_id' => $attempt_id,
545
                        'question_id' => $question_id,
546
                        'marks' => $score,
547
                        'insert_date' => $now,
548
                        'author' => '',
549
                        'session_id' => $session_id,
550
                    );
551
                    Database::insert($recording_table, $attempt_recording);
552
                }
553
            } else {
554
                Database::update($TBL_TRACK_ATTEMPT, $attempt,
555
                    array('exe_id = ? AND question_id = ? AND user_id = ? ' => array($exe_id, $question_id, $user_id)));
556
557
                if (defined('ENABLED_LIVE_EXERCISE_TRACKING')) {
558
559
                    $attempt_recording = array(
560
                        'exe_id' => $exe_id,
561
                        'question_id' => $question_id,
562
                        'marks' => $score,
563
                        'insert_date' => $now,
564
                        'author' => '',
565
                        'session_id' => $session_id,
566
                    );
567
568
                    Database::update($recording_table, $attempt_recording,
569
                        array('exe_id = ? AND question_id = ? AND session_id = ? ' => array($exe_id, $question_id, $session_id))
570
                    );
571
                }
572
                $attempt_id = $exe_id;
573
            }
574
            return $attempt_id;
575
        } else {
576
            return false;
577
        }
578
    }
579
580
    /**
581
     * Record an hotspot spot for this attempt at answering an hotspot question
582
     * @param	int		Exercise ID
583
     * @param	int		Question ID
584
     * @param	int		Answer ID
585
     * @param	int		Whether this answer is correct (1) or not (0)
586
     * @param	string	Coordinates of this point (e.g. 123;324)
587
     * @param	bool update results?
588
     * @return	boolean	Result of the insert query
589
     * @uses Course code and user_id from global scope $_cid and $_user
590
     */
591
    public static function saveExerciseAttemptHotspot($exe_id, $question_id, $answer_id, $correct, $coords, $updateResults = false, $exerciseId = 0)
592
    {
593
        global $safe_lp_id, $safe_lp_item_id;
594
595
        if ($updateResults == false) {
596
            // Validation in case of fraud with activated control time
597
            if (!ExerciseLib::exercise_time_control_is_valid($exerciseId, $safe_lp_id, $safe_lp_item_id)) {
598
                $correct = 0;
599
            }
600
        }
601
        $tbl_track_e_hotspot = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
602
        if ($updateResults) {
603
            $params = array(
604
                'hotspot_correct' => $correct,
605
                'hotspot_coordinate' => $coords
606
            );
607
            Database::update($tbl_track_e_hotspot, $params,
608
                array('hotspot_user_id = ? AND hotspot_exe_id = ? AND hotspot_question_id = ? AND hotspot_answer_id = ? ' => array(
609
                    api_get_user_id(),
610
                    $exe_id,
611
                    $question_id,
612
                    $answer_id,
613
                    $answer_id
614
                )));
615
616
        } else {
617
            return Database::insert(
618
                $tbl_track_e_hotspot,
619
                [
620
                    'hotspot_course_code' => api_get_course_id(),
621
                    'hotspot_user_id' => api_get_user_id(),
622
                    'c_id' => api_get_course_int_id(),
623
                    'hotspot_exe_id' => $exe_id,
624
                    'hotspot_question_id' => $question_id,
625
                    'hotspot_answer_id' => $answer_id,
626
                    'hotspot_correct' => $correct,
627
                    'hotspot_coordinate' => $coords
628
                ]
629
            );
630
        }
631
    }
632
633
    /**
634
     * Records information for common (or admin) events (in the track_e_default table)
635
     * @author Yannick Warnier <[email protected]>
636
     * @param   string  $event_type Type of event
637
     * @param   string  $event_value_type Type of value
638
     * @param   string  $event_value Value
639
     * @param   string  $datetime Datetime (UTC) (defaults to null)
640
     * @param   int     $user_id User ID (defaults to null)
641
     * @param   int $course_id Course ID (defaults to null)
642
     * @param   int $sessionId Session ID
643
     * @return  bool
644
     * @assert ('','','') === false
645
     */
646
    public static function addEvent(
647
        $event_type,
648
        $event_value_type,
649
        $event_value,
650
        $datetime = null,
651
        $user_id = null,
652
        $course_id = null,
653
        $sessionId = 0
654
    ) {
655
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
656
657
        if (empty($event_type)) {
658
            return false;
659
        }
660
        $event_type = Database::escape_string($event_type);
661
        $event_value_type = Database::escape_string($event_value_type);
662
        if (!empty($course_id)) {
663
            $course_id = intval($course_id);
664
        } else {
665
            $course_id = api_get_course_int_id();
666
        }
667
        if (!empty($sessionId)) {
668
            $sessionId = intval($sessionId);
669
        } else {
670
            $sessionId = api_get_session_id();
671
        }
672
673
        //Clean the user_info
674
        if ($event_value_type == LOG_USER_OBJECT) {
675
            if (is_array($event_value)) {
676
                unset($event_value['complete_name']);
677
                unset($event_value['complete_name_with_username']);
678
                unset($event_value['firstName']);
679
                unset($event_value['lastName']);
680
                unset($event_value['avatar_small']);
681
                unset($event_value['avatar']);
682
                unset($event_value['mail']);
683
                unset($event_value['password']);
684
                unset($event_value['last_login']);
685
                unset($event_value['picture_uri']);
686
                $event_value = serialize($event_value);
687
            }
688
        }
689
690
        $event_value = Database::escape_string($event_value);
691
        $sessionId = empty($sessionId) ? api_get_session_id() : intval($sessionId);
692
693
        if (!isset($datetime)) {
694
            $datetime = api_get_utc_datetime();
695
        }
696
697
        $datetime = Database::escape_string($datetime);
698
699
        if (!isset($user_id)) {
700
            $user_id = api_get_user_id();
701
        }
702
703
        $params = array(
704
            'default_user_id' => $user_id,
705
            'c_id' => $course_id,
706
            'default_date' => $datetime,
707
            'default_event_type' => $event_type,
708
            'default_value_type' => $event_value_type,
709
            'default_value' => $event_value,
710
            'session_id' => $sessionId
711
        );
712
        Database::insert($table, $params);
713
714
        return true;
715
    }
716
717
    /**
718
     * Get every email stored in the database
719
     *
720
     * @param int $etId
0 ignored issues
show
Bug introduced by
There is no parameter named $etId. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
721
     * @return type
722
     * @assert () !== false
723
     */
724
    public static function get_all_event_types()
725
    {
726
        global $event_config;
727
728
        $sql = 'SELECT etm.id, event_type_name, activated, language_id, message, subject, dokeos_folder
729
                FROM '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).' etm
730
                INNER JOIN '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' l
731
                ON etm.language_id = l.id';
732
733
        $events_types = Database::store_result(Database::query($sql), 'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like \Database::query($sql) can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
734
735
        $to_return = array();
736
        foreach ($events_types as $et) {
737
            $et['nameLangVar'] = $event_config[$et["event_type_name"]]["name_lang_var"];
738
            $et['descLangVar'] = $event_config[$et["event_type_name"]]["desc_lang_var"];
739
            $to_return[] = $et;
740
        }
741
742
        return $to_return;
743
    }
744
745
    /**
746
     * Get the users related to one event
747
     *
748
     * @param string $event_name
749
     */
750
    public static function get_event_users($event_name)
751
    {
752
        $event_name = Database::escape_string($event_name);
753
        $sql = 'SELECT user.user_id,  user.firstname, user.lastname
754
                FROM '.Database::get_main_table(TABLE_MAIN_USER).' user
755
                JOIN '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' relUser
756
                ON relUser.user_id = user.user_id
757
                WHERE user.status <> '.ANONYMOUS.' AND relUser.event_type_name = "'.$event_name.'"';
758
        $user_list = Database::store_result(Database::query($sql), 'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like \Database::query($sql) can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
759
        return json_encode($user_list);
760
    }
761
762
    /**
763
     * @param int $user_id
764
     * @param string $event_type
765
     * @return array|bool
766
     */
767 View Code Duplication
    public static function get_events_by_user_and_type($user_id, $event_type)
768
    {
769
        $TABLETRACK_DEFAULT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
770
        $user_id = intval($user_id);
771
        $event_type = Database::escape_string($event_type);
772
773
        $sql = "SELECT * FROM $TABLETRACK_DEFAULT
774
                WHERE default_value_type = 'user_id' AND
775
                      default_value = $user_id AND
776
                      default_event_type = '$event_type'
777
                ORDER BY default_date ";
778
        $result = Database::query($sql);
779
        if ($result) {
780
            return Database::store_result($result, 'ASSOC');
781
        }
782
        return false;
783
    }
784
785
    /**
786
     * Save the new message for one event and for one language
787
     *
788
     * @param string $eventName
0 ignored issues
show
Bug introduced by
There is no parameter named $eventName. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
789
     * @param array $users
790
     * @param string $message
791
     * @param string $subject
792
     * @param string $eventMessageLanguage
0 ignored issues
show
Documentation introduced by
There is no parameter named $eventMessageLanguage. Did you maybe mean $message?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
793
     * @param int $activated
794
     */
795
    public static function save_event_type_message($event_name, $users, $message, $subject, $event_message_language, $activated)
796
    {
797
        $event_name = Database::escape_string($event_name);
798
        $activated = intval($activated);
799
        $event_message_language = Database::escape_string($event_message_language);
800
801
        // Deletes then re-adds the users linked to the event
802
        $sql = 'DELETE FROM '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' WHERE event_type_name = "'.$event_name.'"	';
803
        Database::query($sql);
804
805
        foreach ($users as $user) {
806
            $sql = 'INSERT INTO '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' (user_id,event_type_name)
807
                    VALUES('.intval($user).',"'.$event_name.'")';
808
            Database::query($sql);
809
        }
810
        $language_id = api_get_language_id($event_message_language);
811
        // check if this template in this language already exists or not
812
        $sql = 'SELECT COUNT(id) as total FROM '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).'
813
                WHERE event_type_name = "'.$event_name.'" AND language_id = '.$language_id;
814
815
        $sql = Database::store_result(Database::query($sql), 'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like \Database::query($sql) can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
816
817
        // if already exists, we update
818
        if ($sql[0]["total"] > 0) {
819
            $sql = 'UPDATE '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).'
820
                SET message = "'.Database::escape_string($message).'",
821
                subject = "'.Database::escape_string($subject).'",
822
                activated = '.$activated.'
823
                WHERE event_type_name = "'.$event_name.'" AND language_id = (SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).'
824
                    WHERE dokeos_folder = "'.$event_message_language.'")';
825
            Database::query($sql);
826
        } else { // else we create a new record
827
            // gets the language_-_id
828
            $lang_id = '(SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).'
829
                        WHERE dokeos_folder = "'.$event_message_language.'")';
830
            $lang_id = Database::store_result(Database::query($lang_id), 'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like \Database::query($lang_id) can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
831
832
            if (!empty($lang_id[0]["id"])) {
833
                $sql = 'INSERT INTO '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).' (event_type_name, language_id, message, subject, activated)
834
                    VALUES("'.$event_name.'", '.$lang_id[0]["id"].', "'.Database::escape_string($message).'", "'.Database::escape_string($subject).'", '.$activated.')';
835
                Database::query($sql);
836
            }
837
        }
838
839
        // set activated at every save
840
        $sql = 'UPDATE '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).'
841
                    SET activated = '.$activated.'
842
                    WHERE event_type_name = "'.$event_name.'"';
843
        Database::query($sql);
844
    }
845
846
    /**
847
     * Gets the last attempt of an exercise based in the exe_id
848
     * @param int $exe_id
849
     * @return mixed
850
     */
851
    public static function getLastAttemptDateOfExercise($exe_id)
852
    {
853
        $exe_id = intval($exe_id);
854
        $track_attempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
855
        $sql = 'SELECT max(tms) as last_attempt_date
856
                FROM '.$track_attempts.'
857
                WHERE exe_id='.$exe_id;
858
        $rs_last_attempt = Database::query($sql);
859
        $row_last_attempt = Database::fetch_array($rs_last_attempt);
860
        $last_attempt_date = $row_last_attempt['last_attempt_date']; //Get the date of last attempt
861
862
        return $last_attempt_date;
863
    }
864
865
    /**
866
     * Gets the last attempt of an exercise based in the exe_id
867
     * @param int $exe_id
868
     * @return mixed
869
     */
870
    public static function getLatestQuestionIdFromAttempt($exe_id)
871
    {
872
        $exe_id = intval($exe_id);
873
        $track_attempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
874
        $sql = 'SELECT question_id FROM '.$track_attempts.'
875
                WHERE exe_id='.$exe_id.'
876
                ORDER BY tms DESC
877
                LIMIT 1';
878
        $result = Database::query($sql);
879
        if (Database::num_rows($result)) {
880
            $row = Database::fetch_array($result);
881
            return $row['question_id'];
882
        } else {
883
            return false;
884
        }
885
    }
886
887
    /**
888
     * Gets how many attempts exists by user, exercise, learning path
889
     * @param   int user id
890
     * @param   int exercise id
891
     * @param   int lp id
892
     * @param   int lp item id
893
     * @param   int lp item view id
894
     */
895
    public static function get_attempt_count($user_id, $exerciseId, $lp_id, $lp_item_id, $lp_item_view_id)
896
    {
897
        $stat_table = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
898
        $user_id = intval($user_id);
899
        $exerciseId = intval($exerciseId);
900
        $lp_id = intval($lp_id);
901
        $lp_item_id = intval($lp_item_id);
902
        $lp_item_view_id = intval($lp_item_view_id);
903
904
        $sql = "SELECT count(*) as count
905
                FROM $stat_table
906
                WHERE
907
                    exe_exo_id 				= $exerciseId AND
908
                    exe_user_id 			= $user_id AND
909
                    status 			   	   != 'incomplete' AND
910
                    orig_lp_id 				= $lp_id AND
911
                    orig_lp_item_id 		= $lp_item_id AND
912
                    orig_lp_item_view_id 	= $lp_item_view_id AND
913
                    c_id 			        = '".api_get_course_int_id()."' AND
914
                    session_id 				= '".api_get_session_id()."'";
915
916
        $query = Database::query($sql);
917 View Code Duplication
        if (Database::num_rows($query) > 0) {
918
            $attempt = Database :: fetch_array($query, 'ASSOC');
919
            return $attempt['count'];
920
        } else {
921
            return 0;
922
        }
923
    }
924
925
    /**
926
     * @param $user_id
927
     * @param $exerciseId
928
     * @param $lp_id
929
     * @param $lp_item_id
930
     * @return int
931
     */
932
    public static function get_attempt_count_not_finished($user_id, $exerciseId, $lp_id, $lp_item_id)
933
    {
934
        $stat_table = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
935
        $user_id = intval($user_id);
936
        $exerciseId = intval($exerciseId);
937
        $lp_id = intval($lp_id);
938
        $lp_item_id = intval($lp_item_id);
939
        //$lp_item_view_id = intval($lp_item_view_id);
940
941
        $sql = "SELECT count(*) as count
942
                FROM $stat_table
943
                WHERE
944
                    exe_exo_id 			= $exerciseId AND
945
                    exe_user_id 		= $user_id AND
946
                    status 				!= 'incomplete' AND
947
                    orig_lp_id 			= $lp_id AND
948
                    orig_lp_item_id 	= $lp_item_id AND
949
                    c_id = '".api_get_course_int_id()."' AND
950
                    session_id = '".api_get_session_id()."'";
951
952
        $query = Database::query($sql);
953 View Code Duplication
        if (Database::num_rows($query) > 0) {
954
            $attempt = Database :: fetch_array($query, 'ASSOC');
955
            return $attempt['count'];
956
        } else {
957
            return 0;
958
        }
959
    }
960
961
    /**
962
     * @param int $user_id
963
     * @param int $lp_id
964
     * @param array $course
965
     * @param int $session_id
966
     */
967
    public static function delete_student_lp_events($user_id, $lp_id, $course, $session_id)
968
    {
969
        $lp_view_table = Database::get_course_table(TABLE_LP_VIEW);
970
        $lp_item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW);
971
        $lpInteraction = Database::get_course_table(TABLE_LP_IV_INTERACTION);
972
        $lpObjective = Database::get_course_table(TABLE_LP_IV_OBJECTIVE);
973
974
        $course_id = $course['real_id'];
975
976
        if (empty($course_id)) {
977
            $course_id = api_get_course_int_id();
978
        }
979
980
        $track_e_exercises = Database::get_main_table(
981
            TABLE_STATISTIC_TRACK_E_EXERCISES
982
        );
983
        $track_attempts = Database::get_main_table(
984
            TABLE_STATISTIC_TRACK_E_ATTEMPT
985
        );
986
        $recording_table = Database::get_main_table(
987
            TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING
988
        );
989
990
        $user_id = intval($user_id);
991
        $lp_id = intval($lp_id);
992
        $session_id = intval($session_id);
993
994
        //Make sure we have the exact lp_view_id
995
        $sql = "SELECT id FROM $lp_view_table
996
                WHERE
997
                    c_id = $course_id AND
998
                    user_id = $user_id AND
999
                    lp_id = $lp_id AND
1000
                    session_id = $session_id ";
1001
        $result = Database::query($sql);
1002
1003 View Code Duplication
        if (Database::num_rows($result)) {
1004
            $view = Database::fetch_array($result, 'ASSOC');
1005
            $lp_view_id = $view['id'];
1006
1007
            $sql = "DELETE FROM $lp_item_view_table
1008
                    WHERE c_id = $course_id AND lp_view_id = $lp_view_id ";
1009
            Database::query($sql);
1010
1011
            $sql = "DELETE FROM $lpInteraction
1012
                    WHERE c_id = $course_id AND lp_iv_id = $lp_view_id ";
1013
            Database::query($sql);
1014
1015
            $sql = "DELETE FROM $lpObjective
1016
                    WHERE c_id = $course_id AND lp_iv_id = $lp_view_id ";
1017
            Database::query($sql);
1018
        }
1019
1020
        $sql = "DELETE FROM $lp_view_table
1021
            WHERE
1022
                c_id = $course_id AND
1023
                user_id = $user_id AND
1024
                lp_id= $lp_id AND
1025
                session_id = $session_id
1026
            ";
1027
        Database::query($sql);
1028
1029
        $sql = "SELECT exe_id FROM $track_e_exercises
1030
                WHERE   exe_user_id = $user_id AND
1031
                        session_id = $session_id AND
1032
                        c_id = $course_id AND
1033
                        orig_lp_id = $lp_id";
1034
        $result = Database::query($sql);
1035
        $exe_list = array();
1036
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1037
            $exe_list[] = $row['exe_id'];
1038
        }
1039
1040
        if (!empty($exe_list) && is_array($exe_list) && count($exe_list) > 0) {
1041
            $sql = "DELETE FROM $track_e_exercises
1042
                WHERE exe_id IN (" . implode(',', $exe_list) . ")";
1043
            Database::query($sql);
1044
1045
            $sql = "DELETE FROM $track_attempts
1046
                WHERE exe_id IN (" . implode(',', $exe_list) . ")";
1047
            Database::query($sql);
1048
1049
            $sql = "DELETE FROM $recording_table
1050
                WHERE exe_id IN (" . implode(',', $exe_list) . ")";
1051
            Database::query($sql);
1052
        }
1053
1054
        Event::addEvent(
1055
            LOG_LP_ATTEMPT_DELETE,
1056
            LOG_LP_ID,
1057
            $lp_id,
1058
            null,
1059
            null,
1060
            $course_id,
1061
            $session_id
1062
        );
1063
    }
1064
1065
    /**
1066
     * Delete all exercise attempts (included in LP or not)
1067
     *
1068
     * @param 	int		user id
1069
     * @param 	int		exercise id
1070
     * @param 	int	$course_id
1071
     * @param 	int		session id
1072
     */
1073
    public static function delete_all_incomplete_attempts($user_id, $exercise_id, $course_id, $session_id = 0)
1074
    {
1075
        $track_e_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1076
        $user_id = intval($user_id);
1077
        $exercise_id = intval($exercise_id);
1078
        $course_id = intval($course_id);
1079
        $session_id = intval($session_id);
1080
        if (!empty($user_id) && !empty($exercise_id) && !empty($course_code)) {
0 ignored issues
show
Bug introduced by
The variable $course_code seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
1081
            $sql = "DELETE FROM $track_e_exercises
1082
                    WHERE
1083
                        exe_user_id = $user_id AND
1084
                        exe_exo_id = $exercise_id AND
1085
                        c_id = '$course_id' AND
1086
                        session_id = $session_id AND
1087
                        status = 'incomplete' ";
1088
            Database::query($sql);
1089
            Event::addEvent(
1090
                LOG_EXERCISE_RESULT_DELETE,
1091
                LOG_EXERCISE_AND_USER_ID,
1092
                $exercise_id . '-' . $user_id,
1093
                null,
1094
                null,
1095
                $course_id,
1096
                $session_id
1097
            );
1098
        }
1099
    }
1100
1101
    /**
1102
     * Gets all exercise results (NO Exercises in LPs ) from a given exercise id, course, session
1103
     * @param   int     exercise id
1104
     * @param   int $courseId
1105
     * @param   int     session id
1106
     * @return  array   with the results
1107
     *
1108
     */
1109
    public static function get_all_exercise_results(
1110
        $exercise_id,
1111
        $courseId,
1112
        $session_id = 0,
1113
        $load_question_list = true,
1114
        $user_id = null
1115
    ) {
1116
        $TABLETRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1117
        $TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1118
        $courseId = intval($courseId);
1119
        $exercise_id = intval($exercise_id);
1120
        $session_id = intval($session_id);
1121
1122
        $user_condition = null;
1123
        if (!empty($user_id)) {
1124
            $user_id = intval($user_id);
1125
            $user_condition = "AND exe_user_id = $user_id ";
1126
        }
1127
        $sql = "SELECT * FROM $TABLETRACK_EXERCICES
1128
                WHERE
1129
                    status = ''  AND
1130
                    c_id = '$courseId' AND
1131
                    exe_exo_id = '$exercise_id' AND
1132
                    session_id = $session_id  AND
1133
                    orig_lp_id =0 AND
1134
                    orig_lp_item_id = 0
1135
                    $user_condition
1136
                ORDER BY exe_id";
1137
        $res = Database::query($sql);
1138
        $list = array();
1139
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1140
            $list[$row['exe_id']] = $row;
1141
            if ($load_question_list) {
1142
                $sql = "SELECT * FROM $TBL_TRACK_ATTEMPT
1143
                        WHERE exe_id = {$row['exe_id']}";
1144
                $res_question = Database::query($sql);
1145
                while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1146
                    $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1147
                }
1148
            }
1149
        }
1150
        return $list;
1151
    }
1152
1153
    /**
1154
     * Gets all exercise results (NO Exercises in LPs ) from a given exercise id, course, session
1155
     * @param   int  $courseId
1156
     * @param   int     session id
1157
     * @return  array   with the results
1158
     *
1159
     */
1160
    public static function get_all_exercise_results_by_course($courseId, $session_id = 0, $get_count = true)
1161
    {
1162
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1163
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1164
        $courseId = intval($courseId);
1165
        $session_id = intval($session_id);
1166
1167
        $select = '*';
1168
        if ($get_count) {
1169
            $select = 'count(*) as count';
1170
        }
1171
        $sql = "SELECT $select FROM $table_track_exercises
1172
                WHERE   status = ''  AND
1173
                        c_id = '$courseId' AND
1174
                        session_id = $session_id  AND
1175
                        orig_lp_id = 0 AND
1176
                        orig_lp_item_id = 0
1177
                ORDER BY exe_id";
1178
        $res = Database::query($sql);
1179
        if ($get_count) {
1180
            $row = Database::fetch_array($res, 'ASSOC');
1181
            return $row['count'];
1182
        } else {
1183
            $list = array();
1184
            while ($row = Database::fetch_array($res, 'ASSOC')) {
1185
                $list[$row['exe_id']] = $row;
1186
                $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}";
1187
                $res_question = Database::query($sql);
1188
                while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1189
                    $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1190
                }
1191
            }
1192
            return $list;
1193
        }
1194
    }
1195
1196
    /**
1197
     * Gets all exercise results (NO Exercises in LPs) from a given exercise id, course, session
1198
     * @param   int     exercise id
1199
     * @param   int  $courseId
1200
     * @param   int     session id
1201
     * @return  array   with the results
1202
     *
1203
     */
1204 View Code Duplication
    public static function get_all_exercise_results_by_user($user_id, $courseId, $session_id = 0)
1205
    {
1206
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1207
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1208
        $courseId = intval($courseId);
1209
        $session_id = intval($session_id);
1210
        $user_id = intval($user_id);
1211
1212
        $sql = "SELECT * FROM $table_track_exercises
1213
                WHERE
1214
                    status = '' AND
1215
                    exe_user_id = $user_id AND
1216
                    c_id = '$courseId' AND
1217
                    session_id = $session_id AND
1218
                    orig_lp_id = 0 AND
1219
                    orig_lp_item_id = 0
1220
                ORDER by exe_id";
1221
1222
        $res = Database::query($sql);
1223
        $list = array();
1224
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1225
            $list[$row['exe_id']] = $row;
1226
            $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}";
1227
            $res_question = Database::query($sql);
1228
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1229
                $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1230
            }
1231
        }
1232
1233
        return $list;
1234
    }
1235
1236
    /**
1237
     * Gets exercise results (NO Exercises in LPs) from a given exercise id, course, session
1238
     * @param   int     exercise id
1239
     * @param   string  course code
1240
     * @param   int     session id
1241
     * @return  array   with the results
1242
     *
1243
     */
1244
    public static function get_exercise_results_by_attempt($exe_id, $status = null)
1245
    {
1246
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1247
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1248
        $table_track_attempt_recording = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
1249
        $exe_id = intval($exe_id);
1250
1251
        $status = Database::escape_string($status);
1252
1253
        $sql = "SELECT * FROM $table_track_exercises
1254
                WHERE status = '".$status."' AND exe_id = $exe_id";
1255
1256
        $res = Database::query($sql);
1257
        $list = array();
1258
        if (Database::num_rows($res)) {
1259
            $row = Database::fetch_array($res, 'ASSOC');
1260
1261
            //Checking if this attempt was revised by a teacher
1262
            $sql_revised = 'SELECT exe_id FROM '.$table_track_attempt_recording.'
1263
                            WHERE author != "" AND exe_id = '.$exe_id.' LIMIT 1';
1264
            $res_revised = Database::query($sql_revised);
1265
            $row['attempt_revised'] = 0;
1266
            if (Database::num_rows($res_revised) > 0) {
1267
                $row['attempt_revised'] = 1;
1268
            }
1269
            $list[$exe_id] = $row;
1270
            $sql = "SELECT * FROM $table_track_attempt
1271
                    WHERE exe_id = $exe_id ORDER BY tms ASC";
1272
            $res_question = Database::query($sql);
1273
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1274
                $list[$exe_id]['question_list'][$row_q['question_id']] = $row_q;
1275
            }
1276
        }
1277
1278
        return $list;
1279
    }
1280
1281
    /**
1282
     * Gets exercise results (NO Exercises in LPs) from a given user, exercise id, course, session, lp_id, lp_item_id
1283
     * @param   int     user id
1284
     * @param   int     exercise id
1285
     * @param   string  course code
1286
     * @param   int     session id
1287
     * @param   int     lp id
1288
     * @param   int     lp item id
1289
     * @param   string 	order asc or desc
1290
     * @return  array   with the results
1291
     *
1292
     */
1293
    public static function getExerciseResultsByUser($user_id, $exercise_id, $courseId, $session_id = 0, $lp_id = 0, $lp_item_id = 0, $order = null)
1294
    {
1295
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1296
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1297
        $table_track_attempt_recording = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
1298
        $courseId = intval($courseId);
1299
        $exercise_id = intval($exercise_id);
1300
        $session_id = intval($session_id);
1301
        $user_id = intval($user_id);
1302
        $lp_id = intval($lp_id);
1303
        $lp_item_id = intval($lp_item_id);
1304
1305
        if (!in_array(strtolower($order), array('asc', 'desc'))) {
1306
            $order = 'asc';
1307
        }
1308
1309
        $sql = "SELECT * FROM $table_track_exercises
1310
                WHERE
1311
                    status 			= '' AND
1312
                    exe_user_id 	= $user_id AND
1313
                    c_id 	        = $courseId AND
1314
                    exe_exo_id 		= $exercise_id AND
1315
                    session_id 		= $session_id AND
1316
                    orig_lp_id 		= $lp_id AND
1317
                    orig_lp_item_id = $lp_item_id
1318
                ORDER by exe_id $order ";
1319
1320
        $res = Database::query($sql);
1321
        $list = array();
1322
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1323
            //Checking if this attempt was revised by a teacher
1324
            $sql = 'SELECT exe_id FROM '.$table_track_attempt_recording.'
1325
                    WHERE author != "" AND exe_id = '.$row['exe_id'].'
1326
                    LIMIT 1';
1327
            $res_revised = Database::query($sql);
1328
            $row['attempt_revised'] = 0;
1329
            if (Database::num_rows($res_revised) > 0) {
1330
                $row['attempt_revised'] = 1;
1331
            }
1332
            $list[$row['exe_id']] = $row;
1333
            $sql = "SELECT * FROM $table_track_attempt
1334
                    WHERE exe_id = {$row['exe_id']}";
1335
            $res_question = Database::query($sql);
1336
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1337
                $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1338
            }
1339
        }
1340
        return $list;
1341
    }
1342
1343
    /**
1344
     * Count exercise attempts (NO Exercises in LPs ) from a given exercise id, course, session
1345
     * @param int $user_id
1346
     * @param   int     exercise id
1347
     * @param   int     $courseId
1348
     * @param   int     session id
1349
     * @return  array   with the results
1350
     *
1351
     */
1352
    public static function count_exercise_attempts_by_user($user_id, $exercise_id, $courseId, $session_id = 0)
1353
    {
1354
        $TABLETRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1355
        $courseId = intval($courseId);
1356
        $exercise_id = intval($exercise_id);
1357
        $session_id = intval($session_id);
1358
        $user_id = intval($user_id);
1359
1360
        $sql = "SELECT count(*) as count FROM $TABLETRACK_EXERCICES
1361
                WHERE status = ''  AND
1362
                    exe_user_id = '$user_id' AND
1363
                    c_id = '$courseId' AND
1364
                    exe_exo_id = '$exercise_id' AND
1365
                    session_id = $session_id AND
1366
                    orig_lp_id =0 AND
1367
                    orig_lp_item_id = 0
1368
                ORDER BY exe_id";
1369
        $res = Database::query($sql);
1370
        $result = 0;
1371
        if (Database::num_rows($res) > 0) {
1372
            $row = Database::fetch_array($res, 'ASSOC');
1373
            $result = $row['count'];
1374
        }
1375
1376
        return $result;
1377
    }
1378
1379
    /**
1380
     * Gets all exercise BEST results attempts (NO Exercises in LPs ) from a given exercise id, course, session per user
1381
     * @param   int     $exercise_id
1382
     * @param   int     $courseId
1383
     * @param   int     $session_id
1384
     * @return  array   with the results
1385
     * @todo rename this function
1386
     */
1387
    public static function get_best_exercise_results_by_user($exercise_id, $courseId, $session_id = 0)
1388
    {
1389
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1390
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1391
        $courseId = intval($courseId);
1392
        $exercise_id = intval($exercise_id);
1393
        $session_id = intval($session_id);
1394
1395
        $sql = "SELECT * FROM $table_track_exercises
1396
                WHERE
1397
                    status = '' AND
1398
                    c_id = $courseId AND
1399
                    exe_exo_id = '$exercise_id' AND
1400
                    session_id = $session_id AND
1401
                    orig_lp_id = 0 AND
1402
                    orig_lp_item_id = 0
1403
                ORDER BY exe_id";
1404
1405
        $res = Database::query($sql);
1406
        $list = array();
1407
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1408
            $list[$row['exe_id']] = $row;
1409
            $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}";
1410
            $res_question = Database::query($sql);
1411
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1412
                $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1413
            }
1414
        }
1415
1416
        // Getting the best results of every student
1417
        $best_score_return = array();
1418
        foreach ($list as $student_result) {
1419
            $user_id = $student_result['exe_user_id'];
1420
            $current_best_score[$user_id] = $student_result['exe_result'];
1421
1422
            //echo $current_best_score[$user_id].' - '.$best_score_return[$user_id]['exe_result'].'<br />';
1423
            if (!isset($best_score_return[$user_id]['exe_result'])) {
1424
                $best_score_return[$user_id] = $student_result;
1425
            }
1426
1427
            if ($current_best_score[$user_id] > $best_score_return[$user_id]['exe_result']) {
1428
                $best_score_return[$user_id] = $student_result;
1429
            }
1430
        }
1431
1432
        return $best_score_return;
1433
    }
1434
1435
    /**
1436
     * @param int $user_id
1437
     * @param int $exercise_id
1438
     * @param int $courseId
1439
     * @param int $session_id
1440
     * @return array
1441
     */
1442
    public static function get_best_attempt_exercise_results_per_user($user_id, $exercise_id, $courseId, $session_id = 0)
1443
    {
1444
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1445
        $courseId = intval($courseId);
1446
        $exercise_id = intval($exercise_id);
1447
        $session_id = intval($session_id);
1448
        $user_id = intval($user_id);
1449
1450
        $sql = "SELECT * FROM $table_track_exercises
1451
                WHERE
1452
                    status = ''  AND
1453
                    c_id = '$courseId' AND
1454
                    exe_exo_id = '$exercise_id' AND
1455
                    session_id = $session_id  AND
1456
                    exe_user_id = $user_id AND
1457
                    orig_lp_id =0 AND
1458
                    orig_lp_item_id = 0
1459
                ORDER BY exe_id";
1460
1461
        $res = Database::query($sql);
1462
        $list = array();
1463
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1464
            $list[$row['exe_id']] = $row;  /*
1465
              $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}";
1466
              $res_question = Database::query($sql);
1467
              while($row_q = Database::fetch_array($res_question,'ASSOC')) {
1468
              $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1469
              } */
1470
        }
1471
        //Getting the best results of every student
1472
        $best_score_return = array();
1473
        $best_score_return['exe_result'] = 0;
1474
1475
        foreach ($list as $result) {
1476
            $current_best_score = $result;
1477
            if ($current_best_score['exe_result'] > $best_score_return['exe_result']) {
1478
                $best_score_return = $result;
1479
            }
1480
        }
1481
        if (!isset($best_score_return['exe_weighting'])) {
1482
            $best_score_return = array();
1483
        }
1484
        return $best_score_return;
1485
    }
1486
1487
    /**
1488
     * @param int $exercise_id
1489
     * @param int $courseId
1490
     * @param int $session_id
1491
     * @return mixed
1492
     */
1493
    public static function count_exercise_result_not_validated($exercise_id, $courseId, $session_id = 0)
1494
    {
1495
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1496
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
1497
        $courseId = intval($courseId);
1498
        $session_id = intval($session_id);
1499
        $exercise_id = intval($exercise_id);
1500
1501
        $sql = "SELECT count(e.exe_id) as count
1502
                FROM $table_track_exercises e
1503
                LEFT JOIN $table_track_attempt a
1504
                ON e.exe_id = a.exe_id
1505
                WHERE
1506
                    exe_exo_id = $exercise_id AND
1507
                    c_id = '$courseId' AND
1508
                    e.session_id = $session_id  AND
1509
                    orig_lp_id = 0 AND
1510
                    marks IS NULL AND
1511
                    status = '' AND
1512
                    orig_lp_item_id = 0
1513
                ORDER BY e.exe_id";
1514
        $res = Database::query($sql);
1515
        $row = Database::fetch_array($res, 'ASSOC');
1516
1517
        return $row['count'];
1518
    }
1519
1520
    /**
1521
     * Gets all exercise BEST results attempts (NO Exercises in LPs ) from a given exercise id, course, session per user
1522
     * @param   int     exercise id
1523
     * @param   int   course id
1524
     * @param   int     session id
1525
     * @return  array   with the results
1526
     *
1527
     */
1528
    public static function get_count_exercises_attempted_by_course($courseId, $session_id = 0)
1529
    {
1530
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1531
        $courseId = intval($courseId);
1532
        $session_id = intval($session_id);
1533
1534
        $sql = "SELECT DISTINCT exe_exo_id, exe_user_id
1535
                FROM $table_track_exercises
1536
                WHERE
1537
                    status = '' AND
1538
                    c_id = '$courseId' AND
1539
                    session_id = $session_id AND
1540
                    orig_lp_id =0 AND
1541
                    orig_lp_item_id = 0
1542
                ORDER BY exe_id";
1543
        $res = Database::query($sql);
1544
        $count = 0;
1545
        if (Database::num_rows($res) > 0) {
1546
            $count = Database::num_rows($res);
1547
        }
1548
        return $count;
1549
    }
1550
1551
    /**
1552
     * Gets all exercise events from a Learning Path within a Course 	nd Session
1553
     * @param	int		exercise id
1554
     * @param	int	$courseId
1555
     * @param 	int		session id
1556
     * @return 	array
1557
     */
1558 View Code Duplication
    public static function get_all_exercise_event_from_lp($exercise_id, $courseId, $session_id = 0)
1559
    {
1560
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1561
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1562
        $courseId = intval($courseId);
1563
        $exercise_id = intval($exercise_id);
1564
        $session_id = intval($session_id);
1565
1566
        $sql = "SELECT * FROM $table_track_exercises
1567
                WHERE
1568
                    status = '' AND
1569
                    c_id = $courseId AND
1570
                    exe_exo_id = '$exercise_id' AND
1571
                    session_id = $session_id AND
1572
                    orig_lp_id !=0 AND
1573
                    orig_lp_item_id != 0";
1574
1575
        $res = Database::query($sql);
1576
        $list = array();
1577
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1578
            $list[$row['exe_id']] = $row;
1579
            $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}";
1580
            $res_question = Database::query($sql);
1581
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1582
                $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1583
            }
1584
        }
1585
        return $list;
1586
    }
1587
1588
    /**
1589
     * @param int $lp_id
1590
     * @param int $course_id
1591
     *
1592
     * @return array
1593
     */
1594
    public static function get_all_exercises_from_lp($lp_id, $course_id)
1595
    {
1596
        $lp_item_table = Database :: get_course_table(TABLE_LP_ITEM);
1597
        $course_id = intval($course_id);
1598
        $lp_id = intval($lp_id);
1599
        $sql = "SELECT * FROM $lp_item_table
1600
                WHERE
1601
                    c_id = $course_id AND
1602
                    lp_id = '".$lp_id."' AND
1603
                    item_type = 'quiz'
1604
                ORDER BY parent_item_id, display_order";
1605
        $res = Database::query($sql);
1606
1607
        $my_exercise_list = array();
1608
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1609
            $my_exercise_list[] = $row;
1610
        }
1611
1612
        return $my_exercise_list;
1613
    }
1614
1615
    /**
1616
     * This function gets the comments of an exercise
1617
     *
1618
     * @param int $exe_id
1619
     * @param int $question_id
1620
     *
1621
     * @return string the comment
1622
     */
1623 View Code Duplication
    public static function get_comments($exe_id, $question_id)
1624
    {
1625
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1626
        $sql = "SELECT teacher_comment FROM ".$table_track_attempt."
1627
                WHERE
1628
                    exe_id='".Database::escape_string($exe_id)."' AND
1629
                    question_id = '".Database::escape_string($question_id)."'
1630
                ORDER by question_id";
1631
        $sqlres = Database::query($sql);
1632
        $comm = Database::result($sqlres, 0, "teacher_comment");
1633
1634
        return $comm;
1635
    }
1636
1637
    /**
1638
     * @param int $exe_id
1639
     *
1640
     * @return array
1641
     */
1642
    public static function getAllExerciseEventByExeId($exe_id)
1643
    {
1644
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1645
        $exe_id = intval($exe_id);
1646
        $list = array();
1647
1648
        $sql = "SELECT * FROM $table_track_attempt
1649
                WHERE exe_id = $exe_id
1650
                ORDER BY position";
1651
        $res_question = Database::query($sql);
1652
        if (Database::num_rows($res_question)) {
1653
            while ($row = Database::fetch_array($res_question, 'ASSOC')) {
1654
                $list[$row['question_id']][] = $row;
1655
            }
1656
        }
1657
        return $list;
1658
    }
1659
1660
    /**
1661
     *
1662
     * @param int $exe_id
1663
     * @param int $user_id
1664
     * @param int $courseId
1665
     * @param int $session_id
1666
     * @param int $question_id
1667
     */
1668 View Code Duplication
    public static function delete_attempt($exe_id, $user_id, $courseId, $session_id, $question_id)
1669
    {
1670
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1671
1672
        $exe_id = intval($exe_id);
1673
        $user_id = intval($user_id);
1674
        $courseId = intval($courseId);
1675
        $session_id = intval($session_id);
1676
        $question_id = intval($question_id);
1677
1678
        $sql = "DELETE FROM $table_track_attempt
1679
                WHERE
1680
                    exe_id = $exe_id AND
1681
                    user_id = $user_id AND
1682
                    c_id = $courseId AND
1683
                    session_id = $session_id AND
1684
                    question_id = $question_id ";
1685
        Database::query($sql);
1686
1687
        Event::addEvent(
1688
            LOG_QUESTION_RESULT_DELETE,
1689
            LOG_EXERCISE_ATTEMPT_QUESTION_ID,
1690
            $exe_id . '-' . $question_id,
1691
            null,
1692
            null,
1693
            $courseId,
1694
            $session_id
1695
        );
1696
    }
1697
1698
    /**
1699
     * @param $exe_id
1700
     * @param $user_id
1701
     * @param int $courseId
1702
     * @param $question_id
1703
     * @param int $sessionId
1704
     */
1705 View Code Duplication
    public static function delete_attempt_hotspot($exe_id, $user_id, $courseId, $question_id, $sessionId = null)
1706
    {
1707
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
1708
1709
        $exe_id = intval($exe_id);
1710
        $user_id = intval($user_id);
1711
        $courseId = intval($courseId);
1712
        $question_id = intval($question_id);
1713
        if (!isset($sessionId)) {
1714
            $sessionId = api_get_session_id();
1715
        }
1716
1717
        $sql = "DELETE FROM $table_track_attempt
1718
                WHERE   hotspot_exe_id = $exe_id AND
1719
                        hotspot_user_id = $user_id AND
1720
                        c_id = $courseId AND
1721
                        hotspot_question_id = $question_id ";
1722
        Database::query($sql);
1723
        Event::addEvent(
1724
            LOG_QUESTION_RESULT_DELETE,
1725
            LOG_EXERCISE_ATTEMPT_QUESTION_ID,
1726
            $exe_id . '-' . $question_id,
1727
            null,
1728
            null,
1729
            $courseId,
1730
            $sessionId
1731
        );
1732
    }
1733
1734
    /**
1735
     * Registers in track_e_course_access when user logs in for the first time to a course
1736
     * @param int $courseId ID of the course
1737
     * @param int $user_id ID of the user
1738
     * @param int $session_id ID of the session (if any)
1739
     */
1740
    public static function event_course_login($courseId, $user_id, $session_id)
1741
    {
1742
        $course_tracking_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1743
        $loginDate = $logoutDate = api_get_utc_datetime();
1744
1745
        //$counter represents the number of time this record has been refreshed
1746
        $counter = 1;
1747
1748
        $courseId = intval($courseId);
1749
        $user_id = intval($user_id);
1750
        $session_id = intval($session_id);
1751
        $ip = api_get_real_ip();
1752
1753
        $sql = "INSERT INTO $course_tracking_table(c_id, user_ip, user_id, login_course_date, logout_course_date, counter, session_id)
1754
                VALUES('".$courseId."', '".$ip."', '".$user_id."', '$loginDate', '$logoutDate', $counter, '".$session_id."')";
1755
        Database::query($sql);
1756
1757
        // Course catalog stats modifications see #4191
1758
        CourseManager::update_course_ranking(null, null, null, null, true, false);
1759
    }
1760
1761
    /**
1762
     * Register a "fake" time spent on the platform, for example to match the
1763
     * estimated time he took to author an assignment/work, see configuration
1764
     * setting considered_working_time.
1765
     * This assumes there is already some connection of the student to the
1766
     * course, otherwise he wouldn't be able to upload an assignment.
1767
     * This works by creating a new record, copy of the current one, then
1768
     * updating the current one to be just the considered_working_time and
1769
     * end at the same second as the user connected to the course.
1770
     * @param int $courseId The course in which to add the time
1771
     * @param int $userId The user for whom to add the time
1772
     * @param int $sessionId The session in which to add the time (if any)
1773
     * @param string $virtualTime The amount of time to be added, in a hh:mm:ss format. If int, we consider it is expressed in hours.
1774
     * @param string $ip IP address to go on record for this time record
1775
     *
1776
     * @return True on successful insertion, false otherwise
1777
     */
1778
    public static function eventAddVirtualCourseTime(
1779
        $courseId,
1780
        $userId,
1781
        $sessionId,
1782
        $virtualTime = '',
1783
        $ip = ''
1784
    ) {
1785
        $courseTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1786
        $time = $loginDate = $logoutDate = api_get_utc_datetime();
1787
1788
        $courseId = intval($courseId);
1789
        $userId = intval($userId);
1790
        $sessionId = intval($sessionId);
1791
        $ip = Database::escape_string($ip);
1792
1793
        // Get the current latest course connection register. We need that
1794
        // record to re-use the data and create a new record.
1795
        $sql = "SELECT *
1796
                FROM $courseTrackingTable
1797
                WHERE
1798
                    user_id = ".$userId." AND
1799
                    c_id = ".$courseId."  AND
1800
                    session_id  = ".$sessionId." AND
1801
                    login_course_date > '$time' - INTERVAL 3600 SECOND
1802
                ORDER BY login_course_date DESC LIMIT 0,1";
1803
        $result = Database::query($sql);
1804
1805
        // Ignore if we didn't find any course connection record in the last
1806
        // hour. In this case it wouldn't be right to add a "fake" time record.
1807
        if (Database::num_rows($result) > 0) {
1808
            // Found the latest connection
1809
            $row = Database::fetch_row($result);
1810
            $courseAccessId = $row[0];
1811
            $courseAccessLoginDate = $row[3];
1812
            $counter = $row[5];
1813
            $counter = $counter ? $counter : 0;
1814
            // Insert a new record, copy of the current one (except the logout
1815
            // date that we update to the current time)
1816
            $sql = "INSERT INTO $courseTrackingTable(
1817
                    c_id,
1818
                    user_ip, 
1819
                    user_id, 
1820
                    login_course_date, 
1821
                    logout_course_date, 
1822
                    counter, 
1823
                    session_id
1824
                ) VALUES(
1825
                    $courseId, 
1826
                    '$ip', 
1827
                    $userId, 
1828
                    '$courseAccessLoginDate', 
1829
                    '$logoutDate', 
1830
                    $counter, 
1831
                    $sessionId
1832
                )";
1833
            Database::query($sql);
1834
1835
            $loginDate = ChamiloApi::addOrSubTimeToDateTime(
1836
                $virtualTime,
1837
                $courseAccessLoginDate,
1838
                false
1839
            );
1840
            // We update the course tracking table
1841
            $sql = "UPDATE $courseTrackingTable  
1842
                    SET 
1843
                        login_course_date = '$loginDate',
1844
                        logout_course_date = '$courseAccessLoginDate',
1845
                        counter = 0
1846
                    WHERE 
1847
                        course_access_id = ".intval($courseAccessId)." AND 
1848
                        session_id = ".$sessionId;
1849
            Database::query($sql);
1850
1851
            return true;
1852
        }
1853
1854
        return false;
1855
    }
1856
    /**
1857
     * Removes a "fake" time spent on the platform, for example to match the
1858
     * estimated time he took to author an assignment/work, see configuration
1859
     * setting considered_working_time.
1860
     * This method should be called when something that generated a fake
1861
     * time record is removed. Given the database link is weak (no real
1862
     * relationship kept between the deleted item and this record), this
1863
     * method just looks for the latest record that has the same time as the
1864
     * item's fake time, is in the past and in this course+session. If such a
1865
     * record cannot be found, it doesn't do anything.
1866
     * The IP address is not considered a useful filter here.
1867
     * @param int $courseId The course in which to add the time
1868
     * @param int $userId The user for whom to add the time
1869
     * @param $sessionId The session in which to add the time (if any)
1870
     * @param string $virtualTime The amount of time to be added, in a hh:mm:ss format. If int, we consider it is expressed in hours.
1871
     * @return True on successful removal, false otherwise
1872
     */
1873
    public static function eventRemoveVirtualCourseTime($courseId, $userId, $sessionId = 0, $virtualTime = '')
1874
    {
1875
        if (empty($virtualTime)) {
1876
            return false;
1877
        }
1878
        $courseTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1879
        $time = $loginDate = $logoutDate = api_get_utc_datetime();
1880
1881
        $courseId = intval($courseId);
1882
        $userId = intval($userId);
1883
        $sessionId = intval($sessionId);
1884
        // Change $virtualTime format from hh:mm:ss to hhmmss which is the
1885
        // format returned by SQL for a subtraction of two datetime values
1886
        // @todo make sure this is portable between DBMSes
1887
        if (preg_match('/:/', $virtualTime)) {
1888
            list($h, $m, $s) = preg_split('/:/', $virtualTime);
1889
            $virtualTime = $h * 3600 + $m * 60 + $s;
1890
        } else {
1891
            $virtualTime *= 3600;
1892
        }
1893
1894
        // Get the current latest course connection register. We need that
1895
        // record to re-use the data and create a new record.
1896
        $sql = "SELECT course_access_id
1897
                        FROM $courseTrackingTable
1898
                        WHERE
1899
                            user_id = $userId AND
1900
                            c_id = $courseId  AND
1901
                            session_id  = $sessionId AND
1902
                            counter = 0 AND
1903
                            (UNIX_TIMESTAMP(logout_course_date) - UNIX_TIMESTAMP(login_course_date)) = '$virtualTime'
1904
                        ORDER BY login_course_date DESC LIMIT 0,1";
1905
        $result = Database::query($sql);
1906
1907
        // Ignore if we didn't find any course connection record in the last
1908
        // hour. In this case it wouldn't be right to add a "fake" time record.
1909 View Code Duplication
        if (Database::num_rows($result) > 0) {
1910
            // Found the latest connection
1911
            $row = Database::fetch_row($result);
1912
            $courseAccessId = $row[0];
1913
            $sql = "DELETE FROM $courseTrackingTable WHERE course_access_id = $courseAccessId";
1914
            $result = Database::query($sql);
1915
1916
            return $result;
1917
        }
1918
1919
        return false;
1920
    }
1921
1922
    /**
1923
     * For the sake of genericity, this function is a switch.
1924
     * It's called by EventsDispatcher and fires the good function
1925
     * with the good require_once.
1926
     *
1927
     * @param string $event_name
1928
     * @param array $params
1929
     */
1930
    public static function event_send_mail($event_name, $params)
1931
    {
1932
        EventsMail::send_mail($event_name, $params);
1933
    }
1934
1935
    /**
1936
     * Internal function checking if the mail was already sent from that user to that user
1937
     * @param string $event_name
1938
     * @param int $user_from
1939
     * @param int $user_to
1940
     * @return boolean
1941
     */
1942
    public static function check_if_mail_already_sent($event_name, $user_from, $user_to = null)
1943
    {
1944
        if ($user_to == null) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $user_to of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
1945
            $sql = 'SELECT COUNT(*) as total FROM '.Database::get_main_table(TABLE_EVENT_SENT).'
1946
                    WHERE user_from = '.$user_from.' AND event_type_name = "'.$event_name.'"';
1947
        } else {
1948
            $sql = 'SELECT COUNT(*) as total FROM '.Database::get_main_table(TABLE_EVENT_SENT).'
1949
                    WHERE user_from = '.$user_from.' AND user_to = '.$user_to.' AND event_type_name = "'.$event_name.'"';
1950
        }
1951
        $result = Database::store_result(Database::query($sql), 'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like \Database::query($sql) can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1952
        return $result[0]["total"];
1953
    }
1954
1955
    /**
1956
     *
1957
     * Filter EventEmailTemplate Filters see the main/inc/conf/events.conf.dist.php
1958
     *
1959
     */
1960
1961
    /**
1962
     * Basic template event message filter (to be used by other filters as default)
1963
     * @param array $values (passing by reference)
1964
     * @return boolean True if everything is OK, false otherwise
1965
     */
1966
    public function event_send_mail_filter_func(&$values)
1967
    {
1968
        return true;
1969
    }
1970
1971
    /**
1972
     * user_registration - send_mail filter
1973
     * @param array $values (passing by reference)
1974
     * @return boolean True if everything is OK, false otherwise
1975
     */
1976
    public function user_registration_event_send_mail_filter_func(&$values)
1977
    {
1978
        $res = self::event_send_mail_filter_func($values);
1979
        // proper logic for this filter
1980
        return $res;
1981
    }
1982
1983
    /**
1984
     * portal_homepage_edited - send_mail filter
1985
     * @param array $values (passing by reference)
1986
     * @return boolean True if everything is OK, false otherwise
1987
     */
1988
    public function portal_homepage_edited_event_send_mail_filter_func(&$values)
1989
    {
1990
        $res = self::event_send_mail_filter_func($values);
1991
        // proper logic for this filter
1992
        return $res;
1993
    }
1994
}
1995