Passed
Pull Request — master (#5678)
by Angel Fernando Quiroz
07:40
created

who_is_online_in_this_course()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 50
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 36
nc 7
nop 5
dl 0
loc 50
rs 9.0328
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\UserRelUser;
5
use ChamiloSession as Session;
6
7
/**
8
 * Code library for showing Who is online.
9
 *
10
 * @author Istvan Mandak, principal author
11
 * @author Denes Nagy, principal author
12
 * @author Bart Mollet
13
 * @author Roan Embrechts, cleaning and bugfixing
14
 * Insert a login reference for the current user into the track_e_online stats
15
 * table. This table keeps trace of the last login. Nothing else matters (we
16
 * don't keep traces of anything older).
17
 *
18
 * @param int user id
19
 */
20
function LoginCheck($uid)
21
{
22
    $uid = (int) $uid;
23
    if (!empty($uid)) {
24
        $online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
25
        $_course = api_get_course_info();
26
        $user_ip = '';
27
        if (!empty($_SERVER['REMOTE_ADDR'])) {
28
            $user_ip = Database::escape_string(api_get_real_ip());
29
        }
30
31
        $login_date = api_get_utc_datetime();
32
        $access_url_id = 1;
33
        if (api_get_multiple_access_url() && -1 != api_get_current_access_url_id()) {
34
            $access_url_id = api_get_current_access_url_id();
35
        }
36
        $session_id = api_get_session_id();
37
        $cid = 0;
38
        if (is_array($_course) && count($_course) > 0 && !empty($_course['real_id'])) {
39
            $cid = intval($_course['real_id']);
40
        }
41
        $query = "SELECT login_id FROM $online_table WHERE login_user_id = $uid";
42
        $resLogin = Database::query($query);
43
        if (Database::num_rows($resLogin) > 0) {
44
            $query = "UPDATE $online_table SET
45
                      login_date = '$login_date',
46
                      user_ip = '$user_ip',
47
                      c_id = $cid,
48
                      session_id = $session_id,
49
                      access_url_id = $access_url_id
50
                      WHERE login_user_id = $uid";
51
            Database::query($query);
52
        } else {
53
            $query = "INSERT $online_table (
54
                login_user_id,
55
                login_date,
56
                user_ip,
57
                c_id,
58
                session_id,
59
                access_url_id
60
            ) values (
61
                $uid,
62
                '$login_date',
63
                '$user_ip',
64
                $cid,
65
                $session_id,
66
                $access_url_id
67
            )";
68
            Database::query($query);
69
        }
70
    }
71
}
72
73
/**
74
 * @param int $userId
75
 */
76
function preventMultipleLogin($userId)
77
{
78
    $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
79
    $userId = intval($userId);
80
    if ('true' === api_get_setting('prevent_multiple_simultaneous_login')) {
81
        if (!empty($userId) && !api_is_anonymous()) {
82
            $isFirstLogin = Session::read('first_user_login');
83
            if (empty($isFirstLogin)) {
84
                $sql = "SELECT login_id FROM $table
85
                        WHERE login_user_id = $userId
86
                        LIMIT 1";
87
88
                $result = Database::query($sql);
89
                $loginData = [];
90
                if (Database::num_rows($result)) {
91
                    $loginData = Database::fetch_array($result);
92
                }
93
94
                $userIsReallyOnline = user_is_online($userId);
95
96
                // Trying double login.
97
                if (!empty($loginData) && true == $userIsReallyOnline) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
98
                    session_regenerate_id();
99
                    Session::destroy();
100
                    header('Location: '.api_get_path(WEB_PATH).'index.php?loginFailed=1&error=multiple_connection_not_allowed');
101
                    exit;
102
                } else {
103
                    // First time
104
                    Session::write('first_user_login', 1);
105
                }
106
            }
107
        }
108
    }
109
}
110
111
/**
112
 * This function handles the logout and is called whenever there is a $_GET['logout'].
113
 *
114
 * @param int  $user_id
115
 * @param bool $logout_redirect
116
 *
117
 * @author Fernando P. García <[email protected]>
118
 */
