Passed
Push — master ( 0085e5...a02707 )
by Julito
10:26
created

MySpace::getDataAccessTrackingFilters()   C

Complexity

Conditions 13
Paths 40

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 20
c 0
b 0
f 0
nc 40
nop 1
dl 0
loc 33
rs 6.6166

How to fix   Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* 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('Trainers Overview'),
25
            ],
26
            [
27
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=user',
28
                'content' => get_lang('User overview'),
29
            ],
30
            [
31
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=session',
32
                'content' => get_lang('Course sessions overview'),
33
            ],
34
            [
35
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=course',
36
                'content' => get_lang('Courses overview'),
37
            ],
38
            [
39
                'url' => api_get_path(WEB_CODE_PATH).'tracking/question_course_report.php?view=admin',
40
                'content' => get_lang('Learning paths exercises results list'),
41
            ],
42
            [
43
                'url' => api_get_path(WEB_CODE_PATH).'tracking/course_session_report.php?view=admin',
44
                'content' => get_lang('Results of learning paths exercises by session'),
45
            ],
46
            [
47
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=accessoverview',
48
                'content' => get_lang('Accesses by user overview').' ('.get_lang('Beta').')',
49
            ],
50
            [
51
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/exercise_category_report.php',
52
                'content' => get_lang('Exercise report by category for all sessions'),
53
            ],
54
            [
55
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/survey_report.php',
56
                'content' => get_lang('SurveysReport'),
57
            ],
58
            [
59
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/tc_report.php',
60
                'content' => get_lang('TCReport'),
61
            ],
62
            [
63
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/ti_report.php',
64
                'content' => get_lang('TIReport'),
65
            ],
66
            [
67
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/question_stats_global.php',
68
                'content' => get_lang('QuestionStats'),
69
            ],
70
            [
71
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/question_stats_global_detail.php',
72
                'content' => get_lang('QuestionStatsDetailedReport'),
73
            ],
74
        ];
75
76
        $field = new ExtraField('user');
77
        $companyField = $field->get_handler_field_info_by_field_variable('company');
78
        if (!empty($companyField)) {
79
            $actions[] =
80
                [
81
                    'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=company',
82
                    'content' => get_lang('UserByEntityReport'),
83
                ];
84
        }
85
        $field = new ExtraField('lp');
86
        $authorsField = $field->get_handler_field_info_by_field_variable('authors');
87
        if (!empty($authorsField)) {
88
            $actions[] =
89
                [
90
                    'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=learningPath',
91
                    'content' => get_lang('LpByAuthor'),
92
                ];
93
        }
94
        $field = new ExtraField('lp_item');
95
        $authorsItemField = $field->get_handler_field_info_by_field_variable('authorlpitem');
96
        if (!empty($authorsItemField)) {
97
            $actions[] =
98
                [
99
                    'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=learningPathByItem',
100
                    'content' => get_lang('LearningPathItemByAuthor'),
101
                ];
102
        }
103
        return Display::actions($actions, null);
104
    }
105
106
    /**
107
     * @return string
108
     */
109
    public static function getTopMenu()
110
    {
111
        $menuItems = [];
112
        $menuItems[] = Display::url(
113
            Display::return_icon(
114
                'statistics.png',
115
                get_lang('View my progress'),
116
                '',
117
                ICON_SIZE_MEDIUM
118
            ),
119
            api_get_path(WEB_CODE_PATH)."auth/my_progress.php"
120
        );
121
        $menuItems[] = Display::url(
122
            Display::return_icon(
123
                'teacher.png',
124
                get_lang('Trainer View'),
125
                [],
126
                32
127
            ),
128
            api_get_path(WEB_CODE_PATH).'mySpace/?view=teacher'
129
        );
130
        $menuItems[] = Display::url(
131
            Display::return_icon(
132
                'star_na.png',
133
                get_lang('Admin view'),
134
                [],
135
                32
136
            ),
137
            '#'
138
        );
139
        $menuItems[] = Display::url(
140
            Display::return_icon('quiz.png', get_lang('Exam tracking'), [], 32),
141
            api_get_path(WEB_CODE_PATH).'tracking/exams.php'
142
        );
143
        $menu = '';
144
        foreach ($menuItems as $item) {
145
            $menu .= $item;
146
        }
147
        $menu .= '<br />';
148
149
        return $menu;
150
    }
151
152
    /**
153
     * This function serves exporting data in CSV format.
154
     *
155
     * @param array  $header    the header labels
156
     * @param array  $data      the data array
157
     * @param string $file_name the name of the file which contains exported data
158
     *
159
     * @return string mixed             Returns a message (string) if an error occurred
160
     */
161
    public function export_csv($header, $data, $file_name = 'export.csv')
162
    {
163
        $archive_path = api_get_path(SYS_ARCHIVE_PATH);
164
        $archive_url = api_get_path(WEB_CODE_PATH).'course_info/download.php?archive_path=&archive=';
165
        $message = '';
166
        if (!$open = fopen($archive_path.$file_name, 'w+')) {
167
            $message = get_lang('Could not open');
168
        } else {
169
            $info = '';
170
171
            foreach ($header as $value) {
172
                $info .= $value.';';
173
            }
174
            $info .= "\r\n";
175
176
            foreach ($data as $row) {
177
                foreach ($row as $value) {
178
                    $info .= $value.';';
179
                }
180
                $info .= "\r\n";
181
            }
182
183
            fwrite($open, $info);
184
            fclose($open);
185
            @chmod($file_name, api_get_permissions_for_new_files());
186
187
            header("Location:".$archive_url.$file_name);
188
            exit;
189
        }
190
191
        return $message;
192
    }
193
194
    /**
195
     * Gets the connections to a course as an array of login and logout time.
196
     *
197
     * @param int   $userId     User id
198
     * @param array $courseInfo
199
     * @param int   $sessionId  Session id (optional, default = 0)
200
     *
201
     * @return array Connections
202
     */
203
    public static function get_connections_to_course(
204
        $userId,
205
        $courseInfo,
206
        $sessionId = 0
207
    ) {
208
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
209
210
        // protect data
211
        $userId = (int) $userId;
212
        $courseId = (int) $courseInfo['real_id'];
213
        $sessionId = (int) $sessionId;
214
        $sessionCondition = api_get_session_condition($sessionId);
215
216
        $sql = 'SELECT login_course_date, logout_course_date
217
                FROM '.$table.'
218
                WHERE
219
                    user_id = '.$userId.' AND
220
                    c_id = '.$courseId.' 
221
                    '.$sessionCondition.'
222
                ORDER BY login_course_date ASC';
223
        $rs = Database::query($sql);
224
        $connections = [];
225
226
        while ($row = Database::fetch_array($rs)) {
227
            $connections[] = [
228
                'login' => $row['login_course_date'],
229
                'logout' => $row['logout_course_date'],
230
            ];
231
        }
232
233
        return $connections;
234
    }
235
236
    /**
237
     * @param $user_id
238
     * @param $course_list
239
     * @param int $session_id
240
     *
241
     * @return array|bool
242
     */
243
    public static function get_connections_from_course_list(
244
        $user_id,
245
        $course_list,
246
        $session_id = 0
247
    ) {
248
        // Database table definitions
249
        $tbl_track_course = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
250
        if (empty($course_list)) {
251
            return false;
252
        }
253
254
        // protect data
255
        $user_id = (int) $user_id;
256
        $session_id = (int) $session_id;
257
        $new_course_list = [];
258
        foreach ($course_list as $course_item) {
259
            $courseInfo = api_get_course_info($course_item['code']);
260
            if ($courseInfo) {
261
                $courseId = $courseInfo['real_id'];
262
                $new_course_list[] = '"'.$courseId.'"';
263
            }
264
        }
265
        $course_list = implode(', ', $new_course_list);
266
267
        if (empty($course_list)) {
268
            return false;
269
        }
270
        $sql = 'SELECT login_course_date, logout_course_date, c_id
271
                FROM '.$tbl_track_course.'
272
                WHERE
273
                    user_id = '.$user_id.' AND
274
                    c_id IN ('.$course_list.') AND
275
                    session_id = '.$session_id.'
276
                ORDER BY login_course_date ASC';
277
        $rs = Database::query($sql);
278
        $connections = [];
279
280
        while ($row = Database::fetch_array($rs)) {
281
            $timestamp_login_date = api_strtotime($row['login_course_date'], 'UTC');
282
            $timestamp_logout_date = api_strtotime($row['logout_course_date'], 'UTC');
283
            $connections[] = [
284
                'login' => $timestamp_login_date,
285
                'logout' => $timestamp_logout_date,
286
                'c_id' => $row['c_id'],
287
            ];
288
        }
289
290
        return $connections;
291
    }
292
293
    /**
294
     * Creates a small table in the last column of the table with the user overview.
295
     *
296
     * @param int $user_id the id of the user
297
     *
298
     * @return array List course
299
     */
300
    public static function returnCourseTracking($user_id)
301
    {
302
        $user_id = (int) $user_id;
303
304
        if (empty($user_id)) {
305
            return [];
306
        }
307
308
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
309
        // getting all the courses of the user
310
        $sql = "SELECT * FROM $tbl_course_user
311
                WHERE
312
                    user_id = $user_id AND
313
                    relation_type <> ".COURSE_RELATION_TYPE_RRHH;
314
        $result = Database::query($sql);
315
316
        $list = [];
317
318
        while ($row = Database::fetch_array($result)) {
319
            $courseInfo = api_get_course_info_by_id($row['c_id']);
320
            $courseId = $courseInfo['real_id'];
321
            $courseCode = $courseInfo['code'];
322
323
            if (empty($courseInfo)) {
324
                continue;
325
            }
326
327
            $avg_score = Tracking::get_avg_student_score($user_id, $courseCode);
328
            if (is_numeric($avg_score)) {
329
                $avg_score = round($avg_score, 2);
330
            } else {
331
                $avg_score = '-';
332
            }
333
334
            // Student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
335
            $exercisesResults = self::exercises_results($user_id, $courseCode);
336
337
            $resultToString = '';
338
            if (!is_null($exercisesResults['percentage'])) {
339
                $resultToString = $exercisesResults['score_obtained'].'/'.$exercisesResults['score_possible'].' ( '.$exercisesResults['percentage'].'% )';
340
            }
341
342
            $item = [
343
                'code' => $courseInfo['code'],
344
                'real_id' => $courseInfo['real_id'],
345
                'title' => $courseInfo['title'],
346
                'category' => $courseInfo['categoryName'],
347
                'image_small' => $courseInfo['course_image'],
348
                'image_large' => $courseInfo['course_image_large'],
349
                'time_spent' => api_time_to_hms(Tracking::get_time_spent_on_the_course($user_id, $courseId)),
350
                'student_progress' => round(Tracking::get_avg_student_progress($user_id, $courseCode)),
351
                'student_score' => $avg_score,
352
                'student_message' => Tracking::count_student_messages($user_id, $courseCode),
353
                'student_assignments' => Tracking::count_student_assignments($user_id, $courseCode),
354
                'student_exercises' => $resultToString,
355
                'questions_answered' => $exercisesResults['questions_answered'],
356
                'last_connection' => Tracking::get_last_connection_date_on_the_course($user_id, $courseInfo),
357
            ];
358
            $list[] = $item;
359
        }
360
361
        return $list;
362
    }
363
364
    /**
365
     * Display a sortable table that contains an overview off all the
366
     * reporting progress of all users and all courses the user is subscribed to.
367
     *
368
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
369
     *          Alex Aragon <[email protected]>, BeezNest, Perú
370
     *
371
     * @version Chamilo 1.11.8
372
     *
373
     * @since April 2019
374
     */
375
    public static function returnTrackingUserOverviewFilter($user_id)
376
    {
377
        $tpl = new Template('', false, false, false, false, false, false);
378
        $userInfo = api_get_user_info($user_id);
379
380
        $avatar = UserManager::getUserPicture($user_id, USER_IMAGE_SIZE_SMALL);
381
        $user = [
382
            'id' => $user_id,
383
            'code_user' => $userInfo['official_code'],
384
            'complete_name' => $userInfo['complete_name'],
385
            'username' => $userInfo['username'],
386
            'course' => self::returnCourseTracking($user_id),
387
            'avatar' => $avatar,
388
        ];
389
390
        $tpl->assign('item', $user);
391
        $templateName = $tpl->get_template('my_space/partials/tracking_user_overview.tpl');
392
        $content = $tpl->fetch($templateName);
393
394
        return $content;
395
    }
396
397
    /**
398
     * Display a sortable table that contains an overview off all the
399
     * reporting progress of all users and all courses the user is subscribed to.
400
     *
401
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
402
     *         Alex Aragon <[email protected]>, BeezNest, Perú
403
     *
404
     * @version Chamilo 1.11.8
405
     *
406
     * @since October 2008, Update April 2019
407
     */
408
    public static function display_tracking_user_overview()
409
    {
410
        self::display_user_overview_export_options();
411
412
        $params = ['view' => 'admin', 'display' => 'user'];
413
        $table = new SortableTable(
414
            'tracking_user_overview',
415
            ['MySpace', 'get_number_of_users_tracking_overview'],
416
            ['MySpace', 'get_user_data_tracking_overview'],
417
            0,
418
            20,
419
            'ASC',
420
            null, [
421
                'class' => 'table table-transparent',
422
            ]
423
        );
424
        $table->additional_parameters = $params;
425
426
        $table->set_column_filter(0, ['MySpace', 'returnTrackingUserOverviewFilter']);
427
        $tableContent = $table->return_table();
428
        $tpl = new Template('', false, false, false, false, false, false);
429
        $tpl->assign('table', $tableContent);
430
        $templateName = $tpl->get_template('my_space/user_summary.tpl');
431
        $tpl->display($templateName);
432
    }
433
434
    /**
435
     * @param $export_csv
436
     */
437
    public static function display_tracking_coach_overview($export_csv)
