Test Setup Failed
Push — master ( ec638a...cb9435 )
by Julito
51:10
created

Event::event_login()   C

Complexity

Conditions 8
Paths 33

Size

Total Lines 35
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 22
c 0
b 0
f 0
nc 33
nop 1
dl 0
loc 35
rs 5.3846
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
        $userId = intval($userId);
63
64
        if (empty($userInfo)) {
65
            return false;
66
        }
67
68
        $TABLETRACK_LOGIN = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
69
70
        $reallyNow = api_get_utc_datetime();
71
72
        $sql = "INSERT INTO ".$TABLETRACK_LOGIN." (login_user_id, user_ip, login_date, logout_date) VALUES
73
                    ('".$userId."',
74
                    '".Database::escape_string(api_get_real_ip())."',
75
                    '".$reallyNow."',
76
                    '".$reallyNow."'
77
                    )";
78
        Database::query($sql);
79
80
        // Auto subscribe
81
        $user_status = $userInfo['status']  == SESSIONADMIN ? 'sessionadmin' :
82
            $userInfo['status'] == COURSEMANAGER ? 'teacher' :
83
                $userInfo['status'] == DRH ? 'DRH' : 'student';
84
        $autoSubscribe = api_get_setting($user_status.'_autosubscribe');
85
        if ($autoSubscribe) {
86
            $autoSubscribe = explode('|', $autoSubscribe);
87
            foreach ($autoSubscribe as $code) {
88
                if (CourseManager::course_exists($code)) {
89
                    CourseManager::subscribe_user($userId, $code);
90
                }
91
            }
92
        }
93
    }
94
95
    /**
96
     * @param tool name of the tool (name in mainDb.accueil table)
97
     * @author Sebastien Piraux <[email protected]>
98
     * @desc Record information for access event for courses
99
     */
100
    public static function accessCourse()
101
    {
102
        $TABLETRACK_ACCESS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
103
        //for "what's new" notification
104
        $TABLETRACK_LASTACCESS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
105
106
        $id_session = api_get_session_id();
107
        $now = api_get_utc_datetime();
108
        $courseId = api_get_course_int_id();
109
        $user_id = api_get_user_id();
110
        $ip = api_get_real_ip();
111
112
        if ($user_id) {
113
            $user_id = "'".$user_id."'";
114
        } else {
115
            $user_id = "0"; // no one
116
        }
117
        $sql = "INSERT INTO ".$TABLETRACK_ACCESS."  (user_ip, access_user_id, c_id, access_date, access_session_id) VALUES
118
                ('".$ip."', ".$user_id.", '".$courseId."', '".$now."','".$id_session."')";
119
120
        Database::query($sql);
121
122
        // added for "what's new" notification
123
        $sql = "UPDATE $TABLETRACK_LASTACCESS  SET access_date = '$now'
124
                WHERE access_user_id = $user_id AND c_id = '$courseId' AND access_tool IS NULL AND access_session_id=".$id_session;
125
        $result = Database::query($sql);
126
127 View Code Duplication
        if (Database::affected_rows($result) == 0) {
128
            $sql = "INSERT INTO $TABLETRACK_LASTACCESS (access_user_id, c_id, access_date, access_session_id)
129
                    VALUES (".$user_id.", '".$courseId."', '$now', '".$id_session."')";
130
            Database::query($sql);
131
        }
132
133
        return 1;
134
    }
135
136
    /**
137
     * @param tool name of the tool (name in mainDb.accueil table)
138
     * @author Sebastien Piraux <[email protected]>
139
     * @desc Record information for access event for tools
140
     *
141
     *  $tool can take this values :
142
     *  Links, Calendar, Document, Announcements,
143
     *  Group, Video, Works, Users, Exercices, Course Desc
144
     *  ...
145
     *  Values can be added if new modules are created (15char max)
146
     *  I encourage to use $nameTool as $tool when calling this function
147
     *
148
     * 	Functionality for "what's new" notification is added by Toon Van Hoecke
149
     */
150
    public static function event_access_tool($tool, $id_session = 0)
151
    {
152
        if (empty($tool)) {
153
            return false;
154
        }
155
        $TABLETRACK_ACCESS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
156
        //for "what's new" notification
157
        $TABLETRACK_LASTACCESS = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
158
159
        $_course = api_get_course_info();
160
        $courseId = api_get_course_int_id();
161
        $id_session = api_get_session_id();
162
        $tool = Database::escape_string($tool);
163
        $reallyNow = api_get_utc_datetime();
164
        $user_id = api_get_user_id();
165
166
        // record information
167
        // only if user comes from the course $_cid
168
        //if( eregi($_configuration['root_web'].$_cid,$_SERVER['HTTP_REFERER'] ) )
169
        //$pos = strpos($_SERVER['HTTP_REFERER'],$_configuration['root_web'].$_cid);
170
        $coursePath = isset($_course['path']) ? $_course['path'] : null;
171
172
        $pos = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower(api_get_path(WEB_COURSE_PATH).$coursePath)) : false;
173
        // added for "what's new" notification
174
        $pos2 = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower(api_get_path(WEB_PATH)."index")) : false;
175
        // end "what's new" notification
176
        if ($pos !== false || $pos2 !== false) {
177
            $params = [
178
                'access_user_id' => $user_id,
179
                'c_id' => $courseId,
180
                'access_tool' => $tool,
181
                'access_date' => $reallyNow,
182
                'access_session_id' => $id_session,
183
                'user_ip' => api_get_real_ip()
184
            ];
185
            Database::insert($TABLETRACK_ACCESS, $params);
186
        }
187
188
        // "what's new" notification
189
        $sql = "UPDATE $TABLETRACK_LASTACCESS
190
                SET access_date = '$reallyNow'
191
                WHERE access_user_id = ".$user_id." AND c_id = '".$courseId."' AND access_tool = '".$tool."' AND access_session_id=".$id_session;
192
        $result = Database::query($sql);
193 View Code Duplication
        if (Database::affected_rows($result) == 0) {
194
            $sql = "INSERT INTO $TABLETRACK_LASTACCESS (access_user_id, c_id, access_tool, access_date, access_session_id)
195
                    VALUES (".$user_id.", '".$courseId."' , '$tool', '$reallyNow', $id_session)";
196
            Database::query($sql);
197
        }
198
        return 1;
199
    }
200
201
    /**
202
     * @param doc_id id of document (id in mainDb.document table)
203
     * @author Sebastien Piraux <[email protected]>
204
     * @desc Record information for download event
205
     * (when an user click to d/l a document)
206
     * it will be used in a redirection page
207
     * bug fixed: Roan Embrechts
208
     * Roan:
209
     * The user id is put in single quotes,
210
     * (why? perhaps to prevent sql insertion hacks?)
211
     * and later again.
212
     * Doing this twice causes an error, I remove one of them.
213
     */
214 View Code Duplication
    public static function event_download($doc_url)
215
    {
216
        $tbl_stats_downloads = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS);
217
        $doc_url = Database::escape_string($doc_url);
218
219
        $reallyNow = api_get_utc_datetime();
220
        $user_id = "'".api_get_user_id()."'";
221
        $_cid = api_get_course_int_id();
222
223
        $sql = "INSERT INTO $tbl_stats_downloads (
224
                     down_user_id,
225
                     c_id,
226
                     down_doc_path,
227
                     down_date,
228
                     down_session_id
229
                    )
230
                    VALUES (
231
                     ".$user_id.",
232
                     '".$_cid."',
233
                     '".$doc_url."',
234
                     '".$reallyNow."',
235
                     '".api_get_session_id()."'
236
                    )";
237
        Database::query($sql);
238
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 exercise was done
321
     */
