Passed
Push — 1.11.x ( 0efb0a...88fa85 )
by Julito
12:38
created

MySpace::get_user_creator()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 4
nop 1
dl 0
loc 20
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use ChamiloSession as Session;
5
use CpChart\Cache as pCache;
6
use CpChart\Data as pData;
7
use CpChart\Image as pImage;
8
9
/**
10
 * Class MySpace.
11
 */
12
class MySpace
13
{
14
    /**
15
     * Get admin actions.
16
     *
17
     * @return string
18
     */
19
    public static function getAdminActions()
20
    {
21
        $actions = [
22
            [
23
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=coaches',
24
                'content' => get_lang('DisplayCoaches'),
25
            ],
26
            [
27
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=user',
28
                'content' => get_lang('DisplayUserOverview'),
29
            ],
30
            [
31
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=session',
32
                'content' => get_lang('DisplaySessionOverview'),
33
            ],
34
            [
35
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=course',
36
                'content' => get_lang('DisplayCourseOverview'),
37
            ],
38
            [
39
                'url' => api_get_path(WEB_CODE_PATH).'tracking/question_course_report.php?view=admin',
40
                'content' => get_lang('LPQuestionListResults'),
41
            ],
42
            [
43
                'url' => api_get_path(WEB_CODE_PATH).'tracking/course_session_report.php?view=admin',
44
                'content' => get_lang('LPExerciseResultsBySession'),
45
            ],
46
            [
47
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=accessoverview',
48
                'content' => get_lang('DisplayAccessOverview').' ('.get_lang('Beta').')',
49
            ],
50
            [
51
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/exercise_category_report.php',
52
                'content' => get_lang('ExerciseCategoryAllSessionsReport'),
53
            ],
54
            [
55
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/survey_report.php',
56
                'content' => get_lang('SurveysReport'),
57
            ],
58
        ];
59
60
        return Display::actions($actions, null);
61
    }
62
63
    /**
64
     * @return string
65
     */
66
    public static function getTopMenu()
67
    {
68
        $menuItems = [];
69
        $menuItems[] = Display::url(
70
            Display::return_icon(
71
                'statistics.png',
72
                get_lang('MyStats'),
73
                '',
74
                ICON_SIZE_MEDIUM
75
            ),
76
            api_get_path(WEB_CODE_PATH)."auth/my_progress.php"
77
        );
78
        $menuItems[] = Display::url(
79
            Display::return_icon(
80
                'teacher.png',
81
                get_lang('TeacherInterface'),
82
                [],
83
                32
84
            ),
85
            api_get_path(WEB_CODE_PATH).'mySpace/?view=teacher'
86
        );
87
        $menuItems[] = Display::url(
88
            Display::return_icon(
89
                'star_na.png',
90
                get_lang('AdminInterface'),
91
                [],
92
                32
93
            ),
94
            '#'
95
        );
96
        $menuItems[] = Display::url(
97
            Display::return_icon('quiz.png', get_lang('ExamTracking'), [], 32),
98
            api_get_path(WEB_CODE_PATH).'tracking/exams.php'
99
        );
100
        $menu = '';
101
        foreach ($menuItems as $item) {
102
            $menu .= $item;
103
        }
104
        $menu .= '<br />';
105
106
        return $menu;
107
    }
108
109
    /**
110
     * This function serves exporting data in CSV format.
111
     *
112
     * @param array  $header    the header labels
113
     * @param array  $data      the data array
114
     * @param string $file_name the name of the file which contains exported data
115
     *
116
     * @return string mixed             Returns a message (string) if an error occurred
117
     */
118
    public function export_csv($header, $data, $file_name = 'export.csv')
119
    {
120
        $archive_path = api_get_path(SYS_ARCHIVE_PATH);
121
        $archive_url = api_get_path(WEB_CODE_PATH).'course_info/download.php?archive_path=&archive=';
122
        $message = '';
123
        if (!$open = fopen($archive_path.$file_name, 'w+')) {
124
            $message = get_lang('noOpen');
125
        } else {
126
            $info = '';
127
128
            foreach ($header as $value) {
129
                $info .= $value.';';
130
            }
131
            $info .= "\r\n";
132
133
            foreach ($data as $row) {
134
                foreach ($row as $value) {
135
                    $info .= $value.';';
136
                }
137
                $info .= "\r\n";
138
            }
139
140
            fwrite($open, $info);
141
            fclose($open);
142
            @chmod($file_name, api_get_permissions_for_new_files());
143
144
            header("Location:".$archive_url.$file_name);
145
            exit;
146
        }
147
148
        return $message;
149
    }
150
151
    /**
152
     * Gets the connections to a course as an array of login and logout time.
153
     *
154
     * @param int   $userId     User id
155
     * @param array $courseInfo
156
     * @param int   $sessionId  Session id (optional, default = 0)
157
     *
158
     * @return array Connections
159
     */
160
    public static function get_connections_to_course(
161
        $userId,
162
        $courseInfo,
163
        $sessionId = 0
164
    ) {
165
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
166
167
        // protect data
168
        $userId = (int) $userId;
169
        $courseId = (int) $courseInfo['real_id'];
170
        $sessionId = (int) $sessionId;
171
        $sessionCondition = api_get_session_condition($sessionId);
172
173
        $sql = 'SELECT login_course_date, logout_course_date
174
                FROM '.$table.'
175
                WHERE
176
                    user_id = '.$userId.' AND
177
                    c_id = '.$courseId.'
178
                    '.$sessionCondition.'
179
                ORDER BY login_course_date ASC';
180
        $rs = Database::query($sql);
181
        $connections = [];
182
183
        while ($row = Database::fetch_array($rs)) {
184
            $connections[] = [
185
                'login' => $row['login_course_date'],
186
                'logout' => $row['logout_course_date'],
187
            ];
188
        }
189
190
        return $connections;
191
    }
192
193
    /**
194
     * @param $user_id
195
     * @param $course_list
196
     * @param int $session_id
197
     *
198
     * @return array|bool
199
     */
200
    public static function get_connections_from_course_list(
201
        $user_id,
202
        $course_list,
203
        $session_id = 0
204
    ) {
205
        // Database table definitions
206
        $tbl_track_course = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
207
        if (empty($course_list)) {
208
            return false;
209
        }
210
211
        // protect data
212
        $user_id = (int) $user_id;
213
        $session_id = (int) $session_id;
214
        $new_course_list = [];
215
        foreach ($course_list as $course_item) {
216
            $courseInfo = api_get_course_info($course_item['code']);
217
            if ($courseInfo) {
218
                $courseId = $courseInfo['real_id'];
219
                $new_course_list[] = '"'.$courseId.'"';
220
            }
221
        }
222
        $course_list = implode(', ', $new_course_list);
223
224
        if (empty($course_list)) {
225
            return false;
226
        }
227
        $sql = 'SELECT login_course_date, logout_course_date, c_id
228
                FROM '.$tbl_track_course.'
229
                WHERE
230
                    user_id = '.$user_id.' AND
231
                    c_id IN ('.$course_list.') AND
232
                    session_id = '.$session_id.'
233
                ORDER BY login_course_date ASC';
234
        $rs = Database::query($sql);
235
        $connections = [];
236
237
        while ($row = Database::fetch_array($rs)) {
238
            $timestamp_login_date = api_strtotime($row['login_course_date'], 'UTC');
239
            $timestamp_logout_date = api_strtotime($row['logout_course_date'], 'UTC');
240
            $connections[] = [
241
                'login' => $timestamp_login_date,
242
                'logout' => $timestamp_logout_date,
243
                'c_id' => $row['c_id'],
244
            ];
245
        }
246
247
        return $connections;
248
    }
249
250
    /**
251
     * Creates a small table in the last column of the table with the user overview.
252
     *
253
     * @param int $user_id the id of the user
254
     *
255
     * @return array List course
256
     */
257
    public static function returnCourseTracking($user_id)
258
    {
259
        $user_id = (int) $user_id;
260
261
        if (empty($user_id)) {
262
            return [];
263
        }
264
265
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
266
        // getting all the courses of the user
267
        $sql = "SELECT * FROM $tbl_course_user
268
                WHERE
269
                    user_id = $user_id AND
270
                    relation_type <> ".COURSE_RELATION_TYPE_RRHH;
271
        $result = Database::query($sql);
272
273
        $list = [];
274
275
        while ($row = Database::fetch_array($result)) {
276
            $courseInfo = api_get_course_info_by_id($row['c_id']);
277
            $courseId = $courseInfo['real_id'];
278
            $courseCode = $courseInfo['code'];
279
280
            if (empty($courseInfo)) {
281
                continue;
282
            }
283
284
            $avg_score = Tracking::get_avg_student_score($user_id, $courseCode);
285
            if (is_numeric($avg_score)) {
286
                $avg_score = round($avg_score, 2);
287
            } else {
288
                $avg_score = '-';
289
            }
290
291
            // Student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
292
            $exercisesResults = self::exercises_results($user_id, $courseCode);
293
294
            $resultToString = '';
295
            if (!is_null($exercisesResults['percentage'])) {
296
                $resultToString = $exercisesResults['score_obtained'].'/'.$exercisesResults['score_possible'].' ( '.$exercisesResults['percentage'].'% )';
297
            }
298
299
            $item = [
300
                'code' => $courseInfo['code'],
301
                'real_id' => $courseInfo['real_id'],
302
                'title' => $courseInfo['title'],
303
                'category' => $courseInfo['categoryName'],
304
                'image_small' => $courseInfo['course_image'],
305
                'image_large' => $courseInfo['course_image_large'],
306
                'time_spent' => api_time_to_hms(Tracking::get_time_spent_on_the_course($user_id, $courseId)),
307
                'student_progress' => round(Tracking::get_avg_student_progress($user_id, $courseCode)),
308
                'student_score' => $avg_score,
309
                'student_message' => Tracking::count_student_messages($user_id, $courseCode),
310
                'student_assignments' => Tracking::count_student_assignments($user_id, $courseCode),
311
                'student_exercises' => $resultToString,
312
                'questions_answered' => $exercisesResults['questions_answered'],
313
                'last_connection' => Tracking::get_last_connection_date_on_the_course($user_id, $courseInfo),
314
            ];
315
            $list[] = $item;
316
        }
317
318
        return $list;
319
    }
320
321
    /**
322
     * Display a sortable table that contains an overview off all the
323
     * reporting progress of all users and all courses the user is subscribed to.
324
     *
325
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
326
     *          Alex Aragon <[email protected]>, BeezNest, Perú
327
     *
328
     * @version Chamilo 1.11.8
329
     *
330
     * @since April 2019
331
     */
332
    public static function returnTrackingUserOverviewFilter($user_id)
333
    {
334
        $tpl = new Template('', false, false, false, false, false, false);
335
        $userInfo = api_get_user_info($user_id);
336
337
        $avatar = UserManager::getUserPicture($user_id, USER_IMAGE_SIZE_SMALL);
338
        $user = [
339
            'id' => $user_id,
340
            'code_user' => $userInfo['official_code'],
341
            'complete_name' => $userInfo['complete_name'],
342
            'username' => $userInfo['username'],
343
            'course' => self::returnCourseTracking($user_id),
344
            'avatar' => $avatar,
345
        ];
346
347
        $tpl->assign('item', $user);
348
        $templateName = $tpl->get_template('my_space/partials/tracking_user_overview.tpl');
349
        $content = $tpl->fetch($templateName);
350
351
        return $content;
352
    }
353
354
    /**
355
     * Display a sortable table that contains an overview off all the
356
     * reporting progress of all users and all courses the user is subscribed to.
357
     *
358
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
359
     *         Alex Aragon <[email protected]>, BeezNest, Perú
360
     *
361
     * @version Chamilo 1.11.8
362
     *
363
     * @since October 2008, Update April 2019
364
     */
365
    public static function display_tracking_user_overview()
366
    {
367
        self::display_user_overview_export_options();
368
369
        $params = ['view' => 'admin', 'display' => 'user'];
370
        $table = new SortableTable(
371
            'tracking_user_overview',
372
            ['MySpace', 'get_number_of_users_tracking_overview'],
373
            ['MySpace', 'get_user_data_tracking_overview'],
374
            0,
375
            20,
376
            'ASC',
377
            null, [
378
                'class' => 'table table-transparent',
379
            ]
380
        );
381
        $table->additional_parameters = $params;
382
383
        $table->set_column_filter(0, ['MySpace', 'returnTrackingUserOverviewFilter']);
384
        $tableContent = $table->return_table();
385
        $tpl = new Template('', false, false, false, false, false, false);
386
        $tpl->assign('table', $tableContent);
387
        $templateName = $tpl->get_template('my_space/user_summary.tpl');
388
        $tpl->display($templateName);
389
    }
390
391
    /**
392
     * @param $export_csv
393
     */
394
    public static function display_tracking_coach_overview($export_csv)
395
    {
396
        if ($export_csv) {
397
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
398
        } else {
399
            $is_western_name_order = api_is_western_name_order();
400
        }
401
        $sort_by_first_name = api_sort_by_first_name();
402
403
        if (isset($_GET['tracking_list_coaches_column'])) {
404
            $tracking_column = (int) $_GET['tracking_list_coaches_column'];
405
        } else {
406
            $tracking_column = ($is_western_name_order xor $sort_by_first_name) ? 1 : 0;
407
        }
408
409
        $tracking_direction = (isset($_GET['tracking_list_coaches_direction']) && in_array(strtoupper($_GET['tracking_list_coaches_direction']), ['ASC', 'DESC', 'ASCENDING', 'DESCENDING', '0', '1'])) ? $_GET['tracking_list_coaches_direction'] : 'DESC';
410
        // Prepare array for column order - when impossible, use some of user names.
411
        if ($is_western_name_order) {
412
            $order = [
413
                0 => 'firstname',
414
                1 => 'lastname',
415
                2 => $sort_by_first_name ? 'firstname' : 'lastname',
416
                3 => 'login_date',
417
                4 => $sort_by_first_name ? 'firstname' : 'lastname',
418
                5 => $sort_by_first_name ? 'firstname' : 'lastname',
419
            ];
420
        } else {
421
            $order = [
422
                0 => 'lastname',
423
                1 => 'firstname',
424
                2 => $sort_by_first_name ? 'firstname' : 'lastname',
425
                3 => 'login_date',
426
                4 => $sort_by_first_name ? 'firstname' : 'lastname',
427
                5 => $sort_by_first_name ? 'firstname' : 'lastname',
428
            ];
429
        }
430
        $table = new SortableTable(
431
            'tracking_list_coaches_myspace',
432
            ['MySpace', 'count_coaches'],
433
            null,
434
            ($is_western_name_order xor $sort_by_first_name) ? 1 : 0
435
        );
436
        $parameters['view'] = 'admin';
437
        $table->set_additional_parameters($parameters);
438
        if ($is_western_name_order) {
439
            $table->set_header(0, get_lang('FirstName'), true);
440
            $table->set_header(1, get_lang('LastName'), true);
441
        } else {
442
            $table->set_header(0, get_lang('LastName'), true);
443
            $table->set_header(1, get_lang('FirstName'), true);
444
        }
445
        $table->set_header(2, get_lang('TimeSpentOnThePlatform'), false);
446
        $table->set_header(3, get_lang('LastConnexion'), false);
447
        $table->set_header(4, get_lang('NbStudents'), false);
448
        $table->set_header(5, get_lang('CountCours'), false);
449
        $table->set_header(6, get_lang('NumberOfSessions'), false);
450
        $table->set_header(7, get_lang('Sessions'), false);
451
452
        if ($is_western_name_order) {
453
            $csv_header[] = [
454
                get_lang('FirstName'),
455
                get_lang('LastName'),
456
                get_lang('TimeSpentOnThePlatform'),
457
                get_lang('LastConnexion'),
458
                get_lang('NbStudents'),
459
                get_lang('CountCours'),
460
                get_lang('NumberOfSessions'),
461
            ];
462
        } else {
463
            $csv_header[] = [
464
                get_lang('LastName'),
465
                get_lang('FirstName'),
466
                get_lang('TimeSpentOnThePlatform'),
467
                get_lang('LastConnexion'),
468
                get_lang('NbStudents'),
469
                get_lang('CountCours'),
470
                get_lang('NumberOfSessions'),
471
            ];
472
        }
473
474
        $tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
475
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
476
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
477
        $tbl_sessions = Database::get_main_table(TABLE_MAIN_SESSION);
478
479
        $sqlCoachs = "SELECT DISTINCT
480
                        scu.user_id as id_coach,
481
                        u.id as user_id,
482
                        lastname,
483
                        firstname,
484
                        MAX(login_date) as login_date
485
                        FROM $tbl_user u, $tbl_session_course_user scu, $tbl_track_login
486
                        WHERE
487
                            scu.user_id = u.id AND scu.status=2 AND login_user_id=u.id
488
                        GROUP BY user_id ";
489
490
        if (api_is_multiple_url_enabled()) {
491
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
492
            $access_url_id = api_get_current_access_url_id();
493
            if (-1 != $access_url_id) {
494
                $sqlCoachs = "SELECT DISTINCT
495
                                    scu.user_id as id_coach,
496
                                    u.id as user_id,
497
                                    lastname,
498
                                    firstname,
499
                                    MAX(login_date) as login_date
500
                                FROM $tbl_user u,
501
                                $tbl_session_course_user scu,
502
                                $tbl_track_login ,
503
                                $tbl_session_rel_access_url session_rel_url
504
                                WHERE
505
                                    scu.user_id = u.id AND
506
                                    scu.status = 2 AND
507
                                    login_user_id = u.id AND
508
                                    access_url_id = $access_url_id AND
509
                                    session_rel_url.session_id = scu.session_id
510
                                GROUP BY u.id";
511
            }
512
        }
513
        if (!empty($order[$tracking_column])) {
514
            $sqlCoachs .= ' ORDER BY '.$order[$tracking_column].' '.$tracking_direction;
515
        }
516
517
        $result_coaches = Database::query($sqlCoachs);
518
        $global_coaches = [];
519
        while ($coach = Database::fetch_array($result_coaches)) {
520
            $global_coaches[$coach['user_id']] = $coach;
521
        }
522
523
        $sql_session_coach = "SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
524
                                FROM $tbl_user u , $tbl_sessions as session, $tbl_track_login
525
                                WHERE id_coach = u.id AND login_user_id = u.id
526
                                GROUP BY u.id
527
                                ORDER BY login_date $tracking_direction";
528
529
        if (api_is_multiple_url_enabled()) {
530
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
531
            $access_url_id = api_get_current_access_url_id();
532
            if ($access_url_id != -1) {
533
                $sql_session_coach = "SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
534
					FROM $tbl_user u , $tbl_sessions as session, $tbl_track_login , $tbl_session_rel_access_url as session_rel_url
535
					WHERE
536
					    id_coach = u.id AND
537
					    login_user_id = u.id  AND
538
					    access_url_id = $access_url_id AND
539
					    session_rel_url.session_id = session.id
540
					GROUP BY  u.id
541
					ORDER BY login_date $tracking_direction";
542
            }
543
        }
544
545
        $result_sessions_coach = Database::query($sql_session_coach);
546
        //$total_no_coaches += Database::num_rows($result_sessions_coach);
547
        while ($coach = Database::fetch_array($result_sessions_coach)) {
548
            $global_coaches[$coach['user_id']] = $coach;
549
        }
550
551
        $all_datas = [];
552
        foreach ($global_coaches as $id_coach => $coaches) {
553
            $time_on_platform = api_time_to_hms(
554
                Tracking::get_time_spent_on_the_platform($coaches['user_id'])
555
            );
556
            $last_connection = Tracking::get_last_connection_date(
557
                $coaches['user_id']
558
            );
559
            $nb_students = count(
560
                Tracking::get_student_followed_by_coach($coaches['user_id'])
561
            );
562
            $nb_courses = count(
563
                Tracking::get_courses_followed_by_coach($coaches['user_id'])
564
            );
565
            $nb_sessions = count(
566
                Tracking::get_sessions_coached_by_user($coaches['user_id'])
567
            );
568
569
            $table_row = [];
570
            if ($is_western_name_order) {
571
                $table_row[] = $coaches['firstname'];
572
                $table_row[] = $coaches['lastname'];
573
            } else {
574
                $table_row[] = $coaches['lastname'];
575
                $table_row[] = $coaches['firstname'];
576
            }
577
            $table_row[] = $time_on_platform;
578
            $table_row[] = $last_connection;
579
            $table_row[] = $nb_students;
580
            $table_row[] = $nb_courses;
581
            $table_row[] = $nb_sessions;
582
            $table_row[] = '<a href="session.php?id_coach='.$coaches['user_id'].'">
583
                '.Display::return_icon('2rightarrow.png', get_lang('Details')).'
584
            </a>';
585
            $all_datas[] = $table_row;
586
587
            if ($is_western_name_order) {
588
                $csv_content[] = [
589
                    api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
590
                    api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
591
                    $time_on_platform,
592
                    $last_connection,
593
                    $nb_students,
594
                    $nb_courses,
595
                    $nb_sessions,
596
                ];
597
            } else {
598
                $csv_content[] = [
599
                    api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
600
                    api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
601
                    $time_on_platform,
602
                    $last_connection,
603
                    $nb_students,
604
                    $nb_courses,
605
                    $nb_sessions,
606
                ];
607
            }
608
        }
609
610
        if ($tracking_column != 3) {
611
            if ($tracking_direction == 'DESC') {
612
                usort($all_datas, ['MySpace', 'rsort_users']);
613
            } else {
614
                usort($all_datas, ['MySpace', 'sort_users']);
615
            }
616
        }
617
618
        if ($export_csv && $tracking_column != 3) {
619
            usort($csv_content, 'sort_users');
620
        }
621
        if ($export_csv) {
622
            $csv_content = array_merge($csv_header, $csv_content);
623
        }
624
625
        foreach ($all_datas as $row) {
626
            $table->addRow($row, 'align="right"');
627
        }
628
        $table->display();
629
    }
630
631
    /**
632
     * @return mixed
633
     */
634
    public static function count_coaches()
635
    {
636
        global $total_no_coaches;
637
638
        return $total_no_coaches;
639
    }
640
641
    public static function sort_users($a, $b)
642
    {
643
        $tracking = Session::read('tracking_column');
644
645
        return api_strcmp(
646
            trim(api_strtolower($a[$tracking])),
647
            trim(api_strtolower($b[$tracking]))
648
        );
649
    }
650
651
    public static function rsort_users($a, $b)
652
    {
653
        $tracking = Session::read('tracking_column');
654
655
        return api_strcmp(
656
            trim(api_strtolower($b[$tracking])),
657
            trim(api_strtolower($a[$tracking]))
658
        );
659
    }
660
661
    /**
662
     * Display a sortable table that contains an overview off all the progress of the user in a session.
663
     *
664
     * @deprecated ?
665
     *
666
     * @author César Perales <[email protected]>, Beeznest Team
667
     */
668
    public static function display_tracking_lp_progress_overview(
669
        $sessionId = '',
670
        $courseId = '',
671
        $date_from,
672
        $date_to
673
    ) {
674
        $course = api_get_course_info_by_id($courseId);
675
        /**
676
         * Column name
677
         * The order is important you need to check the $column variable in the model.ajax.php file.
678
         */
679
        $columns = [
680
            get_lang('Username'),
681
            get_lang('FirstName'),
682
            get_lang('LastName'),
683
        ];
684
        //add lessons of course
685
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
686
687
        //create columns array
688
        foreach ($lessons as $lesson_id => $lesson) {
689
            $columns[] = $lesson['name'];
690
        }
691
692
        $columns[] = get_lang('Total');
693
694
        /**
695
         * Column config.
696
         */
697
        $column_model = [
698
            [
699
                'name' => 'username',
700
                'index' => 'username',
701
                'align' => 'left',
702
                'search' => 'true',
703
                'wrap_cell' => "true",
704
            ],
705
            [
706
                'name' => 'firstname',
707
                'index' => 'firstname',
708
                'align' => 'left',
709
                'search' => 'true',
710
            ],
711
            [
712
                'name' => 'lastname',
713
                'index' => 'lastname',
714
                'align' => 'left',
715
                'search' => 'true',
716
            ],
717
        ];
718
719
        // Get dinamic column names
720
        foreach ($lessons as $lesson_id => $lesson) {
721
            $column_model[] = [
722
                'name' => $lesson['id'],
723
                'index' => $lesson['id'],
724
                'align' => 'left',
725
                'search' => 'true',
726
            ];
727
        }
728
729
        $column_model[] = [
730
            'name' => 'total',
731
            'index' => 'total',
732
            'align' => 'left',
733
            'search' => 'true',
734
        ];
735
736
        $action_links = '';
737
        // jqgrid will use this URL to do the selects
738
        $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_lp_progress&session_id='.$sessionId.'&course_id='.$courseId.'&date_to='.$date_to.'&date_from='.$date_from;
739
740
        // Table Id
741
        $tableId = 'lpProgress';
742
743
        // Autowidth
744
        $extra_params['autowidth'] = 'true';
745
746
        // height auto
747
        $extra_params['height'] = 'auto';
748
749
        $table = Display::grid_js(
750
            $tableId,
751
            $url,
752
            $columns,
753
            $column_model,
754
            $extra_params,
755
            [],
756
            $action_links,
757
            true
758
        );
759
760
        $return = '<script>$(function() {'.$table.
761
            'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
762
                jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
763
                       caption:"",
764
                       title:"'.get_lang('ExportExcel').'",
765
                       onClickButton : function () {
766
                           jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
767
                       }
768
                });