438
    {
439
        if ($export_csv) {
440
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
441
        } else {
442
            $is_western_name_order = api_is_western_name_order();
443
        }
444
        $sort_by_first_name = api_sort_by_first_name();
445
446
        if (isset($_GET['tracking_list_coaches_column'])) {
447
            $tracking_column = (int) $_GET['tracking_list_coaches_column'];
448
        } else {
449
            $tracking_column = ($is_western_name_order xor $sort_by_first_name) ? 1 : 0;
450
        }
451
452
        $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';
453
        // Prepare array for column order - when impossible, use some of user names.
454
        if ($is_western_name_order) {
455
            $order = [
456
                0 => 'firstname',
457
                1 => 'lastname',
458
                2 => $sort_by_first_name ? 'firstname' : 'lastname',
459
                3 => 'login_date',
460
                4 => $sort_by_first_name ? 'firstname' : 'lastname',
461
                5 => $sort_by_first_name ? 'firstname' : 'lastname',
462
            ];
463
        } else {
464
            $order = [
465
                0 => 'lastname',
466
                1 => 'firstname',
467
                2 => $sort_by_first_name ? 'firstname' : 'lastname',
468
                3 => 'login_date',
469
                4 => $sort_by_first_name ? 'firstname' : 'lastname',
470
                5 => $sort_by_first_name ? 'firstname' : 'lastname',
471
            ];
472
        }
473
        $table = new SortableTable(
474
            'tracking_list_coaches_myspace',
475
            ['MySpace', 'count_coaches'],
476
            null,
477
            ($is_western_name_order xor $sort_by_first_name) ? 1 : 0
478
        );
479
        $parameters['view'] = 'admin';
480
        $table->set_additional_parameters($parameters);
481
        if ($is_western_name_order) {
482
            $table->set_header(0, get_lang('First name'), true);
483
            $table->set_header(1, get_lang('Last name'), true);
484
        } else {
485
            $table->set_header(0, get_lang('Last name'), true);
486
            $table->set_header(1, get_lang('First name'), true);
487
        }
488
        $table->set_header(2, get_lang('Time spent in portal'), false);
489
        $table->set_header(3, get_lang('Latest login'), false);
490
        $table->set_header(4, get_lang('Learners'), false);
491
        $table->set_header(5, get_lang('Courses'), false);
492
        $table->set_header(6, get_lang('Number of sessions'), false);
493
        $table->set_header(7, get_lang('Course sessions'), false);
494
495
        if ($is_western_name_order) {
496
            $csv_header[] = [
497
                get_lang('First name'),
498
                get_lang('Last name'),
499
                get_lang('Time spent in portal'),
500
                get_lang('Latest login'),
501
                get_lang('Learners'),
502
                get_lang('Courses'),
503
                get_lang('Number of sessions'),
504
            ];
505
        } else {
506
            $csv_header[] = [
507
                get_lang('Last name'),
508
                get_lang('First name'),
509
                get_lang('Time spent in portal'),
510
                get_lang('Latest login'),
511
                get_lang('Learners'),
512
                get_lang('Courses'),
513
                get_lang('Number of sessions'),
514
            ];
515
        }
516
517
        $tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
518
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
519
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
520
        $tbl_sessions = Database::get_main_table(TABLE_MAIN_SESSION);
521
522
        $sqlCoachs = "SELECT DISTINCT
523
                        scu.user_id as id_coach,
524
                        u.id as user_id,
525
                        lastname,
526
                        firstname,
527
                        MAX(login_date) as login_date
528
                        FROM $tbl_user u, $tbl_session_course_user scu, $tbl_track_login
529
                        WHERE
530
                            scu.user_id = u.id AND scu.status=2 AND login_user_id=u.id
531
                        GROUP BY user_id ";
532
533
        if (api_is_multiple_url_enabled()) {
534
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
535
            $access_url_id = api_get_current_access_url_id();
536
            if (-1 != $access_url_id) {
537
                $sqlCoachs = "SELECT DISTINCT
538
                                    scu.user_id as id_coach,
539
                                    u.id as user_id,
540
                                    lastname,
541
                                    firstname,
542
                                    MAX(login_date) as login_date
543
                                FROM $tbl_user u,
544
                                $tbl_session_course_user scu,
545
                                $tbl_track_login ,
546
                                $tbl_session_rel_access_url session_rel_url
547
                                WHERE
548
                                    scu.user_id = u.id AND
549
                                    scu.status = 2 AND
550
                                    login_user_id = u.id AND
551
                                    access_url_id = $access_url_id AND
552
                                    session_rel_url.session_id = scu.session_id
553
                                GROUP BY u.id";
554
            }
555
        }
556
        if (!empty($order[$tracking_column])) {
557
            $sqlCoachs .= ' ORDER BY '.$order[$tracking_column].' '.$tracking_direction;
558
        }
559
560
        $result_coaches = Database::query($sqlCoachs);
561
        $global_coaches = [];
562
        while ($coach = Database::fetch_array($result_coaches)) {
563
            $global_coaches[$coach['user_id']] = $coach;
564
        }
565
566
        $sql_session_coach = "SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
567
                                FROM $tbl_user u , $tbl_sessions as session, $tbl_track_login
568
                                WHERE id_coach = u.id AND login_user_id = u.id
569
                                GROUP BY u.id
570
                                ORDER BY login_date $tracking_direction";
571
572
        if (api_is_multiple_url_enabled()) {
573
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
574
            $access_url_id = api_get_current_access_url_id();
575
            if (-1 != $access_url_id) {
576
                $sql_session_coach = "SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
577
					FROM $tbl_user u , $tbl_sessions as session, $tbl_track_login , $tbl_session_rel_access_url as session_rel_url
578
					WHERE
579
					    id_coach = u.id AND
580
					    login_user_id = u.id  AND
581
					    access_url_id = $access_url_id AND
582
					    session_rel_url.session_id = session.id
583
					GROUP BY  u.id
584
					ORDER BY login_date $tracking_direction";
585
            }
586
        }
587
588
        $result_sessions_coach = Database::query($sql_session_coach);
589
        //$total_no_coaches += Database::num_rows($result_sessions_coach);
590
        while ($coach = Database::fetch_array($result_sessions_coach)) {
591
            $global_coaches[$coach['user_id']] = $coach;
592
        }
593
594
        $all_datas = [];
595
        foreach ($global_coaches as $id_coach => $coaches) {
596
            $time_on_platform = api_time_to_hms(
597
                Tracking::get_time_spent_on_the_platform($coaches['user_id'])
598
            );
599
            $last_connection = Tracking::get_last_connection_date(
600
                $coaches['user_id']
601
            );
602
            $nb_students = count(
603
                Tracking::get_student_followed_by_coach($coaches['user_id'])
604
            );
605
            $nb_courses = count(
606
                Tracking::get_courses_followed_by_coach($coaches['user_id'])
607
            );
608
            $nb_sessions = count(
609
                Tracking::get_sessions_coached_by_user($coaches['user_id'])
610
            );
611
612
            $table_row = [];
613
            if ($is_western_name_order) {
614
                $table_row[] = $coaches['firstname'];
615
                $table_row[] = $coaches['lastname'];
616
            } else {
617
                $table_row[] = $coaches['lastname'];
618
                $table_row[] = $coaches['firstname'];
619
            }
620
            $table_row[] = $time_on_platform;
621
            $table_row[] = $last_connection;
622
            $table_row[] = $nb_students;
623
            $table_row[] = $nb_courses;
624
            $table_row[] = $nb_sessions;
625
            $table_row[] = '<a href="session.php?id_coach='.$coaches['user_id'].'">
626
                '.Display::return_icon('2rightarrow.png', get_lang('Details')).'
627
            </a>';
628
            $all_datas[] = $table_row;
629
630
            if ($is_western_name_order) {
631
                $csv_content[] = [
632
                    api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
633
                    api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
634
                    $time_on_platform,
635
                    $last_connection,
636
                    $nb_students,
637
                    $nb_courses,
638
                    $nb_sessions,
639
                ];
640
            } else {
641
                $csv_content[] = [
642
                    api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
643
                    api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
644
                    $time_on_platform,
645
                    $last_connection,
646
                    $nb_students,
647
                    $nb_courses,
648
                    $nb_sessions,
649
                ];
650
            }
651
        }
652
653
        if (3 != $tracking_column) {
654
            if ('DESC' == $tracking_direction) {
655
                usort($all_datas, ['MySpace', 'rsort_users']);
656
            } else {
657
                usort($all_datas, ['MySpace', 'sort_users']);
658
            }
659
        }
660
661
        if ($export_csv && 3 != $tracking_column) {
662
            usort($csv_content, 'sort_users');
663
        }
664
        if ($export_csv) {
665
            $csv_content = array_merge($csv_header, $csv_content);
666
        }
667
668
        foreach ($all_datas as $row) {
669
            $table->addRow($row, 'align="right"');
670
        }
671
        $table->display();
672
    }
673
674
    /**
675
     * @return mixed
676
     */
677
    public static function count_coaches()
678
    {
679
        global $total_no_coaches;
680
681
        return $total_no_coaches;
682
    }
683
684
    public static function sort_users($a, $b)
685
    {
686
        $tracking = Session::read('tracking_column');
687
688
        return api_strcmp(
689
            trim(api_strtolower($a[$tracking])),
690
            trim(api_strtolower($b[$tracking]))
691
        );
692
    }
693
694
    public static function rsort_users($a, $b)
695
    {
696
        $tracking = Session::read('tracking_column');
697
698
        return api_strcmp(
699
            trim(api_strtolower($b[$tracking])),
700
            trim(api_strtolower($a[$tracking]))
701
        );
702
    }
703
704
    /**
705
     * Displays a form with all the additionally defined user fields of the profile
706
     * and give you the opportunity to include these in the CSV export.
707
     *
708
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
709
     *
710
     * @version 1.8.6
711
     *
712
     * @since November 2008
713
     */
714
    public static function display_user_overview_export_options()
715
    {
716
        $message = '';
717
        $defaults = [];
718
        // include the user manager and formvalidator library
719
        if (isset($_GET['export']) && 'options' == $_GET['export']) {
720
            // get all the defined extra fields
721
            $extrafields = UserManager::get_extra_fields(
722
                0,
723
                50,
724
                5,
725
                'ASC',
726
                false,
727
                1
728
            );
729
730
            // creating the form with all the defined extra fields
731
            $form = new FormValidator(
732
                'exportextrafields',
733
                'post',
734
                api_get_self()."?view=".Security::remove_XSS($_GET['view']).'&display='.Security::remove_XSS($_GET['display']).'&export='.Security::remove_XSS($_GET['export'])
735
            );
736
737
            if (is_array($extrafields) && count($extrafields) > 0) {
738
                foreach ($extrafields as $key => $extra) {
739
                    $form->addElement('checkbox', 'extra_export_field'.$extra[0], '', $extra[3]);
740
                }
741
                $form->addButtonSave(get_lang('Validate'), 'submit');
742
743
                // setting the default values for the form that contains all the extra fields
744
                $exportFields = Session::read('additional_export_fields');
745
                if (is_array($exportFields)) {
746
                    foreach ($exportFields as $key => $value) {
747
                        $defaults['extra_export_field'.$value] = 1;
748
                    }
749
                }
750
                $form->setDefaults($defaults);
751
            } else {
752
                $form->addElement('html', Display::return_message(get_lang('There are not extra fields available'), 'warning'));
753
            }
754
755
            if ($form->validate()) {
756
                // exporting the form values
757
                $values = $form->exportValues();
758
759
                // re-initialising the session that contains the additional fields that need to be exported
760
                Session::write('additional_export_fields', []);
761
762
                // adding the fields that are checked to the session
763
                $message = '';
764
                $additionalExportFields = [];
765
                foreach ($values as $field_ids => $value) {
766
                    if (1 == $value && strstr($field_ids, 'extra_export_field')) {
767
                        $additionalExportFields[] = str_replace('extra_export_field', '', $field_ids);
768
                    }
769
                }
770
                Session::write('additional_export_fields', $additionalExportFields);
771
772
                // adding the fields that will be also exported to a message string
773
                $additionalExportFields = Session::read('additional_export_fields');
774
                if (is_array($additionalExportFields)) {
775
                    foreach ($additionalExportFields as $key => $extra_field_export) {
776
                        $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
777
                    }
778
                }
779
780
                // Displaying a feedback message
781
                if (!empty($additionalExportFields)) {
782
                    echo Display::return_message(
783
                        get_lang('The following fields will also be exported').': <br /><ul>'.$message.'</ul>',
784
                        'confirm',
785
                        false
786
                    );
787
                } else {
788
                    echo Display::return_message(
789
                        get_lang('No additional fields will be exported'),
790
                        'confirm',
791
                        false
792
                    );
793
                }
794
            } else {
795
                $form->display();
796
            }
797
        } else {
798
            $additionalExportFields = Session::read('additional_export_fields');
799
            if (!empty($additionalExportFields)) {
800
                // get all the defined extra fields
801
                $extrafields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
802
803
                foreach ($additionalExportFields as $key => $extra_field_export) {
804
                    $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
805
                }
806
807
                echo Display::return_message(
808
                    get_lang('The following fields will also be exported').': <br /><ul>'.$message.'</ul>',
809
                    'normal',
810
                    false
811
                );
812
            }
813
        }
814
    }
815
816
    /**
817
     * Export to cvs a list of users who were enrolled in the lessons.
818
     * It is necessary that in the extra field, a company is defined.
819
     *
820
     * @param string|null $startDate
821
     * @param string|null $endDate
822
     *
823
     * @return array
824
     */
825
    public static function exportCompanyResumeCsv($startDate, $endDate)
826
    {
827
        $companys = self::getCompanyLearnpathSubscription($startDate, $endDate);
828
        $csv_content = [];
829
        // Printing table
830
        $total = 0;
831
        $displayText = get_lang('Company');
832
        // the first line of the csv file with the column headers
833
        $csv_row = [];
834
        $csv_row[] = $displayText;
835
836
        $csv_row[] = get_lang('CountOfSubscribedUsers');
837
        $csv_content[] = $csv_row;
838
839
        foreach ($companys as $entity => $student) {
840
            $csv_row = [];
841
            // user official code
842
            $csv_row[] = $entity;
843
            $csv_row[] = count($student);
844
            $total += count($student);
845
            $csv_content[] = $csv_row;
846
        }
847
848
        $csv_row = [];
849
        // user official code
850
        $csv_row[] = get_lang('GeneralTotal');
851
        $csv_row[] = $total;
852
        $csv_content[] = $csv_row;
853
        Export::arrayToCsv($csv_content, 'reporting_company_resume');
854
        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...
855
    }
856
857
    /**
858
     * Displays a list as a table of users who were enrolled in the lessons.
859
     * It is necessary that in the extra field, a company is defined.
860
     *
861
     * @param string|null $startDate
862
     * @param string|null $endDate
863
     */
864
    public static function displayResumeCompany(
865
        $startDate = null,
866
        $endDate = null
867
    ) {
868
        $companys = self::getCompanyLearnpathSubscription($startDate, $endDate);
869
        $tableHtml = '';
870
        // Printing table
871
        $total = 0;
872
        $table = '<div class="table-responsive"><table class="table table-hover table-striped table-bordered data_table">';
873
874
        $displayText = get_lang('Company');
875
        $table .= "<thead><tr><th class=\"th-header\">$displayText</th><th class=\"th-header\"> ".get_lang('CountOfSubscribedUsers')." </th></tr></thead><tbody>";
876
877
        foreach ($companys as $entity => $student) {
878
            $table .= "<tr><td>$entity</td><td>".count($student)."</td></tr>";
879
            $total += count($student);
880
        }
881
        $table .= "<tr><td>".get_lang('GeneralTotal')."</td><td>$total</td></tr>";
882
        $table .= '</tbody></table></div>';
883
884
        if (!empty($startDate) or !empty($endDate)) {
885
            $tableHtml = $table;
886
        }
887
888
        $form = new FormValidator('searchDate', 'get');
889
        $form->addHidden('display', 'company');
890
        $today = new DateTime();
891
        if (empty($startDate)) {
892
            $startDate = api_get_local_time($today->modify('first day of this month')->format('Y-m-d'));
893
        }
894
        if (empty($endDate)) {
895
            $endDate = api_get_local_time($today->modify('last day of this month')->format('Y-m-d'));
896
        }
897
        $form->addDatePicker(
898
            'startDate',
899
            get_lang('DateStart'),
900
            [
901
                'value' => $startDate,
902
            ]);
903
        $form->addDatePicker(
904
            'endDate',
905
            get_lang('DateEnd'),
906
            [
907
                'value' => $endDate,
908
            ]);
909
        $form->addButtonSearch(get_lang('Search'));
910
        if (count($companys) != 0) {
911
            //$form->addButtonSave(get_lang('Ok'), 'export');
912
            $form
913
                ->addButton(
914
                    'export_csv',
915
                    get_lang('ExportAsCSV'),
916
                    'check',
917
                    'primary',
918
                    null,
919
                    null,
920
                    [
921
                    ]
922
                );
923
        }
924
925
        $tableContent = $form->returnForm();
926
        $tableContent .= $tableHtml;
927
        // $tableContent .= $table->return_table();
928
929
        $tpl = new Template('', false, false, false, false, false, false);
930
        $tpl->assign('table', $tableContent);
931
        $templateName = $tpl->get_template('my_space/course_summary.tpl');
932
        $tpl->display($templateName);
933
    }
934
935
    /**
936
     *  Displays a list as a table of teachers who are set authors by a extra_field authors.
937
     *
938
     * @param string|null $startDate
939
     * @param string|null $endDate
940
     * @param bool        $csv
941
     */
942
    public static function displayResumeLP(
943
        $startDate = null,
944
        $endDate = null,
945
        $csv = false
946
    ) {
947
        $tableHtml = '';
948
        $tblExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
949
        $tblExtraFieldValue = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
950
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
951
        $query = "
952
        SELECT
953
            item_id AS lp_id,
954
            REPLACE (s.value, ';', ',') AS users_id
955
        FROM
956
            $tblExtraFieldValue s
957
        INNER JOIN $tblExtraField sf ON (s.field_id = sf.id)
958
        WHERE
959
            field_id IN (
960
                SELECT
961
                    id
962
                FROM
963
                    $tblExtraField
964
                WHERE
965
                    variable = 'authors'
966
            )
967
        AND sf.extra_field_type = ".ExtraField::FIELD_TYPE_DATE."
968
        AND (s.value != '' OR s.value IS NOT NULL)
969
";
970
        $queryResult = Database::query($query);
971
        $data = [];
972
        while ($row = Database::fetch_array($queryResult, 'ASSOC')) {
973
            $lp_id = (int) $row['lp_id'];
974
            $registeredUsers = self::getCompanyLearnpathSubscription($startDate, $endDate, $lp_id);
975
            if (!empty($registeredUsers)) {
976
                $lpInfo = [];
977
                $teacherList = [];
978
                $teachersId = explode(',', trim($row['users_id'], ","));
979
                $lp_table = Database::get_course_table(TABLE_LP_MAIN);
980
                $query = "
981
            SELECT $lp_table.*,
982
                   $tblCourse.title as courseTitle,
983
                   $tblCourse.code as courseCode
984
            FROM
985
                $lp_table
986
            INNER JOIN $tblCourse ON $tblCourse.id = $lp_table.c_id
987
            WHERE
988
                $lp_table.iid = $lp_id
989
                ";
990
                $res = Database::query($query);
991
                if (Database::num_rows($res)) {
992
                    $lpInfo = Database::fetch_array($res);
993
                }
994
                $studentUsers = [];
995
                for ($i = 0; $i < count($registeredUsers); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
996
                    $studentUsers[] = api_get_user_info($registeredUsers[$i]);
997
                }
998
                $teacherList = [];
999
                for ($i = 0; $i < count($teachersId); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1000
                    $teacherId = $teachersId[$i];
1001
                    $teacher = api_get_user_info($teacherId);
1002
                    $data[$teacher['complete_name']][$lpInfo['name']] = [
1003
                        'students' => count($studentUsers),
1004
                        'studentList' => $studentUsers,
1005
                        'lpInfo' => $lpInfo,
1006
                    ];
1007
                    $teacherList[] = $teacher;
1008
                }
1009
            }
1010
        }
1011
        if ($csv == false) {
1012
            $table = "<div class='table-responsive'>".
1013
                "<table class='table table-hover table-striped table-bordered data_table'>".
1014
                "<thead>".
1015
                "<tr>".
1016
                "<th class=\"th-header\">".get_lang('Author')."</th>".
1017
                "<th class=\"th-header\">".get_lang('LearningPathList')."</th>".
1018
                "<th class=\"th-header\">".get_lang('CountOfSubscribedUsers')."</th>".
1019
                "<th class=\"th-header\">".get_lang('StudentList')."</th>".
1020
                "</tr>".
1021
                "</thead>".
1022
                "<tbody>";
1023
            $index = 0;
1024
            //icons for show and hode
1025
            $iconAdd = Display::return_icon('add.png', get_lang('ShowOrHide'), '', ICON_SIZE_SMALL);
1026
            $iconRemove = Display::return_icon('error.png', get_lang('ShowOrHide'), '', ICON_SIZE_SMALL);
1027
            $teacherNameTemp = '';
1028
            foreach ($data as $teacherName => $reportData) {
1029
                $lpCount = 0;
1030
                $totalStudent = 0;
1031
                foreach ($reportData as $lpName => $row) {
1032
                    $hiddenField = 'student_show_'.$index;
1033
                    $hiddenFieldLink = 'student_show_'.$index.'_';
1034
                    $printTeacherName = ($teacherName == $teacherNameTemp) ? '' : $teacherName;
1035
                    $lpInfo = $row['lpInfo'];
1036
                    $teacherNameTemp = $teacherName;
1037
                    $table .=
1038
                        "<tr>".
1039
                        "<td>$printTeacherName</td>".
1040
                        "<td>$lpName</td>".
1041
                        "<td>".$row['students']."</td>".
1042
                        "<td>".
1043
                        "<a href='#!' id='$hiddenFieldLink' onclick='showHideStudent(\"$hiddenField\")'>".
1044
                        "<div class='icon_add'>$iconAdd</div>".
1045
                        "<div class='icon_remove hidden'>$iconRemove</div>".
1046
                        "</a>".
1047
                        "<div id='$hiddenField' class='hidden'>";
1048
                    foreach ($row['studentList'] as $student) {
1049
                        $reportLink = Display::url(
1050
                            Display::return_icon('statistics.png', get_lang('Stats')),
1051
                            api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?details=true&student='.
1052
                            $student['id']
1053
                            .'&id_session='.$lpInfo['session_id']
1054
                            .'&course='.$lpInfo['courseCode']
1055
                        );
1056
                        $table .= "$reportLink ".$student['complete_name']."<br>";
1057
                        $totalStudent++;
1058
                    }
1059
                    $index++;
1060
                    $lpCount++;
1061
                    $table .= "</div>".
1062
                        "</td>".
1063
                        "</tr>";
1064
                }
1065
                $table .=
1066
                    "<tr>".
1067
                    "<td></td>".
1068
                    "<td><strong>".get_lang('LearnpathsTotal')." $lpCount</strong></td>".
1069
                    "<td><strong>$totalStudent</strong></td>".
1070
                    "<td></td>".
1071
                    "</tr>";
1072
            }
1073
            $table .= "</tbody>".
1074
                "</table>".
1075
                "</div>";
1076
            if (!empty($startDate) or !empty($endDate)) {
1077
                $tableHtml = $table;
1078
            }
1079
1080
            $form = new FormValidator('searchDate', 'get');
1081
            $form->addHidden('display', 'learningPath');
1082
            $today = new DateTime();
1083
            if (empty($startDate)) {
1084
                $startDate = $today->modify('first day of this month')->format('Y-m-d');
1085
            }
1086
            if (empty($endDate)) {
1087
                $endDate = $today->modify('last day of this month')->format('Y-m-d');
1088
            }
1089
            $form->addDatePicker(
1090
                'startDate',
1091
                get_lang('DateStart'),
1092
                [
1093
                    'value' => $startDate,
1094
                ]);
1095
            $form->addDatePicker(
1096
                'endDate',
1097
                get_lang('DateEnd'),
1098
                [
1099
                    'value' => $endDate,
1100
                ]);
1101
            $form->addButtonSearch(get_lang('Search'));
1102
            if (count($data) != 0) {
1103
                //$form->addButtonSave(get_lang('Ok'), 'export');
1104
                $form
1105
                    ->addButton(
1106
                        'export_csv',
1107
                        get_lang('ExportAsCSV'),
1108
                        'check',
1109
                        'primary',
1110
                        null,
1111
                        null,
1112
                        [
1113
                        ]
1114
                    );
1115
            }
1116
            $tableContent = $form->returnForm();
1117
            $tableContent .= $tableHtml;
1118
            $tpl = new Template('', false, false, false, false, false, false);
1119
            $tpl->assign('table', $tableContent);
1120
            $templateName = $tpl->get_template('my_space/course_summary.tpl');
1121
            $tpl->display($templateName);
1122
        } else {
1123
            $csv_content = [];
1124
            $csv_row = [];
1125
            $csv_row[] = get_lang('Author');
1126
            $csv_row[] = get_lang('LearningPathList');
1127
            $csv_row[] = get_lang('CountOfSubscribedUsers');
1128
            $csv_row[] = get_lang('StudentList');
1129
            $csv_content[] = $csv_row;
1130
            foreach ($data as $teacherName => $reportData) {
1131
                foreach ($reportData as $lpName => $row) {
1132
                    $csv_row = [];
1133
                    $csv_row[] = $teacherName;
1134
                    $csv_row[] = $lpName;
1135
                    $csv_row[] = $row['students'];
1136
                    $studentsName = '';
1137
                    foreach ($row['studentList'] as $student) {
1138
                        $studentsName .= $student['complete_name']." / ";
1139
                    }
1140
                    $csv_row[] = trim($studentsName, " / ");
1141
                    $csv_content[] = $csv_row;
1142
                }
1143
            }
1144
            Export::arrayToCsv($csv_content, 'reporting_lp_by_authors');
1145
        }
1146
    }