322
    public static function update_event_exercise(
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	$fileName 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
        $fileName = 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
        $session_id = api_get_session_id();
486
487
        if (!empty($question_id) && !empty($exe_id) && !empty($user_id)) {
488
            if (is_null($answer)) {
489
                $answer = '';
490
            }
491
            $attempt = array(
492
                'user_id' => $user_id,
493
                'question_id' => $question_id,
494
                'answer' => $answer,
495
                'marks' => $score,
496
                'c_id' => $course_id,
497
                'session_id' => $session_id,
498
                'position' => $position,
499
                'tms' => $now,
500
                'filename' => !empty($fileName) ? basename($fileName) : $fileName,
501
                'teacher_comment' => ''
502
            );
503
504
            // Check if attempt exists.
505
            $sql = "SELECT exe_id FROM $TBL_TRACK_ATTEMPT
506
                    WHERE
507
                        c_id = $course_id AND
508
                        session_id = $session_id AND
509
                        exe_id = $exe_id AND
510
                        user_id = $user_id AND
511
                        question_id = $question_id AND
512
                        position = $position";
513
            $result = Database::query($sql);
514
            if (Database::num_rows($result)) {
515
                if ($debug) {
516
                    error_log("Attempt already exist: exe_id: $exe_id - user_id:$user_id - question_id:$question_id");
517
                }
518
                if ($updateResults == false) {
519
                    //The attempt already exist do not update use  update_event_exercise() instead
520
                    return false;
521
                }
522
            } else {
523
                $attempt['exe_id'] = $exe_id;
524
            }
525
526
            if ($debug) {
527
                error_log("updateResults : $updateResults");
528
                error_log("Saving question attempt: ");
529
                error_log($sql);
530
            }
531
532
            $recording_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
533
534
            if ($updateResults == false) {
535
                $attempt_id = Database::insert($TBL_TRACK_ATTEMPT, $attempt);
536
537
                if ($debug) {
538
                    error_log("Insert attempt with id #$attempt_id");
539
                }
540
541
                if (defined('ENABLED_LIVE_EXERCISE_TRACKING')) {
542
                    if ($debug) {
543
                        error_log("Saving e attempt recording ");
544
                    }
545
                    $attempt_recording = array(
546
                        'exe_id' => $attempt_id,
547
                        'question_id' => $question_id,
548
                        'marks' => $score,
549
                        'insert_date' => $now,
550
                        'author' => '',
551
                        'session_id' => $session_id,
552
                    );
553
                    Database::insert($recording_table, $attempt_recording);
554
                }
555
            } else {
556
                Database::update(
557
                    $TBL_TRACK_ATTEMPT,
558
                    $attempt,
559
                    array('exe_id = ? AND question_id = ? AND user_id = ? ' => array($exe_id, $question_id, $user_id))
560
                );
561
562
                if (defined('ENABLED_LIVE_EXERCISE_TRACKING')) {
563
                    $attempt_recording = array(
564
                        'exe_id' => $exe_id,
565
                        'question_id' => $question_id,
566
                        'marks' => $score,
567
                        'insert_date' => $now,
568
                        'author' => '',
569
                        'session_id' => $session_id,
570
                    );
571
572
                    Database::update(
573
                        $recording_table,
574
                        $attempt_recording,
575
                        array('exe_id = ? AND question_id = ? AND session_id = ? ' => array($exe_id, $question_id, $session_id))
576
                    );
577
                }
578
                $attempt_id = $exe_id;
579
            }
580
581
            return $attempt_id;
582
        } else {
583
            return false;
584
        }
585
    }
586
587
    /**
588
     * Record an hotspot spot for this attempt at answering an hotspot question
589
     * @param int $exeId
590
     * @param int $questionId Question ID
591
     * @param int $answerId Answer ID
592
     * @param int $correct
593
     * @param string $coords Coordinates of this point (e.g. 123;324)
594
     * @param bool $updateResults
595
     * @param int $exerciseId
596
     *
597
     * @return bool Result of the insert query
598
     * @uses Course code and user_id from global scope $_cid and $_user
599
     */
600
    public static function saveExerciseAttemptHotspot(
601
        $exeId,
602
        $questionId,
603
        $answerId,
604
        $correct,
605
        $coords,
606
        $updateResults = false,
607
        $exerciseId = 0
608
    ) {
609
        global $safe_lp_id, $safe_lp_item_id;
610
611
        if ($updateResults == false) {
612
            // Validation in case of fraud with activated control time
613
            if (!ExerciseLib::exercise_time_control_is_valid($exerciseId, $safe_lp_id, $safe_lp_item_id)) {
614
                $correct = 0;
615
            }
616
        }
617
618
        if (empty($exeId)) {
619
            return false;
620
        }
621
622
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
623
        if ($updateResults) {
624
            $params = array(
625
                'hotspot_correct' => $correct,
626
                'hotspot_coordinate' => $coords
627
            );
628
            Database::update(
629
                $table,
630
                $params,
631
                array(
632
                    'hotspot_user_id = ? AND hotspot_exe_id = ? AND hotspot_question_id = ? AND hotspot_answer_id = ? ' => array(
633
                        api_get_user_id(),
634
                        $exeId,
635
                        $questionId,
636
                        $answerId
637
                    )
638
                )
639
            );
640
641
        } else {
642
            return Database::insert(
643
                $table,
644
                [
645
                    'hotspot_course_code' => api_get_course_id(),
646
                    'hotspot_user_id' => api_get_user_id(),
647
                    'c_id' => api_get_course_int_id(),
648
                    'hotspot_exe_id' => $exeId,
649
                    'hotspot_question_id' => $questionId,
650
                    'hotspot_answer_id' => $answerId,
651
                    'hotspot_correct' => $correct,
652
                    'hotspot_coordinate' => $coords
653
                ]
654
            );
655
        }
656
    }
657
658
    /**
659
     * Records information for common (or admin) events (in the track_e_default table)
660
     * @author Yannick Warnier <[email protected]>
661
     * @param   string  $event_type Type of event
662
     * @param   string  $event_value_type Type of value
663
     * @param   string  $event_value Value
664
     * @param   string  $datetime Datetime (UTC) (defaults to null)
665
     * @param   int     $user_id User ID (defaults to null)
666
     * @param   int $course_id Course ID (defaults to null)
667
     * @param   int $sessionId Session ID
668
     * @return  bool
669
     * @assert ('','','') === false
670
     */
671
    public static function addEvent(
672
        $event_type,
673
        $event_value_type,
674
        $event_value,
675
        $datetime = null,
676
        $user_id = null,
677
        $course_id = null,
678
        $sessionId = 0
679
    ) {
680
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
681
682
        if (empty($event_type)) {
683
            return false;
684
        }
685
        $event_type = Database::escape_string($event_type);
686
        $event_value_type = Database::escape_string($event_value_type);
687
        if (!empty($course_id)) {
688
            $course_id = intval($course_id);
689
        } else {
690
            $course_id = api_get_course_int_id();
691
        }
692
        if (!empty($sessionId)) {
693
            $sessionId = intval($sessionId);
694
        } else {
695
            $sessionId = api_get_session_id();
696
        }
697
698
        //Clean the user_info
699
        if ($event_value_type == LOG_USER_OBJECT) {
700
            if (is_array($event_value)) {
701
                unset($event_value['complete_name']);
702
                unset($event_value['complete_name_with_username']);
703
                unset($event_value['firstName']);
704
                unset($event_value['lastName']);
705
                unset($event_value['avatar_small']);
706
                unset($event_value['avatar']);
707
                unset($event_value['mail']);
708
                unset($event_value['password']);
709
                unset($event_value['last_login']);
710
                unset($event_value['picture_uri']);
711
                $event_value = serialize($event_value);
712
            }
713
        }
714
        // If event is an array then the $event_value_type should finish with
715
        // the suffix _array for example LOG_WORK_DATA = work_data_array
716
        if (is_array($event_value)) {
717
            $event_value = serialize($event_value);
718
        }
719
720
        $event_value = Database::escape_string($event_value);
721
        $sessionId = empty($sessionId) ? api_get_session_id() : intval($sessionId);
722
723
        if (!isset($datetime)) {
724
            $datetime = api_get_utc_datetime();
725
        }
726
727
        $datetime = Database::escape_string($datetime);
0 ignored issues
show
Bug introduced by
It seems like $datetime can also be of type null or object<DateTime>; however, Database::escape_string() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
728
729
        if (!isset($user_id)) {
730
            $user_id = api_get_user_id();
731
        }
732
733
        $params = array(
734
            'default_user_id' => $user_id,
735
            'c_id' => $course_id,
736
            'default_date' => $datetime,
737
            'default_event_type' => $event_type,
738
            'default_value_type' => $event_value_type,
739
            'default_value' => $event_value,
740
            'session_id' => $sessionId
741
        );
742
        Database::insert($table, $params);
743
744
        return true;
745
    }