769
            });</script>';
770
        $return .= Display::grid_html($tableId);
771
772
        return $return;
773
    }
774
775
    /**
776
     * Display a sortable table that contains an overview off all the progress of the user in a session.
777
     *
778
     * @param int $sessionId  The session ID
779
     * @param int $courseId   The course ID
780
     * @param int $exerciseId The quiz ID
781
     * @param     $date_from
782
     * @param     $date_to
783
     *
784
     * @return string HTML array of results formatted for gridJS
785
     *
786
     * @deprecated ?
787
     *
788
     * @author César Perales <[email protected]>, Beeznest Team
789
     */
790
    public static function display_tracking_exercise_progress_overview(
791
        $sessionId = 0,
792
        $courseId = 0,
793
        $exerciseId = 0,
794
        $date_from = null,
795
        $date_to = null
796
    ) {
797
        $date_from = Security::remove_XSS($date_from);
798
        $date_to = Security::remove_XSS($date_to);
799
        /**
800
         * Column names
801
         * The column order is important. Check $column variable in the main/inc/ajax/model.ajax.php file.
802
         */
803
        $columns = [
804
            get_lang('Session'),
805
            get_lang('ExerciseId'),
806
            get_lang('ExerciseName'),
807
            get_lang('Username'),
808
            get_lang('LastName'),
809
            get_lang('FirstName'),
810
            get_lang('Time'),
811
            get_lang('QuestionId'),
812
            get_lang('QuestionTitle'),
813
            get_lang('WorkDescription'),
814
            get_lang('Answer'),
815
            get_lang('Correct'),
816
        ];
817
818
        /**
819
         * Column config.
820
         */
821
        $column_model = [
822
            ['name' => 'session', 'index' => 'session', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
823
            ['name' => 'exercise_id', 'index' => 'exercise_id', 'align' => 'left', 'search' => 'true'],
824
            ['name' => 'quiz_title', 'index' => 'quiz_title', 'align' => 'left', 'search' => 'true'],
825
            ['name' => 'username', 'index' => 'username', 'align' => 'left', 'search' => 'true'],
826
            ['name' => 'lastname', 'index' => 'lastname', 'align' => 'left', 'search' => 'true'],
827
            ['name' => 'firstname', 'index' => 'firstname', 'align' => 'left', 'search' => 'true'],
828
            ['name' => 'time', 'index' => 'time', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
829
            ['name' => 'question_id', 'index' => 'question_id', 'align' => 'left', 'search' => 'true'],
830
            ['name' => 'question', 'index' => 'question', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
831
            ['name' => 'description', 'index' => 'description', 'align' => 'left', 'width' => '550', 'search' => 'true', 'wrap_cell' => "true"],
832
            ['name' => 'answer', 'index' => 'answer', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
833
            ['name' => 'correct', 'index' => 'correct', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
834
        ];
835
        //get dynamic column names
836
837
        // jqgrid will use this URL to do the selects
838
        $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_progress&session_id='.$sessionId.'&course_id='.$courseId.'&exercise_id='.$exerciseId.'&date_to='.$date_to.'&date_from='.$date_from;
839
840
        // Autowidth
841
        $extra_params['autowidth'] = 'true';
842
843
        // height auto
844
        $extra_params['height'] = 'auto';
845
846
        $tableId = 'exerciseProgressOverview';
847
        $table = Display::grid_js(
848
            $tableId,
849
            $url,
850
            $columns,
851
            $column_model,
852
            $extra_params,
853
            [],
854
            '',
855
            true
856
        );
857
858
        $return = '<script>$(function() {'.$table.
859
            'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
860
                jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
861
                       caption:"",
862
                       title:"'.get_lang('ExportExcel').'",
863
                       onClickButton : function () {
864
                           jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
865
                       }
866
                });
867
            });</script>';
868
        $return .= Display::grid_html($tableId);
869
870
        return $return;
871
    }
872
873
    /**
874
     * Displays a form with all the additionally defined user fields of the profile
875
     * and give you the opportunity to include these in the CSV export.
876
     *
877
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
878
     *
879
     * @version 1.8.6
880
     *
881
     * @since November 2008
882
     */
883
    public static function display_user_overview_export_options()
884
    {
885
        $message = '';
886
        $defaults = [];
887
        // include the user manager and formvalidator library
888
        if (isset($_GET['export']) && 'options' == $_GET['export']) {
889
            // get all the defined extra fields
890
            $extrafields = UserManager::get_extra_fields(
891
                0,
892
                50,
893
                5,
894
                'ASC',
895
                false,
896
                1
897
            );
898
899
            // creating the form with all the defined extra fields
900
            $form = new FormValidator(
901
                'exportextrafields',
902
                'post',
903
                api_get_self()."?view=".Security::remove_XSS($_GET['view']).'&display='.Security::remove_XSS($_GET['display']).'&export='.Security::remove_XSS($_GET['export'])
904
            );
905
906
            if (is_array($extrafields) && count($extrafields) > 0) {
907
                foreach ($extrafields as $key => $extra) {
908
                    $form->addElement('checkbox', 'extra_export_field'.$extra[0], '', $extra[3]);
909
                }
910
                $form->addButtonSave(get_lang('Ok'), 'submit');
911
912
                // setting the default values for the form that contains all the extra fields
913
                $exportFields = Session::read('additional_export_fields');
914
                if (is_array($exportFields)) {
915
                    foreach ($exportFields as $key => $value) {
916
                        $defaults['extra_export_field'.$value] = 1;
917
                    }
918
                }
919
                $form->setDefaults($defaults);
920
            } else {
921
                $form->addElement('html', Display::return_message(get_lang('ThereAreNotExtrafieldsAvailable'), 'warning'));
922
            }
923
924
            if ($form->validate()) {
925
                // exporting the form values
926
                $values = $form->exportValues();
927
928
                // re-initialising the session that contains the additional fields that need to be exported
929
                Session::write('additional_export_fields', []);
930
931
                // adding the fields that are checked to the session
932
                $message = '';
933
                $additionalExportFields = [];
934
                foreach ($values as $field_ids => $value) {
935
                    if ($value == 1 && strstr($field_ids, 'extra_export_field')) {
936
                        $additionalExportFields[] = str_replace('extra_export_field', '', $field_ids);
937
                    }
938
                }
939
                Session::write('additional_export_fields', $additionalExportFields);
940
941
                // adding the fields that will be also exported to a message string
942
                $additionalExportFields = Session::read('additional_export_fields');
943
                if (is_array($additionalExportFields)) {
944
                    foreach ($additionalExportFields as $key => $extra_field_export) {
945
                        $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
946
                    }
947
                }
948
949
                // Displaying a feedback message
950
                if (!empty($additionalExportFields)) {
951
                    echo Display::return_message(
952
                        get_lang('FollowingFieldsWillAlsoBeExported').': <br /><ul>'.$message.'</ul>',
953
                        'confirm',
954
                        false
955
                    );
956
                } else {
957
                    echo Display::return_message(
958
                        get_lang('NoAdditionalFieldsWillBeExported'),
959
                        'confirm',
960
                        false
961
                    );
962
                }
963
            } else {
964
                $form->display();
965
            }
966
        } else {
967
            $additionalExportFields = Session::read('additional_export_fields');
968
            if (!empty($additionalExportFields)) {
969
                // get all the defined extra fields
970
                $extrafields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
971
972
                foreach ($additionalExportFields as $key => $extra_field_export) {
973
                    $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
974
                }
975
976
                echo Display::return_message(
977
                    get_lang('FollowingFieldsWillAlsoBeExported').': <br /><ul>'.$message.'</ul>',
978
                    'normal',
979
                    false
980
                );
981
            }
982
        }
983
    }
984
985
    /**
986
     * Display a sortable table that contains an overview of all the reporting progress of all courses.
987
     */
988
    public static function display_tracking_course_overview()
989
    {
990
        $params = ['view' => 'admin', 'display' => 'courseoverview'];
991
        $table = new SortableTable(
992
            'tracking_session_overview',
993
            ['MySpace', 'get_total_number_courses'],
994
            ['MySpace', 'get_course_data_tracking_overview'],
995
            1,
996
            20,
997
            'ASC',
998
            null, [
999
                'class' => 'table table-transparent',
1000
            ]
1001
        );
1002
        $table->additional_parameters = $params;
1003
        $table->set_column_filter(0, ['MySpace', 'course_tracking_filter']);
1004
        $tableContent = $table->return_table();
1005
1006
        $tpl = new Template('', false, false, false, false, false, false);
1007
        $tpl->assign('table', $tableContent);
1008
        $templateName = $tpl->get_template('my_space/course_summary.tpl');
1009
        $tpl->display($templateName);
1010
    }
1011
1012
    /**
1013
     * Get the total number of courses.
1014
     *
1015
     * @return int Total number of courses
1016
     */
1017
    public static function get_total_number_courses()
1018
    {
1019
        return CourseManager::count_courses(api_get_current_access_url_id());
1020
    }
1021
1022
    /**
1023
     * Get data for the courses.
1024
     *
1025
     * @param int    $from        Inferior limit
1026
     * @param int    $numberItems Number of items to select
1027
     * @param string $column      Column to order on
1028
     * @param string $direction   Order direction
1029
     *
1030
     * @return array Results
1031
     */
1032
    public static function get_course_data_tracking_overview(
1033
        $from,
1034
        $numberItems,
1035
        $column,
1036
        $direction
1037
    ) {
1038
        $courses = CourseManager::get_courses_list(
1039
            $from,
1040
            $numberItems,
1041
            $column,
1042
            $direction,
1043
             -1,
1044
            '',
1045
            api_get_current_access_url_id()
1046
        );
1047
1048
        $list = [];
1049
        foreach ($courses as $course) {
1050
            $list[] = [
1051
                '0' => $course['code'],
1052
                'col0' => $course['code'],
1053
            ];
1054
        }
1055
1056
        return $list;
1057
    }
1058
1059
    /**
1060
     * Fills in course reporting data.
1061
     *
1062
     * @param int course code
1063
     * @param array $url_params additional url parameters
1064
     * @param array $row        the row information (the other columns)
1065
     *
1066
     * @return string html code
1067
     */
1068
    public static function course_tracking_filter($course_code, $url_params, $row)
1069
    {
1070
        $course_code = $row[0];
1071
        $courseInfo = api_get_course_info($course_code);
1072
        $courseId = $courseInfo['real_id'];
1073
1074
        $tpl = new Template('', false, false, false, false, false, false);
1075
        $data = null;
1076
1077
        // database table definition
1078
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1079
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1080
1081
        // getting all the courses of the user
1082
        $sql = "SELECT *
1083
                FROM $tbl_user AS u
1084
                INNER JOIN $tbl_course_rel_user AS cu
1085
                ON cu.user_id = u.user_id
1086
                WHERE cu.c_id = '".$courseId."'";
1087
        $result = Database::query($sql);
1088
        $time_spent = 0;
1089
        $progress = 0;
1090
        $nb_progress_lp = 0;
1091
        $score = 0;
1092
        $nb_score_lp = 0;
1093
        $nb_messages = 0;
1094
        $nb_assignments = 0;
1095
        $last_login_date = false;
1096
        $total_score_obtained = 0;
1097
        $total_score_possible = 0;
1098
        $total_questions_answered = 0;
1099
        while ($row = Database::fetch_object($result)) {
1100
            // get time spent in the course and session
1101
            $time_spent += Tracking::get_time_spent_on_the_course(
1102
                $row->user_id,
1103
                $courseInfo['real_id']
1104
            );
1105
            $progress_tmp = Tracking::get_avg_student_progress(
1106
                $row->user_id,
1107
                $course_code,
1108
                [],
1109
                null,
1110
                true
1111
            );
1112
            $progress += $progress_tmp[0];
1113
            $nb_progress_lp += $progress_tmp[1];
1114
            $score_tmp = Tracking::get_avg_student_score(
1115
                $row->user_id,
1116
                $course_code,
1117
                [],
1118
                null,
1119
                true
1120
            );
1121
            if (is_array($score_tmp)) {
1122
                $score += $score_tmp[0];
1123
                $nb_score_lp += $score_tmp[1];
1124
            }
1125
            $nb_messages += Tracking::count_student_messages(
1126
                $row->user_id,
1127
                $course_code
1128
            );
1129
            $nb_assignments += Tracking::count_student_assignments(
1130
                $row->user_id,
1131
                $course_code
1132
            );
1133
            $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
1134
                $row->user_id,
1135
                $courseInfo,
1136
                null,
1137
                false
1138
            );
1139
            if ($last_login_date_tmp != false &&
1140
                $last_login_date == false
1141
            ) { // TODO: To be cleaned
1142
                $last_login_date = $last_login_date_tmp;
1143
            } elseif ($last_login_date_tmp != false && $last_login_date != false) {
1144
                // TODO: Repeated previous condition. To be cleaned.
1145
                // Find the max and assign it to first_login_date
1146
                if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1147
                    $last_login_date = $last_login_date_tmp;
1148
                }
1149
            }
1150
1151
            $exercise_results_tmp = self::exercises_results($row->user_id, $course_code);
1152
            $total_score_obtained += $exercise_results_tmp['score_obtained'];
1153
            $total_score_possible += $exercise_results_tmp['score_possible'];
1154
            $total_questions_answered += $exercise_results_tmp['questions_answered'];
1155
        }