1147
1148
    /**
1149
     *  Displays a list as a table of teachers who are set authors of lp's item by a extra_field authors.
1150
     *
1151
     * @param string|null $startDate
1152
     * @param string|null $endDate
1153
     * @param bool        $csv
1154
     */
1155
    public static function displayResumeLpByItem(
1156
        $startDate = null,
1157
        $endDate = null,
1158
        $csv = false
1159
    ) {
1160
        $tableHtml = '';
1161
        $table = '';
1162
        $tblExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
1163
        $tblExtraFieldValue = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
1164
        $extraFieldLpByAutorName = 'authorlpitem';
1165
        $extraFieldLpPrice = 'price';
1166
1167
        $queryExtraFieldPrice = "SELECT id  ".
1168
            " FROM $tblExtraField ".
1169
            " WHERE variable = '$extraFieldLpPrice'";
1170
        $queryExtraFieldValue = "SELECT id ".
1171
            " FROM $tblExtraField ".
1172
            " WHERE variable = '$extraFieldLpByAutorName'";
1173
1174
        // search items of lp
1175
        $cLpItemsQuery = "select item_id as lp_item_id ".
1176
            " from $tblExtraFieldValue ".
1177
            " where field_id IN ( $queryExtraFieldValue ) ".
1178
            " group by lp_item_id";
1179
        $queryResult = Database::query($cLpItemsQuery);
1180
        $cLpItems = [];
1181
        while ($row = Database::fetch_array($queryResult, 'ASSOC')) {
1182
            $cLpItems[] = (int) $row['lp_item_id'];
1183
        }
1184
        if (count($cLpItems) == 0) {
1185
            $tableContent = "<div class='table-responsive'>".
1186
                "<table class='table table-hover table-striped table-bordered data_table'>".
1187
                "<thead>".
1188
                "<tr>".
1189
                "<th class=\"th-header\">".get_lang('NoDataAvailable')."</th>".
1190
                "</tr>".
1191
                "</thead>".
1192
                "</tbody>".
1193
                "</tbody>".
1194
                "</table>".
1195
                "</div>";
1196
            $tableHtml = $tableContent;
1197
        } else {
1198
            $cLpItems = implode(',', $cLpItems);
1199
            // search by price
1200
            $cLpItemsPriceQuery = "select value as price, item_id as lp_item_id ".
1201
                " from $tblExtraFieldValue ".
1202
                " where field_id IN ( $queryExtraFieldPrice ) and item_id in ($cLpItems)";
1203
            $queryResult = Database::query($cLpItemsPriceQuery);
1204
            $lpItemPrice = [];
1205
            while ($row = Database::fetch_array($queryResult, 'ASSOC')) {
1206
                $lpItemPrice[$row['lp_item_id']] = $row['price'];
1207
            }
1208
            // search authors of lp
1209
            $autorsStr = '';
1210
            $autorsQuery = "select value as users_id ".
1211
                " from $tblExtraFieldValue ".
1212
                " where field_id IN ( $queryExtraFieldValue ) ".
1213
                " group by users_id ";
1214
            $queryResult = Database::query($autorsQuery);
1215
            while ($row = Database::fetch_array($queryResult, 'ASSOC')) {
1216
                $autorsStr .= " ".str_replace(';', ' ', $row['users_id']);
1217
                $autorsStr = trim($autorsStr);
1218
            }
1219
            $autorsStr = str_replace(' ', ',', $autorsStr);
1220
1221
            //search autors detailed
1222
            $authors = [];
1223
            if (!empty($autorsStr)) {
1224
                $autorsStr = explode(',', $autorsStr);
1225
                foreach ($autorsStr as $item) {
1226
                    $authors[$item] = api_get_user_info($item);
1227
                }
1228
            }
1229
            unset($autorsStr);
1230
1231
            //search info of lp's items
1232
            $cLpItemsData = [];
1233
            if (!empty($cLpItems)) {
1234
                $query = "select * ".
1235
                    " from c_lp_item ".
1236
                    " where iid in ($cLpItems)";
1237
                $queryResult = Database::query($query);
1238
                while ($row = Database::fetch_array($queryResult, 'ASSOC')) {
1239
                    $row['price'] = isset($lpItemPrice[$row['iid']]) ? $lpItemPrice[$row['iid']] : 0;
1240
                    $cLpItemsData[$row['iid']] = $row;
1241
                }
1242
            }
1243
1244
            $query = "select item_id as lp_item_id ,value as users_id ".
1245
                " from $tblExtraFieldValue ".
1246
                " where field_id IN ( $queryExtraFieldValue )";
1247
            $queryResult = Database::query($query);
1248
            $printData = [];
1249
            while ($row = Database::fetch_array($queryResult, 'ASSOC')) {
1250
                $cLpItem = (int) $row['lp_item_id'];
1251
                // get full lp data
1252
                $cLpItemData = isset($cLpItemsData[$cLpItem]) ? $cLpItemsData[$cLpItem] : [];
1253
                $authorData = $row['users_id'];
1254
                if (!empty($authorData)) {
1255
                    if (strpos($authorData, ";") === false) {
1256
                        $printData[(int) $authorData][$cLpItem] = $cLpItemData;
1257
                    } else {
1258
                        foreach (explode(';', $authorData) as $item) {
1259
                            $printData[$item][$cLpItem] = $cLpItemData;
1260
                        }
1261
                    }
1262
                }
1263
            }
1264
            $index = 0;
1265
        }
1266
        if ($csv == false) {
1267
            if (empty($tableHtml)) {
1268
                $table .= "<div class='table-responsive'>".
1269
                    "<table class='table table-hover table-striped table-bordered data_table'>".
1270
                    "<thead>".
1271
                    "<tr>".
1272
                    "<th class=\"th-header\">".get_lang('Author')."</th>".
1273
                    "<th class=\"th-header\">".get_lang('ContentList')."</th>".
1274
                    "<th class=\"th-header\">".get_lang('Tariff')."</th>".
1275
                    "<th class=\"th-header\">".get_lang('CountOfSubscribedUsers')."</th>".
1276
                    "<th class=\"th-header\">".get_lang('ToInvoice')."</th>".
1277
                    "<th class=\"th-header\">".get_lang('StudentList')."</th>".
1278
                    "</tr>".
1279
                    "</thead>".
1280
                    "<tbody>";
1281
                //Icon Constant
1282
                $iconAdd = Display::return_icon('add.png', get_lang('ShowOrHide'), '', ICON_SIZE_SMALL);
1283
                $iconRemove = Display::return_icon('error.png', get_lang('ShowOrHide'), '', ICON_SIZE_SMALL);
1284
1285
                $lastAuthor = '';
1286
                $total = 0;
1287
                foreach ($printData as $authorId => $lpItemData) {
1288
                    $autor = $authors[$authorId];
1289
                    $totalSudent = 0;
1290
                    foreach ($lpItemData as $lpItemId => $lpitem) {
1291
                        $title = $lpitem['title'];
1292
                        $price = $lpitem['price'];
1293
                        $hide = "class='author_$authorId hidden' ";
1294
                        if ($lastAuthor != $autor) {
1295
                            $table .= "<tr>";
1296
                            $table .= "<td>".$autor['complete_name'].
1297
                                "</td>";
1298
                        } else {
1299
                            $table .= "<tr $hide >";
1300
                            $table .= "<td></td>";
1301
                        }
1302
1303
                        $hiddenField = 'student_show_'.$index;
1304
                        $hiddenFieldLink = 'student_show_'.$index.'_';
1305
                        if ($lastAuthor != $autor) {
1306
                            $table .= "<td>$title".
1307
                                "</td>";
1308
                        } else {
1309
                            $table .= "<td>$title</td>";
1310
                        }
1311
                        $table .= "<td>$price</td>";
1312
                        $registeredUsers = self::getCompanyLearnpathSubscription($startDate, $endDate, $lpitem['lp_id'], true);
1313
                        $studenRegister = count($registeredUsers);
1314
                        $table .= "<td>$studenRegister</td>";
1315
                        $facturar = ($studenRegister * $price);
1316
                        $table .= "<td>$facturar</td>";
1317
                        $total += $facturar;
1318
                        $totalSudent += $studenRegister;
1319
                        if ($studenRegister != 0) {
1320
                            $table .= "<td>".
1321
                                "<a href='#!' id='$hiddenFieldLink' onclick='showHideStudent(\"$hiddenField\")'>".
1322
                                "<div class='icon_add'>$iconAdd</div>".
1323
                                "<div class='icon_remove hidden'>$iconRemove</div>".
1324
                                "</a>".
1325
                                "<div id='$hiddenField' class='hidden'>";
1326
                            for ($i = 0; $i < $studenRegister; $i++) {
1327
                                $tempStudent = api_get_user_info($registeredUsers[$i]['id']);
1328
                                $table .= $tempStudent['complete_name']." (".$registeredUsers[$i]['company'].")<br>";
1329
                            }
1330
                            $index++;
1331
                            $table .= "</div>".
1332
                                "</td>";
1333
                        } else {
1334
                            $table .= "<td></td>";
1335
                        }
1336
                        $table .= "</tr>";
1337
                        $lastAuthor = $autor;
1338
                    }
1339
                    //footer
1340
                    $table .= "<tr><th class=\"th-header\"></th>".
1341
                        "<th class=\"th-header\">".
1342
                        "<a href='#!' id='$hiddenFieldLink' onclick='ShowMoreAuthor(\"$authorId\")'>".
1343
                        "<div class='icon_add_author_$authorId'>$iconAdd</div>".
1344
                        "<div class='icon_remove_author_$authorId hidden'>$iconRemove</div>".
1345
                        "</a>"."</th>".
1346
                        "<th class=\"th-header\"></th>".
1347
                        "<th class=\"th-header\">$totalSudent</th>".
1348
                        "<th class=\"th-header\">$total</th>".
1349
                        "<th class=\"th-header\"></tr>";
1350
                    $total = 0;
1351
                }
1352
                $table .= "</tbody>".
1353
                    "</table>".
1354
                    "</div>";
1355
                $tableHtml = $table;
1356
            }
1357
1358
            $form = new FormValidator('searchDate', 'get');
1359
            $form->addHidden('display', 'learningPathByItem');
1360
            $today = new DateTime();
1361
            if (empty($startDate)) {
1362
                $startDate = $today->modify('first day of this month')->format('Y-m-d');
1363
            }
1364
            if (empty($endDate)) {
1365
                $endDate = $today->modify('last day of this month')->format('Y-m-d');
1366
            }
1367
            $form->addDatePicker(
1368
                'startDate',
1369
                get_lang('DateStart'),
1370
                [
1371
                    'value' => $startDate,
1372
                ]);
1373
            $form->addDatePicker(
1374
                'endDate',
1375
                get_lang('DateEnd'),
1376
                [
1377
                    'value' => $endDate,
1378
                ]);
1379
            $form->addButtonSearch(get_lang('Search'));
1380
1381
            if (count($printData) != 0) {
1382
                //$form->addButtonSave(get_lang('Ok'), 'export');
1383
                $form
1384
                    ->addButton(
1385
                        'export_csv',
1386
                        get_lang('ExportAsCSV'),
1387
                        'check',
1388
                        'primary',
1389
                        null,
1390
                        null,
1391
                        [
1392
                        ]
1393
                    );
1394
            }
1395
            $tableContent = $form->returnForm();
1396
            $tableContent .= $tableHtml;
1397
            $tpl = new Template('', false, false, false, false, false, false);
1398
            $tpl->assign('table', $tableContent);
1399
            $templateName = $tpl->get_template('my_space/course_summary.tpl');
1400
            $tpl->display($templateName);
1401
        } else {
1402
            $csv_content = [];
1403
            $csv_row = [];
1404
1405
            $csv_row[] = get_lang('Author');
1406
            $csv_row[] = get_lang('ContentList');
1407
            $csv_row[] = get_lang('Tariff');
1408
            $csv_row[] = get_lang('CountOfSubscribedUsers');
1409
            $csv_row[] = get_lang('ToInvoice');
1410
            $csv_row[] = get_lang('StudentList');
1411
            $csv_content[] = $csv_row;
1412
            foreach ($printData as $authorId => $lpItemData) {
1413
                $autor = $authors[$authorId];
1414
                foreach ($lpItemData as $lpItemId => $lpitem) {
1415
                    $title = $lpitem['title'];
1416
                    $price = $lpitem['price'];
1417
1418
                    $csv_row = [];
1419
                    $csv_row[] = $autor['complete_name'];
1420
                    $csv_row[] = $title;
1421
                    $csv_row[] = $price;
1422
                    $registeredUsers = self::getCompanyLearnpathSubscription($startDate, $endDate, $lpitem['lp_id'], true);
1423
                    $studenRegister = count($registeredUsers);
1424
                    $csv_row[] = $studenRegister;
1425
                    $facturar = ($studenRegister * $price);
1426
                    $csv_row[] = $facturar;
1427
                    $totalSudent += $studenRegister;
1428
                    if ($studenRegister != 0) {
1429
                        $studentsName = '';
1430
                        for ($i = 0; $i < $studenRegister; $i++) {
1431
                            $tempStudent = api_get_user_info($registeredUsers[$i]['id']);
1432
                            $studentsName .= $tempStudent['complete_name']." (".$registeredUsers[$i]['company'].") / ";
1433
1434
                            $totalStudent++;
1435
                        }
1436
                        $csv_row[] = trim($studentsName, " / ");
1437
                        $csv_content[] = $csv_row;
1438
                        $index++;
1439
                        $lpCount++;
1440
                    }
1441
                }
1442
            }
1443
            Export::arrayToCsv($csv_content, 'reporting_lp_by_authors');
1444
        }
1445
    }
1446
1447
    /**
1448
     * Display a sortable table that contains an overview of all the reporting progress of all courses.
1449
     */
1450
    public static function display_tracking_course_overview()