746
747
    /**
748
     * Get every email stored in the database
749
     *
750
     * @return array
751
     * @assert () !== false
752
     */
753
    public static function get_all_event_types()
754
    {
755
        global $event_config;
756
757
        $sql = 'SELECT etm.id, event_type_name, activated, language_id, message, subject, dokeos_folder
758
                FROM '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).' etm
759
                INNER JOIN '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' l
760
                ON etm.language_id = l.id';
761
762
        $events_types = Database::store_result(Database::query($sql), 'ASSOC');
763
764
        $to_return = array();
765
        foreach ($events_types as $et) {
766
            $et['nameLangVar'] = $event_config[$et["event_type_name"]]["name_lang_var"];
767
            $et['descLangVar'] = $event_config[$et["event_type_name"]]["desc_lang_var"];
768
            $to_return[] = $et;
769
        }
770
771
        return $to_return;
772
    }
773
774
    /**
775
     * Get the users related to one event
776
     *
777
     * @param string $event_name
778
     */
779
    public static function get_event_users($event_name)
780
    {
781
        $event_name = Database::escape_string($event_name);
782
        $sql = 'SELECT user.user_id,  user.firstname, user.lastname
783
                FROM '.Database::get_main_table(TABLE_MAIN_USER).' user
784
                JOIN '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' relUser
785
                ON relUser.user_id = user.user_id
786
                WHERE user.status <> '.ANONYMOUS.' AND relUser.event_type_name = "'.$event_name.'"';
787
        $user_list = Database::store_result(Database::query($sql), 'ASSOC');
788
789
        return json_encode($user_list);
790
    }
791
792
    /**
793
     * @param int $user_id
794
     * @param string $event_type
795
     * @return array|bool
796
     */
797 View Code Duplication
    public static function get_events_by_user_and_type($user_id, $event_type)
798
    {
799
        $TABLETRACK_DEFAULT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
800
        $user_id = intval($user_id);
801
        $event_type = Database::escape_string($event_type);
802
803
        $sql = "SELECT * FROM $TABLETRACK_DEFAULT
804
                WHERE default_value_type = 'user_id' AND
805
                      default_value = $user_id AND
806
                      default_event_type = '$event_type'
807
                ORDER BY default_date ";
808
        $result = Database::query($sql);
809
        if ($result) {
810
            return Database::store_result($result, 'ASSOC');
811
        }
812
        return false;
813
    }
814
815
    /**
816
     * Save the new message for one event and for one language
817
     *
818
     * @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...
819
     * @param array $users
820
     * @param string $message
821
     * @param string $subject
822
     * @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...
823
     * @param int $activated
824
     */
825
    public static function save_event_type_message($event_name, $users, $message, $subject, $event_message_language, $activated)
826
    {
827
        $event_name = Database::escape_string($event_name);
828
        $activated = intval($activated);
829
        $event_message_language = Database::escape_string($event_message_language);
830
831
        // Deletes then re-adds the users linked to the event
832
        $sql = 'DELETE FROM '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' WHERE event_type_name = "'.$event_name.'"	';
833
        Database::query($sql);
834
835
        foreach ($users as $user) {
836
            $sql = 'INSERT INTO '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' (user_id,event_type_name)
837
                    VALUES('.intval($user).',"'.$event_name.'")';
838
            Database::query($sql);
839
        }
840
        $language_id = api_get_language_id($event_message_language);
841
        // check if this template in this language already exists or not
842
        $sql = 'SELECT COUNT(id) as total FROM '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).'
843
                WHERE event_type_name = "'.$event_name.'" AND language_id = '.$language_id;
844
845
        $sql = Database::store_result(Database::query($sql), 'ASSOC');
846
847
        // if already exists, we update
848
        if ($sql[0]["total"] > 0) {
849
            $sql = 'UPDATE '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).'
850
                SET message = "'.Database::escape_string($message).'",
851
                subject = "'.Database::escape_string($subject).'",
852
                activated = '.$activated.'
853
                WHERE event_type_name = "'.$event_name.'" AND language_id = (SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).'
854
                    WHERE dokeos_folder = "'.$event_message_language.'")';
855
            Database::query($sql);
856
        } else { // else we create a new record
857
            // gets the language_-_id
858
            $lang_id = '(SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).'
859
                        WHERE dokeos_folder = "'.$event_message_language.'")';
860
            $lang_id = Database::store_result(Database::query($lang_id), 'ASSOC');
861
862
            if (!empty($lang_id[0]["id"])) {
863
                $sql = 'INSERT INTO '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).' (event_type_name, language_id, message, subject, activated)
864
                    VALUES("'.$event_name.'", '.$lang_id[0]["id"].', "'.Database::escape_string($message).'", "'.Database::escape_string($subject).'", '.$activated.')';
865
                Database::query($sql);
866
            }
867
        }
868
869
        // set activated at every save
870
        $sql = 'UPDATE '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).'
871
                    SET activated = '.$activated.'
872
                    WHERE event_type_name = "'.$event_name.'"';
873
        Database::query($sql);
874
    }
875
876
    /**
877
     * Gets the last attempt of an exercise based in the exe_id
878
     * @param int $exe_id
879
     * @return mixed
880
     */
881
    public static function getLastAttemptDateOfExercise($exe_id)
882
    {
883
        $exe_id = intval($exe_id);
884
        $track_attempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
885
        $sql = 'SELECT max(tms) as last_attempt_date
886
                FROM '.$track_attempts.'
887
                WHERE exe_id='.$exe_id;
888
        $rs_last_attempt = Database::query($sql);
889
        $row_last_attempt = Database::fetch_array($rs_last_attempt);
890
        $last_attempt_date = $row_last_attempt['last_attempt_date']; //Get the date of last attempt
891
892
        return $last_attempt_date;
893
    }
894
895
    /**
896
     * Gets the last attempt of an exercise based in the exe_id
897
     * @param int $exe_id
898
     * @return mixed
899
     */
900
    public static function getLatestQuestionIdFromAttempt($exe_id)
901
    {
902
        $exe_id = intval($exe_id);
903
        $track_attempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
904
        $sql = 'SELECT question_id FROM '.$track_attempts.'
905
                WHERE exe_id='.$exe_id.'
906
                ORDER BY tms DESC
907
                LIMIT 1';
908
        $result = Database::query($sql);
909
        if (Database::num_rows($result)) {
910
            $row = Database::fetch_array($result);
911
            return $row['question_id'];
912
        } else {
913
            return false;
914
        }
915
    }
916
917
    /**
918
     * Gets how many attempts exists by user, exercise, learning path
919
     * @param   int user id
920
     * @param   int exercise id
921
     * @param   int lp id
922
     * @param   int lp item id
923
     * @param   int lp item view id
924
     */
925
    public static function get_attempt_count($user_id, $exerciseId, $lp_id, $lp_item_id, $lp_item_view_id)
926
    {
927
        $stat_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
928
        $user_id = intval($user_id);
929
        $exerciseId = intval($exerciseId);
930
        $lp_id = intval($lp_id);
931
        $lp_item_id = intval($lp_item_id);
932
        $lp_item_view_id = intval($lp_item_view_id);
933
934
        $sql = "SELECT count(*) as count
935
                FROM $stat_table
936
                WHERE
937
                    exe_exo_id = $exerciseId AND
938
                    exe_user_id = $user_id AND
939
                    status != 'incomplete' AND
940
                    orig_lp_id = $lp_id AND
941
                    orig_lp_item_id = $lp_item_id AND
942
                    orig_lp_item_view_id = $lp_item_view_id AND
943
                    c_id = '".api_get_course_int_id()."' AND
944
                    session_id = '".api_get_session_id()."'";
945
946
        $query = Database::query($sql);
947 View Code Duplication
        if (Database::num_rows($query) > 0) {
948
            $attempt = Database::fetch_array($query, 'ASSOC');
949
            return $attempt['count'];
950
        } else {
951
            return 0;
952
        }
953
    }