1156
        if ($nb_progress_lp > 0) {
1157
            $avg_progress = round($progress / $nb_progress_lp, 2);
1158
        } else {
1159
            $avg_progress = 0;
1160
        }
1161
        if ($nb_score_lp > 0) {
1162
            $avg_score = round($score / $nb_score_lp, 2);
1163
        } else {
1164
            $avg_score = '-';
1165
        }
1166
        if ($last_login_date) {
1167
            $last_login_date = api_convert_and_format_date(
1168
                $last_login_date,
1169
                DATE_FORMAT_SHORT,
1170
                date_default_timezone_get()
1171
            );
1172
        } else {
1173
            $last_login_date = '-';
1174
        }
1175
        if ($total_score_possible > 0) {
1176
            $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1177
        } else {
1178
            $total_score_percentage = 0;
1179
        }
1180
        if ($total_score_percentage > 0) {
1181
            $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
1182
        } else {
1183
            $total_score = '-';
1184
        }
1185
1186
        $data = [
1187
            'course_code' => $course_code,
1188
            'id' => $courseId,
1189
            'image' => $courseInfo['course_image_large'],
1190
            'image_small' => $courseInfo['course_image'],
1191
            'title' => $courseInfo['title'],
1192
            'url' => $courseInfo['course_public_url'],
1193
            'category' => $courseInfo['categoryName'],
1194
            'time_spent' => api_time_to_hms($time_spent),
1195
            'avg_progress' => $avg_progress,
1196
            'avg_score' => $avg_score,
1197
            'number_message' => $nb_messages,
1198
            'number_assignments' => $nb_assignments,
1199
            'total_score' => $total_score,
1200
            'questions_answered' => $total_questions_answered,
1201
            'last_login' => $last_login_date,
1202
        ];
1203
1204
        $tpl->assign('data', $data);
1205
        $layout = $tpl->get_template('my_space/partials/tracking_course_overview.tpl');
1206
        $content = $tpl->fetch($layout);
1207
1208
        return $content;
1209
    }
1210
1211
    /**
1212
     * This function exports the table that we see in display_tracking_course_overview().
1213
     */
1214
    public static function export_tracking_course_overview()
1215
    {
1216
        // database table definition
1217
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1218
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1219
1220
        // the values of the sortable table
1221
        if ($_GET['tracking_course_overview_page_nr']) {
1222
            $from = $_GET['tracking_course_overview_page_nr'];
1223
        } else {
1224
            $from = 0;
1225
        }
1226
        if ($_GET['tracking_course_overview_column']) {
1227
            $orderby = $_GET['tracking_course_overview_column'];
1228
        } else {
1229
            $orderby = 0;
1230
        }
1231
1232
        if ($_GET['tracking_course_overview_direction']) {
1233
            $direction = $_GET['tracking_course_overview_direction'];
1234
        } else {
1235
            $direction = 'ASC';
1236
        }
1237
1238
        $course_data = self::get_course_data_tracking_overview(
1239
            $from,
1240
            1000,
1241
            $orderby,
1242
            $direction
1243
        );
1244
1245
        $csv_content = [];
1246
1247
        // the first line of the csv file with the column headers
1248
        $csv_row = [];
1249
        $csv_row[] = get_lang('Course');
1250
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse');
1251
        $csv_row[] = get_lang('AvgStudentsProgress');
1252
        $csv_row[] = get_lang('AvgCourseScore');
1253
        $csv_row[] = get_lang('TotalNumberOfMessages');
1254
        $csv_row[] = get_lang('TotalNumberOfAssignments');
1255
        $csv_row[] = get_lang('TotalExercisesScoreObtained');
1256
        $csv_row[] = get_lang('TotalExercisesScorePossible');
1257
        $csv_row[] = get_lang('TotalExercisesAnswered');
1258
        $csv_row[] = get_lang('TotalExercisesScorePercentage');
1259
        $csv_row[] = get_lang('LatestLogin');
1260
        $csv_content[] = $csv_row;
1261
1262
        // the other lines (the data)
1263
        foreach ($course_data as $key => $course) {
1264
            $course_code = $course[0];
1265
            $courseInfo = api_get_course_info($course_code);
1266
            $course_title = $courseInfo['title'];
1267
            $courseId = $courseInfo['real_id'];
1268
1269
            $csv_row = [];
1270
            $csv_row[] = $course_title;
1271
1272
            // getting all the courses of the session
1273
            $sql = "SELECT *
1274
                    FROM $tbl_user AS u
1275
                    INNER JOIN $tbl_course_rel_user AS cu
1276
                    ON cu.user_id = u.user_id
1277
                    WHERE cu.c_id = '".$courseId."'";
1278
            $result = Database::query($sql);
1279
            $time_spent = 0;
1280
            $progress = 0;
1281
            $nb_progress_lp = 0;
1282
            $score = 0;
1283
            $nb_score_lp = 0;
1284
            $nb_messages = 0;
1285
            $nb_assignments = 0;
1286
            $last_login_date = false;
1287
            $total_score_obtained = 0;
1288
            $total_score_possible = 0;
1289
            $total_questions_answered = 0;
1290
            while ($row = Database::fetch_object($result)) {
1291
                // get time spent in the course and session
1292
                $time_spent += Tracking::get_time_spent_on_the_course(
1293
                    $row->user_id,
1294
                    $courseId
1295
                );
1296
                $progress_tmp = Tracking::get_avg_student_progress(
1297
                    $row->user_id,
1298
                    $course_code,
1299
                    [],
1300
                    null,
1301
                    true
1302
                );
1303
                $progress += $progress_tmp[0];
1304
                $nb_progress_lp += $progress_tmp[1];
1305
                $score_tmp = Tracking::get_avg_student_score(
1306
                    $row->user_id,
1307
                    $course_code,
1308
                    [],
1309
                    null,
1310
                    true
1311
                );
1312
                if (is_array($score_tmp)) {
1313
                    $score += $score_tmp[0];
1314
                    $nb_score_lp += $score_tmp[1];
1315
                }
1316
                $nb_messages += Tracking::count_student_messages(
1317
                    $row->user_id,
1318
                    $course_code
1319
                );
1320
                $nb_assignments += Tracking::count_student_assignments(
1321
                    $row->user_id,
1322
                    $course_code
1323
                );
1324
1325
                $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
1326
                    $row->user_id,
1327
                    $courseInfo,
1328
                    null,
1329
                    false
1330
                );
1331
                if ($last_login_date_tmp != false && $last_login_date == false) {
1332
                    // TODO: To be cleaned.
1333
                    $last_login_date = $last_login_date_tmp;
1334
                } elseif ($last_login_date_tmp != false && $last_login_date == false) {
1335
                    // TODO: Repeated previous condition. To be cleaned.
1336
                    // Find the max and assign it to first_login_date
1337
                    if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1338
                        $last_login_date = $last_login_date_tmp;
1339
                    }
1340
                }
1341
1342
                $exercise_results_tmp = self::exercises_results($row->user_id, $course_code);
1343
                $total_score_obtained += $exercise_results_tmp['score_obtained'];
1344
                $total_score_possible += $exercise_results_tmp['score_possible'];
1345
                $total_questions_answered += $exercise_results_tmp['questions_answered'];
1346
            }