1451
    {
1452
        $params = ['view' => 'admin', 'display' => 'courseoverview'];
1453
        $table = new SortableTable(
1454
            'tracking_session_overview',
1455
            ['MySpace', 'get_total_number_courses'],
1456
            ['MySpace', 'get_course_data_tracking_overview'],
1457
            1,
1458
            20,
1459
            'ASC',
1460
            null, [
1461
                'class' => 'table table-transparent',
1462
            ]
1463
        );
1464
        $table->additional_parameters = $params;
1465
        $table->set_column_filter(0, ['MySpace', 'course_tracking_filter']);
1466
        $tableContent = $table->return_table();
1467
1468
        $tpl = new Template('', false, false, false, false, false, false);
1469
        $tpl->assign('table', $tableContent);
1470
        $templateName = $tpl->get_template('my_space/course_summary.tpl');
1471
        $tpl->display($templateName);
1472
    }
1473
1474
    /**
1475
     * Get the total number of courses.
1476
     *
1477
     * @return int Total number of courses
1478
     */
1479
    public static function get_total_number_courses()
1480
    {
1481
        return CourseManager::count_courses(api_get_current_access_url_id());
1482
    }
1483
1484
    /**
1485
     * Get data for the courses.
1486
     *
1487
     * @param int    $from        Inferior limit
1488
     * @param int    $numberItems Number of items to select
1489
     * @param string $column      Column to order on
1490
     * @param string $direction   Order direction
1491
     *
1492
     * @return array Results
1493
     */
1494
    public static function get_course_data_tracking_overview(
1495
        $from,
1496
        $numberItems,
1497
        $column,
1498
        $direction
1499
    ) {
1500
        $courses = CourseManager::get_courses_list(
1501
            $from,
1502
            $numberItems,
1503
            $column,
1504
            $direction,
1505
             -1,
1506
            '',
1507
            api_get_current_access_url_id()
1508
        );
1509
1510
        $list = [];
1511
        foreach ($courses as $course) {
1512
            $list[] = [
1513
                '0' => $course['code'],
1514
                'col0' => $course['code'],
1515
            ];
1516
        }
1517
1518
        return $list;
1519
    }
1520
1521
    /**
1522
     * Fills in course reporting data.
1523
     *
1524
     * @param int course code
1525
     * @param array $url_params additional url parameters
1526
     * @param array $row        the row information (the other columns)
1527
     *
1528
     * @return string html code
1529
     */
1530
    public static function course_tracking_filter($course_code, $url_params, $row)
1531
    {
1532
        $course_code = $row[0];
1533
        $courseInfo = api_get_course_info($course_code);
1534
        $courseId = $courseInfo['real_id'];
1535
1536
        $tpl = new Template('', false, false, false, false, false, false);
1537
        $data = null;
1538
1539
        // database table definition
1540
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1541
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1542
1543
        // getting all the courses of the user
1544
        $sql = "SELECT *
1545
                FROM $tbl_user AS u
1546
                INNER JOIN $tbl_course_rel_user AS cu
1547
                ON cu.user_id = u.user_id
1548
                WHERE cu.c_id = '".$courseId."'";
1549
        $result = Database::query($sql);
1550
        $time_spent = 0;
1551
        $progress = 0;
1552
        $nb_progress_lp = 0;
1553
        $score = 0;
1554
        $nb_score_lp = 0;
1555
        $nb_messages = 0;
1556
        $nb_assignments = 0;
1557
        $last_login_date = false;
1558
        $total_score_obtained = 0;
1559
        $total_score_possible = 0;
1560
        $total_questions_answered = 0;
1561
        while ($row = Database::fetch_object($result)) {
1562
            // get time spent in the course and session
1563
            $time_spent += Tracking::get_time_spent_on_the_course(
1564
                $row->user_id,
1565
                $courseInfo['real_id']
1566
            );
1567
            $progress_tmp = Tracking::get_avg_student_progress(
1568
                $row->user_id,
1569
                $course_code,
1570
                [],
1571
                null,
1572
                true
1573
            );
1574
            $progress += $progress_tmp[0];
1575
            $nb_progress_lp += $progress_tmp[1];
1576
            $score_tmp = Tracking::get_avg_student_score(
1577
                $row->user_id,
1578
                $course_code,
1579
                [],
1580
                null,
1581
                true
1582
            );
1583
            if (is_array($score_tmp)) {
1584
                $score += $score_tmp[0];
1585
                $nb_score_lp += $score_tmp[1];
1586
            }
1587
            $nb_messages += Tracking::count_student_messages(
1588
                $row->user_id,
1589
                $course_code
1590
            );
1591
            $nb_assignments += Tracking::count_student_assignments(
1592
                $row->user_id,
1593
                $course_code
1594
            );
1595
            $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
1596
                $row->user_id,
1597
                $courseInfo,
1598
                null,
1599
                false
1600
            );
1601
            if (false != $last_login_date_tmp &&
1602
                false == $last_login_date
1603
            ) { // TODO: To be cleaned
1604
                $last_login_date = $last_login_date_tmp;
1605
            } elseif (false != $last_login_date_tmp && false != $last_login_date) {
1606
                // TODO: Repeated previous condition. To be cleaned.
1607
                // Find the max and assign it to first_login_date
1608
                if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1609
                    $last_login_date = $last_login_date_tmp;
1610
                }
1611
            }
1612
1613
            $exercise_results_tmp = self::exercises_results($row->user_id, $course_code);
1614
            $total_score_obtained += $exercise_results_tmp['score_obtained'];
1615
            $total_score_possible += $exercise_results_tmp['score_possible'];
1616
            $total_questions_answered += $exercise_results_tmp['questions_answered'];
1617
        }
1618
        if ($nb_progress_lp > 0) {
1619
            $avg_progress = round($progress / $nb_progress_lp, 2);
1620
        } else {
1621
            $avg_progress = 0;
1622
        }
1623
        if ($nb_score_lp > 0) {
1624
            $avg_score = round($score / $nb_score_lp, 2);
1625
        } else {
1626
            $avg_score = '-';
1627
        }
1628
        if ($last_login_date) {
1629
            $last_login_date = api_convert_and_format_date(
1630
                $last_login_date,
1631
                DATE_FORMAT_SHORT,
1632
                date_default_timezone_get()
1633
            );
1634
        } else {
1635
            $last_login_date = '-';
1636
        }
1637
        if ($total_score_possible > 0) {
1638
            $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1639
        } else {
1640
            $total_score_percentage = 0;
1641
        }
1642
        if ($total_score_percentage > 0) {
1643
            $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
1644
        } else {
1645
            $total_score = '-';
1646
        }
1647
1648
        $data = [
1649
            'course_code' => $course_code,
1650
            'id' => $courseId,
1651
            'image' => $courseInfo['course_image_large'],
1652
            'image_small' => $courseInfo['course_image'],
1653
            'title' => $courseInfo['title'],
1654
            'url' => $courseInfo['course_public_url'],
1655
            'category' => $courseInfo['categoryName'],
1656
            'time_spent' => api_time_to_hms($time_spent),
1657
            'avg_progress' => $avg_progress,
1658
            'avg_score' => $avg_score,
1659
            'number_message' => $nb_messages,
1660
            'number_assignments' => $nb_assignments,
1661
            'total_score' => $total_score,
1662
            'questions_answered' => $total_questions_answered,
1663
            'last_login' => $last_login_date,
1664
        ];
1665
1666
        $tpl->assign('data', $data);
1667
        $layout = $tpl->get_template('my_space/partials/tracking_course_overview.tpl');
1668
        $content = $tpl->fetch($layout);
1669
1670
        return $content;
1671
    }
1672
1673
    /**
1674
     * This function exports the table that we see in display_tracking_course_overview().
1675
     */
1676
    public static function export_tracking_course_overview()
1677
    {
1678
        // database table definition
1679
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1680
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1681
1682
        // the values of the sortable table
1683
        if ($_GET['tracking_course_overview_page_nr']) {
1684
            $from = $_GET['tracking_course_overview_page_nr'];
1685
        } else {
1686
            $from = 0;
1687
        }
1688
        if ($_GET['tracking_course_overview_column']) {
1689
            $orderby = $_GET['tracking_course_overview_column'];
1690
        } else {
1691
            $orderby = 0;
1692
        }
1693
1694
        if ($_GET['tracking_course_overview_direction']) {
1695
            $direction = $_GET['tracking_course_overview_direction'];
1696
        } else {
1697
            $direction = 'ASC';
1698
        }
1699
1700
        $course_data = self::get_course_data_tracking_overview(
1701
            $from,
1702
            1000,
1703
            $orderby,
1704
            $direction
1705
        );
1706
1707
        $csv_content = [];
1708
1709
        // the first line of the csv file with the column headers
1710
        $csv_row = [];
1711
        $csv_row[] = get_lang('Course');
1712
        $csv_row[] = get_lang('Time');
1713
        $csv_row[] = get_lang('Progress');
1714
        $csv_row[] = get_lang('Average score in learning paths');
1715
        $csv_row[] = get_lang('Total number of messages');
1716
        $csv_row[] = get_lang('Total number of assignments');
1717
        $csv_row[] = get_lang('Total score obtained for tests');
1718
        $csv_row[] = get_lang('Total possible score for tests');
1719
        $csv_row[] = get_lang('Number of tests answered');
1720
        $csv_row[] = get_lang('Total score percentage for tests');
1721
        $csv_row[] = get_lang('Latest login');
1722
        $csv_content[] = $csv_row;
1723
1724
        // the other lines (the data)
1725
        foreach ($course_data as $key => $course) {
1726
            $course_code = $course[0];
1727
            $courseInfo = api_get_course_info($course_code);
1728
            $course_title = $courseInfo['title'];
1729
            $courseId = $courseInfo['real_id'];
1730
1731
            $csv_row = [];
1732
            $csv_row[] = $course_title;
1733
1734
            // getting all the courses of the session
1735
            $sql = "SELECT *
1736
                    FROM $tbl_user AS u
1737
                    INNER JOIN $tbl_course_rel_user AS cu
1738
                    ON cu.user_id = u.user_id
1739
                    WHERE cu.c_id = '".$courseId."'";
1740
            $result = Database::query($sql);
1741
            $time_spent = 0;
1742
            $progress = 0;
1743
            $nb_progress_lp = 0;
1744
            $score = 0;
1745
            $nb_score_lp = 0;
1746
            $nb_messages = 0;
1747
            $nb_assignments = 0;
1748
            $last_login_date = false;
1749
            $total_score_obtained = 0;
1750
            $total_score_possible = 0;
1751
            $total_questions_answered = 0;
1752
            while ($row = Database::fetch_object($result)) {
1753
                // get time spent in the course and session
1754
                $time_spent += Tracking::get_time_spent_on_the_course(
1755
                    $row->user_id,
1756
                    $courseId
1757
                );
1758
                $progress_tmp = Tracking::get_avg_student_progress(
1759
                    $row->user_id,
1760
                    $course_code,
1761
                    [],
1762
                    null,
1763
                    true
1764
                );
1765
                $progress += $progress_tmp[0];
1766
                $nb_progress_lp += $progress_tmp[1];
1767
                $score_tmp = Tracking::get_avg_student_score(
1768
                    $row->user_id,
1769
                    $course_code,
1770
                    [],
1771
                    null,
1772
                    true
1773
                );
1774
                if (is_array($score_tmp)) {
1775
                    $score += $score_tmp[0];
1776
                    $nb_score_lp += $score_tmp[1];
1777
                }
1778
                $nb_messages += Tracking::count_student_messages(
1779
                    $row->user_id,
1780
                    $course_code
1781
                );
1782
                $nb_assignments += Tracking::count_student_assignments(
1783
                    $row->user_id,
1784
                    $course_code
1785
                );
1786
1787
                $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
1788
                    $row->user_id,
1789
                    $courseInfo,
1790
                    null,
1791
                    false
1792
                );
1793
                if (false != $last_login_date_tmp && false == $last_login_date) {
1794
                    // TODO: To be cleaned.
1795
                    $last_login_date = $last_login_date_tmp;
1796
                } elseif (false != $last_login_date_tmp && false == $last_login_date) {
1797
                    // TODO: Repeated previous condition. To be cleaned.
1798
                    // Find the max and assign it to first_login_date
1799
                    if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1800
                        $last_login_date = $last_login_date_tmp;
1801
                    }
1802
                }
1803
1804
                $exercise_results_tmp = self::exercises_results($row->user_id, $course_code);
1805
                $total_score_obtained += $exercise_results_tmp['score_obtained'];
1806
                $total_score_possible += $exercise_results_tmp['score_possible'];
1807
                $total_questions_answered += $exercise_results_tmp['questions_answered'];
1808
            }
1809
            if ($nb_progress_lp > 0) {
1810
                $avg_progress = round($progress / $nb_progress_lp, 2);
1811
            } else {
1812
                $avg_progress = 0;
1813
            }
1814
            if ($nb_score_lp > 0) {
1815
                $avg_score = round($score / $nb_score_lp, 2);
1816
            } else {
1817
                $avg_score = '-';
1818
            }
1819
            if ($last_login_date) {
1820
                $last_login_date = api_convert_and_format_date(
1821
                    $last_login_date,
1822
                    DATE_FORMAT_SHORT,
1823
                    date_default_timezone_get()
1824
                );
1825
            } else {
1826
                $last_login_date = '-';
1827
            }
1828
            if ($total_score_possible > 0) {
1829
                $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1830
            } else {
1831
                $total_score_percentage = 0;
1832
            }
1833
            // time spent in the course
1834
            $csv_row[] = api_time_to_hms($time_spent);
1835
            // student progress in course
1836
            $csv_row[] = $avg_progress;
1837
            // student score
1838
            $csv_row[] = $avg_score;
1839
            // student messages
1840
            $csv_row[] = $nb_messages;
1841
            // student assignments
1842
            $csv_row[] = $nb_assignments;
1843
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
1844
            $csv_row[] = $total_score_obtained;
1845
            $csv_row[] = $total_score_possible;
1846
            $csv_row[] = $total_questions_answered;
1847
            $csv_row[] = $total_score_percentage;
1848
            // last connection
1849
            $csv_row[] = $last_login_date;
1850
            $csv_content[] = $csv_row;
1851
        }
1852
        Export::arrayToCsv($csv_content, 'reporting_course_overview');
1853
        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...
1854
    }
1855
1856
    /**
1857
     * Display a sortable table that contains an overview of all the reporting
1858
     * progress of all sessions and all courses the user is subscribed to.
1859
     *
1860
     * @author Guillaume Viguier <[email protected]>
1861
     */
1862
    public static function display_tracking_session_overview()
1863
    {
1864
        $head = '<table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
1865
        $head .= '<tr>';
1866
        $head .= '<th width="155px" style="border-left:0;border-bottom:0"><span>'.get_lang('Course').'</span></th>';
1867
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('Time'), 6, true).'</span></th>';
1868
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('Progress'), 6, true).'</span></th>';
1869
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('Average score in learning paths'), 6, true).'</span></th>';
1870
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('Total number of messages'), 6, true).'</span></th>';
1871
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('Total number of assignments'), 6, true).'</span></th>';
1872
        $head .= '<th width="105px" style="border-bottom:0"><span>'.get_lang('Total score obtained for tests').'</span></th>';
1873
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('Number of tests answered'), 6, true).'</span></th>';
1874
        $head .= '<th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('Latest login').'</span></th>';
1875
        $head .= '</tr></table>';
1876
1877
        $params = ['view' => 'admin', 'display' => 'sessionoverview'];
1878
        $table = new SortableTable(
1879
            'tracking_session_overview',
1880
            ['MySpace', 'get_total_number_sessions'],
1881
            ['MySpace', 'get_session_data_tracking_overview'],
1882
            1
1883
        );
1884
        $table->additional_parameters = $params;
1885
1886
        $table->set_header(0, '', false, null, ['style' => 'display: none']);
1887
        $table->set_header(
1888
            1,
1889
            get_lang('Session'),
1890
            true,
1891
            ['style' => 'font-size:8pt'],
1892
            ['style' => 'font-size:8pt']
1893
        );
1894
        $table->set_header(
1895
            2,
1896
            $head,
1897
            false,
1898
            ['style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'],
1899
            ['style' => 'width:90%;padding:0;font-size:7.5pt;']
1900
        );
1901
        $table->set_column_filter(2, ['MySpace', 'session_tracking_filter']);
1902
        $table->display();
1903
    }
1904
1905
    /**
1906
     * Get the total number of sessions.
1907
     *
1908
     * @return int Total number of sessions
1909
     */
1910
    public static function get_total_number_sessions()
1911
    {
1912
        return SessionManager::count_sessions(api_get_current_access_url_id());
1913
    }
1914
1915
    /**
1916
     * Get data for the sessions.
1917
     *
1918
     * @param int    $from        Inferior limit
1919
     * @param int    $numberItems Number of items to select
1920
     * @param string $column      Column to order on
1921
     * @param string $direction   Order direction
1922
     *
1923
     * @return array Results
1924
     */
1925
    public static function get_session_data_tracking_overview(
1926
        $from,
1927
        $numberItems,
1928
        $column,
1929
        $direction
1930
    ) {
1931
        $from = (int) $from;
1932
        $numberItems = (int) $numberItems;
1933
        $direction = Database::escape_string($direction);
1934
        $columnName = 'name';
1935
        if (1 === $column) {
1936
            $columnName = 'id';
1937
        }
1938
1939
        $options = [
1940
            'order' => " $columnName $direction",
1941
            'limit' => " $from,$numberItems",
1942
        ];
1943
        $sessions = SessionManager::formatSessionsAdminForGrid($options);
1944
        $list = [];
1945
        foreach ($sessions as $session) {
1946
            $list[] = [
1947
                '0' => $session['id'],
1948
                'col0' => $session['id'],
1949
                '1' => strip_tags($session['name']),
1950
                'col1' => strip_tags($session['name']),
1951
            ];
1952
        }
1953
1954
        return $list;
1955
    }
1956
1957
    /**
1958
     * Fills in session reporting data.
1959
     *
1960
     * @param int   $session_id the id of the user
1961
     * @param array $url_params additonal url parameters
1962
     * @param array $row        the row information (the other columns)
1963
     *
1964
     * @return string html code
1965
     */
1966
    public static function session_tracking_filter($session_id, $url_params, $row)