954
955
    /**
956
     * @param $user_id
957
     * @param $exerciseId
958
     * @param $lp_id
959
     * @param $lp_item_id
960
     * @return int
961
     */
962
    public static function get_attempt_count_not_finished($user_id, $exerciseId, $lp_id, $lp_item_id)
963
    {
964
        $stat_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
965
        $user_id = intval($user_id);
966
        $exerciseId = intval($exerciseId);
967
        $lp_id = intval($lp_id);
968
        $lp_item_id = intval($lp_item_id);
969
        //$lp_item_view_id = intval($lp_item_view_id);
970
971
        $sql = "SELECT count(*) as count
972
                FROM $stat_table
973
                WHERE
974
                    exe_exo_id 			= $exerciseId AND
975
                    exe_user_id 		= $user_id AND
976
                    status 				!= 'incomplete' AND
977
                    orig_lp_id 			= $lp_id AND
978
                    orig_lp_item_id 	= $lp_item_id AND
979
                    c_id = '".api_get_course_int_id()."' AND
980
                    session_id = '".api_get_session_id()."'";
981
982
        $query = Database::query($sql);
983 View Code Duplication
        if (Database::num_rows($query) > 0) {
984
            $attempt = Database::fetch_array($query, 'ASSOC');
985
            return $attempt['count'];
986
        } else {
987
            return 0;
988
        }
989
    }
990
991
    /**
992
     * @param int $user_id
993
     * @param int $lp_id
994
     * @param array $course
995
     * @param int $session_id
996
     */
997
    public static function delete_student_lp_events($user_id, $lp_id, $course, $session_id)
998
    {
999
        $lp_view_table = Database::get_course_table(TABLE_LP_VIEW);
1000
        $lp_item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW);
1001
        $lpInteraction = Database::get_course_table(TABLE_LP_IV_INTERACTION);
1002
        $lpObjective = Database::get_course_table(TABLE_LP_IV_OBJECTIVE);
1003
1004
        $course_id = $course['real_id'];
1005
1006
        if (empty($course_id)) {
1007
            $course_id = api_get_course_int_id();
1008
        }
1009
1010
        $track_e_exercises = Database::get_main_table(
1011
            TABLE_STATISTIC_TRACK_E_EXERCISES
1012
        );
1013
        $track_attempts = Database::get_main_table(
1014
            TABLE_STATISTIC_TRACK_E_ATTEMPT
1015
        );
1016
        $recording_table = Database::get_main_table(
1017
            TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING
1018
        );
1019
1020
        $user_id = intval($user_id);
1021
        $lp_id = intval($lp_id);
1022
        $session_id = intval($session_id);
1023
1024
        //Make sure we have the exact lp_view_id
1025
        $sql = "SELECT id FROM $lp_view_table
1026
                WHERE
1027
                    c_id = $course_id AND
1028
                    user_id = $user_id AND
1029
                    lp_id = $lp_id AND
1030
                    session_id = $session_id ";
1031
        $result = Database::query($sql);
1032
1033 View Code Duplication
        if (Database::num_rows($result)) {
1034
            $view = Database::fetch_array($result, 'ASSOC');
1035
            $lp_view_id = $view['id'];
1036
1037
            $sql = "DELETE FROM $lp_item_view_table
1038
                    WHERE c_id = $course_id AND lp_view_id = $lp_view_id ";
1039
            Database::query($sql);
1040
1041
            $sql = "DELETE FROM $lpInteraction
1042
                    WHERE c_id = $course_id AND lp_iv_id = $lp_view_id ";
1043
            Database::query($sql);
1044
1045
            $sql = "DELETE FROM $lpObjective
1046
                    WHERE c_id = $course_id AND lp_iv_id = $lp_view_id ";
1047
            Database::query($sql);
1048
        }
1049
1050
        $sql = "DELETE FROM $lp_view_table
1051
            WHERE
1052
                c_id = $course_id AND
1053
                user_id = $user_id AND
1054
                lp_id= $lp_id AND
1055
                session_id = $session_id
1056
            ";
1057
        Database::query($sql);
1058
1059
        $sql = "SELECT exe_id FROM $track_e_exercises
1060
                WHERE   exe_user_id = $user_id AND
1061
                        session_id = $session_id AND
1062
                        c_id = $course_id AND
1063
                        orig_lp_id = $lp_id";
1064
        $result = Database::query($sql);
1065
        $exe_list = array();
1066
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1067
            $exe_list[] = $row['exe_id'];
1068
        }
1069
1070
        if (!empty($exe_list) && is_array($exe_list) && count($exe_list) > 0) {
1071
            $sql = "DELETE FROM $track_e_exercises
1072
                WHERE exe_id IN (" . implode(',', $exe_list) . ")";
1073
            Database::query($sql);
1074
1075
            $sql = "DELETE FROM $track_attempts
1076
                WHERE exe_id IN (" . implode(',', $exe_list) . ")";
1077
            Database::query($sql);
1078
1079
            $sql = "DELETE FROM $recording_table
1080
                WHERE exe_id IN (" . implode(',', $exe_list) . ")";
1081
            Database::query($sql);
1082
        }
1083
1084
        self::addEvent(
1085
            LOG_LP_ATTEMPT_DELETE,
1086
            LOG_LP_ID,
1087
            $lp_id,
1088
            null,
1089
            null,
1090
            $course_id,
1091
            $session_id
1092
        );
1093
    }
1094
1095
    /**
1096
     * Delete all exercise attempts (included in LP or not)
1097
     *
1098
     * @param 	int		user id
1099
     * @param 	int		exercise id
1100
     * @param 	int	$course_id
1101
     * @param 	int		session id
1102
     */
1103
    public static function delete_all_incomplete_attempts($user_id, $exercise_id, $course_id, $session_id = 0)
1104
    {
1105
        $track_e_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1106
        $user_id = intval($user_id);
1107
        $exercise_id = intval($exercise_id);
1108
        $course_id = intval($course_id);
1109
        $session_id = intval($session_id);
1110
        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...
1111
            $sql = "DELETE FROM $track_e_exercises
1112
                    WHERE
1113
                        exe_user_id = $user_id AND
1114
                        exe_exo_id = $exercise_id AND
1115
                        c_id = '$course_id' AND
1116
                        session_id = $session_id AND
1117
                        status = 'incomplete' ";
1118
            Database::query($sql);
1119
            self::addEvent(
1120
                LOG_EXERCISE_RESULT_DELETE,
1121
                LOG_EXERCISE_AND_USER_ID,
1122
                $exercise_id . '-' . $user_id,
1123
                null,
1124
                null,
1125
                $course_id,
1126
                $session_id
1127
            );
1128
        }
1129
    }
1130
1131
    /**
1132
     * Gets all exercise results (NO Exercises in LPs ) from a given exercise id, course, session
1133
     * @param   int     exercise id
1134
     * @param   int $courseId
1135
     * @param   int     session id
1136
     * @return  array   with the results
1137
     *
1138
     */
1139
    public static function get_all_exercise_results(
1140
        $exercise_id,
1141
        $courseId,
1142
        $session_id = 0,
1143
        $load_question_list = true,
1144
        $user_id = null
1145
    ) {
1146
        $TABLETRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1147
        $TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1148
        $courseId = intval($courseId);
1149
        $exercise_id = intval($exercise_id);
1150
        $session_id = intval($session_id);
1151
1152
        $user_condition = null;
1153
        if (!empty($user_id)) {
1154
            $user_id = intval($user_id);
1155
            $user_condition = "AND exe_user_id = $user_id ";
1156
        }
1157
        $sql = "SELECT * FROM $TABLETRACK_EXERCICES
1158
                WHERE
1159
                    status = ''  AND
1160
                    c_id = '$courseId' AND
1161
                    exe_exo_id = '$exercise_id' AND
1162
                    session_id = $session_id  AND
1163
                    orig_lp_id =0 AND
1164
                    orig_lp_item_id = 0
1165
                    $user_condition
1166
                ORDER BY exe_id";
1167
        $res = Database::query($sql);
1168
        $list = array();
1169
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1170
            $list[$row['exe_id']] = $row;
1171
            if ($load_question_list) {
1172
                $sql = "SELECT * FROM $TBL_TRACK_ATTEMPT
1173
                        WHERE exe_id = {$row['exe_id']}";
1174
                $res_question = Database::query($sql);
1175
                while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1176
                    $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1177
                }
1178
            }