119
function online_logout($user_id = null, $logout_redirect = false)
120
{
121
    global $extAuthSource;
122
123
    // Database table definition
124
    $tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
125
126
    if (empty($user_id)) {
127
        $user_id = isset($_GET['uid']) ? intval($_GET['uid']) : 0;
128
    }
129
130
    // Changing global chat status to offline
131
    if (api_is_global_chat_enabled()) {
132
        $chat = new Chat();
133
        $chat->setUserStatus(0);
134
    }
135
136
    $chat = new Chat();
137
    $chat->close();
138
139
    // selecting the last login of the user
140
    $sql = "SELECT login_id, login_date
141
    		FROM $tbl_track_login
142
    		WHERE login_user_id = $user_id
143
    		ORDER BY login_date DESC
144
    		LIMIT 0,1";
145
    $q_last_connection = Database::query($sql);
146
    $i_id_last_connection = 0;
147
    if (Database::num_rows($q_last_connection) > 0) {
148
        $i_id_last_connection = Database::result($q_last_connection, 0, "login_id");
149
    }
150
151
    if (!isset($_SESSION['login_as']) && !empty($i_id_last_connection)) {
152
        $current_date = api_get_utc_datetime();
153
        $sql = "UPDATE $tbl_track_login SET logout_date='".$current_date."'
154
        		WHERE login_id='$i_id_last_connection'";
155
        Database::query($sql);
156
    }
157
    $logInfo = [
158
        'tool' => 'logout',
159
        'tool_id' => 0,
160
        'tool_id_detail' => 0,
161
    ];
162
    Event::registerLog($logInfo);
0 ignored issues
show
Bug introduced by
The method registerLog() does not exist on Event. ( Ignorable by Annotation )

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

162
    Event::/** @scrutinizer ignore-call */ 
163
           registerLog($logInfo);

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

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

Loading history...
163
164
    UserManager::loginDelete($user_id);
165
166
    //the following code enables the use of an external logout function.
167
    //example: define a $extAuthSource['ldap']['logout']="file.php" in configuration.php
168
    // then a function called ldap_logout() inside that file
169
    // (using *authent_name*_logout as the function name) and the following code
170
    // will find and execute it
171
    $uinfo = api_get_user_info($user_id);
172
    if ((PLATFORM_AUTH_SOURCE != $uinfo['auth_source']) && is_array($extAuthSource)) {
173
        if (is_array($extAuthSource[$uinfo['auth_source']])) {
174
            $subarray = $extAuthSource[$uinfo['auth_source']];
175
            if (!empty($subarray['logout']) && file_exists($subarray['logout'])) {
176
                require_once $subarray['logout'];
177
                $logout_function = $uinfo['auth_source'].'_logout';
178
                if (function_exists($logout_function)) {
179
                    $logout_function($uinfo);
180
                }
181
            }
182
        }
183
    }
184
185
    // After logout redirect to
186
    $url = api_get_path(WEB_PATH).'index.php';
187
188
    if ($logout_redirect && 'true' == api_get_plugin_setting('azure_active_directory', 'enable')) {
189
        if ('azure_active_directory' === ChamiloSession::read('_user_auth_source')) {
190
            $activeDirectoryPlugin = AzureActiveDirectory::create();
191
            $azureLogout = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_LOGOUT);
192
            if (!empty($azureLogout)) {
193
                $url = $azureLogout;
194
            }
195
        }
196
    }
197
198
    Session::erase('last_id');
199
    CourseChatUtils::exitChat($user_id);
200
    session_regenerate_id();
201
    Session::destroy();
202
203
    $pluginKeycloak = 'true' === api_get_plugin_setting('keycloak', 'tool_enable');
204
    if ($pluginKeycloak && 'keycloak' === $uinfo['auth_source']) {
205
        $pluginUrl = api_get_path(WEB_PLUGIN_PATH).'keycloak/start.php?slo';
206
        header('Location: '.$pluginUrl);
207
        exit;
208
    }
209
210
    if ($logout_redirect) {
211
        header("Location: $url");
212
        exit;
213
    }
214
}
215
216
/**
217
 * @param int $user_id
218
 *
219
 * @return bool
220
 */
221
function user_is_online($user_id)
222
{
223
    $track_online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
224
    $table_user = Database::get_main_table(TABLE_MAIN_USER);
225
226
    $access_url_id = api_get_current_access_url_id();
227
    $time_limit = api_get_setting('time_limit_whosonline');
228
229
    $online_time = time() - $time_limit * 60;
230
    $limit_date = api_get_utc_datetime($online_time);
231
    $user_id = (int) $user_id;
232
233
    $query = " SELECT login_user_id, login_date
234
               FROM $track_online_table track
235
               INNER JOIN $table_user u
236
               ON (u.id=track.login_user_id)
237
               WHERE
238
                    track.access_url_id =  $access_url_id AND
239
                    login_date >= '".$limit_date."'  AND
240
                    u.id =  $user_id
241
               LIMIT 1 ";
242
243
    $result = Database::query($query);
244
    if (Database::num_rows($result)) {
245
        return true;
246
    }
247
248
    return false;
249
}
250
251
/**
252
 * Gives a list of people online now (and in the last $valid minutes).
253
 *
254
 * @param $from
255
 * @param $number_of_items
256
 * @param null $column
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $column is correct as it would always require null to be passed?
Loading history...
257
 * @param null $direction
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $direction is correct as it would always require null to be passed?
Loading history...
258
 * @param null $time_limit
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $time_limit is correct as it would always require null to be passed?
Loading history...
259
 * @param bool $friends
260
 *
261
 * @return array|bool For each line, a list of user IDs and login dates, or FALSE on error or empty results
262
 */