1967
    {
1968
        $session_id = $row[0];
1969
        // the table header
1970
        $return = '<table class="data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
1971
1972
        // database table definition
1973
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1974
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
1975
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1976
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1977
1978
        // getting all the courses of the user
1979
        $sql = "SELECT * FROM $tbl_course AS c
1980
                INNER JOIN $tbl_session_rel_course AS sc
1981
                ON sc.c_id = c.id
1982
                WHERE sc.session_id = '".$session_id."'";
1983
        $result = Database::query($sql);
1984
        while ($row = Database::fetch_object($result)) {
1985
            $courseId = $row->c_id;
1986
            $courseInfo = api_get_course_info_by_id($courseId);
1987
            $return .= '<tr>';
1988
            // course code
1989
            $return .= '    <td width="157px" >'.$row->title.'</td>';
1990
            // get the users in the course
1991
            $sql = "SELECT u.user_id
1992
                    FROM $tbl_user AS u
1993
                    INNER JOIN $tbl_session_rel_course_rel_user AS scu
1994
                    ON u.user_id = scu.user_id
1995
                    WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
1996
            $result_users = Database::query($sql);
1997
            $time_spent = 0;
1998
            $progress = 0;
1999
            $nb_progress_lp = 0;
2000
            $score = 0;
2001
            $nb_score_lp = 0;
2002
            $nb_messages = 0;
2003
            $nb_assignments = 0;
2004
            $last_login_date = false;
2005
            $total_score_obtained = 0;
2006
            $total_score_possible = 0;
2007
            $total_questions_answered = 0;
2008
            while ($row_user = Database::fetch_object($result_users)) {
2009
                // get time spent in the course and session
2010
                $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
2011
                $progress_tmp = Tracking::get_avg_student_progress($row_user->user_id, $row->code, [], $session_id, true);
2012
                $progress += $progress_tmp[0];
2013
                $nb_progress_lp += $progress_tmp[1];
2014
                $score_tmp = Tracking::get_avg_student_score($row_user->user_id, $row->code, [], $session_id, true);
2015
                if (is_array($score_tmp)) {
2016
                    $score += $score_tmp[0];
2017
                    $nb_score_lp += $score_tmp[1];
2018
                }
2019
                $nb_messages += Tracking::count_student_messages($row_user->user_id, $row->code, $session_id);
2020
                $nb_assignments += Tracking::count_student_assignments($row_user->user_id, $row->code, $session_id);
2021
                $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
2022
                    $row_user->user_id,
2023
                    $courseInfo,
2024
                    $session_id,
2025
                    false
2026
                );
2027
                if (false != $last_login_date_tmp && false == $last_login_date) {
2028
                    // TODO: To be cleaned.
2029
                    $last_login_date = $last_login_date_tmp;
2030
                } elseif (false != $last_login_date_tmp && false != $last_login_date) {
2031
                    // TODO: Repeated previous condition! To be cleaned.
2032
                    // Find the max and assign it to first_login_date
2033
                    if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
2034
                        $last_login_date = $last_login_date_tmp;
2035
                    }
2036
                }
2037
2038
                $exercise_results_tmp = self::exercises_results($row_user->user_id, $row->code, $session_id);
2039
                $total_score_obtained += $exercise_results_tmp['score_obtained'];
2040
                $total_score_possible += $exercise_results_tmp['score_possible'];
2041
                $total_questions_answered += $exercise_results_tmp['questions_answered'];
2042
            }
2043
            if ($nb_progress_lp > 0) {
2044
                $avg_progress = round($progress / $nb_progress_lp, 2);
2045
            } else {
2046
                $avg_progress = 0;
2047
            }
2048
            if ($nb_score_lp > 0) {
2049
                $avg_score = round($score / $nb_score_lp, 2);
2050
            } else {
2051
                $avg_score = '-';
2052
            }
2053
            if ($last_login_date) {
2054
                $last_login_date = api_convert_and_format_date(
2055
                    $last_login_date,
2056
                    DATE_FORMAT_SHORT,
2057
                    date_default_timezone_get()
2058
                );
2059
            } else {
2060
                $last_login_date = '-';
2061
            }
2062
            if ($total_score_possible > 0) {
2063
                $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
2064
            } else {
2065
                $total_score_percentage = 0;
2066
            }
2067
            if ($total_score_percentage > 0) {
2068
                $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
2069
            } else {
2070
                $total_score = '-';
2071
            }
2072
            // time spent in the course
2073
            $return .= '    <td><div>'.api_time_to_hms($time_spent).'</div></td>';
2074
            // student progress in course
2075
            $return .= '    <td><div>'.$avg_progress.'</div></td>';
2076
            // student score
2077
            $return .= '    <td><div>'.$avg_score.'</div></td>';
2078
            // student messages
2079
            $return .= '    <td><div>'.$nb_messages.'</div></td>';
2080
            // student assignments
2081
            $return .= '    <td><div>'.$nb_assignments.'</div></td>';
2082
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
2083
            $return .= '<td width="105px;">'.$total_score.'</td>';
2084
            $return .= '<td>'.$total_questions_answered.'</td>';
2085
            // last connection
2086
            $return .= '    <td><div>'.$last_login_date.'</div></td>';
2087
            $return .= '<tr>';
2088
        }
2089
        $return .= '</table>';
2090
2091
        return $return;
2092
    }
2093
2094
    /**
2095
     * This function exports the table that we see in display_tracking_session_overview().
2096
     */
2097
    public static function export_tracking_session_overview()
2098
    {
2099
        // database table definition
2100
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2101
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
2102
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2103
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2104
2105
        // the values of the sortable table
2106
        $from = 0;
2107
        if ($_GET['tracking_session_overview_page_nr']) {
2108
            $from = $_GET['tracking_session_overview_page_nr'];
2109
        }
2110
2111
        $orderby = 0;
2112
        if ($_GET['tracking_session_overview_column']) {
2113
            $orderby = $_GET['tracking_session_overview_column'];
2114
        }
2115
2116
        $direction = 'ASC';
2117
        if ($_GET['tracking_session_overview_direction']) {
2118
            $direction = $_GET['tracking_session_overview_direction'];
2119
        }
2120
2121
        $session_data = self::get_session_data_tracking_overview($from, 1000, $orderby, $direction);
2122
2123
        $csv_content = [];
2124
2125
        // the first line of the csv file with the column headers
2126
        $csv_row = [];
2127
        $csv_row[] = get_lang('Session');
2128
        $csv_row[] = get_lang('Course');
2129
        $csv_row[] = get_lang('Time');
2130
        $csv_row[] = get_lang('Progress');
2131
        $csv_row[] = get_lang('Average score in learning paths');
2132
        $csv_row[] = get_lang('Total number of messages');
2133
        $csv_row[] = get_lang('Total number of assignments');
2134
        $csv_row[] = get_lang('Total score obtained for tests');
2135
        $csv_row[] = get_lang('Total possible score for tests');
2136
        $csv_row[] = get_lang('Number of tests answered');
2137
        $csv_row[] = get_lang('Total score percentage for tests');
2138
        $csv_row[] = get_lang('Latest login');
2139
        $csv_content[] = $csv_row;
2140
2141
        // the other lines (the data)
2142
        foreach ($session_data as $key => $session) {
2143
            $session_id = $session[0];
2144
            $session_title = $session[1];
2145
2146
            // getting all the courses of the session
2147
            $sql = "SELECT * FROM $tbl_course AS c
2148
                    INNER JOIN $tbl_session_rel_course AS sc
2149
                    ON sc.c_id = c.id
2150
                    WHERE sc.session_id = '".$session_id."';";
2151
            $result = Database::query($sql);
2152
            while ($row = Database::fetch_object($result)) {
2153
                $courseId = $row->c_id;
2154
                $courseInfo = api_get_course_info_by_id($courseId);
2155
                $csv_row = [];
2156
                $csv_row[] = $session_title;
2157
                $csv_row[] = $row->title;
2158
                // get the users in the course
2159
                $sql = "SELECT scu.user_id
2160
                        FROM $tbl_user AS u
2161
                        INNER JOIN $tbl_session_rel_course_rel_user AS scu
2162
                        ON u.user_id = scu.user_id
2163
                        WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
2164
                $result_users = Database::query($sql);
2165
                $time_spent = 0;
2166
                $progress = 0;
2167
                $nb_progress_lp = 0;
2168
                $score = 0;
2169
                $nb_score_lp = 0;
2170
                $nb_messages = 0;
2171
                $nb_assignments = 0;
2172
                $last_login_date = false;
2173
                $total_score_obtained = 0;
2174
                $total_score_possible = 0;
2175
                $total_questions_answered = 0;
2176
                while ($row_user = Database::fetch_object($result_users)) {
2177
                    // get time spent in the course and session
2178
                    $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
2179
                    $progress_tmp = Tracking::get_avg_student_progress(
2180
                        $row_user->user_id,
2181
                        $row->code,
2182
                        [],
2183
                        $session_id,
2184
                        true
2185
                    );
2186
                    $progress += $progress_tmp[0];
2187
                    $nb_progress_lp += $progress_tmp[1];
2188
                    $score_tmp = Tracking::get_avg_student_score(
2189
                        $row_user->user_id,
2190
                        $row->code,
2191
                        [],
2192
                        $session_id,
2193
                        true
2194
                    );
2195
                    if (is_array($score_tmp)) {
2196
                        $score += $score_tmp[0];
2197
                        $nb_score_lp += $score_tmp[1];
2198
                    }
2199
                    $nb_messages += Tracking::count_student_messages(
2200
                        $row_user->user_id,
2201
                        $row->code,
2202
                        $session_id
2203
                    );
2204
2205
                    $nb_assignments += Tracking::count_student_assignments(
2206
                        $row_user->user_id,
2207
                        $row->code,
2208
                        $session_id
2209
                    );
2210
2211
                    $last_login_date_tmp = Tracking:: get_last_connection_date_on_the_course(
2212
                        $row_user->user_id,
2213
                        $courseInfo,
2214
                        $session_id,
2215
                        false
2216
                    );
2217
                    if (false != $last_login_date_tmp && false == $last_login_date) {
2218
                        // TODO: To be cleaned.
2219
                        $last_login_date = $last_login_date_tmp;
2220
                    } elseif (false != $last_login_date_tmp && false == $last_login_date) {
2221
                        // TODO: Repeated previous condition. To be cleaned.
2222
                        // Find the max and assign it to first_login_date
2223
                        if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
2224
                            $last_login_date = $last_login_date_tmp;
2225
                        }
2226
                    }
2227
2228
                    $exercise_results_tmp = self::exercises_results($row_user->user_id, $row->code, $session_id);
2229
                    $total_score_obtained += $exercise_results_tmp['score_obtained'];
2230
                    $total_score_possible += $exercise_results_tmp['score_possible'];
2231
                    $total_questions_answered += $exercise_results_tmp['questions_answered'];
2232
                }
2233
                if ($nb_progress_lp > 0) {
2234
                    $avg_progress = round($progress / $nb_progress_lp, 2);
2235
                } else {
2236
                    $avg_progress = 0;
2237
                }
2238
                if ($nb_score_lp > 0) {
2239
                    $avg_score = round($score / $nb_score_lp, 2);
2240
                } else {
2241
                    $avg_score = '-';
2242
                }
2243
                if ($last_login_date) {
2244
                    $last_login_date = api_convert_and_format_date(
2245
                        $last_login_date,
2246
                        DATE_FORMAT_SHORT,
2247
                        date_default_timezone_get()
2248
                    );
2249
                } else {
2250
                    $last_login_date = '-';
2251
                }
2252
                if ($total_score_possible > 0) {
2253
                    $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
2254
                } else {
2255
                    $total_score_percentage = 0;
2256
                }
2257
                if ($total_score_percentage > 0) {
2258
                    $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
2259
                } else {
2260
                    $total_score = '-';
2261
                }
2262
                // time spent in the course
2263
                $csv_row[] = api_time_to_hms($time_spent);
2264
                // student progress in course
2265
                $csv_row[] = $avg_progress;
2266
                // student score
2267
                $csv_row[] = $avg_score;
2268
                // student messages
2269
                $csv_row[] = $nb_messages;
2270
                // student assignments
2271
                $csv_row[] = $nb_assignments;
2272
                // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
2273
                $csv_row[] = $total_score_obtained;
2274
                $csv_row[] = $total_score_possible;
2275
                $csv_row[] = $total_questions_answered;
2276
                $csv_row[] = $total_score_percentage;
2277
                // last connection
2278
                $csv_row[] = $last_login_date;
2279
                $csv_content[] = $csv_row;
2280
            }
2281
        }
2282
        Export::arrayToCsv($csv_content, 'reporting_session_overview');
2283
        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...
2284
    }
2285
2286
    /**
2287
     * Get general information about the exercise performance of the user
2288
     * the total obtained score (all the score on all the questions)
2289
     * the maximum score that could be obtained
2290
     * the number of questions answered
2291
     * the success percentage.
2292
     *
2293
     * @param int    $user_id     the id of the user
2294
     * @param string $course_code the course code
2295
     * @param int    $session_id
2296
     *
2297
     * @return array
2298
     *
2299
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
2300
     *
2301
     * @version Dokeos 1.8.6
2302
     *
2303
     * @since November 2008
2304
     */
2305
    public static function exercises_results($user_id, $course_code, $session_id = 0)
2306
    {
2307
        $user_id = (int) $user_id;
2308
        $courseId = api_get_course_int_id($course_code);
2309
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
2310
2311
        $sql = "SELECT score, max_score
2312
                FROM $table
2313
                WHERE 
2314
                    c_id = $courseId AND 
2315
                    exe_user_id = $user_id";
2316
2317
        $session_id = (int) $session_id;
2318
        if (!empty($session_id)) {
2319
            $sql .= " AND session_id = '".$session_id."' ";
2320
        }
2321
        $result = Database::query($sql);
2322
        $score_obtained = 0;
2323
        $score_possible = 0;
2324
        $questions_answered = 0;
2325
        while ($row = Database::fetch_array($result)) {
2326
            $score_obtained += $row['score'];
2327
            $score_possible += $row['max_score'];
2328
            $questions_answered++;
2329
        }
2330
2331
        $percentage = null;
2332
        if (0 != $score_possible) {
2333
            $percentage = round(($score_obtained / $score_possible * 100), 2);
2334
        }
2335
2336
        return [
2337
            'score_obtained' => $score_obtained,
2338
            'score_possible' => $score_possible,
2339
            'questions_answered' => $questions_answered,
2340
            'percentage' => $percentage,
2341
        ];
2342
    }
2343
2344
    /**
2345
     * This function exports the table that we see in display_tracking_user_overview().
2346
     *
2347
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
2348
     *
2349
     * @version Dokeos 1.8.6
2350
     *
2351
     * @since October 2008
2352
     */
2353
    public static function export_tracking_user_overview()
2354
    {
2355
        // database table definitions
2356
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2357
        $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
2358
2359
        // the values of the sortable table
2360
        if ($_GET['tracking_user_overview_page_nr']) {
2361
            $from = $_GET['tracking_user_overview_page_nr'];
2362
        } else {
2363
            $from = 0;
2364
        }
2365
        if ($_GET['tracking_user_overview_column']) {
2366
            $orderby = $_GET['tracking_user_overview_column'];
2367
        } else {
2368
            $orderby = 0;
2369
        }
2370
        if ($is_western_name_order != api_is_western_name_order() && (1 == $orderby || 2 == $orderby)) {
2371
            // Swapping the sorting column if name order for export is different than the common name order.
2372
            $orderby = 3 - $orderby;
2373
        }
2374
        if ($_GET['tracking_user_overview_direction']) {
2375
            $direction = $_GET['tracking_user_overview_direction'];
2376
        } else {
2377
            $direction = 'ASC';
2378
        }
2379
2380
        $user_data = self::get_user_data_tracking_overview(
2381
            $from,
2382
            1000,
2383
            $orderby,
2384
            $direction
2385
        );
2386
2387
        // the first line of the csv file with the column headers
2388
        $csv_row = [];
2389
        $csv_row[] = get_lang('Code');
2390
        if ($is_western_name_order) {
2391
            $csv_row[] = get_lang('First name');
2392
            $csv_row[] = get_lang('Last name');
2393
        } else {
2394
            $csv_row[] = get_lang('Last name');
2395
            $csv_row[] = get_lang('First name');
2396
        }
2397
        $csv_row[] = get_lang('Login');
2398
        $csv_row[] = get_lang('Code');
2399
2400
        // the additional user defined fields (only those that were selected to be exported)
2401
        $fields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
2402
2403
        $additionalExportFields = Session::read('additional_export_fields');
2404
2405
        if (is_array($additionalExportFields)) {
2406
            foreach ($additionalExportFields as $key => $extra_field_export) {
2407
                $csv_row[] = $fields[$extra_field_export][3];
2408
                $field_names_to_be_exported[] = 'extra_'.$fields[$extra_field_export][1];
2409
            }
2410
        }
2411
        $csv_row[] = get_lang('Time');
2412
        $csv_row[] = get_lang('Progress');
2413
        $csv_row[] = get_lang('Average score in learning paths');
2414
        $csv_row[] = get_lang('AvgExercisesScore');
2415
        $csv_row[] = get_lang('AvgMessages');
2416
        $csv_row[] = get_lang('AvgAssignments');
2417
        $csv_row[] = get_lang('Total score obtained for tests');
2418
        $csv_row[] = get_lang('Total possible score for tests');
2419
        $csv_row[] = get_lang('Number of tests answered');
2420
        $csv_row[] = get_lang('Total score percentage for tests');
2421
        $csv_row[] = get_lang('FirstLogin');
2422
        $csv_row[] = get_lang('Latest login');
2423
        $csv_content[] = $csv_row;
2424
2425
        // the other lines (the data)
2426
        foreach ($user_data as $key => $user) {
2427
            // getting all the courses of the user
2428
            $sql = "SELECT * FROM $tbl_course_user
2429
                    WHERE user_id = '".intval($user[4])."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
2430
            $result = Database::query($sql);
2431
            while ($row = Database::fetch_row($result)) {
2432
                $courseInfo = api_get_course_info($row['course_code']);
2433
                $courseId = $courseInfo['real_id'];
2434
2435
                $csv_row = [];
2436
                // user official code
2437
                $csv_row[] = $user[0];
2438
                // user first|last name
2439
                $csv_row[] = $user[1];
2440
                // user last|first name
2441
                $csv_row[] = $user[2];
2442
                // user login name
2443
                $csv_row[] = $user[3];
2444
                // course code
2445
                $csv_row[] = $row[0];
2446
                // the additional defined user fields
2447
                $extra_fields = self::get_user_overview_export_extra_fields($user[4]);
2448
2449
                if (is_array($field_names_to_be_exported)) {
2450
                    foreach ($field_names_to_be_exported as $key => $extra_field_export) {
2451
                        $csv_row[] = $extra_fields[$extra_field_export];
2452
                    }
2453
                }
2454
                // time spent in the course
2455
                $csv_row[] = api_time_to_hms(Tracking::get_time_spent_on_the_course($user[4], $courseId));
2456
                // student progress in course
2457
                $csv_row[] = round(Tracking::get_avg_student_progress($user[4], $row[0]), 2);
2458
                // student score
2459
                $csv_row[] = round(Tracking::get_avg_student_score($user[4], $row[0]), 2);
2460
                // student tes score
2461
                $csv_row[] = round(Tracking::get_avg_student_exercise_score($user[4], $row[0]), 2);
2462
                // student messages
2463
                $csv_row[] = Tracking::count_student_messages($user[4], $row[0]);
2464
                // student assignments
2465
                $csv_row[] = Tracking::count_student_assignments($user[4], $row[0]);
2466
                // student exercises results
2467
                $exercises_results = self::exercises_results($user[4], $row[0]);
2468
                $csv_row[] = $exercises_results['score_obtained'];
2469
                $csv_row[] = $exercises_results['score_possible'];
2470
                $csv_row[] = $exercises_results['questions_answered'];
2471
                $csv_row[] = $exercises_results['percentage'];
2472
                // first connection
2473
                $csv_row[] = Tracking::get_first_connection_date_on_the_course($user[4], $courseId);
2474
                // last connection
2475
                $csv_row[] = strip_tags(Tracking::get_last_connection_date_on_the_course($user[4], $courseInfo));
2476
2477
                $csv_content[] = $csv_row;
2478
            }
2479
        }
2480
        Export::arrayToCsv($csv_content, 'reporting_user_overview');
2481
        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...
2482
    }