1347
            if ($nb_progress_lp > 0) {
1348
                $avg_progress = round($progress / $nb_progress_lp, 2);
1349
            } else {
1350
                $avg_progress = 0;
1351
            }
1352
            if ($nb_score_lp > 0) {
1353
                $avg_score = round($score / $nb_score_lp, 2);
1354
            } else {
1355
                $avg_score = '-';
1356
            }
1357
            if ($last_login_date) {
1358
                $last_login_date = api_convert_and_format_date(
1359
                    $last_login_date,
1360
                    DATE_FORMAT_SHORT,
1361
                    date_default_timezone_get()
1362
                );
1363
            } else {
1364
                $last_login_date = '-';
1365
            }
1366
            if ($total_score_possible > 0) {
1367
                $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1368
            } else {
1369
                $total_score_percentage = 0;
1370
            }
1371
            // time spent in the course
1372
            $csv_row[] = api_time_to_hms($time_spent);
1373
            // student progress in course
1374
            $csv_row[] = $avg_progress;
1375
            // student score
1376
            $csv_row[] = $avg_score;
1377
            // student messages
1378
            $csv_row[] = $nb_messages;
1379
            // student assignments
1380
            $csv_row[] = $nb_assignments;
1381
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
1382
            $csv_row[] = $total_score_obtained;
1383
            $csv_row[] = $total_score_possible;
1384
            $csv_row[] = $total_questions_answered;
1385
            $csv_row[] = $total_score_percentage;
1386
            // last connection
1387
            $csv_row[] = $last_login_date;
1388
            $csv_content[] = $csv_row;
1389
        }
1390
        Export::arrayToCsv($csv_content, 'reporting_course_overview');
1391
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1392
    }
1393
1394
    /**
1395
     * Display a sortable table that contains an overview of all the reporting
1396
     * progress of all sessions and all courses the user is subscribed to.
1397
     *
1398
     * @author Guillaume Viguier <[email protected]>
1399
     */
1400
    public static function display_tracking_session_overview()
1401
    {
1402
        $head = '<table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
1403
        $head .= '<tr>';
1404
        $head .= '<th width="155px" style="border-left:0;border-bottom:0"><span>'.get_lang('Course').'</span></th>';
1405
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgTimeSpentInTheCourse'), 6, true).'</span></th>';
1406
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgStudentsProgress'), 6, true).'</span></th>';
1407
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgCourseScore'), 6, true).'</span></th>';
1408
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfMessages'), 6, true).'</span></th>';
1409
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfAssignments'), 6, true).'</span></th>';
1410
        $head .= '<th width="105px" style="border-bottom:0"><span>'.get_lang('TotalExercisesScoreObtained').'</span></th>';
1411
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalExercisesAnswered'), 6, true).'</span></th>';
1412
        $head .= '<th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('LatestLogin').'</span></th>';
1413
        $head .= '</tr></table>';
1414
1415
        $params = ['view' => 'admin', 'display' => 'sessionoverview'];
1416
        $table = new SortableTable(
1417
            'tracking_session_overview',
1418
            ['MySpace', 'get_total_number_sessions'],
1419
            ['MySpace', 'get_session_data_tracking_overview'],
1420
            1
1421
        );
1422
        $table->additional_parameters = $params;
1423
1424
        $table->set_header(0, '', false, null, ['style' => 'display: none']);
1425
        $table->set_header(
1426
            1,
1427
            get_lang('Session'),
1428
            true,
1429
            ['style' => 'font-size:8pt'],
1430
            ['style' => 'font-size:8pt']
1431
        );
1432
        $table->set_header(
1433
            2,
1434
            $head,
1435
            false,
1436
            ['style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'],
1437
            ['style' => 'width:90%;padding:0;font-size:7.5pt;']
1438
        );
1439
        $table->set_column_filter(2, ['MySpace', 'session_tracking_filter']);
1440
        $table->display();
1441
    }
1442
1443
    /**
1444
     * Get the total number of sessions.
1445
     *
1446
     * @return int Total number of sessions
1447
     */
1448
    public static function get_total_number_sessions()
1449
    {
1450
        return SessionManager::count_sessions(api_get_current_access_url_id());
1451
    }
1452
1453
    /**
1454
     * Get data for the sessions.
1455
     *
1456
     * @param int    $from        Inferior limit
1457
     * @param int    $numberItems Number of items to select
1458
     * @param string $column      Column to order on
1459
     * @param string $direction   Order direction
1460
     *
1461
     * @return array Results
1462
     */
1463
    public static function get_session_data_tracking_overview(
1464
        $from,
1465
        $numberItems,
1466
        $column,
1467
        $direction
1468
    ) {
1469
        $from = (int) $from;
1470
        $numberItems = (int) $numberItems;
1471
        $direction = Database::escape_string($direction);
1472
        $columnName = 'name';
1473
        if ($column === 1) {
1474
            $columnName = 'id';
1475
        }
1476
1477
        $options = [
1478
            'order' => " $columnName $direction",
1479
            'limit' => " $from,$numberItems",
1480
        ];
1481
        $sessions = SessionManager::formatSessionsAdminForGrid($options);
1482
        $list = [];
1483
        foreach ($sessions as $session) {
1484
            $list[] = [
1485
                '0' => $session['id'],
1486
                'col0' => $session['id'],
1487
                '1' => strip_tags($session['name']),
1488
                'col1' => strip_tags($session['name']),
1489
            ];
1490
        }
1491
1492
        return $list;
1493
    }
1494
1495
    /**
1496
     * Fills in session reporting data.
1497
     *
1498
     * @param int   $session_id the id of the user
1499
     * @param array $url_params additonal url parameters
1500
     * @param array $row        the row information (the other columns)
1501
     *
1502
     * @return string html code
1503
     */
1504
    public static function session_tracking_filter($session_id, $url_params, $row)
1505
    {
1506
        $session_id = $row[0];
1507
        // the table header
1508
        $return = '<table class="data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
1509
1510
        // database table definition
1511
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1512
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
1513
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1514
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1515
1516
        // getting all the courses of the user
1517
        $sql = "SELECT * FROM $tbl_course AS c
1518
                INNER JOIN $tbl_session_rel_course AS sc
1519
                ON sc.c_id = c.id
1520
                WHERE sc.session_id = '".$session_id."'";
1521
        $result = Database::query($sql);
1522
        while ($row = Database::fetch_object($result)) {
1523
            $courseId = $row->c_id;
1524
            $courseInfo = api_get_course_info_by_id($courseId);
1525
            $return .= '<tr>';
1526
            // course code
1527
            $return .= '    <td width="157px" >'.$row->title.'</td>';
1528
            // get the users in the course
1529
            $sql = "SELECT u.user_id
1530
                    FROM $tbl_user AS u
1531
                    INNER JOIN $tbl_session_rel_course_rel_user AS scu
1532
                    ON u.user_id = scu.user_id
1533
                    WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
1534
            $result_users = Database::query($sql);
1535
            $time_spent = 0;
1536
            $progress = 0;
1537
            $nb_progress_lp = 0;
1538
            $score = 0;
1539
            $nb_score_lp = 0;
1540
            $nb_messages = 0;
1541
            $nb_assignments = 0;
1542
            $last_login_date = false;
1543
            $total_score_obtained = 0;
1544
            $total_score_possible = 0;
1545
            $total_questions_answered = 0;
1546
            while ($row_user = Database::fetch_object($result_users)) {
1547
                // get time spent in the course and session
1548
                $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
1549
                $progress_tmp = Tracking::get_avg_student_progress($row_user->user_id, $row->code, [], $session_id, true);
1550
                $progress += $progress_tmp[0];
1551
                $nb_progress_lp += $progress_tmp[1];
1552
                $score_tmp = Tracking::get_avg_student_score($row_user->user_id, $row->code, [], $session_id, true);
1553
                if (is_array($score_tmp)) {
1554
                    $score += $score_tmp[0];
1555
                    $nb_score_lp += $score_tmp[1];
1556
                }
1557
                $nb_messages += Tracking::count_student_messages($row_user->user_id, $row->code, $session_id);
1558
                $nb_assignments += Tracking::count_student_assignments($row_user->user_id, $row->code, $session_id);
1559
                $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
1560
                    $row_user->user_id,
1561
                    $courseInfo,
1562
                    $session_id,
1563
                    false
1564
                );
1565
                if ($last_login_date_tmp != false && $last_login_date == false) {
1566
                    // TODO: To be cleaned.
1567
                    $last_login_date = $last_login_date_tmp;
1568
                } elseif ($last_login_date_tmp != false && $last_login_date != false) {
1569
                    // TODO: Repeated previous condition! To be cleaned.
1570
                    // Find the max and assign it to first_login_date
1571
                    if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1572
                        $last_login_date = $last_login_date_tmp;
1573
                    }
1574
                }
1575
1576
                $exercise_results_tmp = self::exercises_results($row_user->user_id, $row->code, $session_id);
1577
                $total_score_obtained += $exercise_results_tmp['score_obtained'];
1578
                $total_score_possible += $exercise_results_tmp['score_possible'];
1579
                $total_questions_answered += $exercise_results_tmp['questions_answered'];
1580
            }
1581
            if ($nb_progress_lp > 0) {
1582
                $avg_progress = round($progress / $nb_progress_lp, 2);
1583
            } else {
1584
                $avg_progress = 0;
1585
            }
1586
            if ($nb_score_lp > 0) {
1587
                $avg_score = round($score / $nb_score_lp, 2);
1588
            } else {
1589
                $avg_score = '-';
1590
            }
1591
            if ($last_login_date) {
1592
                $last_login_date = api_convert_and_format_date(
1593
                    $last_login_date,
1594
                    DATE_FORMAT_SHORT,
1595
                    date_default_timezone_get()
1596
                );
1597
            } else {
1598
                $last_login_date = '-';
1599
            }
1600
            if ($total_score_possible > 0) {
1601
                $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1602
            } else {
1603
                $total_score_percentage = 0;
1604
            }
1605
            if ($total_score_percentage > 0) {
1606
                $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
1607
            } else {
1608
                $total_score = '-';
1609
            }
1610
            // time spent in the course
1611
            $return .= '    <td><div>'.api_time_to_hms($time_spent).'</div></td>';
1612
            // student progress in course
1613
            $return .= '    <td><div>'.$avg_progress.'</div></td>';
1614
            // student score
1615
            $return .= '    <td><div>'.$avg_score.'</div></td>';
1616
            // student messages
1617
            $return .= '    <td><div>'.$nb_messages.'</div></td>';
1618
            // student assignments
1619
            $return .= '    <td><div>'.$nb_assignments.'</div></td>';
1620
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
1621
            $return .= '<td width="105px;">'.$total_score.'</td>';
1622
            $return .= '<td>'.$total_questions_answered.'</td>';
1623
            // last connection
1624
            $return .= '    <td><div>'.$last_login_date.'</div></td>';
1625
            $return .= '<tr>';
1626
        }
1627
        $return .= '</table>';
1628
1629
        return $return;
1630
    }
1631
1632
    /**
1633
     * This function exports the table that we see in display_tracking_session_overview().
1634
     */
1635
    public static function export_tracking_session_overview()