263
function who_is_online(
264
    $from,
265
    $number_of_items,
266
    $column = null,
267
    $direction = null,
268
    $time_limit = null,
269
    $friends = false
270
) {
271
    // Time limit in seconds?
272
    if (empty($time_limit)) {
273
        $time_limit = api_get_setting('time_limit_whosonline');
274
    } else {
275
        $time_limit = intval($time_limit);
276
    }
277
278
    $from = intval($from);
279
    $number_of_items = intval($number_of_items);
280
281
    if (empty($column)) {
282
        $column = 'picture_uri';
283
        if ($friends) {
284
            $column = 'login_date';
285
        }
286
    }
287
288
    $direction = strtolower($direction);
289
    if (empty($direction)) {
290
        $direction = 'DESC';
291
    } else {
292
        if (!in_array($direction, ['asc', 'desc'])) {
293
            $direction = 'DESC';
294
        }
295
    }
296
297
    $online_time = time() - $time_limit * 60;
298
    $current_date = api_get_utc_datetime($online_time);
299
    $track_online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
300
    $friend_user_table = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
301
    $table_user = Database::get_main_table(TABLE_MAIN_USER);
302
303
    if ($friends) {
304
        // 	who friends from social network is online
305
        $query = "SELECT DISTINCT login_user_id, login_date
306
                  FROM $track_online_table INNER JOIN $friend_user_table
307
                  ON (friend_user_id = login_user_id)
308
                  WHERE
309
                    login_date >= '".$current_date."' AND
310
                    friend_user_id <> '".api_get_user_id()."' AND
311
                    relation_type='".UserRelUser::USER_RELATION_TYPE_FRIEND."' AND
312
                    user_id = '".api_get_user_id()."'
313
                  ORDER BY `$column` $direction
314
                  LIMIT $from, $number_of_items";
315
    } else {
316
        $query = "SELECT DISTINCT login_user_id, login_date
317
                    FROM ".$track_online_table." e
318
                    INNER JOIN ".$table_user." u ON (u.id = e.login_user_id)
319
                  WHERE u.active <> ".USER_SOFT_DELETED." AND u.status != ".ANONYMOUS." AND login_date >= '".$current_date."'
320
                  ORDER BY `$column` $direction
321
                  LIMIT $from, $number_of_items";
322
    }
323
324
    if (api_get_multiple_access_url()) {
325
        $access_url_id = api_get_current_access_url_id();
326
        if (-1 != $access_url_id) {
327
            if ($friends) {
328
                // 	friends from social network is online
329
                $query = "SELECT distinct login_user_id, login_date
330
                            FROM $track_online_table track INNER JOIN $friend_user_table
331
                            ON (friend_user_id = login_user_id)
332
                            WHERE   track.access_url_id =  $access_url_id AND
333
                                    login_date >= '".$current_date."' AND
334
                                    friend_user_id <> '".api_get_user_id()."' AND
335
                                    relation_type='".UserRelUser::USER_RELATION_TYPE_FRIEND."'
336
                            ORDER BY `$column` $direction
337
                            LIMIT $from, $number_of_items";
338
            } else {
339
                // all users online
340
                $query = "SELECT login_user_id, login_date
341
                          FROM ".$track_online_table." track
342
                          INNER JOIN ".$table_user." u
343
                          ON (u.id=track.login_user_id)
344
                          WHERE u.active <> ".USER_SOFT_DELETED." AND u.status != ".ANONYMOUS." AND track.access_url_id =  $access_url_id AND
345
                                login_date >= '".$current_date."'
346
                          ORDER BY `$column` $direction
347
                          LIMIT $from, $number_of_items";
348
            }
349
        }
350
    }
351
352
    //This query will show all registered users. Only for dev purposes.
353
    /*$query = "SELECT DISTINCT u.id as login_user_id, login_date
354
            FROM $track_online_table e, $table_user u
355
            GROUP by u.id
356
            ORDER BY $column $direction
357
            LIMIT $from, $number_of_items";*/
358
359
    $result = Database::query($query);
360
    if ($result) {
361
        $users_online = [];
362
        while (list($login_user_id, $login_date) = Database::fetch_row($result)) {
363
            $users_online[] = $login_user_id;
364
        }
365
366
        return $users_online;
367
    } else {
368
        return false;
369
    }
370
}
371
372
/**
373
 * @param string $time_limit
374
 */