2483
2484
    /**
2485
     * Get data for courses list in sortable with pagination.
2486
     *
2487
     * @return array
2488
     */
2489
    public static function get_course_data($from, $number_of_items, $column, $direction)
2490
    {
2491
        global $courses, $csv_content, $charset, $session_id;
2492
2493
        // definition database tables
2494
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
2495
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2496
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2497
2498
        $course_data = [];
2499
        $courses_code = array_keys($courses);
2500
2501
        foreach ($courses_code as &$code) {
2502
            $code = "'$code'";
2503
        }
2504
2505
        // get all courses with limit
2506
        $sql = "SELECT course.code as col1, course.title as col2
2507
                FROM $tbl_course course
2508
                WHERE course.code IN (".implode(',', $courses_code).")";
2509
2510
        if (!in_array($direction, ['ASC', 'DESC'])) {
2511
            $direction = 'ASC';
2512
        }
2513
2514
        $column = intval($column);
2515
        $from = intval($from);
2516
        $number_of_items = intval($number_of_items);
2517
        $sql .= " ORDER BY col$column $direction ";
2518
        $sql .= " LIMIT $from,$number_of_items";
2519
2520
        $res = Database::query($sql);
2521
        while ($row_course = Database::fetch_row($res)) {
2522
            $course_code = $row_course[0];
2523
            $courseInfo = api_get_course_info($course_code);
2524
            $courseId = $courseInfo['real_id'];
2525
            $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;
2526
2527
            // students directly subscribed to the course
2528
            if (empty($session_id)) {
2529
                $sql = "SELECT user_id
2530
                        FROM $tbl_course_user as course_rel_user
2531
                        WHERE
2532
                            course_rel_user.status='5' AND
2533
                            course_rel_user.c_id = '$courseId'";
2534
            } else {
2535
                $sql = "SELECT user_id FROM $tbl_session_course_user srcu
2536
                        WHERE
2537
                            c_id = '$courseId' AND
2538
                            session_id = '$session_id' AND
2539
                            status<>2";
2540
            }
2541
            $rs = Database::query($sql);
2542
            $users = [];
2543
            while ($row = Database::fetch_array($rs)) {
2544
                $users[] = $row['user_id'];
2545
            }
2546
2547
            if (count($users) > 0) {
2548
                $nb_students_in_course = count($users);
2549
                $avg_assignments_in_course = Tracking::count_student_assignments($users, $course_code, $session_id);
2550
                $avg_messages_in_course = Tracking::count_student_messages($users, $course_code, $session_id);
2551
                $avg_progress_in_course = Tracking::get_avg_student_progress($users, $course_code, [], $session_id);
2552
                $avg_score_in_course = Tracking::get_avg_student_score($users, $course_code, [], $session_id);
2553
                $avg_score_in_exercise = Tracking::get_avg_student_exercise_score($users, $course_code, 0, $session_id);
2554
                $avg_time_spent_in_course = Tracking::get_time_spent_on_the_course(
2555
                    $users,
2556
                    $courseInfo['real_id'],
2557
                    $session_id
2558
                );
2559
2560
                $avg_progress_in_course = round($avg_progress_in_course / $nb_students_in_course, 2);
2561
                if (is_numeric($avg_score_in_course)) {
2562
                    $avg_score_in_course = round($avg_score_in_course / $nb_students_in_course, 2);
2563
                }
2564
                $avg_time_spent_in_course = api_time_to_hms($avg_time_spent_in_course / $nb_students_in_course);
2565
            } else {
2566
                $avg_time_spent_in_course = null;
2567
                $avg_progress_in_course = null;
2568
                $avg_score_in_course = null;
2569
                $avg_score_in_exercise = null;
2570
                $avg_messages_in_course = null;
2571
                $avg_assignments_in_course = null;
2572
            }
2573
            $table_row = [];
2574
            $table_row[] = $row_course[1];
2575
            $table_row[] = $nb_students_in_course;
2576
            $table_row[] = $avg_time_spent_in_course;
2577
            $table_row[] = is_null($avg_progress_in_course) ? '' : $avg_progress_in_course.'%';
2578
            $table_row[] = is_null($avg_score_in_course) ? '' : $avg_score_in_course.'%';
2579
            $table_row[] = is_null($avg_score_in_exercise) ? '' : $avg_score_in_exercise.'%';
2580
            $table_row[] = $avg_messages_in_course;
2581
            $table_row[] = $avg_assignments_in_course;
2582
2583
            //set the "from" value to know if I access the Reporting by the chamilo tab or the course link
2584
            $table_row[] = '<center><a href="../../tracking/courseLog.php?cidReq='.$course_code.'&from=myspace&id_session='.$session_id.'">
2585
                             '.Display::return_icon('2rightarrow.png', get_lang('Details')).'
2586
                             </a>
2587
                            </center>';
2588
2589
            $scoreInCourse = null;
2590
            if (null !== $avg_score_in_course) {
2591
                if (is_numeric($avg_score_in_course)) {
2592
                    $scoreInCourse = $avg_score_in_course.'%';
2593
                } else {
2594
                    $scoreInCourse = $avg_score_in_course;
2595
                }
2596
            }
2597
2598
            $csv_content[] = [
2599
                api_html_entity_decode($row_course[1], ENT_QUOTES, $charset),
2600
                $nb_students_in_course,
2601
                $avg_time_spent_in_course,
2602
                is_null($avg_progress_in_course) ? null : $avg_progress_in_course.'%',
2603
                $scoreInCourse,
2604
                is_null($avg_score_in_exercise) ? null : $avg_score_in_exercise.'%',
2605
                $avg_messages_in_course,
2606
                $avg_assignments_in_course,
2607
            ];
2608
            $course_data[] = $table_row;
2609
        }
2610
2611
        return $course_data;
2612
    }
2613
2614
    /**
2615
     * Get the number of users of the platform.
2616
     *
2617
     * @return int
2618
     */
2619
    public static function get_number_of_users_tracking_overview()
2620
    {
2621
        return UserManager::get_number_of_users(0, api_get_current_access_url_id());
2622
    }
2623
2624
    /**
2625
     * Get all the data for the sortable table of the reporting progress of
2626
     * all users and all the courses the user is subscribed to.
2627
     *
2628
     * @param int    $from
2629
     * @param int    $numberItems
2630
     * @param int    $column
2631
     * @param string $direction
2632
     *
2633
     * @return array
2634
     */
2635
    public static function get_user_data_tracking_overview($from, $numberItems, $column, $direction)
2636
    {
2637
        $isWestern = api_is_western_name_order();
2638
2639
        switch ($column) {
2640
            case '0':
2641
                $column = $isWestern ? 'firstname' : 'lastname';
2642
                break;
2643
        }
2644
2645
        $order = [
2646
            "$column $direction",
2647
        ];
2648
        $userList = UserManager::get_user_list([], $order, $from, $numberItems);
2649
        $return = [];
2650
        foreach ($userList as $user) {
2651
            $return[] = [
2652
                '0' => $user['user_id'],
2653
                'col0' => $user['user_id'],
2654
            ];
2655
        }
2656
2657
        return $return;
2658
    }
2659
2660
    /**
2661
     * Get all information that the user with user_id = $user_data has
2662
     * entered in the additionally defined profile fields.
2663
     *
2664
     * @param int $user_id the id of the user
2665
     *
2666
     * @return array
2667
     *
2668
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
2669
     *
2670
     * @version Dokeos 1.8.6
2671
     *
2672
     * @since November 2008
2673
     */
2674
    public static function get_user_overview_export_extra_fields($user_id)
2675
    {
2676
        // include the user manager
2677
        $data = UserManager::get_extra_user_data($user_id, true);
2678
2679
        return $data;
2680
    }
2681
2682
    /**
2683
     * Checks if a username exist in the DB otherwise it create a "double"
2684
     * i.e. if we look into for jmontoya but the user's name already exist we create the user jmontoya2
2685
     * the return array will be array(username=>'jmontoya', sufix='2').
2686
     *
2687
     * @param string firstname
2688
     * @param string lastname
2689
     * @param string username
2690
     *
2691
     * @return array with the username, the sufix
2692
     *
2693
     * @author Julio Montoya
2694
     */
2695
    public static function make_username($firstname, $lastname, $username, $language = null, $encoding = null)
2696
    {
2697
        // if username exist
2698
        if (!UserManager::is_username_available($username) || empty($username)) {
2699
            $i = 0;
2700
            while (1) {
2701
                if (0 == $i) {
2702
                    $sufix = '';
2703
                } else {
2704
                    $sufix = $i;
2705
                }
2706
                $desired_username = UserManager::create_username(
2707
                    $firstname,
2708
                    $lastname
2709
                );
2710
                if (UserManager::is_username_available($desired_username.$sufix)) {
2711
                    break;
2712
                } else {
2713
                    $i++;
2714
                }
2715
            }
2716
            $username_array = ['username' => $desired_username, 'sufix' => $sufix];
2717
2718
            return $username_array;
2719
        } else {
2720
            $username_array = ['username' => $username, 'sufix' => ''];
2721
2722
            return $username_array;
2723
        }
2724
    }
2725
2726
    /**
2727
     * Checks if there are repeted users in a given array.
2728
     *
2729
     * @param array $usernames  list of the usernames in the uploaded file
2730
     * @param array $user_array $user_array['username'] and $user_array['sufix']
2731
     *                          where suffix is the number part in a login i.e -> jmontoya2
2732
     *
2733
     * @return array with the $usernames array and the $user_array array
2734
     *
2735
     * @author Julio Montoya
2736
     */
2737
    public static function check_user_in_array($usernames, $user_array)
2738
    {
2739
        $user_list = array_keys($usernames);
2740
        $username = $user_array['username'].$user_array['sufix'];
2741
2742
        if (in_array($username, $user_list)) {
2743
            $user_array['sufix'] += $usernames[$username];
2744
            $usernames[$username]++;
2745
        } else {
2746
            $usernames[$username] = 1;
2747
        }
2748
        $result_array = [$usernames, $user_array];
2749
2750
        return $result_array;
2751
    }
2752
2753
    /**
2754
     * Checks whether a username has been already subscribed in a session.
2755
     *
2756
     * @param string $username    a given username
2757
     * @param array  $course_list the array with the course list id
2758
     * @param int    $id_session  the session id
2759
     *
2760
     * @return int 0 if the user is not subscribed otherwise it returns the user_id of the given username
2761
     *
2762
     * @author Julio Montoya
2763
     */
2764
    public static function user_available_in_session($username, $course_list, $id_session)
2765
    {
2766
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2767
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2768
        $id_session = (int) $id_session;
2769
        $username = Database::escape_string($username);
2770
        foreach ($course_list as $courseId) {
2771
            $courseId = (int) $courseId;
2772
            $sql = " SELECT u.user_id FROM $tbl_session_rel_course_rel_user rel
2773
                     INNER JOIN $table_user u
2774
                     ON (rel.user_id = u.user_id)
2775
                     WHERE
2776
                        rel.session_id='$id_session' AND
2777
                        u.status='5' AND
2778
                        u.username ='$username' AND
2779
                        rel.c_id='$courseId'";
2780
            $rs = Database::query($sql);
2781
            if (Database::num_rows($rs) > 0) {
2782
                return Database::result($rs, 0, 0);
2783
            }
2784
        }
2785
2786
        return 0;
2787
    }
2788
2789
    /**
2790
     * This function checks whether some users in the uploaded file
2791
     * repeated and creates unique usernames if necesary.
2792
     * A case: Within the file there is an user repeted twice (Julio Montoya / Julio Montoya)
2793
     * and the username fields are empty.
2794
     * Then, this function would create unique usernames based on the first and the last name.
2795
     * Two users wiould be created - jmontoya and jmontoya2.
2796
     * Of course, if in the database there is a user with the name jmontoya,
2797
     * the newly created two users registered would be jmontoya2 and jmontoya3.
2798
     *
2799
     * @param $users list of users
2800
     *
2801
     * @return array
2802
     *
2803
     * @author Julio Montoya Armas
2804
     */
2805
    public static function check_all_usernames($users, $course_list, $id_session)
2806
    {
2807
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2808
        $usernames = [];
2809
        $new_users = [];
2810
        foreach ($users as $index => $user) {
2811
            $desired_username = [];
2812
            if (empty($user['UserName'])) {
2813
                $desired_username = self::make_username($user['FirstName'], $user['LastName'], '');
2814
                $pre_username = $desired_username['username'].$desired_username['sufix'];
2815
                $user['UserName'] = $pre_username;
2816
                $user['create'] = '1';
2817
            } else {
2818
                if (UserManager::is_username_available($user['UserName'])) {
2819
                    $desired_username = self::make_username($user['FirstName'], $user['LastName'], $user['UserName']);
2820
                    $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
2821
                    $user['create'] = '1';
2822
                } else {
2823
                    $is_session_avail = self::user_available_in_session($user['UserName'], $course_list, $id_session);
2824
                    if (0 == $is_session_avail) {
2825
                        $user_name = $user['UserName'];
2826
                        $sql_select = "SELECT user_id FROM $table_user WHERE username ='$user_name' ";
2827
                        $rs = Database::query($sql_select);
2828
                        $user['create'] = Database::result($rs, 0, 0);
2829
                    } else {
2830
                        $user['create'] = $is_session_avail;
2831
                    }
2832
                }
2833
            }
2834
            // Usernames is the current list of users in the file.
2835
            $result_array = self::check_user_in_array($usernames, $desired_username);
2836
            $usernames = $result_array[0];
2837
            $desired_username = $result_array[1];
2838
            $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
2839
            $new_users[] = $user;
2840
        }
2841
2842
        return $new_users;
2843
    }
2844
2845
    /**
2846
     * This functions checks whether there are users that are already
2847
     * registered in the DB by different creator than the current coach.
2848
     *
2849
     * @param array $users
2850
     *
2851
     * @return array
2852
     *
2853
     * @author Julio Montoya Armas
2854
     */
2855
    public static function get_user_creator($users)
2856
    {
2857
        $errors = [];
2858
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2859
        foreach ($users as $index => $user) {
2860
            $username = Database::escape_string($user['UserName']);
2861
            $sql = "SELECT creator_id FROM $table_user WHERE username='$username' ";
2862
2863
            $rs = Database::query($sql);
2864
            $creator_id = Database::result($rs, 0, 0);
2865
            // check if we are the creators or not
2866
            if ('' != $creator_id) {
2867
                if ($creator_id != api_get_user_id()) {
2868
                    $user['error'] = get_lang('User already register by other coach.');
2869
                    $errors[] = $user;
2870
                }
2871
            }
2872
        }
2873
2874
        return $errors;
2875
    }
2876
2877
    /**
2878
     * Validates imported data.
2879
     *
2880
     * @param array $users list of users
2881
     */
2882
    public static function validate_data($users, $id_session = null)
2883
    {
2884
        $errors = [];
2885
        $new_users = [];
2886
        foreach ($users as $index => $user) {
2887
            // 1. Check whether mandatory fields are set.
2888
            $mandatory_fields = ['LastName', 'FirstName'];
2889
            if ('true' == api_get_setting('registration', 'email')) {
2890
                $mandatory_fields[] = 'Email';
2891
            }
2892
2893
            foreach ($mandatory_fields as $key => $field) {
2894
                if (!isset($user[$field]) || 0 == strlen($user[$field])) {
2895
                    $user['error'] = get_lang($field.'Mandatory');
2896
                    $errors[] = $user;
2897
                }
2898
            }
2899
            // 2. Check whether the username is too long.
2900
            if (UserManager::is_username_too_long($user['UserName'])) {
2901
                $user['error'] = get_lang('UserNameTooLong');
2902
                $errors[] = $user;
2903
            }
2904
2905
            $user['UserName'] = trim($user['UserName']);
2906
2907
            if (empty($user['UserName'])) {
2908
                $user['UserName'] = UserManager::create_username($user['FirstName'], $user['LastName']);
2909
            }
2910
            $new_users[] = $user;
2911
        }
2912
        $results = ['errors' => $errors, 'users' => $new_users];
2913
2914
        return $results;
2915
    }