1636
    {
1637
        // database table definition
1638
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1639
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
1640
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1641
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1642
1643
        // the values of the sortable table
1644
        $from = 0;
1645
        if ($_GET['tracking_session_overview_page_nr']) {
1646
            $from = $_GET['tracking_session_overview_page_nr'];
1647
        }
1648
1649
        $orderby = 0;
1650
        if ($_GET['tracking_session_overview_column']) {
1651
            $orderby = $_GET['tracking_session_overview_column'];
1652
        }
1653
1654
        $direction = 'ASC';
1655
        if ($_GET['tracking_session_overview_direction']) {
1656
            $direction = $_GET['tracking_session_overview_direction'];
1657
        }
1658
1659
        $session_data = self::get_session_data_tracking_overview($from, 1000, $orderby, $direction);
1660
1661
        $csv_content = [];
1662
1663
        // the first line of the csv file with the column headers
1664
        $csv_row = [];
1665
        $csv_row[] = get_lang('Session');
1666
        $csv_row[] = get_lang('Course');
1667
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse');
1668
        $csv_row[] = get_lang('AvgStudentsProgress');
1669
        $csv_row[] = get_lang('AvgCourseScore');
1670
        $csv_row[] = get_lang('TotalNumberOfMessages');
1671
        $csv_row[] = get_lang('TotalNumberOfAssignments');
1672
        $csv_row[] = get_lang('TotalExercisesScoreObtained');
1673
        $csv_row[] = get_lang('TotalExercisesScorePossible');
1674
        $csv_row[] = get_lang('TotalExercisesAnswered');
1675
        $csv_row[] = get_lang('TotalExercisesScorePercentage');
1676
        $csv_row[] = get_lang('LatestLogin');
1677
        $csv_content[] = $csv_row;
1678
1679
        // the other lines (the data)
1680
        foreach ($session_data as $key => $session) {
1681
            $session_id = $session[0];
1682
            $session_title = $session[1];
1683
1684
            // getting all the courses of the session
1685
            $sql = "SELECT * FROM $tbl_course AS c
1686
                    INNER JOIN $tbl_session_rel_course AS sc
1687
                    ON sc.c_id = c.id
1688
                    WHERE sc.session_id = '".$session_id."';";
1689
            $result = Database::query($sql);
1690
            while ($row = Database::fetch_object($result)) {
1691
                $courseId = $row->c_id;
1692
                $courseInfo = api_get_course_info_by_id($courseId);
1693
                $csv_row = [];
1694
                $csv_row[] = $session_title;
1695
                $csv_row[] = $row->title;
1696
                // get the users in the course
1697
                $sql = "SELECT scu.user_id
1698
                        FROM $tbl_user AS u
1699
                        INNER JOIN $tbl_session_rel_course_rel_user AS scu
1700
                        ON u.user_id = scu.user_id
1701
                        WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
1702
                $result_users = Database::query($sql);
1703
                $time_spent = 0;
1704
                $progress = 0;
1705
                $nb_progress_lp = 0;
1706
                $score = 0;
1707
                $nb_score_lp = 0;
1708
                $nb_messages = 0;
1709
                $nb_assignments = 0;
1710
                $last_login_date = false;
1711
                $total_score_obtained = 0;
1712
                $total_score_possible = 0;
1713
                $total_questions_answered = 0;
1714
                while ($row_user = Database::fetch_object($result_users)) {
1715
                    // get time spent in the course and session
1716
                    $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
1717
                    $progress_tmp = Tracking::get_avg_student_progress(
1718
                        $row_user->user_id,
1719
                        $row->code,
1720
                        [],
1721
                        $session_id,
1722
                        true
1723
                    );
1724
                    $progress += $progress_tmp[0];
1725
                    $nb_progress_lp += $progress_tmp[1];
1726
                    $score_tmp = Tracking::get_avg_student_score(
1727
                        $row_user->user_id,
1728
                        $row->code,
1729
                        [],
1730
                        $session_id,
1731
                        true
1732
                    );
1733
                    if (is_array($score_tmp)) {
1734
                        $score += $score_tmp[0];
1735
                        $nb_score_lp += $score_tmp[1];
1736
                    }
1737
                    $nb_messages += Tracking::count_student_messages(
1738
                        $row_user->user_id,
1739
                        $row->code,
1740
                        $session_id
1741
                    );
1742
1743
                    $nb_assignments += Tracking::count_student_assignments(
1744
                        $row_user->user_id,
1745
                        $row->code,
1746
                        $session_id
1747
                    );
1748
1749
                    $last_login_date_tmp = Tracking:: get_last_connection_date_on_the_course(
1750
                        $row_user->user_id,
1751
                        $courseInfo,
1752
                        $session_id,
1753
                        false
1754
                    );
1755
                    if ($last_login_date_tmp != false && $last_login_date == false) {
1756
                        // TODO: To be cleaned.
1757
                        $last_login_date = $last_login_date_tmp;
1758
                    } elseif ($last_login_date_tmp != false && $last_login_date == false) {
1759
                        // TODO: Repeated previous condition. To be cleaned.
1760
                        // Find the max and assign it to first_login_date
1761
                        if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1762
                            $last_login_date = $last_login_date_tmp;
1763
                        }
1764
                    }
1765
1766
                    $exercise_results_tmp = self::exercises_results($row_user->user_id, $row->code, $session_id);
1767
                    $total_score_obtained += $exercise_results_tmp['score_obtained'];
1768
                    $total_score_possible += $exercise_results_tmp['score_possible'];
1769
                    $total_questions_answered += $exercise_results_tmp['questions_answered'];
1770
                }
1771
                if ($nb_progress_lp > 0) {
1772
                    $avg_progress = round($progress / $nb_progress_lp, 2);
1773
                } else {
1774
                    $avg_progress = 0;
1775
                }
1776
                if ($nb_score_lp > 0) {
1777
                    $avg_score = round($score / $nb_score_lp, 2);
1778
                } else {
1779
                    $avg_score = '-';
1780
                }
1781
                if ($last_login_date) {
1782
                    $last_login_date = api_convert_and_format_date(
1783
                        $last_login_date,
1784
                        DATE_FORMAT_SHORT,
1785
                        date_default_timezone_get()
1786
                    );
1787
                } else {
1788
                    $last_login_date = '-';
1789
                }
1790
                if ($total_score_possible > 0) {
1791
                    $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1792
                } else {
1793
                    $total_score_percentage = 0;
1794
                }
1795
                if ($total_score_percentage > 0) {
1796
                    $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
1797
                } else {
1798
                    $total_score = '-';
1799
                }
1800
                // time spent in the course
1801
                $csv_row[] = api_time_to_hms($time_spent);
1802
                // student progress in course
1803
                $csv_row[] = $avg_progress;
1804
                // student score
1805
                $csv_row[] = $avg_score;
1806
                // student messages
1807
                $csv_row[] = $nb_messages;
1808
                // student assignments
1809
                $csv_row[] = $nb_assignments;
1810
                // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
1811
                $csv_row[] = $total_score_obtained;
1812
                $csv_row[] = $total_score_possible;
1813
                $csv_row[] = $total_questions_answered;
1814
                $csv_row[] = $total_score_percentage;
1815
                // last connection
1816
                $csv_row[] = $last_login_date;
1817
                $csv_content[] = $csv_row;
1818
            }
1819
        }
1820
        Export::arrayToCsv($csv_content, 'reporting_session_overview');
1821
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1822
    }
1823
1824
    /**
1825
     * Get general information about the exercise performance of the user
1826
     * the total obtained score (all the score on all the questions)
1827
     * the maximum score that could be obtained
1828
     * the number of questions answered
1829
     * the success percentage.
1830
     *
1831
     * @param int    $user_id     the id of the user
1832
     * @param string $course_code the course code
1833
     * @param int    $session_id
1834
     *
1835
     * @return array
1836
     *
1837
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
1838
     *
1839
     * @version Dokeos 1.8.6
1840
     *
1841
     * @since November 2008
1842
     */
1843
    public static function exercises_results($user_id, $course_code, $session_id = 0)
1844
    {
1845
        $user_id = (int) $user_id;
1846
        $courseId = api_get_course_int_id($course_code);
1847
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1848
1849
        $sql = "SELECT exe_result, exe_weighting
1850
                FROM $table
1851
                WHERE
1852
                    c_id = $courseId AND
1853
                    exe_user_id = $user_id";
1854
1855
        $session_id = (int) $session_id;
1856
        if (!empty($session_id)) {
1857
            $sql .= " AND session_id = '".$session_id."' ";
1858
        }
1859
        $result = Database::query($sql);
1860
        $score_obtained = 0;
1861
        $score_possible = 0;
1862
        $questions_answered = 0;
1863
        while ($row = Database::fetch_array($result)) {
1864
            $score_obtained += $row['exe_result'];
1865
            $score_possible += $row['exe_weighting'];
1866
            $questions_answered++;
1867
        }
1868
1869
        $percentage = null;
1870
        if ($score_possible != 0) {
1871
            $percentage = round(($score_obtained / $score_possible * 100), 2);
1872
        }
1873
1874
        return [
1875
            'score_obtained' => $score_obtained,
1876
            'score_possible' => $score_possible,
1877
            'questions_answered' => $questions_answered,
1878
            'percentage' => $percentage,
1879
        ];
1880
    }
1881
1882
    /**
1883
     * This function exports the table that we see in display_tracking_user_overview().
1884
     *
1885
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
1886
     *
1887
     * @version Dokeos 1.8.6
1888
     *
1889
     * @since October 2008
1890
     */
1891
    public static function export_tracking_user_overview()
1892
    {
1893
        // database table definitions
1894
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1895
        $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1896
1897
        // the values of the sortable table
1898
        if ($_GET['tracking_user_overview_page_nr']) {
1899
            $from = $_GET['tracking_user_overview_page_nr'];
1900
        } else {
1901
            $from = 0;
1902
        }
1903
        if ($_GET['tracking_user_overview_column']) {
1904
            $orderby = $_GET['tracking_user_overview_column'];
1905
        } else {
1906
            $orderby = 0;
1907
        }
1908
        if ($is_western_name_order != api_is_western_name_order() && ($orderby == 1 || $orderby == 2)) {
1909
            // Swapping the sorting column if name order for export is different than the common name order.
1910
            $orderby = 3 - $orderby;
1911
        }
1912
        if ($_GET['tracking_user_overview_direction']) {
1913
            $direction = $_GET['tracking_user_overview_direction'];
1914
        } else {
1915
            $direction = 'ASC';
1916
        }
1917
1918
        $user_data = self::get_user_data_tracking_overview(
1919
            $from,
1920
            1000,
1921
            $orderby,
1922
            $direction
1923
        );
1924
1925
        // the first line of the csv file with the column headers
1926
        $csv_row = [];
1927
        $csv_row[] = get_lang('OfficialCode');
1928
        if ($is_western_name_order) {
1929
            $csv_row[] = get_lang('FirstName');
1930
            $csv_row[] = get_lang('LastName');
1931
        } else {
1932
            $csv_row[] = get_lang('LastName');
1933
            $csv_row[] = get_lang('FirstName');
1934
        }
1935
        $csv_row[] = get_lang('LoginName');
1936
        $csv_row[] = get_lang('CourseCode');
1937
1938
        // the additional user defined fields (only those that were selected to be exported)
1939
        $fields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
1940
1941
        $additionalExportFields = Session::read('additional_export_fields');
1942
1943
        if (is_array($additionalExportFields)) {
1944
            foreach ($additionalExportFields as $key => $extra_field_export) {
1945
                $csv_row[] = $fields[$extra_field_export][3];
1946
                $field_names_to_be_exported[] = 'extra_'.$fields[$extra_field_export][1];
1947
            }
1948
        }
1949
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse', '');
1950
        $csv_row[] = get_lang('AvgStudentsProgress', '');
1951
        $csv_row[] = get_lang('AvgCourseScore', '');
1952
        $csv_row[] = get_lang('AvgExercisesScore', '');
1953
        $csv_row[] = get_lang('AvgMessages', '');
1954
        $csv_row[] = get_lang('AvgAssignments', '');
1955
        $csv_row[] = get_lang('TotalExercisesScoreObtained', '');
1956
        $csv_row[] = get_lang('TotalExercisesScorePossible', '');
1957
        $csv_row[] = get_lang('TotalExercisesAnswered', '');
1958
        $csv_row[] = get_lang('TotalExercisesScorePercentage', '');
1959
        $csv_row[] = get_lang('FirstLogin', '');
1960
        $csv_row[] = get_lang('LatestLogin', '');
1961
        $csv_content[] = $csv_row;
1962
1963
        // the other lines (the data)
1964
        foreach ($user_data as $key => $user) {
1965
            // getting all the courses of the user
1966
            $sql = "SELECT * FROM $tbl_course_user
1967
                    WHERE user_id = '".intval($user[4])."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
1968
            $result = Database::query($sql);
1969
            while ($row = Database::fetch_row($result)) {
1970
                $courseInfo = api_get_course_info($row['course_code']);
1971
                $courseId = $courseInfo['real_id'];
1972
1973
                $csv_row = [];
1974
                // user official code
1975
                $csv_row[] = $user[0];
1976
                // user first|last name
1977
                $csv_row[] = $user[1];
1978
                // user last|first name
1979
                $csv_row[] = $user[2];
1980
                // user login name
1981
                $csv_row[] = $user[3];
1982
                // course code
1983
                $csv_row[] = $row[0];
1984
                // the additional defined user fields
1985
                $extra_fields = self::get_user_overview_export_extra_fields($user[4]);
1986
1987
                if (is_array($field_names_to_be_exported)) {
1988
                    foreach ($field_names_to_be_exported as $key => $extra_field_export) {
1989
                        $csv_row[] = $extra_fields[$extra_field_export];
1990
                    }
1991
                }
1992
                // time spent in the course
1993
                $csv_row[] = api_time_to_hms(Tracking::get_time_spent_on_the_course($user[4], $courseId));
1994
                // student progress in course
1995
                $csv_row[] = round(Tracking::get_avg_student_progress($user[4], $row[0]), 2);
1996
                // student score
1997
                $csv_row[] = round(Tracking::get_avg_student_score($user[4], $row[0]), 2);
1998
                // student tes score
1999
                $csv_row[] = round(Tracking::get_avg_student_exercise_score($user[4], $row[0]), 2);
2000
                // student messages
2001
                $csv_row[] = Tracking::count_student_messages($user[4], $row[0]);
2002
                // student assignments
2003
                $csv_row[] = Tracking::count_student_assignments($user[4], $row[0]);
2004
                // student exercises results
2005
                $exercises_results = self::exercises_results($user[4], $row[0]);
2006
                $csv_row[] = $exercises_results['score_obtained'];
2007
                $csv_row[] = $exercises_results['score_possible'];
2008
                $csv_row[] = $exercises_results['questions_answered'];
2009
                $csv_row[] = $exercises_results['percentage'];
2010
                // first connection
2011
                $csv_row[] = Tracking::get_first_connection_date_on_the_course($user[4], $courseId);
2012
                // last connection
2013
                $csv_row[] = strip_tags(Tracking::get_last_connection_date_on_the_course($user[4], $courseInfo));
2014
2015
                $csv_content[] = $csv_row;
2016
            }
2017
        }
2018
        Export::arrayToCsv($csv_content, 'reporting_user_overview');
2019
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2020
    }
2021
2022
    /**
2023
     * Get data for courses list in sortable with pagination.
2024
     *
2025
     * @return array
2026
     */
2027
    public static function get_course_data($from, $number_of_items, $column, $direction)