1179
        }
1180
        return $list;
1181
    }
1182
1183
    /**
1184
     * Gets all exercise results (NO Exercises in LPs ) from a given exercise id, course, session
1185
     * @param   int  $courseId
1186
     * @param   int     session id
1187
     * @return  array   with the results
1188
     *
1189
     */
1190
    public static function get_all_exercise_results_by_course($courseId, $session_id = 0, $get_count = true)
1191
    {
1192
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1193
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1194
        $courseId = intval($courseId);
1195
        $session_id = intval($session_id);
1196
1197
        $select = '*';
1198
        if ($get_count) {
1199
            $select = 'count(*) as count';
1200
        }
1201
        $sql = "SELECT $select FROM $table_track_exercises
1202
                WHERE   status = ''  AND
1203
                        c_id = '$courseId' AND
1204
                        session_id = $session_id  AND
1205
                        orig_lp_id = 0 AND
1206
                        orig_lp_item_id = 0
1207
                ORDER BY exe_id";
1208
        $res = Database::query($sql);
1209 View Code Duplication
        if ($get_count) {
1210
            $row = Database::fetch_array($res, 'ASSOC');
1211
            return $row['count'];
1212
        } else {
1213
            $list = array();
1214
            while ($row = Database::fetch_array($res, 'ASSOC')) {
1215
                $list[$row['exe_id']] = $row;
1216
            }
1217
            return $list;
1218
        }
1219
    }
1220
1221
    /**
1222
     * Gets all exercise results (NO Exercises in LPs) from a given exercise id, course, session
1223
     * @param   int     exercise id
1224
     * @param   int  $courseId
1225
     * @param   int     session id
1226
     * @return  array   with the results
1227
     *
1228
     */
1229 View Code Duplication
    public static function get_all_exercise_results_by_user($user_id, $courseId, $session_id = 0)
1230
    {
1231
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1232
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1233
        $courseId = intval($courseId);
1234
        $session_id = intval($session_id);
1235
        $user_id = intval($user_id);
1236
1237
        $sql = "SELECT * FROM $table_track_exercises
1238
                WHERE
1239
                    status = '' AND
1240
                    exe_user_id = $user_id AND
1241
                    c_id = '$courseId' AND
1242
                    session_id = $session_id AND
1243
                    orig_lp_id = 0 AND
1244
                    orig_lp_item_id = 0
1245
                ORDER by exe_id";
1246
1247
        $res = Database::query($sql);
1248
        $list = array();
1249
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1250
            $list[$row['exe_id']] = $row;
1251
            $sql = "SELECT * FROM $table_track_attempt 
1252
                    WHERE exe_id = {$row['exe_id']}";
1253
            $res_question = Database::query($sql);
1254
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1255
                $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1256
            }
1257
        }
1258
1259
        return $list;
1260
    }
1261
1262
    /**
1263
     * Gets exercise results (NO Exercises in LPs) from a given exercise id, course, session
1264
     * @param   int     $exe_id exercise id
1265
     * @param string $status
1266
     * @return  array   with the results
1267
     *
1268
     */
1269
    public static function get_exercise_results_by_attempt($exe_id, $status = null)
1270
    {
1271
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1272
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1273
        $table_track_attempt_recording = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
1274
        $exe_id = intval($exe_id);
1275
1276
        $status = Database::escape_string($status);
1277
1278
        $sql = "SELECT * FROM $table_track_exercises
1279
                WHERE status = '".$status."' AND exe_id = $exe_id";
1280
1281
        $res = Database::query($sql);
1282
        $list = array();
1283
        if (Database::num_rows($res)) {
1284
            $row = Database::fetch_array($res, 'ASSOC');
1285
1286
            //Checking if this attempt was revised by a teacher
1287
            $sql_revised = 'SELECT exe_id FROM '.$table_track_attempt_recording.'
1288
                            WHERE author != "" AND exe_id = '.$exe_id.' 
1289
                            LIMIT 1';
1290
            $res_revised = Database::query($sql_revised);
1291
            $row['attempt_revised'] = 0;
1292
            if (Database::num_rows($res_revised) > 0) {
1293
                $row['attempt_revised'] = 1;
1294
            }
1295
            $list[$exe_id] = $row;
1296
            $sql = "SELECT * FROM $table_track_attempt
1297
                    WHERE exe_id = $exe_id 
1298
                    ORDER BY tms ASC";
1299
            $res_question = Database::query($sql);
1300
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1301
                $list[$exe_id]['question_list'][$row_q['question_id']] = $row_q;
1302
            }
1303
        }
1304
1305
        return $list;
1306
    }
1307
1308
    /**
1309
     * Gets exercise results (NO Exercises in LPs) from a given user, exercise id, course, session, lp_id, lp_item_id
1310
     * @param   int     user id
1311
     * @param   int     exercise id
1312
     * @param   string  course code
1313
     * @param   int     session id
1314
     * @param   int     lp id
1315
     * @param   int     lp item id
1316
     * @param   string 	order asc or desc
1317
     * @return  array   with the results
1318
     *
1319
     */
1320
    public static function getExerciseResultsByUser(
1321
        $user_id,
1322
        $exercise_id,
1323
        $courseId,
1324
        $session_id = 0,
1325
        $lp_id = 0,
1326
        $lp_item_id = 0,
1327
        $order = null
1328
    ) {
1329
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1330
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1331
        $table_track_attempt_recording = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
1332
        $courseId = intval($courseId);
1333
        $exercise_id = intval($exercise_id);
1334
        $session_id = intval($session_id);
1335
        $user_id = intval($user_id);
1336
        $lp_id = intval($lp_id);
1337
        $lp_item_id = intval($lp_item_id);
1338
1339
        if (!in_array(strtolower($order), array('asc', 'desc'))) {
1340
            $order = 'asc';
1341
        }
1342
1343
        $sql = "SELECT * FROM $table_track_exercises
1344
                WHERE
1345
                    status 			= '' AND
1346
                    exe_user_id 	= $user_id AND
1347
                    c_id 	        = $courseId AND
1348
                    exe_exo_id 		= $exercise_id AND
1349
                    session_id 		= $session_id AND
1350
                    orig_lp_id 		= $lp_id AND
1351
                    orig_lp_item_id = $lp_item_id
1352
                ORDER by exe_id $order ";
1353
1354
        $res = Database::query($sql);
1355
        $list = array();
1356
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1357
            // Checking if this attempt was revised by a teacher
1358
            $sql = 'SELECT exe_id FROM '.$table_track_attempt_recording.'
1359
                    WHERE author != "" AND exe_id = '.$row['exe_id'].'
1360
                    LIMIT 1';
1361
            $res_revised = Database::query($sql);
1362
            $row['attempt_revised'] = 0;
1363
            if (Database::num_rows($res_revised) > 0) {
1364
                $row['attempt_revised'] = 1;
1365
            }
1366
            $list[$row['exe_id']] = $row;
1367
            $sql = "SELECT * FROM $table_track_attempt
1368
                    WHERE exe_id = {$row['exe_id']}";
1369
            $res_question = Database::query($sql);
1370 View Code Duplication
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1371
                $list[$row['exe_id']]['question_list'][$row_q['question_id']][] = $row_q;
1372
            }
1373
        }
1374
        return $list;
1375
    }
1376
1377
    /**
1378
     * Count exercise attempts (NO Exercises in LPs ) from a given exercise id, course, session
1379
     * @param int $user_id
1380
     * @param   int     exercise id
1381
     * @param   int     $courseId
1382
     * @param   int     session id
1383
     * @return  array   with the results
1384
     *
1385
     */