2916
2917
    /**
2918
     * Adds missing user-information (which isn't required, like password, etc).
2919
     */
2920
    public static function complete_missing_data($user)
2921
    {
2922
        // 1. Generate a password if it is necessary.
2923
        if (!isset($user['Password']) || 0 == strlen($user['Password'])) {
2924
            $user['Password'] = api_generate_password();
2925
        }
2926
2927
        return $user;
2928
    }
2929
2930
    /**
2931
     * Saves imported data.
2932
     */
2933
    public static function save_data($users, $course_list, $id_session)
2934
    {
2935
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2936
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2937
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2938
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2939
2940
        $id_session = (int) $id_session;
2941
        $sendMail = $_POST['sendMail'] ? 1 : 0;
2942
2943
        // Adding users to the platform.
2944
        $new_users = [];
2945
        foreach ($users as $index => $user) {
2946
            $user = self::complete_missing_data($user);
2947
            // coach only will registered users
2948
            $default_status = STUDENT;
2949
            if (COURSEMANAGER == $user['create']) {
2950
                $user['id'] = UserManager:: create_user(
2951
                    $user['FirstName'],
2952
                    $user['LastName'],
2953
                    $default_status,
2954
                    $user['Email'],
2955
                    $user['UserName'],
2956
                    $user['Password'],
2957
                    $user['OfficialCode'],
2958
                    api_get_setting('PlatformLanguage'),
2959
                    $user['PhoneNumber'],
2960
                    ''
2961
                );
2962
                $user['added_at_platform'] = 1;
2963
            } else {
2964
                $user['id'] = $user['create'];
2965
                $user['added_at_platform'] = 0;
2966
            }
2967
            $new_users[] = $user;
2968
        }
2969
        // Update user list.
2970
        $users = $new_users;
2971
2972
        // Inserting users.
2973
        foreach ($course_list as $enreg_course) {
2974
            $nbr_users = 0;
2975
            $new_users = [];
2976
            $enreg_course = Database::escape_string($enreg_course);
2977
            foreach ($users as $index => $user) {
2978
                $userid = (int) $user['id'];
2979
                $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user(session_id, c_id, user_id)
2980
                        VALUES('$id_session','$enreg_course','$userid')";
2981
                $result = Database::query($sql);
2982
                if (Database::affected_rows($result)) {
2983
                    $nbr_users++;
2984
                }
2985
                $new_users[] = $user;
2986
            }
2987
2988
            //update the nbr_users field
2989
            $sql_select = "SELECT COUNT(user_id) as nbUsers FROM $tbl_session_rel_course_rel_user
2990
                           WHERE session_id='$id_session' AND c_id='$enreg_course'";
2991
            $rs = Database::query($sql_select);
2992
            list($nbr_users) = Database::fetch_array($rs);
2993
            $sql_update = "UPDATE $tbl_session_rel_course SET nbr_users=$nbr_users
2994
                           WHERE session_id='$id_session' AND c_id='$enreg_course'";
2995
            Database::query($sql_update);
2996
2997
            $sql_update = "UPDATE $tbl_session SET nbr_users= '$nbr_users' WHERE id='$id_session'";
2998
            Database::query($sql_update);
2999
        }
3000
3001
        $new_users = [];
3002
        foreach ($users as $index => $user) {
3003
            $userid = $user['id'];
3004
            $sql_insert = "INSERT IGNORE INTO $tbl_session_rel_user(session_id, user_id, registered_at)
3005
                           VALUES ('$id_session','$userid', '".api_get_utc_datetime()."')";
3006
            Database::query($sql_insert);
3007
            $user['added_at_session'] = 1;
3008
            $new_users[] = $user;
3009
        }
3010
3011
        $users = $new_users;
3012
        $registered_users = get_lang('File imported').'<br /> Import file results : <br />';
3013
        // Sending emails.
3014
        $addedto = '';
3015
        if ($sendMail) {
3016
            foreach ($users as $index => $user) {
3017
                $emailsubject = '['.api_get_setting('siteName').'] '.get_lang('Your registration on').' '.api_get_setting('siteName');
3018
                $emailbody = get_lang('Dear').' '.
3019
                    api_get_person_name($user['First name'], $user['Last name']).",\n\n".
3020
                    get_lang('You are registered to')." ".api_get_setting('siteName')." ".get_lang('with the following settings:')."\n\n".
3021
                    get_lang('Username')." : $user[UserName]\n".
3022
                    get_lang('Pass')." : $user[Password]\n\n".
3023
                    get_lang('The address of')." ".api_get_setting('siteName')." ".get_lang('is')." : ".api_get_path(WEB_PATH)." \n\n".
3024
                    get_lang('In case of trouble, contact us.')."\n\n".
3025
                    get_lang('Sincerely').",\n\n".
3026
                    api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))."\n".
3027
                    get_lang('Administrator')." ".api_get_setting('siteName')."\nT. ".
3028
                    api_get_setting('administratorTelephone')."\n".get_lang('e-mail')." : ".api_get_setting('emailAdministrator');
3029
3030
                api_mail_html(
3031
                    api_get_person_name($user['First name'], $user['Last name'], null, PERSON_NAME_EMAIL_ADDRESS),
3032
                    $user['e-mail'],
3033
                    $emailsubject,
3034
                    $emailbody
3035
                );
3036
                $userInfo = api_get_user_info($user['id']);
3037
3038
                if ((1 == $user['added_at_platform'] && 1 == $user['added_at_session']) || 1 == $user['added_at_session']) {
3039
                    if (1 == $user['added_at_platform']) {
3040
                        $addedto = get_lang('User created in portal');
3041
                    } else {
3042
                        $addedto = '          ';
3043
                    }
3044
3045
                    if (1 == $user['added_at_session']) {
3046
                        $addedto .= get_lang('User added into the session');
3047
                    }
3048
                } else {
3049
                    $addedto = get_lang('User not added.');
3050
                }
3051
3052
                $registered_users .= UserManager::getUserProfileLink($userInfo).' - '.$addedto.'<br />';
3053
            }
3054
        } else {
3055
            foreach ($users as $index => $user) {
3056
                $userInfo = api_get_user_info($user['id']);
3057
                if ((1 == $user['added_at_platform'] && 1 == $user['added_at_session']) || 1 == $user['added_at_session']) {
3058
                    if (1 == $user['added_at_platform']) {
3059
                        $addedto = get_lang('User created in portal');
3060
                    } else {
3061
                        $addedto = '          ';
3062
                    }
3063
3064
                    if (1 == $user['added_at_session']) {
3065
                        $addedto .= ' '.get_lang('User added into the session');
3066
                    }
3067
                } else {
3068
                    $addedto = get_lang('User not added.');
3069
                }
3070
                $registered_users .= "<a href=\"../user/userInfo.php?uInfo=".$user['id']."\">".
3071
                    Security::remove_XSS($userInfo['complete_user_name'])."</a> - ".$addedto.'<br />';
3072
            }
3073
        }
3074
        Display::addFlash(Display::return_message($registered_users, 'normal', false));
3075
        header('Location: course.php?id_session='.$id_session);
3076
        exit;
3077
    }
3078
3079
    /**
3080
     * Reads CSV-file.
3081
     *
3082
     * @param string $file Path to the CSV-file
3083
     *
3084
     * @return array All userinformation read from the file
3085
     */
3086
    public function parse_csv_data($file)
3087
    {
3088
        $users = Import::csvToArray($file);
3089
        foreach ($users as $index => $user) {
3090
            if (isset($user['Courses'])) {
3091
                $user['Courses'] = explode('|', trim($user['Courses']));
3092
            }
3093
            $users[$index] = $user;
3094
        }
3095
3096
        return $users;
3097
    }
3098
3099
    /**
3100
     * Reads XML-file.
3101
     *
3102
     * @param string $file Path to the XML-file
3103
     *
3104
     * @return array All userinformation read from the file
3105
     */
3106
    public static function parse_xml_data($file)
3107
    {
3108
        $crawler = new \Symfony\Component\DomCrawler\Crawler();
3109
        $crawler->addXmlContent(file_get_contents($file));
3110
        $crawler = $crawler->filter('Contacts > Contact ');
3111
        $array = [];
3112
        foreach ($crawler as $domElement) {
3113
            $row = [];
3114
            foreach ($domElement->childNodes as $node) {
3115
                if ('#text' != $node->nodeName) {
3116
                    $row[$node->nodeName] = $node->nodeValue;
3117
                }
3118
            }
3119
            if (!empty($row)) {
3120
                $array[] = $row;
3121
            }
3122
        }
3123
3124
        return $array;
3125
    }
3126
3127
    /**
3128
     * @param int $courseId
3129
     * @param int $sessionId
3130
     * @param int $studentId
3131
     */
3132
    public static function displayTrackingAccessOverView(
3133
        $courseId,
3134
        $sessionId,
3135
        $studentId,
3136
        $perPage = 20,
3137
        $dates = null
3138
    ) {
3139
        $courseId = (int) $courseId;
3140
        $sessionId = (int) $sessionId;
3141
        $studentId = (int) $studentId;
3142
3143
        $courseList = [];
3144
        $sessionList = [];
3145
        $studentList = [];
3146
3147
        if (!empty($courseId)) {
3148
            $course = api_get_course_entity($courseId);
3149
            if ($course) {
3150
                $courseList[$course->getId()] = $course->getTitle();
3151
            }
3152
        }
3153
3154
        if (!empty($sessionId)) {
3155
            $session = api_get_session_entity($sessionId);
3156
            if ($session) {
3157
                $sessionList[$session->getId()] = $session->getName();
3158
            }
3159
        }
3160
3161
        if (!empty($studentId)) {
3162
            $student = api_get_user_entity($studentId);
3163
            if ($student) {
3164
                $studentList[$student->getId()] = UserManager::formatUserFullName($student);
3165
            }
3166
        }
3167
3168
        $form = new FormValidator('access_overview', 'GET');
3169
        $form->addElement(
3170
            'select_ajax',
3171
            'course_id',
3172
            get_lang('Search courses'),
3173
            $courseList,
3174
            [
3175
                'url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?'.http_build_query([
3176
                    'a' => 'search_course_by_session_all',
3177
                    'session_id' => $sessionId,
3178
                    'course_id' => $courseId,
3179
                ]),
3180
            ]
3181
        );
3182
3183
        $form->addElement(
3184
            'select_ajax',
3185
            'session_id',
3186
            get_lang('Search sessions'),
3187
            $sessionList,
3188
            [
3189
                'url_function' => "
3190
                    function () {
3191
                        var params = $.param({
3192
                            a: 'search_session_by_course',
3193
                            course_id: $('#access_overview_course_id').val() || 0
3194
                        });
3195
3196
                        return '".api_get_path(WEB_AJAX_PATH)."session.ajax.php?' + params;
3197
                    }
3198
                ",
3199
            ]
3200
        );
3201
3202
        $form->addSelect(
3203
            'profile',
3204
            get_lang('Profile'),
3205
            [
3206
                '' => get_lang('Select'),
3207
                STUDENT => get_lang('Learner'),
3208
                COURSEMANAGER => get_lang('CourseAdministrator'),
3209
                DRH => get_lang('Human Resources Manager'),
3210
            ],
3211
            ['id' => 'profile']
3212
        );
3213
3214
        $form->addElement(
3215
            'select_ajax',
3216
            'student_id',
3217
            get_lang('Search users'),
3218
            $studentList,
3219
            [
3220
                'placeholder' => get_lang('All'),
3221
                'url_function' => "
3222
                    function () {                    
3223
                        var params = $.param({
3224
                            a: 'search_user_by_course',
3225
                            session_id: $('#access_overview_session_id').val(),
3226
                            course_id: $('#access_overview_course_id').val()
3227
                        });
3228
3229
                        return '".api_get_path(WEB_AJAX_PATH)."course.ajax.php?' + params;
3230
                    }
3231
                ",
3232
            ]
3233
        );
3234
        $form->addDateRangePicker(
3235
            'date',
3236
            get_lang('Date range'),
3237
            true,
3238
            [
3239
                'id' => 'date_range',
3240
                'format' => 'YYYY-MM-DD HH:mm',
3241
                'timePicker' => 'true',
3242
            ]
3243
        );
3244
        $form->addHidden('display', 'accessoverview');
3245
        $form->addRule('course_id', get_lang('Required'), 'required');
3246
        $form->addRule('profile', get_lang('Required'), 'required');
3247
        $form->addButton('submit', get_lang('Generate'), 'gear', 'primary');
3248
3249
        $table = null;
3250
        if (!empty($dates)) {
3251
3252
            $table = new SortableTable(
3253
                'tracking_access_overview',
3254
                ['MySpace', 'getNumberOfTrackAccessOverview'],
3255
                ['MySpace', 'getUserDataAccessTrackingOverview'],
3256
                0,
3257
                $perPage
3258
            );
3259
            $table->set_additional_parameters(
3260
                [
3261
                    'course_id' => $courseId,
3262
                    'session_id' => $sessionId,
3263
                    'student_id' => $studentId,
3264
                    'date' => $dates,
3265
                    'tracking_access_overview_per_page' => $perPage,
3266
                    'display' => 'accessoverview',
3267
                ]
3268
            );
3269
            $table->set_header(0, get_lang('LoginDate'), true);
3270
            $table->set_header(1, get_lang('Username'), true);
3271
            if (api_is_western_name_order()) {
3272
                $table->set_header(2, get_lang('FirstName'), true);
3273
                $table->set_header(3, get_lang('LastName'), true);
3274
            } else {
3275
                $table->set_header(2, get_lang('LastName'), true);
3276
                $table->set_header(3, get_lang('FirstName'), true);
3277
            }
3278
            $table->set_header(4, get_lang('IP'), false);
3279
            $table->set_header(5, get_lang('TimeLoggedIn'), false);
3280
        }
3281
3282
        $template = new Template(
3283
            null,
3284
            false,
3285
            false,
3286
            false,
3287
            false,
3288
            false,
3289
            false
3290
        );
3291
        $template->assign('form', $form->returnForm());
3292
        $template->assign('table', $table ? $table->return_table() : null);
3293
3294
        echo $template->fetch(
3295
            $template->get_template('my_space/accessoverview.tpl')
3296
        );
3297
    }
3298
3299
    /**
3300
     * @return int
3301
     */
3302
    public static function getNumberOfTrackAccessOverview()
3303
    {
3304
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
3305
        $sql = "SELECT COUNT(course_access_id) count FROM $table";
3306
        $result = Database::query($sql);
3307
        $row = Database::fetch_assoc($result);
3308
3309
        if ($row) {
3310
            return $row['count'];
3311
        }
3312
3313
        return 0;
3314
    }
3315
3316
    /**
3317
     * @param $from
3318
     * @param $numberItems
3319
     * @param $column
3320
     * @param $orderDirection
3321
     *
3322
     * @return array
3323
     */
3324
    public static function getUserDataAccessTrackingOverview(
3325
        $from,
3326
        $numberItems,
3327
        $column,
3328
        $orderDirection
3329
    ) {
3330
        $from = (int) $from;
3331
        $numberItems = (int) $numberItems;
3332
        $column = (int) $column;
3333
        $orderDirection = Database::escape_string($orderDirection);
3334
3335
        $user = Database::get_main_table(TABLE_MAIN_USER);
3336
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
3337
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
3338
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
3339
3340
        global $export_csv;
3341
        $is_western_name_order = api_is_western_name_order();
3342
        if ($export_csv) {
3343
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
3344
        }
3345
3346
        //TODO add course name
3347
        $sql = "SELECT
3348
                a.login_course_date as col0,
3349
                u.username as col1,
3350
                ".(
3351
                    $is_western_name_order ? "
3352
                        u.firstname AS col2,
3353
                        u.lastname AS col3,
3354
                    " : "
3355
                        u.lastname AS col2,
3356
                        u.firstname AS col3,
3357
                "
3358
        )."
3359
                a.login_course_date,
3360
                a.logout_course_date,
3361
                c.title,
3362
                c.code,
3363
                u.id as user_id,
3364
                user_ip
3365
            FROM $trackCourseAccess a
3366
            INNER JOIN $user u
3367
            ON a.user_id = u.id
3368
            INNER JOIN $course c
3369
            ON a.c_id = c.id
3370
            WHERE 1=1 ";
3371
3372
        $sql = self::getDataAccessTrackingFilters($sql);
3373
3374
        $sql .= " ORDER BY col$column $orderDirection ";
3375
        $sql .= " LIMIT $from,$numberItems";
3376
3377
        $result = Database::query($sql);
3378
3379
        $data = [];
3380
        while ($user = Database::fetch_assoc($result)) {
3381
            $data[] = $user;
3382
        }
3383
3384
        $return = [];
3385
        //TODO: Dont use numeric index
3386
        foreach ($data as $key => $info) {
3387
            $return[] = [
3388
                api_get_local_time($info['login_course_date']),
3389
                $info['col1'],
3390
                $info['col2'],
3391
                $info['col3'],
3392
                $info['user_ip'],
3393
                gmdate('H:i:s', strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
3394
            ];
3395
        }
3396
3397
3398
        return $return;
3399
    }
3400
3401
    /**
3402
     * Gets the connections to a course as an array of login and logout time.
3403
     *
3404
     * @param int    $user_id
3405
     * @param array  $course_info
3406
     * @param int    $sessionId
3407
     * @param string $start_date
3408
     * @param string $end_date
3409
     * @param bool   $addUserIp
3410
     *
3411
     * @author  Jorge Frisancho Jibaja
3412
     * @author  Julio Montoya <[email protected]> fixing the function
3413
     *
3414
     * @version OCT-22- 2010
3415
     *
3416
     * @return array
3417
     */