2028
    {
2029
        global $courses, $csv_content, $charset, $session_id;
2030
2031
        // definition database tables
2032
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
2033
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2034
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2035
2036
        $course_data = [];
2037
        $courses_code = array_keys($courses);
2038
2039
        foreach ($courses_code as &$code) {
2040
            $code = "'$code'";
2041
        }
2042
2043
        // get all courses with limit
2044
        $sql = "SELECT course.code as col1, course.title as col2
2045
                FROM $tbl_course course
2046
                WHERE course.code IN (".implode(',', $courses_code).")";
2047
2048
        if (!in_array($direction, ['ASC', 'DESC'])) {
2049
            $direction = 'ASC';
2050
        }
2051
2052
        $column = intval($column);
2053
        $from = intval($from);
2054
        $number_of_items = intval($number_of_items);
2055
        $sql .= " ORDER BY col$column $direction ";
2056
        $sql .= " LIMIT $from,$number_of_items";
2057
2058
        $res = Database::query($sql);
2059
        while ($row_course = Database::fetch_row($res)) {
2060
            $course_code = $row_course[0];
2061
            $courseInfo = api_get_course_info($course_code);
2062
            $courseId = $courseInfo['real_id'];
2063
            $avg_assignments_in_course = $avg_messages_in_course = $nb_students_in_course = $avg_progress_in_course = $avg_score_in_course = $avg_time_spent_in_course = $avg_score_in_exercise = 0;
2064
2065
            // students directly subscribed to the course
2066
            if (empty($session_id)) {
2067
                $sql = "SELECT user_id
2068
                        FROM $tbl_course_user as course_rel_user
2069
                        WHERE
2070
                            course_rel_user.status='5' AND
2071
                            course_rel_user.c_id = '$courseId'";
2072
            } else {
2073
                $sql = "SELECT user_id FROM $tbl_session_course_user srcu
2074
                        WHERE
2075
                            c_id = '$courseId' AND
2076
                            session_id = '$session_id' AND
2077
                            status<>2";
2078
            }
2079
            $rs = Database::query($sql);
2080
            $users = [];
2081
            while ($row = Database::fetch_array($rs)) {
2082
                $users[] = $row['user_id'];
2083
            }
2084
2085
            if (count($users) > 0) {
2086
                $nb_students_in_course = count($users);
2087
                $avg_assignments_in_course = Tracking::count_student_assignments($users, $course_code, $session_id);
2088
                $avg_messages_in_course = Tracking::count_student_messages($users, $course_code, $session_id);
2089
                $avg_progress_in_course = Tracking::get_avg_student_progress($users, $course_code, [], $session_id);
2090
                $avg_score_in_course = Tracking::get_avg_student_score($users, $course_code, [], $session_id);
2091
                $avg_score_in_exercise = Tracking::get_avg_student_exercise_score($users, $course_code, 0, $session_id);
2092
                $avg_time_spent_in_course = Tracking::get_time_spent_on_the_course(
2093
                    $users,
2094
                    $courseInfo['real_id'],
2095
                    $session_id
2096
                );
2097
2098
                $avg_progress_in_course = round($avg_progress_in_course / $nb_students_in_course, 2);
2099
                if (is_numeric($avg_score_in_course)) {
2100
                    $avg_score_in_course = round($avg_score_in_course / $nb_students_in_course, 2);
2101
                }
2102
                $avg_time_spent_in_course = api_time_to_hms($avg_time_spent_in_course / $nb_students_in_course);
2103
            } else {
2104
                $avg_time_spent_in_course = null;
2105
                $avg_progress_in_course = null;
2106
                $avg_score_in_course = null;
2107
                $avg_score_in_exercise = null;
2108
                $avg_messages_in_course = null;
2109
                $avg_assignments_in_course = null;
2110
            }
2111
            $table_row = [];
2112
            $table_row[] = $row_course[1];
2113
            $table_row[] = $nb_students_in_course;
2114
            $table_row[] = $avg_time_spent_in_course;
2115
            $table_row[] = is_null($avg_progress_in_course) ? '' : $avg_progress_in_course.'%';
2116
            $table_row[] = is_null($avg_score_in_course) ? '' : $avg_score_in_course.'%';
2117
            $table_row[] = is_null($avg_score_in_exercise) ? '' : $avg_score_in_exercise.'%';
2118
            $table_row[] = $avg_messages_in_course;
2119
            $table_row[] = $avg_assignments_in_course;
2120
2121
            //set the "from" value to know if I access the Reporting by the chamilo tab or the course link
2122
            $table_row[] = '<center><a href="../../tracking/courseLog.php?cidReq='.$course_code.'&from=myspace&id_session='.$session_id.'">
2123
                             '.Display::return_icon('2rightarrow.png', get_lang('Details')).'
2124
                             </a>
2125
                            </center>';
2126
2127
            $scoreInCourse = null;
2128
            if (null !== $avg_score_in_course) {
2129
                if (is_numeric($avg_score_in_course)) {
2130
                    $scoreInCourse = $avg_score_in_course.'%';
2131
                } else {
2132
                    $scoreInCourse = $avg_score_in_course;
2133
                }
2134
            }
2135
2136
            $csv_content[] = [
2137
                api_html_entity_decode($row_course[1], ENT_QUOTES, $charset),
2138
                $nb_students_in_course,
2139
                $avg_time_spent_in_course,
2140
                is_null($avg_progress_in_course) ? null : $avg_progress_in_course.'%',
2141
                $scoreInCourse,
2142
                is_null($avg_score_in_exercise) ? null : $avg_score_in_exercise.'%',
2143
                $avg_messages_in_course,
2144
                $avg_assignments_in_course,
2145
            ];
2146
            $course_data[] = $table_row;
2147
        }
2148
2149
        return $course_data;
2150
    }
2151
2152
    /**
2153
     * Get the number of users of the platform.
2154
     *
2155
     * @return int
2156
     */
2157
    public static function get_number_of_users_tracking_overview()
2158
    {
2159
        return UserManager::get_number_of_users(0, api_get_current_access_url_id());
2160
    }
2161
2162
    /**
2163
     * Get all the data for the sortable table of the reporting progress of
2164
     * all users and all the courses the user is subscribed to.
2165
     *
2166
     * @param int    $from
2167
     * @param int    $numberItems
2168
     * @param int    $column
2169
     * @param string $direction
2170
     *
2171
     * @return array
2172
     */
2173
    public static function get_user_data_tracking_overview($from, $numberItems, $column, $direction)
2174
    {
2175
        $isWestern = api_is_western_name_order();
2176
2177
        switch ($column) {
2178
            case '0':
2179
                $column = $isWestern ? 'firstname' : 'lastname';
2180
                break;
2181
        }
2182
2183
        $order = [
2184
            "$column $direction",
2185
        ];
2186
        $userList = UserManager::get_user_list([], $order, $from, $numberItems);
2187
        $return = [];
2188
        foreach ($userList as $user) {
2189
            $return[] = [
2190
                '0' => $user['user_id'],
2191
                'col0' => $user['user_id'],
2192
            ];
2193
        }
2194
2195
        return $return;
2196
    }
2197
2198
    /**
2199
     * Get all information that the user with user_id = $user_data has
2200
     * entered in the additionally defined profile fields.
2201
     *
2202
     * @param int $user_id the id of the user
2203
     *
2204
     * @return array
2205
     *
2206
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
2207
     *
2208
     * @version Dokeos 1.8.6
2209
     *
2210
     * @since November 2008
2211
     */
2212
    public static function get_user_overview_export_extra_fields($user_id)
2213
    {
2214
        // include the user manager
2215
        $data = UserManager::get_extra_user_data($user_id, true);
2216
2217
        return $data;
2218
    }
2219
2220
    /**
2221
     * Checks if a username exist in the DB otherwise it create a "double"
2222
     * i.e. if we look into for jmontoya but the user's name already exist we create the user jmontoya2
2223
     * the return array will be array(username=>'jmontoya', sufix='2').
2224
     *
2225
     * @param string firstname
2226
     * @param string lastname
2227
     * @param string username
2228
     *
2229
     * @return array with the username, the sufix
2230
     *
2231
     * @author Julio Montoya
2232
     */
2233
    public static function make_username($firstname, $lastname, $username, $language = null, $encoding = null)
2234
    {
2235
        // if username exist
2236
        if (!UserManager::is_username_available($username) || empty($username)) {
2237
            $i = 0;
2238
            while (1) {
2239
                if ($i == 0) {
2240
                    $sufix = '';
2241
                } else {
2242
                    $sufix = $i;
2243
                }
2244
                $desired_username = UserManager::create_username(
2245
                    $firstname,
2246
                    $lastname
2247
                );
2248
                if (UserManager::is_username_available($desired_username.$sufix)) {
2249
                    break;
2250
                } else {
2251
                    $i++;
2252
                }
2253
            }
2254
            $username_array = ['username' => $desired_username, 'sufix' => $sufix];
2255
2256
            return $username_array;
2257
        } else {
2258
            $username_array = ['username' => $username, 'sufix' => ''];
2259
2260
            return $username_array;
2261
        }
2262
    }
2263
2264
    /**
2265
     * Checks if there are repeted users in a given array.
2266
     *
2267
     * @param array $usernames  list of the usernames in the uploaded file
2268
     * @param array $user_array $user_array['username'] and $user_array['sufix']
2269
     *                          where suffix is the number part in a login i.e -> jmontoya2
2270
     *
2271
     * @return array with the $usernames array and the $user_array array
2272
     *
2273
     * @author Julio Montoya
2274
     */
2275
    public static function check_user_in_array($usernames, $user_array)
2276
    {
2277
        $user_list = array_keys($usernames);
2278
        $username = $user_array['username'].$user_array['sufix'];
2279
2280
        if (in_array($username, $user_list)) {
2281
            $user_array['sufix'] += $usernames[$username];
2282
            $usernames[$username]++;
2283
        } else {
2284
            $usernames[$username] = 1;
2285
        }
2286
        $result_array = [$usernames, $user_array];
2287
2288
        return $result_array;
2289
    }
2290
2291
    /**
2292
     * Checks whether a username has been already subscribed in a session.
2293
     *
2294
     * @param string $username    a given username
2295
     * @param array  $course_list the array with the course list id
2296
     * @param int    $id_session  the session id
2297
     *
2298
     * @return int 0 if the user is not subscribed otherwise it returns the user_id of the given username
2299
     *
2300
     * @author Julio Montoya
2301
     */
2302
    public static function user_available_in_session($username, $course_list, $id_session)
2303
    {
2304
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2305
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2306
        $id_session = (int) $id_session;
2307
        $username = Database::escape_string($username);
2308
        foreach ($course_list as $courseId) {
2309
            $courseId = (int) $courseId;
2310
            $sql = " SELECT u.user_id FROM $tbl_session_rel_course_rel_user rel
2311
                     INNER JOIN $table_user u
2312
                     ON (rel.user_id = u.user_id)
2313
                     WHERE
2314
                        rel.session_id='$id_session' AND
2315
                        u.status='5' AND
2316
                        u.username ='$username' AND
2317
                        rel.c_id='$courseId'";
2318
            $rs = Database::query($sql);
2319
            if (Database::num_rows($rs) > 0) {
2320
                return Database::result($rs, 0, 0);
2321
            }
2322
        }
2323
2324
        return 0;
2325
    }
2326
2327
    /**
2328
     * This function checks whether some users in the uploaded file
2329
     * repeated and creates unique usernames if necesary.
2330
     * A case: Within the file there is an user repeted twice (Julio Montoya / Julio Montoya)
2331
     * and the username fields are empty.
2332
     * Then, this function would create unique usernames based on the first and the last name.
2333
     * Two users wiould be created - jmontoya and jmontoya2.
2334
     * Of course, if in the database there is a user with the name jmontoya,
2335
     * the newly created two users registered would be jmontoya2 and jmontoya3.
2336
     *
2337
     * @param $users list of users
2338
     *
2339
     * @return array
2340
     *
2341
     * @author Julio Montoya Armas
2342
     */
2343
    public static function check_all_usernames($users, $course_list, $id_session)
2344
    {
2345
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2346
        $usernames = [];
2347
        $new_users = [];
2348
        foreach ($users as $index => $user) {
2349
            $desired_username = [];
2350
            if (empty($user['UserName'])) {
2351
                $desired_username = self::make_username($user['FirstName'], $user['LastName'], '');
2352
                $pre_username = $desired_username['username'].$desired_username['sufix'];
2353
                $user['UserName'] = $pre_username;
2354
                $user['create'] = '1';
2355
            } else {
2356
                if (UserManager::is_username_available($user['UserName'])) {
2357
                    $desired_username = self::make_username($user['FirstName'], $user['LastName'], $user['UserName']);
2358
                    $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
2359
                    $user['create'] = '1';
2360
                } else {
2361
                    $is_session_avail = self::user_available_in_session($user['UserName'], $course_list, $id_session);
2362
                    if (0 == $is_session_avail) {
2363
                        $user_name = $user['UserName'];
2364
                        $sql_select = "SELECT user_id FROM $table_user WHERE username ='$user_name' ";
2365
                        $rs = Database::query($sql_select);
2366
                        $user['create'] = Database::result($rs, 0, 0);
2367
                    } else {
2368
                        $user['create'] = $is_session_avail;
2369
                    }
2370
                }
2371
            }
2372
            // Usernames is the current list of users in the file.
2373
            $result_array = self::check_user_in_array($usernames, $desired_username);
2374
            $usernames = $result_array[0];
2375
            $desired_username = $result_array[1];
2376
            $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
2377
            $new_users[] = $user;
2378
        }
2379
2380
        return $new_users;
2381
    }
2382
2383
    /**
2384
     * This functions checks whether there are users that are already
2385
     * registered in the DB by different creator than the current coach.
2386
     *
2387
     * @param array $users
2388
     *
2389
     * @return array
2390
     *
2391
     * @author Julio Montoya Armas
2392
     */
2393
    public static function get_user_creator($users)
2394
    {
2395
        $errors = [];
2396
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2397
        foreach ($users as $index => $user) {
2398
            $username = Database::escape_string($user['UserName']);
2399
            $sql = "SELECT creator_id FROM $table_user WHERE username='$username' ";
2400
2401
            $rs = Database::query($sql);
2402
            $creator_id = Database::result($rs, 0, 0);
2403
            // check if we are the creators or not
2404
            if ($creator_id != '') {
2405
                if ($creator_id != api_get_user_id()) {
2406
                    $user['error'] = get_lang('UserAlreadyRegisteredByOtherCreator');
2407
                    $errors[] = $user;
2408
                }
2409
            }
2410
        }
2411
2412
        return $errors;
2413
    }
2414
2415
    /**
2416
     * Validates imported data.
2417
     *
2418
     * @param array $users list of users
2419
     */
2420
    public static function validate_data($users, $id_session = null)
2421
    {
2422
        $errors = [];
2423
        $new_users = [];
2424
        foreach ($users as $index => $user) {
2425
            // 1. Check whether mandatory fields are set.
2426
            $mandatory_fields = ['LastName', 'FirstName'];
2427
            if (api_get_setting('registration', 'email') == 'true') {
2428
                $mandatory_fields[] = 'Email';
2429
            }
2430
2431
            foreach ($mandatory_fields as $key => $field) {
2432
                if (!isset($user[$field]) || strlen($user[$field]) == 0) {
2433
                    $user['error'] = get_lang($field.'Mandatory');
2434
                    $errors[] = $user;
2435
                }
2436
            }
2437
            // 2. Check whether the username is too long.
2438
            if (UserManager::is_username_too_long($user['UserName'])) {
2439
                $user['error'] = get_lang('UserNameTooLong');
2440
                $errors[] = $user;
2441
            }
2442
2443
            $user['UserName'] = trim($user['UserName']);
2444
2445
            if (empty($user['UserName'])) {
2446
                $user['UserName'] = UserManager::create_username($user['FirstName'], $user['LastName']);
2447
            }
2448
            $new_users[] = $user;
2449
        }
2450
        $results = ['errors' => $errors, 'users' => $new_users];
2451
2452
        return $results;
2453
    }
2454
2455
    /**
2456
     * Adds missing user-information (which isn't required, like password, etc).
2457
     */
2458
    public static function complete_missing_data($user)
2459
    {
2460
        // 1. Generate a password if it is necessary.
2461
        if (!isset($user['Password']) || strlen($user['Password']) == 0) {
2462
            $user['Password'] = api_generate_password();
2463
        }
2464
2465
        return $user;
2466
    }
2467
2468
    /**
2469
     * Saves imported data.
2470
     */
2471
    public static function save_data($users, $course_list, $id_session)