1386
    public static function count_exercise_attempts_by_user($user_id, $exercise_id, $courseId, $session_id = 0)
1387
    {
1388
        $TABLETRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1389
        $courseId = intval($courseId);
1390
        $exercise_id = intval($exercise_id);
1391
        $session_id = intval($session_id);
1392
        $user_id = intval($user_id);
1393
1394
        $sql = "SELECT count(*) as count FROM $TABLETRACK_EXERCICES
1395
                WHERE status = ''  AND
1396
                    exe_user_id = '$user_id' AND
1397
                    c_id = '$courseId' AND
1398
                    exe_exo_id = '$exercise_id' AND
1399
                    session_id = $session_id AND
1400
                    orig_lp_id =0 AND
1401
                    orig_lp_item_id = 0
1402
                ORDER BY exe_id";
1403
        $res = Database::query($sql);
1404
        $result = 0;
1405
        if (Database::num_rows($res) > 0) {
1406
            $row = Database::fetch_array($res, 'ASSOC');
1407
            $result = $row['count'];
1408
        }
1409
1410
        return $result;
1411
    }
1412
1413
    /**
1414
     * Gets all exercise BEST results attempts (NO Exercises in LPs) from a given exercise id, course, session per user
1415
     * @param   int     $exercise_id
1416
     * @param   int     $courseId
1417
     * @param   int     $session_id
1418
     * @return  array   with the results
1419
     * @todo rename this function
1420
     */
1421
    public static function get_best_exercise_results_by_user($exercise_id, $courseId, $session_id = 0)
1422
    {
1423
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1424
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1425
        $courseId = intval($courseId);
1426
        $exercise_id = intval($exercise_id);
1427
        $session_id = intval($session_id);
1428
1429
        $sql = "SELECT * FROM $table_track_exercises
1430
                WHERE
1431
                    status = '' AND
1432
                    c_id = $courseId AND
1433
                    exe_exo_id = '$exercise_id' AND
1434
                    session_id = $session_id AND
1435
                    orig_lp_id = 0 AND
1436
                    orig_lp_item_id = 0
1437
                ORDER BY exe_id";
1438
1439
        $res = Database::query($sql);
1440
        $list = array();
1441
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1442
            $list[$row['exe_id']] = $row;
1443
            $sql = "SELECT * FROM $table_track_attempt 
1444
                    WHERE exe_id = {$row['exe_id']}";
1445
            $res_question = Database::query($sql);
1446
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1447
                $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1448
            }
1449
        }
1450
1451
        // Getting the best results of every student
1452
        $best_score_return = array();
1453
        foreach ($list as $student_result) {
1454
            $user_id = $student_result['exe_user_id'];
1455
            $current_best_score[$user_id] = $student_result['exe_result'];
1456
1457
            //echo $current_best_score[$user_id].' - '.$best_score_return[$user_id]['exe_result'].'<br />';
1458
            if (!isset($best_score_return[$user_id]['exe_result'])) {
1459
                $best_score_return[$user_id] = $student_result;
1460
            }
1461
1462
            if ($current_best_score[$user_id] > $best_score_return[$user_id]['exe_result']) {
1463
                $best_score_return[$user_id] = $student_result;
1464
            }
1465
        }
1466
1467
        return $best_score_return;
1468
    }
1469
1470
    /**
1471
     * @param int $user_id
1472
     * @param int $exercise_id
1473
     * @param int $courseId
1474
     * @param int $session_id
1475
     * @return array
1476
     */
1477
    public static function get_best_attempt_exercise_results_per_user($user_id, $exercise_id, $courseId, $session_id = 0)
1478
    {
1479
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1480
        $courseId = intval($courseId);
1481
        $exercise_id = intval($exercise_id);
1482
        $session_id = intval($session_id);
1483
        $user_id = intval($user_id);
1484
1485
        $sql = "SELECT * FROM $table_track_exercises
1486
                WHERE
1487
                    status = ''  AND
1488
                    c_id = '$courseId' AND
1489
                    exe_exo_id = '$exercise_id' AND
1490
                    session_id = $session_id  AND
1491
                    exe_user_id = $user_id AND
1492
                    orig_lp_id =0 AND
1493
                    orig_lp_item_id = 0
1494
                ORDER BY exe_id";
1495
1496
        $res = Database::query($sql);
1497
        $list = array();
1498
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1499
            $list[$row['exe_id']] = $row;
1500
        }
1501
        //Getting the best results of every student
1502
        $best_score_return = array();
1503
        $best_score_return['exe_result'] = 0;
1504
1505
        foreach ($list as $result) {
1506
            $current_best_score = $result;
1507
            if ($current_best_score['exe_result'] > $best_score_return['exe_result']) {
1508
                $best_score_return = $result;
1509
            }
1510
        }
1511
        if (!isset($best_score_return['exe_weighting'])) {
1512
            $best_score_return = array();
1513
        }
1514
        return $best_score_return;
1515
    }
1516
1517
    /**
1518
     * @param int $exercise_id
1519
     * @param int $courseId
1520
     * @param int $session_id
1521
     * @return mixed
1522
     */
1523
    public static function count_exercise_result_not_validated($exercise_id, $courseId, $session_id = 0)
1524
    {
1525
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1526
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
1527
        $courseId = intval($courseId);
1528
        $session_id = intval($session_id);
1529
        $exercise_id = intval($exercise_id);
1530
1531
        $sql = "SELECT count(e.exe_id) as count
1532
                FROM $table_track_exercises e
1533
                LEFT JOIN $table_track_attempt a
1534
                ON e.exe_id = a.exe_id
1535
                WHERE
1536
                    exe_exo_id = $exercise_id AND
1537
                    c_id = '$courseId' AND
1538
                    e.session_id = $session_id  AND
1539
                    orig_lp_id = 0 AND
1540
                    marks IS NULL AND
1541
                    status = '' AND
1542
                    orig_lp_item_id = 0
1543
                ORDER BY e.exe_id";
1544
        $res = Database::query($sql);
1545
        $row = Database::fetch_array($res, 'ASSOC');
1546
1547
        return $row['count'];
1548
    }
1549
1550
    /**
1551
     * Gets all exercise BEST results attempts (NO Exercises in LPs) from a given exercise id, course, session per user
1552
     * @param   int     exercise id
1553
     * @param   int   course id
1554
     * @param   int     session id
1555
     * @return  array   with the results
1556
     *
1557
     */
1558
    public static function get_count_exercises_attempted_by_course($courseId, $session_id = 0)
1559
    {
1560
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1561
        $courseId = intval($courseId);
1562
        $session_id = intval($session_id);
1563
1564
        $sql = "SELECT DISTINCT exe_exo_id, exe_user_id
1565
                FROM $table_track_exercises
1566
                WHERE
1567
                    status = '' AND
1568
                    c_id = '$courseId' AND
1569
                    session_id = $session_id AND
1570
                    orig_lp_id =0 AND
1571
                    orig_lp_item_id = 0
1572
                ORDER BY exe_id";
1573
        $res = Database::query($sql);
1574
        $count = 0;
1575
        if (Database::num_rows($res) > 0) {
1576
            $count = Database::num_rows($res);
1577
        }
1578
        return $count;
1579
    }
1580
1581
    /**
1582
     * Gets all exercise events from a Learning Path within a Course 	nd Session
1583
     * @param	int $exercise_id
1584
     * @param	int $courseId
1585
     * @param 	int $session_id
1586
     * @return 	array
1587
     */
1588 View Code Duplication
    public static function get_all_exercise_event_from_lp($exercise_id, $courseId, $session_id = 0)
1589
    {
1590
        $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1591
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1592
        $courseId = intval($courseId);
1593
        $exercise_id = intval($exercise_id);
1594
        $session_id = intval($session_id);
1595
1596
        $sql = "SELECT * FROM $table_track_exercises
1597
                WHERE
1598
                    status = '' AND
1599
                    c_id = $courseId AND
1600
                    exe_exo_id = '$exercise_id' AND
1601
                    session_id = $session_id AND
1602
                    orig_lp_id !=0 AND
1603
                    orig_lp_item_id != 0";
1604
1605
        $res = Database::query($sql);
1606
        $list = array();
1607
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1608
            $list[$row['exe_id']] = $row;
1609
            $sql = "SELECT * FROM $table_track_attempt 
1610
                    WHERE exe_id = {$row['exe_id']}";
1611
            $res_question = Database::query($sql);
1612
            while ($row_q = Database::fetch_array($res_question, 'ASSOC')) {
1613
                $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
1614
            }
1615
        }