3418
    public static function get_connections_to_course_by_date(
3419
        $user_id,
3420
        $course_info,
3421
        $sessionId,
3422
        $start_date,
3423
        $end_date,
3424
        $addUserIp = false
3425
    ) {
3426
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
3427
        $user_id = (int) $user_id;
3428
        $connections = [];
3429
        if (!empty($course_info)) {
3430
            $courseId = (int) $course_info['real_id'];
3431
            $end_date = self::add_day_to($end_date);
3432
3433
            $start_date = Database::escape_string($start_date);
3434
            $end_date = Database::escape_string($end_date);
3435
            $sessionCondition = api_get_session_condition($sessionId);
3436
            $sql = "SELECT 
3437
                        login_course_date, 
3438
                        logout_course_date, 
3439
                        TIMESTAMPDIFF(SECOND, login_course_date, logout_course_date) duration,
3440
                        user_ip
3441
                    FROM $table
3442
                    WHERE
3443
                        user_id = $user_id AND
3444
                        c_id = $courseId AND
3445
                        login_course_date BETWEEN '$start_date' AND '$end_date' AND
3446
                        logout_course_date BETWEEN '$start_date' AND '$end_date'
3447
                        $sessionCondition
3448
                    ORDER BY login_course_date ASC";
3449
            $rs = Database::query($sql);
3450
3451
            while ($row = Database::fetch_array($rs)) {
3452
                $item = [
3453
                    'login' => $row['login_course_date'],
3454
                    'logout' => $row['logout_course_date'],
3455
                    'duration' => $row['duration'],
3456
                ];
3457
                if ($addUserIp) {
3458
                    $item['user_ip'] = $row['user_ip'];
3459
                }
3460
                $connections[] = $item;
3461
            }
3462
        }
3463
3464
        return $connections;
3465
    }
3466
3467
    /**
3468
     * @param int   $user_id
3469
     * @param array $course_info
3470
     * @param int   $sessionId
3471
     * @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...
3472
     * @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...
3473
     *
3474
     * @return array
3475
     */
3476
    public static function getStats($user_id, $course_info, $sessionId, $start_date = null, $end_date = null)
3477
    {
3478
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
3479
        $result = [];
3480
        if (!empty($course_info)) {
3481
            $stringStartDate = '';
3482
            $stringEndDate = '';
3483
            if (null != $start_date && null != $end_date) {
3484
                $end_date = self::add_day_to($end_date);
3485
3486
                $start_date = Database::escape_string($start_date);
3487
                $end_date = Database::escape_string($end_date);
3488
3489
                $stringStartDate = "AND login_course_date BETWEEN '$start_date' AND '$end_date'";
3490
                $stringEndDate = "AND logout_course_date BETWEEN '$start_date' AND '$end_date'";
3491
            }
3492
            $user_id = (int) $user_id;
3493
            $courseId = (int) $course_info['real_id'];
3494
            $sessionCondition = api_get_session_condition($sessionId);
3495
            $sql = "SELECT
3496
                SEC_TO_TIME(AVG(time_to_sec(timediff(logout_course_date,login_course_date)))) as avrg,
3497
                SEC_TO_TIME(SUM(time_to_sec(timediff(logout_course_date,login_course_date)))) as total,
3498
                count(user_id) as times
3499
                FROM $table
3500
                WHERE
3501
                    user_id = $user_id AND
3502
                    c_id = $courseId $stringStartDate $stringEndDate 
3503
                    $sessionCondition                    
3504
                ORDER BY login_course_date ASC";
3505
3506
            $rs = Database::query($sql);
3507
            if ($row = Database::fetch_array($rs)) {
3508
                $foo_avg = $row['avrg'];
3509
                $foo_total = $row['total'];
3510
                $foo_times = $row['times'];
3511
                $result = [
3512
                'avg' => $foo_avg,
3513
                'total' => $foo_total,
3514
                'times' => $foo_times,
3515
            ];
3516
            }
3517
        }
3518
3519
        return $result;
3520
    }
3521
3522
    public static function add_day_to($end_date)
3523
    {
3524
        $foo_date = strtotime($end_date);
3525
        $foo_date = strtotime(' +1 day', $foo_date);
3526
        $foo_date = date('Y-m-d', $foo_date);
3527
3528
        return $foo_date;
3529
    }
3530
3531
    /**
3532
     * This function draw the graphic to be displayed on the user view as an image.
3533
     *
3534
     * @param array  $sql_result
3535
     * @param string $start_date
3536
     * @param string $end_date
3537
     * @param string $type
3538
     *
3539
     * @author Jorge Frisancho Jibaja
3540
     *
3541
     * @version OCT-22- 2010
3542
     *
3543
     * @return string
3544
     */
3545
    public static function grapher($sql_result, $start_date, $end_date, $type = '')
3546
    {
3547
        if (empty($start_date)) {
3548
            $start_date = '';
3549
        }
3550
        if (empty($end_date)) {
3551
            $end_date = '';
3552
        }
3553
        if ('' == $type) {
3554
            $type = 'day';
3555
        }
3556
        $main_year = $main_month_year = $main_day = [];
3557
3558
        $period = new DatePeriod(
3559
        new DateTime($start_date),
3560
        new DateInterval('P1D'),
3561
        new DateTime($end_date)
3562
    );
3563
3564
        foreach ($period as $date) {
3565
            $main_day[$date->format('d-m-Y')] = 0;
3566
        }
3567
3568
        $period = new DatePeriod(
3569
        new DateTime($start_date),
3570
        new DateInterval('P1M'),
3571
        new DateTime($end_date)
3572
    );
3573
3574
        foreach ($period as $date) {
3575
            $main_month_year[$date->format('m-Y')] = 0;
3576
        }
3577
3578
        $i = 0;
3579
        if (is_array($sql_result) && count($sql_result) > 0) {
3580
            foreach ($sql_result as $key => $data) {
3581
                $login = api_strtotime($data['login']);
3582
                $logout = api_strtotime($data['logout']);
3583
                //creating the main array
3584
                if (isset($main_month_year[date('m-Y', $login)])) {
3585
                    $main_month_year[date('m-Y', $login)] += (float) ($logout - $login) / 60;
3586
                }
3587
                if (isset($main_day[date('d-m-Y', $login)])) {
3588
                    $main_day[date('d-m-Y', $login)] += (float) ($logout - $login) / 60;
3589
                }
3590
                if ($i > 500) {
3591
                    break;
3592
                }
3593
                $i++;
3594
            }
3595
            switch ($type) {
3596
            case 'day':
3597
                $main_date = $main_day;
3598
                break;
3599
            case 'month':
3600
                $main_date = $main_month_year;
3601
                break;
3602
            case 'year':
3603
                $main_date = $main_year;
3604
                break;
3605
        }
3606
3607
            $labels = array_keys($main_date);
3608
            if (1 == count($main_date)) {
3609
                $labels = $labels[0];
3610
                $main_date = $main_date[$labels];
3611
            }
3612
3613
            /* Create and populate the pData object */
3614
            $myData = new pData();
3615
            $myData->addPoints($main_date, 'Serie1');
3616
            if (1 != count($main_date)) {
3617
                $myData->addPoints($labels, 'Labels');
3618
                $myData->setSerieDescription('Labels', 'Months');
3619
                $myData->setAbscissa('Labels');
3620
            }
3621
            $myData->setSerieWeight('Serie1', 1);
3622
            $myData->setSerieDescription('Serie1', get_lang('My results'));
3623
            $myData->setAxisName(0, get_lang('Minutes'));
3624
            $myData->loadPalette(api_get_path(SYS_CODE_PATH).'palettes/pchart/default.color', true);
3625
3626
            // Cache definition
3627
            $cachePath = api_get_path(SYS_ARCHIVE_PATH);
3628
            $myCache = new pCache(['CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)]);
3629
            $chartHash = $myCache->getHash($myData);
3630
3631
            if ($myCache->isInCache($chartHash)) {
3632
                //if we already created the img
3633
                $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
3634
                $myCache->saveFromCache($chartHash, $imgPath);
3635
                $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
3636
            } else {
3637
                /* Define width, height and angle */
3638
                $mainWidth = 760;
3639
                $mainHeight = 230;
3640
                $angle = 50;
3641
3642
                /* Create the pChart object */
3643
                $myPicture = new pImage($mainWidth, $mainHeight, $myData);
3644
3645
                /* Turn of Antialiasing */
3646
                $myPicture->Antialias = false;
3647
                /* Draw the background */
3648
                $settings = ["R" => 255, "G" => 255, "B" => 255];
3649
                $myPicture->drawFilledRectangle(0, 0, $mainWidth, $mainHeight, $settings);
3650
3651
                /* Add a border to the picture */
3652
                $myPicture->drawRectangle(
3653
                0,
3654
                0,
3655
                $mainWidth - 1,
3656
                $mainHeight - 1,
3657
                ["R" => 0, "G" => 0, "B" => 0]
3658
            );
3659
3660
                /* Set the default font */
3661
                $myPicture->setFontProperties(
3662
                [
3663
                    "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
3664
                    "FontSize" => 10, ]
3665
            );
3666
                /* Write the chart title */
3667
                $myPicture->drawText(
3668
                $mainWidth / 2,
3669
                30,
3670
                get_lang('Time spent in the course'),
3671
                [
3672
                    "FontSize" => 12,
3673
                    "Align" => TEXT_ALIGN_BOTTOMMIDDLE,
3674
                ]
3675
            );
3676
3677
                /* Set the default font */
3678
                $myPicture->setFontProperties(
3679
                [
3680
                    "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
3681
                    "FontSize" => 8,
3682
                ]
3683
            );
3684
3685
                /* Define the chart area */
3686
                $myPicture->setGraphArea(50, 40, $mainWidth - 40, $mainHeight - 80);
3687
3688
                /* Draw the scale */
3689
                $scaleSettings = [
3690
                'XMargin' => 10,
3691
                'YMargin' => 10,
3692
                'Floating' => true,
3693
                'GridR' => 200,
3694
                'GridG' => 200,
3695
                'GridB' => 200,
3696
                'DrawSubTicks' => true,
3697
                'CycleBackground' => true,
3698
                'LabelRotation' => $angle,
3699
                'Mode' => SCALE_MODE_ADDALL_START0,
3700
            ];
3701
                $myPicture->drawScale($scaleSettings);
3702
3703
                /* Turn on Antialiasing */
3704
                $myPicture->Antialias = true;
3705
3706
                /* Enable shadow computing */
3707
                $myPicture->setShadow(
3708
                true,
3709
                [
3710
                    "X" => 1,
3711
                    "Y" => 1,
3712
                    "R" => 0,
3713
                    "G" => 0,
3714
                    "B" => 0,
3715
                    "Alpha" => 10,
3716
                ]
3717
            );
3718
3719
                /* Draw the line chart */
3720
                $myPicture->setFontProperties(
3721
                [
3722
                    "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
3723
                    "FontSize" => 10,
3724
                ]
3725
            );
3726
                $myPicture->drawSplineChart();
3727
                $myPicture->drawPlotChart(
3728
                [
3729
                    "DisplayValues" => true,
3730
                    "PlotBorder" => true,
3731
                    "BorderSize" => 1,
3732
                    "Surrounding" => -60,
3733
                    "BorderAlpha" => 80,
3734
                ]
3735
            );
3736
3737
                /* Do NOT Write the chart legend */
3738
3739
                /* Write and save into cache */
3740
                $myCache->writeToCache($chartHash, $myPicture);
3741
                $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
3742
                $myCache->saveFromCache($chartHash, $imgPath);
3743
                $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
3744
            }
3745
3746
            return '<img src="'.$imgPath.'">';
3747
        } else {
3748
            return api_convert_encoding(
3749
                '<div id="messages" class="warning-message">'.get_lang('GraphicNotAvailable').'</div>',
3750
            'UTF-8'
3751
        );
3752
        }
3753
    }
3754
3755
    /**
3756
     * Gets a list of users who were enrolled in the lessons.
3757
     * It is necessary that in the extra field, a company is defined.
3758
     *
3759
     *  if lpId is different to 0, this search by lp id too
3760
     *
3761
     * @param string|null $startDate
3762
     * @param string|null $endDate
3763
     * @param int         $lpId
3764
     * @param bool        $whitCompany
3765
     *
3766
     * @return array
3767
     */
3768
    protected static function getCompanyLearnpathSubscription(
3769
        $startDate = null,
3770
        $endDate = null,
3771
        $lpId = 0,
3772
        $whitCompany = false
3773
    ) {
3774
        $tblItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
3775
        $tblLp = Database::get_course_table(TABLE_LP_MAIN);
3776
        $tblExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
3777
        $tblExtraFieldValue = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
3778
3779
        $whereCondition = '';
3780
3781
        //Validating dates
3782
        if (!empty($startDate)) {
3783
            $startDate = new DateTime($startDate);
3784
        }
3785
        if (!empty($endDate)) {
3786
            $endDate = new DateTime($endDate);
3787
        }
3788
        if (!empty($startDate) and !empty($endDate)) {
3789
            if ($startDate > $endDate) {
3790
                $dateTemp = $endDate;
3791
                $endDate = $startDate;
3792
                $startDate = $dateTemp;
3793
                unset($dateTemp);
3794
            }
3795
        }
3796
3797
        // Settings condition and parametter GET to right date
3798
        if (!empty($startDate)) {
3799
            $startDate = api_get_utc_datetime($startDate->setTime(0, 0, 0)->format('Y-m-d H:i:s'));
3800
            $_GET['startDate'] = $startDate;
3801
            $whereCondition .= "
3802
            AND $tblItemProperty.lastedit_date >= '$startDate' ";
3803
        }
3804
        if (!empty($endDate)) {
3805
            $endDate = api_get_utc_datetime($endDate->setTime(23, 59, 59)->format('Y-m-d H:i:s'));
3806
            $_GET['endDate'] = $endDate;
3807
            $whereCondition .= "
3808
            AND $tblItemProperty.lastedit_date <= '$endDate' ";
3809
        }
3810
        if ($lpId != 0) {
3811
            $whereCondition .= "
3812
            AND c_item_property.ref = $lpId ";
3813
        }
3814
3815
        $companys = [];
3816
        if (!empty($startDate) or !empty($endDate)) {
3817
            // get Compnay data
3818
            $selectToCompany = " (
3819
            SELECT
3820
                value
3821
            FROM
3822
                $tblExtraFieldValue
3823
            WHERE
3824
                field_id IN (
3825
                    SELECT
3826
                        id
3827
                    FROM
3828
                        $tblExtraField
3829
                    WHERE
3830
                        variable = 'company'
3831
                )
3832
            AND item_id = $tblItemProperty.to_user_id
3833
            ) ";
3834
            $query = "
3835
            SELECT
3836
                * ,
3837
                 $selectToCompany  as company,
3838
                    (
3839
                    SELECT
3840
                        name
3841
                    FROM
3842
                        $tblLp
3843
                    WHERE
3844
                    $tblLp.iid = c_item_property.ref
3845
                 ) as name_lp
3846
            FROM
3847
                $tblItemProperty
3848
            WHERE
3849
                c_id IN (
3850
                    SELECT
3851
                        c_id
3852
                    FROM
3853
                        ".TABLE_MAIN_COURSE_USER."
3854
                    WHERE
3855
                        STATUS = 5
3856
                )
3857
                AND lastedit_type = 'LearnpathSubscription'
3858
3859
                ";
3860
            // -- AND $selectToCompany IS NOT NULL
3861
            if (strlen($whereCondition) > 2) {
3862
                $query .= $whereCondition;
3863
            }
3864
            $queryResult = Database::query($query);
3865
            while ($row = Database::fetch_array($queryResult, 'ASSOC')) {
3866
                // $courseId = (int)$row['c_id'];
3867
                $studentId = (int) $row['to_user_id'];
3868
                $company = isset($row['company']) ? $row['company'] : '';
3869
                if ($company == '') {
3870
                    $company = get_lang('NoEntity');
3871
                }
3872
                // $lpId = $row['ref'];
3873
                if ($lpId != 0 && $studentId != 0) {
3874
                    if ($whitCompany == true) {
3875
                        $companys[] = [
3876
                            'id' => $studentId,
3877
                            'company' => $company,
3878
                        ];
3879
                    } else {
3880
                        $companys[] = $studentId;
3881
                    }
3882
                } else {
3883
                    $companys[$company][] = $studentId;
3884
                    $companys[$company] = array_unique($companys[$company]);
3885
                }
3886
            }
3887
        }
3888
3889
        return $companys;
3890
    }
3891
3892
    private static function getDataAccessTrackingFilters($sql)
3893
    {
3894
        if (isset($_GET['course_id']) && !empty($_GET['course_id'])) {
3895
            $courseId = (int) $_GET['course_id'];
3896
            $sql .= " AND c.id = ".$courseId;
3897
        }
3898
3899
        if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
3900
            $sessionId = (int) $_GET['session_id'];
3901
            $sql .= " AND a.session_id = ".$sessionId;
3902
        }
3903
3904
        if (isset($_GET['student_id']) && !empty($_GET['student_id'])) {
3905
            $userId = (int) $_GET['student_id'];
3906
            $sql .= " AND u.user_id = ".$userId;
3907
        }
3908
3909
        $sql .= " AND u.status <> ".ANONYMOUS;
3910
3911
        if (isset($_GET['date']) && !empty($_GET['date'])) {
3912
            $dateRangePicker = new DateRangePicker('date', '', ['timePicker' => 'true']);
3913
            $dates = $dateRangePicker->parseDateRange($_GET['date']);
3914
            if (isset($dates['start']) && !empty($dates['start'])) {
3915
                $dates['start'] = Database::escape_string(api_get_utc_datetime($dates['start']));
3916
                $sql .= " AND login_course_date >= '".$dates['start']."'";
3917
            }
3918
            if (isset($dates['end']) && !empty($dates['end'])) {
3919
                $dates['end'] = Database::escape_string(api_get_utc_datetime($dates['end']));
3920
                $sql .= " AND logout_course_date <= '".$dates['end']."'";
3921
            }
3922
        }
3923
3924
        return $sql;
3925
    }
3926
}
3927