2472
    {
2473
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2474
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2475
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2476
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2477
2478
        $id_session = (int) $id_session;
2479
        $sendMail = $_POST['sendMail'] ? 1 : 0;
2480
2481
        // Adding users to the platform.
2482
        $new_users = [];
2483
        foreach ($users as $index => $user) {
2484
            $user = self::complete_missing_data($user);
2485
            // coach only will registered users
2486
            $default_status = STUDENT;
2487
            if ($user['create'] == COURSEMANAGER) {
2488
                $user['id'] = UserManager:: create_user(
2489
                    $user['FirstName'],
2490
                    $user['LastName'],
2491
                    $default_status,
2492
                    $user['Email'],
2493
                    $user['UserName'],
2494
                    $user['Password'],
2495
                    $user['OfficialCode'],
2496
                    api_get_setting('PlatformLanguage'),
2497
                    $user['PhoneNumber'],
2498
                    ''
2499
                );
2500
                $user['added_at_platform'] = 1;
2501
            } else {
2502
                $user['id'] = $user['create'];
2503
                $user['added_at_platform'] = 0;
2504
            }
2505
            $new_users[] = $user;
2506
        }
2507
        // Update user list.
2508
        $users = $new_users;
2509
2510
        // Inserting users.
2511
        foreach ($course_list as $enreg_course) {
2512
            $nbr_users = 0;
2513
            $new_users = [];
2514
            $enreg_course = Database::escape_string($enreg_course);
2515
            foreach ($users as $index => $user) {
2516
                $userid = (int) $user['id'];
2517
                $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user(session_id, c_id, user_id)
2518
                        VALUES('$id_session','$enreg_course','$userid')";
2519
                $result = Database::query($sql);
2520
                if (Database::affected_rows($result)) {
2521
                    $nbr_users++;
2522
                }
2523
                $new_users[] = $user;
2524
            }
2525
2526
            //update the nbr_users field
2527
            $sql_select = "SELECT COUNT(user_id) as nbUsers FROM $tbl_session_rel_course_rel_user
2528
                           WHERE session_id='$id_session' AND c_id='$enreg_course'";
2529
            $rs = Database::query($sql_select);
2530
            list($nbr_users) = Database::fetch_array($rs);
2531
            $sql_update = "UPDATE $tbl_session_rel_course SET nbr_users=$nbr_users
2532
                           WHERE session_id='$id_session' AND c_id='$enreg_course'";
2533
            Database::query($sql_update);
2534
2535
            $sql_update = "UPDATE $tbl_session SET nbr_users= '$nbr_users' WHERE id='$id_session'";
2536
            Database::query($sql_update);
2537
        }
2538
2539
        $new_users = [];
2540
        foreach ($users as $index => $user) {
2541
            $userid = $user['id'];
2542
            $sql_insert = "INSERT IGNORE INTO $tbl_session_rel_user(session_id, user_id, registered_at)
2543
                           VALUES ('$id_session','$userid', '".api_get_utc_datetime()."')";
2544
            Database::query($sql_insert);
2545
            $user['added_at_session'] = 1;
2546
            $new_users[] = $user;
2547
        }
2548
2549
        $users = $new_users;
2550
        $registered_users = get_lang('FileImported').'<br /> Import file results : <br />';
2551
        // Sending emails.
2552
        $addedto = '';
2553
        if ($sendMail) {
2554
            foreach ($users as $index => $user) {
2555
                $emailsubject = '['.api_get_setting('siteName').'] '.get_lang('YourReg').' '.api_get_setting('siteName');
2556
                $emailbody = get_lang('Dear').' '.
2557
                    api_get_person_name($user['FirstName'], $user['LastName']).",\n\n".
2558
                    get_lang('YouAreReg')." ".api_get_setting('siteName')." ".get_lang('WithTheFollowingSettings')."\n\n".
2559
                    get_lang('Username')." : $user[UserName]\n".
2560
                    get_lang('Pass')." : $user[Password]\n\n".
2561
                    get_lang('Address')." ".api_get_setting('siteName')." ".get_lang('Is')." : ".api_get_path(WEB_PATH)." \n\n".
2562
                    get_lang('Problem')."\n\n".
2563
                    get_lang('SignatureFormula').",\n\n".
2564
                    api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))."\n".
2565
                    get_lang('Manager')." ".api_get_setting('siteName')."\nT. ".
2566
                    api_get_setting('administratorTelephone')."\n".get_lang('Email')." : ".api_get_setting('emailAdministrator');
2567
2568
                api_mail_html(
2569
                    api_get_person_name($user['FirstName'], $user['LastName'], null, PERSON_NAME_EMAIL_ADDRESS),
2570
                    $user['Email'],
2571
                    $emailsubject,
2572
                    $emailbody
2573
                );
2574
                $userInfo = api_get_user_info($user['id']);
2575
2576
                if (($user['added_at_platform'] == 1 && $user['added_at_session'] == 1) || $user['added_at_session'] == 1) {
2577
                    if ($user['added_at_platform'] == 1) {
2578
                        $addedto = get_lang('UserCreatedPlatform');
2579
                    } else {
2580
                        $addedto = '          ';
2581
                    }
2582
2583
                    if ($user['added_at_session'] == 1) {
2584
                        $addedto .= get_lang('UserInSession');
2585
                    }
2586
                } else {
2587
                    $addedto = get_lang('UserNotAdded');
2588
                }
2589
2590
                $registered_users .= UserManager::getUserProfileLink($userInfo).' - '.$addedto.'<br />';
2591
            }
2592
        } else {
2593
            foreach ($users as $index => $user) {
2594
                $userInfo = api_get_user_info($user['id']);
2595
                if (($user['added_at_platform'] == 1 && $user['added_at_session'] == 1) || $user['added_at_session'] == 1) {
2596
                    if ($user['added_at_platform'] == 1) {
2597
                        $addedto = get_lang('UserCreatedPlatform');
2598
                    } else {
2599
                        $addedto = '          ';
2600
                    }
2601
2602
                    if ($user['added_at_session'] == 1) {
2603
                        $addedto .= ' '.get_lang('UserInSession');
2604
                    }
2605
                } else {
2606
                    $addedto = get_lang('UserNotAdded');
2607
                }
2608
                $registered_users .= "<a href=\"../user/userInfo.php?uInfo=".$user['id']."\">".
2609
                    Security::remove_XSS($userInfo['complete_user_name'])."</a> - ".$addedto.'<br />';
2610
            }
2611
        }
2612
        Display::addFlash(Display::return_message($registered_users, 'normal', false));
2613
        header('Location: course.php?id_session='.$id_session);
2614
        exit;
2615
    }
2616
2617
    /**
2618
     * Reads CSV-file.
2619
     *
2620
     * @param string $file Path to the CSV-file
2621
     *
2622
     * @return array All userinformation read from the file
2623
     */
2624
    public function parse_csv_data($file)
2625
    {
2626
        $users = Import::csvToArray($file);
2627
        foreach ($users as $index => $user) {
2628
            if (isset($user['Courses'])) {
2629
                $user['Courses'] = explode('|', trim($user['Courses']));
2630
            }
2631
            $users[$index] = $user;
2632
        }
2633
2634
        return $users;
2635
    }
2636
2637
    /**
2638
     * Reads XML-file.
2639
     *
2640
     * @param string $file Path to the XML-file
2641
     *
2642
     * @return array All userinformation read from the file
2643
     */
2644
    public static function parse_xml_data($file)
2645
    {
2646
        $crawler = new \Symfony\Component\DomCrawler\Crawler();
2647
        $crawler->addXmlContent(file_get_contents($file));
2648
        $crawler = $crawler->filter('Contacts > Contact ');
2649
        $array = [];
2650
        foreach ($crawler as $domElement) {
2651
            $row = [];
2652
            foreach ($domElement->childNodes as $node) {
2653
                if ($node->nodeName != '#text') {
2654
                    $row[$node->nodeName] = $node->nodeValue;
2655
                }
2656
            }
2657
            if (!empty($row)) {
2658
                $array[] = $row;
2659
            }
2660
        }
2661
2662
        return $array;
2663
    }
2664
2665
    /**
2666
     * @param int $courseId
2667
     * @param int $sessionId
2668
     * @param int $studentId
2669
     */
2670
    public static function displayTrackingAccessOverView($courseId, $sessionId, $studentId)
2671
    {
2672
        $courseId = (int) $courseId;
2673
        $sessionId = (int) $sessionId;
2674
        $studentId = (int) $studentId;
2675
2676
        $courseList = [];
2677
        $sessionList = [];
2678
        $studentList = [];
2679
2680
        if (!empty($courseId)) {
2681
            $course = api_get_course_entity($courseId);
2682
            if ($course) {
2683
                $courseList[$course->getId()] = $course->getTitle();
2684
            }
2685
        }
2686
2687
        if (!empty($sessionId)) {
2688
            $session = api_get_session_entity($sessionId);
2689
            if ($session) {
2690
                $sessionList[$session->getId()] = $session->getName();
2691
            }
2692
        }
2693
2694
        if (!empty($studentId)) {
2695
            $student = api_get_user_entity($studentId);
2696
            if ($student) {
2697
                $studentList[$student->getId()] = UserManager::formatUserFullName($student);
2698
            }
2699
        }
2700
2701
        $form = new FormValidator('access_overview', 'GET');
2702
        $form->addElement(
2703
            'select_ajax',
2704
            'course_id',
2705
            get_lang('SearchCourse'),
2706
            $courseList,
2707
            [
2708
                'url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?'.http_build_query(
2709
                    [
2710
                        'a' => 'search_course_by_session_all',
2711
                        'session_id' => $sessionId,
2712
                        'course_id' => $courseId,
2713
                    ]
2714
                ),
2715
            ]
2716
        );
2717
2718
        $form->addElement(
2719
            'select_ajax',
2720
            'session_id',
2721
            get_lang('SearchSession'),
2722
            $sessionList,
2723
            [
2724
                'url_function' => "
2725
                    function () {
2726
                        var params = $.param({
2727
                            a: 'search_session_by_course',
2728
                            course_id: $('#access_overview_course_id').val() || 0
2729
                        });
2730
2731
                        return '".api_get_path(WEB_AJAX_PATH)."session.ajax.php?' + params;
2732
                    }
2733
                ",
2734
            ]
2735
        );
2736
2737
        $form->addSelect(
2738
            'profile',
2739
            get_lang('Profile'),
2740
            [
2741
                '' => get_lang('Select'),
2742
                STUDENT => get_lang('Student'),
2743
                COURSEMANAGER => get_lang('CourseManager'),
2744
                DRH => get_lang('Drh'),
2745
            ],
2746
            ['id' => 'profile']
2747
        );
2748
2749
        $form->addElement(
2750
            'select_ajax',
2751
            'student_id',
2752
            get_lang('SearchUsers'),
2753
            $studentList,
2754
            [
2755
                'placeholder' => get_lang('All'),
2756
                'url_function' => "
2757
                    function () {
2758
                        var params = $.param({
2759
                            a: 'search_user_by_course',
2760
                            session_id: $('#access_overview_session_id').val(),
2761
                            course_id: $('#access_overview_course_id').val()
2762
                        });
2763
2764
                        return '".api_get_path(WEB_AJAX_PATH)."course.ajax.php?' + params;
2765
                    }
2766
                ",
2767
            ]
2768
        );
2769
2770
        $form->addDateRangePicker(
2771
            'date',
2772
            get_lang('DateRange'),
2773
            true,
2774
            [
2775
                'id' => 'date_range',
2776
                'format' => 'YYYY-MM-DD HH:mm',
2777
                'timePicker' => 'true',
2778
                //'validate_format' => 'Y-m-d',
2779
            ]
2780
        );
2781
2782
        $form->addHidden('display', 'accessoverview');
2783
        $form->addRule('course_id', get_lang('Required'), 'required');
2784
        $form->addRule('profile', get_lang('Required'), 'required');
2785
        $form->addButton('submit', get_lang('Generate'), 'gear', 'primary');
2786
2787
        $table = null;
2788
        if ($form->validate()) {
2789
            $table = new SortableTable(
2790
                'tracking_access_overview',
2791
                ['MySpace', 'getNumberOfTrackAccessOverview'],
2792
                ['MySpace', 'getUserDataAccessTrackingOverview'],
2793
                0
2794
            );
2795
            $table->set_header(0, get_lang('LoginDate'), true);
2796
            $table->set_header(1, get_lang('Username'), true);
2797
            if (api_is_western_name_order()) {
2798
                $table->set_header(2, get_lang('FirstName'), true);
2799
                $table->set_header(3, get_lang('LastName'), true);
2800
            } else {
2801
                $table->set_header(2, get_lang('LastName'), true);
2802
                $table->set_header(3, get_lang('FirstName'), true);
2803
            }
2804
            //$table->set_header(4, get_lang('Clicks'), false);
2805
            $table->set_header(4, get_lang('IP'), false);
2806
            $table->set_header(5, get_lang('TimeLoggedIn'), false);
2807
        }
2808
2809
        $template = new Template(
2810
            null,
2811
            false,
2812
            false,
2813
            false,
2814
            false,
2815
            false,
2816
            false
2817
        );
2818
        $template->assign('form', $form->returnForm());
2819
        $template->assign('table', $table ? $table->return_table() : null);
2820
2821
        echo $template->fetch(
2822
            $template->get_template('my_space/accessoverview.tpl')
2823
        );
2824
    }
2825
2826
    /**
2827
     * @return int
2828
     */
2829
    public static function getNumberOfTrackAccessOverview()
2830
    {
2831
        $user = Database::get_main_table(TABLE_MAIN_USER);
2832
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
2833
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2834
2835
        $sql = "SELECT COUNT(course_access_id) count
2836
                FROM $trackCourseAccess a
2837
                INNER JOIN $user u
2838
                ON a.user_id = u.id
2839
                INNER JOIN $course c
2840
                ON a.c_id = c.id
2841
                ";
2842
        $sql = self::getDataAccessTrackingFilters($sql);
2843
2844
        $result = Database::query($sql);
2845
        $row = Database::fetch_assoc($result);
2846
2847
        if ($row) {
2848
            return $row['count'];
2849
        }
2850
2851
        return 0;
2852
    }
2853
2854
    private static function getDataAccessTrackingFilters($sql)
2855
    {
2856
        if (isset($_GET['course_id']) && !empty($_GET['course_id'])) {
2857
            $courseId = (int) $_GET['course_id'];
2858
            $sql .= " AND c.id = ".$courseId;
2859
        }
2860
2861
        if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
2862
            $sessionId = (int) $_GET['session_id'];
2863
            $sql .= " AND a.session_id = ".$sessionId;
2864
        }
2865
2866
        if (isset($_GET['student_id']) && !empty($_GET['student_id'])) {
2867
            $userId = (int) $_GET['student_id'];
2868
            $sql .= " AND u.user_id = ".$userId;
2869
        }
2870
2871
        $sql .= " AND u.status <> ".ANONYMOUS;
2872
2873
        if (isset($_GET['date']) && !empty($_GET['date'])) {
2874
            $dateRangePicker = new DateRangePicker('date', '', ['timePicker' => 'true']);
2875
            $dates = $dateRangePicker->parseDateRange($_GET['date']);
2876
            if (isset($dates['start']) && !empty($dates['start'])) {
2877
                $dates['start'] = Database::escape_string(api_get_utc_datetime($dates['start']));
2878
                $sql .= " AND login_course_date >= '".$dates['start']."'";
2879
            }
2880
            if (isset($dates['end']) && !empty($dates['end'])) {
2881
                $dates['end'] = Database::escape_string(api_get_utc_datetime($dates['end']));
2882
                $sql .= " AND logout_course_date <= '".$dates['end']."'";
2883
            }
2884
        }
2885
2886
        return $sql;
2887
    }