1616
        return $list;
1617
    }
1618
1619
    /**
1620
     * @param int $lp_id
1621
     * @param int $course_id
1622
     *
1623
     * @return array
1624
     */
1625 View Code Duplication
    public static function get_all_exercises_from_lp($lp_id, $course_id)
1626
    {
1627
        $lp_item_table = Database::get_course_table(TABLE_LP_ITEM);
1628
        $course_id = intval($course_id);
1629
        $lp_id = intval($lp_id);
1630
        $sql = "SELECT * FROM $lp_item_table
1631
                WHERE
1632
                    c_id = $course_id AND
1633
                    lp_id = '".$lp_id."' AND
1634
                    item_type = 'quiz'
1635
                ORDER BY parent_item_id, display_order";
1636
        $res = Database::query($sql);
1637
1638
        $my_exercise_list = array();
1639
        while ($row = Database::fetch_array($res, 'ASSOC')) {
1640
            $my_exercise_list[] = $row;
1641
        }
1642
1643
        return $my_exercise_list;
1644
    }
1645
1646
    /**
1647
     * This function gets the comments of an exercise
1648
     *
1649
     * @param int $exe_id
1650
     * @param int $question_id
1651
     *
1652
     * @return string the comment
1653
     */
1654 View Code Duplication
    public static function get_comments($exe_id, $question_id)
1655
    {
1656
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1657
        $sql = "SELECT teacher_comment 
1658
                FROM $table_track_attempt
1659
                WHERE
1660
                    exe_id='".Database::escape_string($exe_id)."' AND
1661
                    question_id = '".Database::escape_string($question_id)."'
1662
                ORDER by question_id";
1663
        $sqlres = Database::query($sql);
1664
        $comm = Database::result($sqlres, 0, 'teacher_comment');
1665
1666
        return $comm;
1667
    }
1668
1669
    /**
1670
     * @param int $exe_id
1671
     *
1672
     * @return array
1673
     */
1674 View Code Duplication
    public static function getAllExerciseEventByExeId($exe_id)
1675
    {
1676
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1677
        $exe_id = intval($exe_id);
1678
        $list = array();
1679
1680
        $sql = "SELECT * FROM $table_track_attempt
1681
                WHERE exe_id = $exe_id
1682
                ORDER BY position";
1683
        $res_question = Database::query($sql);
1684
        if (Database::num_rows($res_question)) {
1685
            while ($row = Database::fetch_array($res_question, 'ASSOC')) {
1686
                $list[$row['question_id']][] = $row;
1687
            }
1688
        }
1689
        return $list;
1690
    }
1691
1692
    /**
1693
     *
1694
     * @param int $exe_id
1695
     * @param int $user_id
1696
     * @param int $courseId
1697
     * @param int $session_id
1698
     * @param int $question_id
1699
     */
1700 View Code Duplication
    public static function delete_attempt($exe_id, $user_id, $courseId, $session_id, $question_id)
1701
    {
1702
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1703
1704
        $exe_id = intval($exe_id);
1705
        $user_id = intval($user_id);
1706
        $courseId = intval($courseId);
1707
        $session_id = intval($session_id);
1708
        $question_id = intval($question_id);
1709
1710
        $sql = "DELETE FROM $table_track_attempt
1711
                WHERE
1712
                    exe_id = $exe_id AND
1713
                    user_id = $user_id AND
1714
                    c_id = $courseId AND
1715
                    session_id = $session_id AND
1716
                    question_id = $question_id ";
1717
        Database::query($sql);
1718
1719
        self::addEvent(
1720
            LOG_QUESTION_RESULT_DELETE,
1721
            LOG_EXERCISE_ATTEMPT_QUESTION_ID,
1722
            $exe_id . '-' . $question_id,
1723
            null,
1724
            null,
1725
            $courseId,
1726
            $session_id
1727
        );
1728
    }
1729
1730
    /**
1731
     * @param $exe_id
1732
     * @param $user_id
1733
     * @param int $courseId
1734
     * @param $question_id
1735
     * @param int $sessionId
1736
     */
1737 View Code Duplication
    public static function delete_attempt_hotspot($exe_id, $user_id, $courseId, $question_id, $sessionId = null)
1738
    {
1739
        $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
1740
1741
        $exe_id = intval($exe_id);
1742
        $user_id = intval($user_id);
1743
        $courseId = intval($courseId);
1744
        $question_id = intval($question_id);
1745
        if (!isset($sessionId)) {
1746
            $sessionId = api_get_session_id();
1747
        }
1748
1749
        $sql = "DELETE FROM $table_track_attempt
1750
                WHERE   
1751
                    hotspot_exe_id = $exe_id AND
1752
                    hotspot_user_id = $user_id AND
1753
                    c_id = $courseId AND
1754
                    hotspot_question_id = $question_id ";
1755
        Database::query($sql);
1756
        self::addEvent(
1757
            LOG_QUESTION_RESULT_DELETE,
1758
            LOG_EXERCISE_ATTEMPT_QUESTION_ID,
1759
            $exe_id . '-' . $question_id,
1760
            null,
1761
            null,
1762
            $courseId,
1763
            $sessionId
1764
        );
1765
    }
1766
1767
    /**
1768
     * Registers in track_e_course_access when user logs in for the first time to a course
1769
     * @param int $courseId ID of the course
1770
     * @param int $user_id ID of the user
1771
     * @param int $session_id ID of the session (if any)
1772
     */
1773
    public static function event_course_login($courseId, $user_id, $session_id)
1774
    {
1775
        $course_tracking_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1776
        $loginDate = $logoutDate = api_get_utc_datetime();
1777
1778
        //$counter represents the number of time this record has been refreshed
1779
        $counter = 1;
1780
1781
        $courseId = intval($courseId);
1782
        $user_id = intval($user_id);
1783
        $session_id = intval($session_id);
1784
        $ip = api_get_real_ip();
1785
1786
        $sql = "INSERT INTO $course_tracking_table(c_id, user_ip, user_id, login_course_date, logout_course_date, counter, session_id)
1787
                VALUES('".$courseId."', '".$ip."', '".$user_id."', '$loginDate', '$logoutDate', $counter, '".$session_id."')";
1788
        Database::query($sql);
1789
1790
        // Course catalog stats modifications see #4191
1791
        CourseManager::update_course_ranking(
1792
            null,
1793
            null,
1794
            null,
1795
            null,
1796
            true,
1797
            false
1798
        );
1799
    }
1800
1801
    /**
1802
     * Register a "fake" time spent on the platform, for example to match the
1803
     * estimated time he took to author an assignment/work, see configuration
1804
     * setting considered_working_time.
1805
     * This assumes there is already some connection of the student to the
1806
     * course, otherwise he wouldn't be able to upload an assignment.
1807
     * This works by creating a new record, copy of the current one, then
1808
     * updating the current one to be just the considered_working_time and
1809
     * end at the same second as the user connected to the course.
1810
     * @param int $courseId The course in which to add the time
1811
     * @param int $userId The user for whom to add the time
1812
     * @param int $sessionId The session in which to add the time (if any)
1813
     * @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.
1814
     * @param string $ip IP address to go on record for this time record
1815
     *
1816
     * @return True on successful insertion, false otherwise
1817
     */