375
function who_is_online_count($time_limit = null, $friends = false)
376
{
377
    if (empty($time_limit)) {
378
        $time_limit = api_get_setting('time_limit_whosonline');
379
    } else {
380
        $time_limit = intval($time_limit);
381
    }
382
    $track_online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
383
    $friend_user_table = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
384
    $table_user = Database::get_main_table(TABLE_MAIN_USER);
385
    $online_time = time() - $time_limit * 60;
386
    $current_date = api_get_utc_datetime($online_time);
387
388
    if ($friends) {
389
        // who friends from social network is online
390
        $query = "SELECT DISTINCT count(login_user_id) as count
391
				  FROM $track_online_table INNER JOIN $friend_user_table
392
                  ON (friend_user_id = login_user_id)
393
				  WHERE
394
				        login_date >= '$current_date' AND
395
				        friend_user_id <> '".api_get_user_id()."' AND
396
				        relation_type='".UserRelUser::USER_RELATION_TYPE_FRIEND."' AND
397
				        user_id = '".api_get_user_id()."' ";
398
    } else {
399
        // All users online
400
        $query = "SELECT count(login_id) as count
401
                  FROM $track_online_table track INNER JOIN $table_user u
402
                  ON (u.id=track.login_user_id)
403
                  WHERE u.active <> ".USER_SOFT_DELETED." AND u.status != ".ANONYMOUS." AND login_date >= '$current_date'  ";
404
    }
405
406
    if (api_get_multiple_access_url()) {
407
        $access_url_id = api_get_current_access_url_id();
408
        if (-1 != $access_url_id) {
409
            if ($friends) {
410
                // friends from social network is online
411
                $query = "SELECT DISTINCT count(login_user_id) as count
412
							FROM $track_online_table track
413
							INNER JOIN $friend_user_table ON (friend_user_id = login_user_id)
414
							WHERE
415
							    track.access_url_id = $access_url_id AND
416
							    login_date >= '".$current_date."' AND
417
							    friend_user_id <> '".api_get_user_id()."' AND
418
							    relation_type='".UserRelUser::USER_RELATION_TYPE_FRIEND."'  ";
419
            } else {
420
                // all users online
421
                $query = "SELECT count(login_id) as count FROM $track_online_table  track
422
                          INNER JOIN $table_user u ON (u.id=track.login_user_id)
423
						  WHERE
424
						    u.active <> ".USER_SOFT_DELETED." AND
425
						    u.status != ".ANONYMOUS." AND
426
						    track.access_url_id =  $access_url_id AND
427
						    login_date >= '$current_date' ";
428
            }
429
        }
430
    }
431
432
    // Dev purposes show all users online
433
    /*$table_user = Database::get_main_table(TABLE_MAIN_USER);
434
    $query = "SELECT count(*)  as count FROM ".$table_user;*/
435
436
    $result = Database::query($query);
437
    if (Database::num_rows($result) > 0) {
438
        $row = Database::fetch_array($result);
439
440
        return $row['count'];
441
    } else {
442
        return false;
443
    }
444
}
445
446
/**
447
 * Returns a list (array) of users who are online and in this course.
448
 *
449
 * @param    int User ID
450
 * @param    int Number of minutes
451
 * @param    string  Course code (could be empty, but then the function returns false)
452
 *
453
 * @return array Each line gives a user id and a login time
454
 */