2888
2889
    /**
2890
     * @param $from
2891
     * @param $numberItems
2892
     * @param $column
2893
     * @param $orderDirection
2894
     *
2895
     * @return array
2896
     */
2897
    public static function getUserDataAccessTrackingOverview(
2898
        $from,
2899
        $numberItems,
2900
        $column,
2901
        $orderDirection
2902
    ) {
2903
        $from = (int) $from;
2904
        $numberItems = (int) $numberItems;
2905
        $column = (int) $column;
2906
        $orderDirection = Database::escape_string($orderDirection);
2907
2908
        $user = Database::get_main_table(TABLE_MAIN_USER);
2909
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
2910
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
2911
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2912
2913
        global $export_csv;
2914
        $is_western_name_order = api_is_western_name_order();
2915
        if ($export_csv) {
2916
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
2917
        }
2918
2919
        //TODO add course name
2920
        $sql = "SELECT
2921
                a.login_course_date as col0,
2922
                u.username as col1,
2923
                ".(
2924
                    $is_western_name_order ? "
2925
                        u.firstname AS col2,
2926
                        u.lastname AS col3,
2927
                    " : "
2928
                        u.lastname AS col2,
2929
                        u.firstname AS col3,
2930
                "
2931
        )."
2932
                a.login_course_date,
2933
                a.logout_course_date,
2934
                c.title,
2935
                c.code,
2936
                u.id as user_id,
2937
                user_ip
2938
            FROM $trackCourseAccess a
2939
            INNER JOIN $user u
2940
            ON a.user_id = u.id
2941
            INNER JOIN $course c
2942
            ON a.c_id = c.id
2943
            WHERE 1=1 ";
2944
2945
        $sql = self::getDataAccessTrackingFilters($sql);
2946
2947
        $sql .= " ORDER BY col$column $orderDirection ";
2948
        $sql .= " LIMIT $from, $numberItems";
2949
2950
        $result = Database::query($sql);
2951
2952
        $data = [];
2953
        while ($user = Database::fetch_assoc($result)) {
2954
            $data[] = $user;
2955
        }
2956
2957
        $return = [];
2958
        //TODO: Dont use numeric index
2959
        foreach ($data as $key => $info) {
2960
            $return[] = [
2961
                api_get_local_time($info['login_course_date']),
2962
                $info['col1'],
2963
                $info['col2'],
2964
                $info['col3'],
2965
                $info['user_ip'],
2966
                gmdate('H:i:s', strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
2967
            ];
2968
        }
2969
2970
        return $return;
2971
    }
2972
2973
    /**
2974
     * Gets the connections to a course as an array of login and logout time.
2975
     *
2976
     * @param int    $user_id
2977
     * @param array  $course_info
2978
     * @param int    $sessionId
2979
     * @param string $start_date
2980
     * @param string $end_date
2981
     * @param bool   $addUserIp
2982
     *
2983
     * @author  Jorge Frisancho Jibaja
2984
     * @author  Julio Montoya <[email protected]> fixing the function
2985
     *
2986
     * @version OCT-22- 2010
2987
     *
2988
     * @return array
2989
     */
2990
    public static function get_connections_to_course_by_date(
2991
        $user_id,
2992
        $course_info,
2993
        $sessionId,
2994
        $start_date,
2995
        $end_date,
2996
        $addUserIp = false
2997
    ) {
2998
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2999
        $user_id = (int) $user_id;
3000
        $connections = [];
3001
        if (!empty($course_info)) {
3002
            $courseId = (int) $course_info['real_id'];
3003
            $end_date = self::add_day_to($end_date);
3004
3005
            $start_date = Database::escape_string($start_date);
3006
            $end_date = Database::escape_string($end_date);
3007
            $sessionCondition = api_get_session_condition($sessionId);
3008
            $sql = "SELECT
3009
                        login_course_date,
3010
                        logout_course_date,
3011
                        TIMESTAMPDIFF(SECOND, login_course_date, logout_course_date) duration,
3012
                        user_ip
3013
                    FROM $table
3014
                    WHERE
3015
                        user_id = $user_id AND
3016
                        c_id = $courseId AND
3017
                        login_course_date BETWEEN '$start_date' AND '$end_date' AND
3018
                        logout_course_date BETWEEN '$start_date' AND '$end_date'
3019
                        $sessionCondition
3020
                    ORDER BY login_course_date ASC";
3021
            $rs = Database::query($sql);
3022
3023
            while ($row = Database::fetch_array($rs)) {
3024
                $item = [
3025
                    'login' => $row['login_course_date'],
3026
                    'logout' => $row['logout_course_date'],
3027
                    'duration' => $row['duration'],
3028
                ];
3029
                if ($addUserIp) {
3030
                    $item['user_ip'] = $row['user_ip'];
3031
                }
3032
                $connections[] = $item;
3033
            }
3034
        }
3035
3036
        return $connections;
3037
    }
3038
3039
    /**
3040
     * @param int   $user_id
3041
     * @param array $course_info
3042
     * @param int   $sessionId
3043
     * @param null  $start_date
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $start_date is correct as it would always require null to be passed?
Loading history...
3044
     * @param null  $end_date
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $end_date is correct as it would always require null to be passed?
Loading history...
3045
     *
3046
     * @return array
3047
     */
3048
    public static function getStats($user_id, $course_info, $sessionId, $start_date = null, $end_date = null)
3049
    {
3050
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
3051
        $result = [];
3052
        if (!empty($course_info)) {
3053
            $stringStartDate = '';
3054
            $stringEndDate = '';
3055
            if ($start_date != null && $end_date != null) {
3056
                $end_date = self::add_day_to($end_date);
3057
3058
                $start_date = Database::escape_string($start_date);
3059
                $end_date = Database::escape_string($end_date);
3060
3061
                $stringStartDate = "AND login_course_date BETWEEN '$start_date' AND '$end_date'";
3062
                $stringEndDate = "AND logout_course_date BETWEEN '$start_date' AND '$end_date'";
3063
            }
3064
            $user_id = (int) $user_id;
3065
            $courseId = (int) $course_info['real_id'];
3066
            $sessionCondition = api_get_session_condition($sessionId);
3067
            $sql = "SELECT
3068
                SEC_TO_TIME(AVG(time_to_sec(timediff(logout_course_date,login_course_date)))) as avrg,
3069
                SEC_TO_TIME(SUM(time_to_sec(timediff(logout_course_date,login_course_date)))) as total,
3070
                count(user_id) as times
3071
                FROM $table
3072
                WHERE
3073
                    user_id = $user_id AND
3074
                    c_id = $courseId $stringStartDate $stringEndDate
3075
                    $sessionCondition
3076
                ORDER BY login_course_date ASC";
3077
3078
            $rs = Database::query($sql);
3079
            if ($row = Database::fetch_array($rs)) {
3080
                $foo_avg = $row['avrg'];
3081
                $foo_total = $row['total'];
3082
                $foo_times = $row['times'];
3083
                $result = [
3084
                    'avg' => $foo_avg,
3085
                    'total' => $foo_total,
3086
                    'times' => $foo_times,
3087
                ];
3088
            }
3089
        }
3090
3091
        return $result;
3092
    }
3093
3094
    public static function add_day_to($end_date)
3095
    {
3096
        $foo_date = strtotime($end_date);
3097
        $foo_date = strtotime(' +1 day', $foo_date);
3098
        $foo_date = date('Y-m-d', $foo_date);
3099
3100
        return $foo_date;
3101
    }
3102
3103
    /**
3104
     * This function draw the graphic to be displayed on the user view as an image.
3105
     *
3106
     * @param array  $sql_result
3107
     * @param string $start_date
3108
     * @param string $end_date
3109
     * @param string $type
3110
     *
3111
     * @author Jorge Frisancho Jibaja
3112
     *
3113
     * @version OCT-22- 2010
3114
     *
3115
     * @return string
3116
     */
3117
    public static function grapher($sql_result, $start_date, $end_date, $type = '')
3118
    {
3119
        if (empty($start_date)) {
3120
            $start_date = '';
3121
        }
3122
        if (empty($end_date)) {
3123
            $end_date = '';
3124
        }
3125
        if ('' == $type) {
3126
            $type = 'day';
3127
        }
3128
        $main_year = $main_month_year = $main_day = [];
3129
3130
        $period = new DatePeriod(
3131
            new DateTime($start_date),
3132
            new DateInterval('P1D'),
3133
            new DateTime($end_date)
3134
        );
3135
3136
        foreach ($period as $date) {
3137
            $main_day[$date->format('d-m-Y')] = 0;
3138
        }
3139
3140
        $period = new DatePeriod(
3141
            new DateTime($start_date),
3142
            new DateInterval('P1M'),
3143
            new DateTime($end_date)
3144
        );
3145
3146
        foreach ($period as $date) {
3147
            $main_month_year[$date->format('m-Y')] = 0;
3148
        }
3149
3150
        $i = 0;
3151
        if (is_array($sql_result) && count($sql_result) > 0) {
3152
            foreach ($sql_result as $key => $data) {
3153
                $login = api_strtotime($data['login']);
3154
                $logout = api_strtotime($data['logout']);
3155
                //creating the main array
3156
                if (isset($main_month_year[date('m-Y', $login)])) {
3157
                    $main_month_year[date('m-Y', $login)] += (float) ($logout - $login) / 60;
3158
                }
3159
                if (isset($main_day[date('d-m-Y', $login)])) {
3160
                    $main_day[date('d-m-Y', $login)] += (float) ($logout - $login) / 60;
3161
                }
3162
                if ($i > 500) {
3163
                    break;
3164
                }
3165
                $i++;
3166
            }
3167
            switch ($type) {
3168
                case 'day':
3169
                    $main_date = $main_day;
3170
                    break;
3171
                case 'month':
3172
                    $main_date = $main_month_year;
3173
                    break;
3174
                case 'year':
3175
                    $main_date = $main_year;
3176
                    break;
3177
            }
3178
3179
            $labels = array_keys($main_date);
3180
            if (1 == count($main_date)) {
3181
                $labels = $labels[0];
3182
                $main_date = $main_date[$labels];
3183
            }
3184
3185
            /* Create and populate the pData object */
3186
            $myData = new pData();
3187
            $myData->addPoints($main_date, 'Serie1');
3188
            if (count($main_date) != 1) {
3189
                $myData->addPoints($labels, 'Labels');
3190
                $myData->setSerieDescription('Labels', 'Months');
3191
                $myData->setAbscissa('Labels');
3192
            }
3193
            $myData->setSerieWeight('Serie1', 1);
3194
            $myData->setSerieDescription('Serie1', get_lang('MyResults'));
3195
            $myData->setAxisName(0, get_lang('Minutes'));
3196
            $myData->loadPalette(api_get_path(SYS_CODE_PATH).'palettes/pchart/default.color', true);
3197
3198
            // Cache definition
3199
            $cachePath = api_get_path(SYS_ARCHIVE_PATH);
3200
            $myCache = new pCache(['CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)]);
3201
            $chartHash = $myCache->getHash($myData);
3202
3203
            if ($myCache->isInCache($chartHash)) {
3204
                //if we already created the img
3205
                $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
3206
                $myCache->saveFromCache($chartHash, $imgPath);
3207
                $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
3208
            } else {
3209
                /* Define width, height and angle */
3210
                $mainWidth = 760;
3211
                $mainHeight = 230;
3212
                $angle = 50;
3213
3214
                /* Create the pChart object */
3215
                $myPicture = new pImage($mainWidth, $mainHeight, $myData);
3216
3217
                /* Turn of Antialiasing */
3218
                $myPicture->Antialias = false;
3219
                /* Draw the background */
3220
                $settings = ["R" => 255, "G" => 255, "B" => 255];
3221
                $myPicture->drawFilledRectangle(0, 0, $mainWidth, $mainHeight, $settings);
3222
3223
                /* Add a border to the picture */
3224
                $myPicture->drawRectangle(
3225
                    0,
3226
                    0,
3227
                    $mainWidth - 1,
3228
                    $mainHeight - 1,
3229
                    ["R" => 0, "G" => 0, "B" => 0]
3230
                );
3231
3232
                /* Set the default font */
3233
                $myPicture->setFontProperties(
3234
                    [
3235
                        "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
3236
                        "FontSize" => 10, ]
3237
                );
3238
                /* Write the chart title */
3239
                $myPicture->drawText(
3240
                    $mainWidth / 2,
3241
                    30,
3242
                    get_lang('TimeSpentInTheCourse'),
3243
                    [
3244
                        "FontSize" => 12,
3245
                        "Align" => TEXT_ALIGN_BOTTOMMIDDLE,
3246
                    ]
3247
                );
3248
3249
                /* Set the default font */
3250
                $myPicture->setFontProperties(
3251
                    [
3252
                        "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
3253
                        "FontSize" => 8,
3254
                    ]
3255
                );
3256
3257
                /* Define the chart area */
3258
                $myPicture->setGraphArea(50, 40, $mainWidth - 40, $mainHeight - 80);
3259
3260
                /* Draw the scale */
3261
                $scaleSettings = [
3262
                    'XMargin' => 10,
3263
                    'YMargin' => 10,
3264
                    'Floating' => true,
3265
                    'GridR' => 200,
3266
                    'GridG' => 200,
3267
                    'GridB' => 200,
3268
                    'DrawSubTicks' => true,
3269
                    'CycleBackground' => true,
3270
                    'LabelRotation' => $angle,
3271
                    'Mode' => SCALE_MODE_ADDALL_START0,
3272
                ];
3273
                $myPicture->drawScale($scaleSettings);
3274
3275
                /* Turn on Antialiasing */
3276
                $myPicture->Antialias = true;
3277
3278
                /* Enable shadow computing */
3279
                $myPicture->setShadow(
3280
                    true,
3281
                    [
3282
                        "X" => 1,
3283
                        "Y" => 1,
3284
                        "R" => 0,
3285
                        "G" => 0,
3286
                        "B" => 0,
3287
                        "Alpha" => 10,
3288
                    ]
3289
                );
3290
3291
                /* Draw the line chart */
3292
                $myPicture->setFontProperties(
3293
                    [
3294
                        "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
3295
                        "FontSize" => 10,
3296
                    ]
3297
                );
3298
                $myPicture->drawSplineChart();
3299
                $myPicture->drawPlotChart(
3300
                    [
3301
                        "DisplayValues" => true,
3302
                        "PlotBorder" => true,
3303
                        "BorderSize" => 1,
3304
                        "Surrounding" => -60,
3305
                        "BorderAlpha" => 80,
3306
                    ]
3307
                );
3308
3309
                /* Do NOT Write the chart legend */
3310
3311
                /* Write and save into cache */
3312
                $myCache->writeToCache($chartHash, $myPicture);
3313
                $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
3314
                $myCache->saveFromCache($chartHash, $imgPath);
3315
                $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
3316
            }
3317
3318
            return '<img src="'.$imgPath.'">';
3319
        } else {
3320
            return api_convert_encoding(
3321
                '<div id="messages" class="warning-message">'.get_lang('GraphicNotAvailable').'</div>',
3322
                'UTF-8'
3323
            );
3324
        }
3325
    }
3326
}
3327