1818
    public static function eventAddVirtualCourseTime(
1819
        $courseId,
1820
        $userId,
1821
        $sessionId,
1822
        $virtualTime = '',
1823
        $ip = ''
1824
    ) {
1825
        $courseTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1826
        $time = $loginDate = $logoutDate = api_get_utc_datetime();
1827
1828
        $courseId = intval($courseId);
1829
        $userId = intval($userId);
1830
        $sessionId = intval($sessionId);
1831
        $ip = Database::escape_string($ip);
1832
1833
        // Get the current latest course connection register. We need that
1834
        // record to re-use the data and create a new record.
1835
        $sql = "SELECT *
1836
                FROM $courseTrackingTable
1837
                WHERE
1838
                    user_id = ".$userId." AND
1839
                    c_id = ".$courseId."  AND
1840
                    session_id  = ".$sessionId." AND
1841
                    login_course_date > '$time' - INTERVAL 3600 SECOND
1842
                ORDER BY login_course_date DESC LIMIT 0,1";
1843
        $result = Database::query($sql);
1844
1845
        // Ignore if we didn't find any course connection record in the last
1846
        // hour. In this case it wouldn't be right to add a "fake" time record.
1847
        if (Database::num_rows($result) > 0) {
1848
            // Found the latest connection
1849
            $row = Database::fetch_row($result);
1850
            $courseAccessId = $row[0];
1851
            $courseAccessLoginDate = $row[3];
1852
            $counter = $row[5];
1853
            $counter = $counter ? $counter : 0;
1854
            // Insert a new record, copy of the current one (except the logout
1855
            // date that we update to the current time)
1856
            $sql = "INSERT INTO $courseTrackingTable(
1857
                    c_id,
1858
                    user_ip, 
1859
                    user_id, 
1860
                    login_course_date, 
1861
                    logout_course_date, 
1862
                    counter, 
1863
                    session_id
1864
                ) VALUES(
1865
                    $courseId, 
1866
                    '$ip', 
1867
                    $userId, 
1868
                    '$courseAccessLoginDate', 
1869
                    '$logoutDate', 
1870
                    $counter, 
1871
                    $sessionId
1872
                )";
1873
            Database::query($sql);
1874
1875
            $loginDate = ChamiloApi::addOrSubTimeToDateTime(
1876
                $virtualTime,
1877
                $courseAccessLoginDate,
1878
                false
1879
            );
1880
            // We update the course tracking table
1881
            $sql = "UPDATE $courseTrackingTable  
1882
                    SET 
1883
                        login_course_date = '$loginDate',
1884
                        logout_course_date = '$courseAccessLoginDate',
1885
                        counter = 0
1886
                    WHERE 
1887
                        course_access_id = ".intval($courseAccessId)." AND 
1888
                        session_id = ".$sessionId;
1889
            Database::query($sql);
1890
1891
            return true;
1892
        }
1893
1894
        return false;
1895
    }
1896
    /**
1897
     * Removes a "fake" time spent on the platform, for example to match the
1898
     * estimated time he took to author an assignment/work, see configuration
1899
     * setting considered_working_time.
1900
     * This method should be called when something that generated a fake
1901
     * time record is removed. Given the database link is weak (no real
1902
     * relationship kept between the deleted item and this record), this
1903
     * method just looks for the latest record that has the same time as the
1904
     * item's fake time, is in the past and in this course+session. If such a
1905
     * record cannot be found, it doesn't do anything.
1906
     * The IP address is not considered a useful filter here.
1907
     * @param int $courseId The course in which to add the time
1908
     * @param int $userId The user for whom to add the time
1909
     * @param int $sessionId The session in which to add the time (if any)
1910
     * @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.
1911
     * @return True on successful removal, false otherwise
1912
     */
1913
    public static function eventRemoveVirtualCourseTime($courseId, $userId, $sessionId = 0, $virtualTime = '')
1914
    {
1915
        if (empty($virtualTime)) {
1916
            return false;
1917
        }
1918
        $courseTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1919
        $time = $loginDate = $logoutDate = api_get_utc_datetime();
1920
1921
        $courseId = intval($courseId);
1922
        $userId = intval($userId);
1923
        $sessionId = intval($sessionId);
1924
        // Change $virtualTime format from hh:mm:ss to hhmmss which is the
1925
        // format returned by SQL for a subtraction of two datetime values
1926
        // @todo make sure this is portable between DBMSes
1927
        if (preg_match('/:/', $virtualTime)) {
1928
            list($h, $m, $s) = preg_split('/:/', $virtualTime);
1929
            $virtualTime = $h * 3600 + $m * 60 + $s;
1930
        } else {
1931
            $virtualTime *= 3600;
1932
        }
1933
1934
        // Get the current latest course connection register. We need that
1935
        // record to re-use the data and create a new record.
1936
        $sql = "SELECT course_access_id
1937
                        FROM $courseTrackingTable
1938
                        WHERE
1939
                            user_id = $userId AND
1940
                            c_id = $courseId  AND
1941
                            session_id  = $sessionId AND
1942
                            counter = 0 AND
1943
                            (UNIX_TIMESTAMP(logout_course_date) - UNIX_TIMESTAMP(login_course_date)) = '$virtualTime'
1944
                        ORDER BY login_course_date DESC LIMIT 0,1";
1945
        $result = Database::query($sql);
1946
1947
        // Ignore if we didn't find any course connection record in the last
1948
        // hour. In this case it wouldn't be right to add a "fake" time record.
1949 View Code Duplication
        if (Database::num_rows($result) > 0) {
1950
            // Found the latest connection
1951
            $row = Database::fetch_row($result);
1952
            $courseAccessId = $row[0];
1953
            $sql = "DELETE FROM $courseTrackingTable WHERE course_access_id = $courseAccessId";
1954
            $result = Database::query($sql);
1955
1956
            return $result;
1957
        }
1958
1959
        return false;
1960
    }
1961
1962
    /**
1963
     * For the sake of genericity, this function is a switch.
1964
     * It's called by EventsDispatcher and fires the good function
1965
     * with the good require_once.
1966
     *
1967
     * @param string $event_name
1968
     * @param array $params
1969
     */
1970
    public static function event_send_mail($event_name, $params)
1971
    {
1972
        EventsMail::send_mail($event_name, $params);
1973
    }
1974
1975
    /**
1976
     * Internal function checking if the mail was already sent from that user to that user
1977
     * @param string $event_name
1978
     * @param int $user_from
1979
     * @param int $user_to
1980
     * @return boolean
1981
     */
1982
    public static function check_if_mail_already_sent($event_name, $user_from, $user_to = null)
1983
    {
1984
        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...
1985
            $sql = 'SELECT COUNT(*) as total FROM '.Database::get_main_table(TABLE_EVENT_SENT).'
1986
                    WHERE user_from = '.$user_from.' AND event_type_name = "'.$event_name.'"';
1987
        } else {
1988
            $sql = 'SELECT COUNT(*) as total FROM '.Database::get_main_table(TABLE_EVENT_SENT).'
1989
                    WHERE user_from = '.$user_from.' AND user_to = '.$user_to.' AND event_type_name = "'.$event_name.'"';
1990
        }
1991
        $result = Database::store_result(Database::query($sql), 'ASSOC');
1992
1993
        return $result[0]["total"];
1994
    }
1995
1996
    /**
1997
     *
1998
     * Filter EventEmailTemplate Filters see the main/inc/conf/events.conf.dist.php
1999
     *
2000
     */
2001
2002
    /**
2003
     * Basic template event message filter (to be used by other filters as default)
2004
     * @param array $values (passing by reference)
2005
     * @return boolean True if everything is OK, false otherwise
2006
     */
2007
    public function event_send_mail_filter_func(&$values)
2008
    {
2009
        return true;
2010
    }
2011
2012
    /**
2013
     * user_registration - send_mail filter
2014
     * @param array $values (passing by reference)
2015
     * @return boolean True if everything is OK, false otherwise
2016
     */
2017
    public function user_registration_event_send_mail_filter_func(&$values)
2018
    {
2019
        $res = self::event_send_mail_filter_func($values);
2020
        // proper logic for this filter
2021
        return $res;
2022
    }
2023
2024
    /**
2025
     * portal_homepage_edited - send_mail filter
2026
     * @param array $values (passing by reference)
2027
     * @return boolean True if everything is OK, false otherwise
2028
     */
2029
    public function portal_homepage_edited_event_send_mail_filter_func(&$values)
2030
    {
2031
        $res = self::event_send_mail_filter_func($values);
2032
        // proper logic for this filter
2033
        return $res;
2034
    }
2035
}
2036