455
function who_is_online_in_this_course($from, $number_of_items, $uid, $time_limit, $course_code)
456
{
457
    if (empty($course_code)) {
458
        return false;
459
    }
460
461
    $time_limit = (int) $time_limit;
462
    if (empty($time_limit)) {
463
        $time_limit = api_get_setting('time_limit_whosonline');
464
    }
465
466
    $online_time = time() - $time_limit * 60;
467
    $current_date = api_get_utc_datetime($online_time);
468
    $track_online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
469
    $tableUser = Database::get_main_table(TABLE_MAIN_USER);
470
    $course_code = Database::escape_string($course_code);
471
    $courseInfo = api_get_course_info($course_code);
472
    $courseId = $courseInfo['real_id'];
473
474
    $from = (int) $from;
475
    $number_of_items = (int) $number_of_items;
476
477
    $accessUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
478
    $urlId = api_get_current_access_url_id();
479
    $urlJoin = " INNER JOIN $accessUrlUser a ON (a.user_id = u.id) ";
480
    $urlCondition = " AND a.access_url_id = $urlId ";
481
482
    $query = "SELECT o.login_user_id, o.login_date
483
              FROM $track_online_table o
484
              INNER JOIN $tableUser u
485
              ON (o.login_user_id = u.id)
486
              $urlJoin
487
              WHERE
488
                u.active <> ".USER_SOFT_DELETED." AND
489
                u.status <> '".ANONYMOUS."' AND
490
                o.c_id = $courseId AND
491
                o.login_date >= '$current_date'
492
                $urlCondition
493
              LIMIT $from, $number_of_items ";
494
495
    $result = Database::query($query);
496
    if ($result) {
497
        $users_online = [];
498
        while (list($login_user_id, $login_date) = Database::fetch_row($result)) {
499
            $users_online[] = $login_user_id;
500
        }
501
502
        return $users_online;
503
    } else {
504
        return false;
505
    }
506
}
507
508
/**
509
 * @param int    $uid
510
 * @param string $time_limit
511
 */
512
function who_is_online_in_this_course_count(
513
    $uid,
514
    $time_limit,
515
    $coursecode = null
516
) {
517
    if (empty($coursecode)) {
518
        return false;
519
    }
520
    $track_online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
521
    $tableUser = Database::get_main_table(TABLE_MAIN_USER);
522
    $time_limit = Database::escape_string($time_limit);
523
    $online_time = time() - $time_limit * 60;
524
    $current_date = api_get_utc_datetime($online_time);
525
    $courseId = api_get_course_int_id($coursecode);
526
527
    if (empty($courseId)) {
528
        return false;
529
    }
530
531
    $accessUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
532
    $urlId = api_get_current_access_url_id();
533
    $urlJoin = " INNER JOIN $accessUrlUser a ON (a.user_id = u.id) ";
534
    $urlCondition = " AND a.access_url_id = $urlId ";
535
536
    $query = "SELECT count(login_user_id) as count
537
              FROM $track_online_table o
538
              INNER JOIN $tableUser u
539
              ON (login_user_id = u.id)
540
              $urlJoin
541
              WHERE
542
                u.active <> ".USER_SOFT_DELETED." AND
543
                u.status <> '".ANONYMOUS."' AND
544
                c_id = $courseId AND
545
                login_date >= '$current_date'
546
                $urlCondition
547
                ";
548
    $result = Database::query($query);
549
    if (Database::num_rows($result) > 0) {
550
        $row = Database::fetch_array($result);
551
552
        return $row['count'];
553
    } else {
554
        return false;
555
    }
556
}
557
558
/**
559
 * @param string $timeLimit
560
 * @param int    $sessionId
561
 *
562
 * @return bool
563
 */
564
function whoIsOnlineInThisSessionCount($timeLimit, $sessionId)
565
{
566
    if (!$sessionId) {
567
        return 0;
568
    }
569
570
    $tblTrackOnline = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
571
    $tableUser = Database::get_main_table(TABLE_MAIN_USER);
572
573
    $timeLimit = Database::escape_string($timeLimit);
574
    $online_time = time() - $timeLimit * 60;
575
    $current_date = api_get_utc_datetime($online_time);
576
577
    $accessUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
578
    $urlId = api_get_current_access_url_id();
579
    $urlJoin = " INNER JOIN $accessUrlUser a ON (a.user_id = u.id) ";
580
    $urlCondition = " AND a.access_url_id = $urlId ";
581
582
    $query = "SELECT count(login_user_id) as count
583
              FROM $tblTrackOnline o
584
              INNER JOIN $tableUser u
585
              ON (login_user_id = u.id)
586
              $urlJoin
587
              WHERE
588
                    u.active <> ".USER_SOFT_DELETED." AND
589
                    u.status <> '".ANONYMOUS."' AND
590
                    session_id = $sessionId AND
591
                    login_date >= '$current_date'
592
                    $urlCondition
593
            ";
594
    $result = Database::query($query);
595
596
    if (Database::num_rows($result) > 0) {
597
        $row = Database::fetch_assoc($result);
598
599
        return $row['count'];
600
    }
601
602
    return 0;
603
}
604