Completed
Push — 1.11.x ( 0adea3...e968b6 )
by Angel Fernando Quiroz
01:23 queued 37s
created

MySpace::get_course_data()   F

Complexity

Conditions 15
Paths 4612

Size

Total Lines 124
Code Lines 86

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 86
nc 4612
nop 4
dl 0
loc 124
rs 1.7054
c 0
b 0
f 0

How to fix   Long Method    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('DisplayCoaches'),
25
            ],
26
            [
27
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=user',
28
                'content' => get_lang('DisplayUserOverview'),
29
            ],
30
            [
31
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=session',
32
                'content' => get_lang('DisplaySessionOverview'),
33
            ],
34
            [
35
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=course',
36
                'content' => get_lang('DisplayCourseOverview'),
37
            ],
38
            [
39
                'url' => api_get_path(WEB_CODE_PATH).'tracking/question_course_report.php?view=admin',
40
                'content' => get_lang('LPQuestionListResults'),
41
            ],
42
            [
43
                'url' => api_get_path(WEB_CODE_PATH).'tracking/course_session_report.php?view=admin',
44
                'content' => get_lang('LPExerciseResultsBySession'),
45
            ],
46
            [
47
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=accessoverview',
48
                'content' => get_lang('DisplayAccessOverview').' ('.get_lang('Beta').')',
49
            ],
50
            [
51
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/exercise_category_report.php',
52
                'content' => get_lang('ExerciseCategoryAllSessionsReport'),
53
            ],
54
            [
55
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/survey_report.php',
56
                'content' => get_lang('SurveysReport'),
57
            ],
58
            [
59
                '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
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=company',
81
                'content' => get_lang('UserByEntityReport'),
82
            ];
83
        }
84
        $field = new ExtraField('lp');
85
        $authorsField = $field->get_handler_field_info_by_field_variable('authors');
86
        if (!empty($authorsField)) {
87
            $actions[] = [
88
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=learningPath',
89
                'content' => get_lang('LpByAuthor'),
90
            ];
91
        }
92
        $field = new ExtraField('lp_item');
93
        $authorsItemField = $field->get_handler_field_info_by_field_variable('authorlpitem');
94
        if (!empty($authorsItemField)) {
95
            $actions[] = [
96
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=learningPathByItem',
97
                'content' => get_lang('LearningPathItemByAuthor'),
98
            ];
99
        }
100
101
        return Display::actions($actions, null);
102
    }
103
104
    /**
105
     * @return string
106
     */
107
    public static function getTopMenu()
108
    {
109
        $menuItems = [];
110
        $menuItems[] = Display::url(
111
            Display::return_icon(
112
                'statistics.png',
113
                get_lang('MyStats'),
114
                '',
115
                ICON_SIZE_MEDIUM
116
            ),
117
            api_get_path(WEB_CODE_PATH)."auth/my_progress.php"
118
        );
119
        $menuItems[] = Display::url(
120
            Display::return_icon(
121
                'teacher.png',
122
                get_lang('TeacherInterface'),
123
                [],
124
                32
125
            ),
126
            api_get_path(WEB_CODE_PATH).'mySpace/?view=teacher'
127
        );
128
        $menuItems[] = Display::url(
129
            Display::return_icon(
130
                'star_na.png',
131
                get_lang('AdminInterface'),
132
                [],
133
                32
134
            ),
135
            '#'
136
        );
137
        $menuItems[] = Display::url(
138
            Display::return_icon('quiz.png', get_lang('ExamTracking'), [], 32),
139
            api_get_path(WEB_CODE_PATH).'tracking/exams.php'
140
        );
141
        $menu = '';
142
        foreach ($menuItems as $item) {
143
            $menu .= $item;
144
        }
145
        $menu .= '<br />';
146
147
        return $menu;
148
    }
149
150
    /**
151
     * This function serves exporting data in CSV format.
152
     *
153
     * @param array  $header    the header labels
154
     * @param array  $data      the data array
155
     * @param string $file_name the name of the file which contains exported data
156
     *
157
     * @return string mixed             Returns a message (string) if an error occurred
158
     */
159
    public function export_csv($header, $data, $file_name = 'export.csv')
160
    {
161
        $archive_path = api_get_path(SYS_ARCHIVE_PATH);
162
        $archive_url = api_get_path(WEB_CODE_PATH).'course_info/download.php?archive_path=&archive=';
163
        $message = '';
164
        if (!$open = fopen($archive_path.$file_name, 'w+')) {
165
            $message = get_lang('noOpen');
166
        } else {
167
            $info = '';
168
169
            foreach ($header as $value) {
170
                $info .= $value.';';
171
            }
172
            $info .= "\r\n";
173
174
            foreach ($data as $row) {
175
                foreach ($row as $value) {
176
                    $info .= $value.';';
177
                }
178
                $info .= "\r\n";
179
            }
180
181
            fwrite($open, $info);
182
            fclose($open);
183
            @chmod($file_name, api_get_permissions_for_new_files());
184
185
            header("Location:".$archive_url.$file_name);
186
            exit;
187
        }
188
189
        return $message;
190
    }
191
192
    /**
193
     * Gets the connections to a course as an array of login and logout time.
194
     *
195
     * @param int   $userId     User id
196
     * @param array $courseInfo
197
     * @param int   $sessionId  Session id (optional, default = 0)
198
     *
199
     * @return array Connections
200
     */
201
    public static function get_connections_to_course(
202
        $userId,
203
        $courseInfo,
204
        $sessionId = 0
205
    ) {
206
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
207
208
        // protect data
209
        $userId = (int) $userId;
210
        $courseId = (int) $courseInfo['real_id'];
211
        $sessionId = (int) $sessionId;
212
        $sessionCondition = api_get_session_condition($sessionId);
213
214
        $sql = 'SELECT login_course_date, logout_course_date
215
                FROM '.$table.'
216
                WHERE
217
                    user_id = '.$userId.' AND
218
                    c_id = '.$courseId.'
219
                    '.$sessionCondition.'
220
                ORDER BY login_course_date ASC';
221
        $rs = Database::query($sql);
222
        $connections = [];
223
224
        while ($row = Database::fetch_array($rs)) {
225
            $connections[] = [
226
                'login' => $row['login_course_date'],
227
                'logout' => $row['logout_course_date'],
228
            ];
229
        }
230
231
        return $connections;
232
    }
233
234
    /**
235
     * @param $user_id
236
     * @param $course_list
237
     * @param int $session_id
238
     *
239
     * @return array|bool
240
     */
241
    public static function get_connections_from_course_list(
242
        $user_id,
243
        $course_list,
244
        $session_id = 0
245
    ) {
246
        // Database table definitions
247
        $tbl_track_course = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
248
        if (empty($course_list)) {
249
            return false;
250
        }
251
252
        // protect data
253
        $user_id = (int) $user_id;
254
        $session_id = (int) $session_id;
255
        $new_course_list = [];
256
        foreach ($course_list as $course_item) {
257
            $courseInfo = api_get_course_info($course_item['code']);
258
            if ($courseInfo) {
259
                $courseId = $courseInfo['real_id'];
260
                $new_course_list[] = '"'.$courseId.'"';
261
            }
262
        }
263
        $course_list = implode(', ', $new_course_list);
264
265
        if (empty($course_list)) {
266
            return false;
267
        }
268
        $sql = 'SELECT login_course_date, logout_course_date, c_id
269
                FROM '.$tbl_track_course.'
270
                WHERE
271
                    user_id = '.$user_id.' AND
272
                    c_id IN ('.$course_list.') AND
273
                    session_id = '.$session_id.'
274
                ORDER BY login_course_date ASC';
275
        $rs = Database::query($sql);
276
        $connections = [];
277
278
        while ($row = Database::fetch_array($rs)) {
279
            $timestamp_login_date = api_strtotime($row['login_course_date'], 'UTC');
280
            $timestamp_logout_date = api_strtotime($row['logout_course_date'], 'UTC');
281
            $connections[] = [
282
                'login' => $timestamp_login_date,
283
                'logout' => $timestamp_logout_date,
284
                'c_id' => $row['c_id'],
285
            ];
286
        }
287
288
        return $connections;
289
    }
290
291
    /**
292
     * Creates a small table in the last column of the table with the user overview.
293
     *
294
     * @param int $user_id the id of the user
295
     *
296
     * @return array List course
297
     */
298
    public static function returnCourseTracking($user_id)
299
    {
300
        $user_id = (int) $user_id;
301
302
        if (empty($user_id)) {
303
            return [];
304
        }
305
306
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
307
        // getting all the courses of the user
308
        $sql = "SELECT * FROM $tbl_course_user
309
                WHERE
310
                    user_id = $user_id AND
311
                    relation_type <> ".COURSE_RELATION_TYPE_RRHH;
312
        $result = Database::query($sql);
313
314
        $list = [];
315
316
        while ($row = Database::fetch_array($result)) {
317
            $courseInfo = api_get_course_info_by_id($row['c_id']);
318
            $courseId = $courseInfo['real_id'];
319
            $courseCode = $courseInfo['code'];
320
321
            if (empty($courseInfo)) {
322
                continue;
323
            }
324
325
            $avg_score = Tracking::get_avg_student_score($user_id, $courseCode);
326
            if (is_numeric($avg_score)) {
327
                $avg_score = round($avg_score, 2);
328
            } else {
329
                $avg_score = '-';
330
            }
331
332
            // Student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
333
            $exercisesResults = self::exercises_results($user_id, $courseCode);
334
335
            $resultToString = '';
336
            if (!is_null($exercisesResults['percentage'])) {
337
                $resultToString = $exercisesResults['score_obtained'].'/'.$exercisesResults['score_possible'].' ( '.$exercisesResults['percentage'].'% )';
338
            }
339
340
            $item = [
341
                'code' => $courseInfo['code'],
342
                'real_id' => $courseInfo['real_id'],
343
                'title' => $courseInfo['title'],
344
                'category' => $courseInfo['categoryName'],
345
                'image_small' => $courseInfo['course_image'],
346
                'image_large' => $courseInfo['course_image_large'],
347
                'time_spent' => api_time_to_hms(Tracking::get_time_spent_on_the_course($user_id, $courseId)),
348
                'student_progress' => round(Tracking::get_avg_student_progress($user_id, $courseCode)),
349
                'student_score' => $avg_score,
350
                'student_message' => Tracking::count_student_messages($user_id, $courseCode),
351
                'student_assignments' => Tracking::count_student_assignments($user_id, $courseCode),
352
                'student_exercises' => $resultToString,
353
                'questions_answered' => $exercisesResults['questions_answered'],
354
                'last_connection' => Tracking::get_last_connection_date_on_the_course($user_id, $courseInfo),
355
            ];
356
            $list[] = $item;
357
        }
358
359
        return $list;
360
    }
361
362
    /**
363
     * Display a sortable table that contains an overview off all the
364
     * reporting progress of all users and all courses the user is subscribed to.
365
     *
366
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
367
     *          Alex Aragon <[email protected]>, BeezNest, Perú
368
     *
369
     * @version Chamilo 1.11.8
370
     *
371
     * @since April 2019
372
     */
373
    public static function returnTrackingUserOverviewFilter($user_id)
374
    {
375
        $tpl = new Template('', false, false, false, false, false, false);
376
        $userInfo = api_get_user_info($user_id);
377
378
        $avatar = UserManager::getUserPicture($user_id, USER_IMAGE_SIZE_SMALL);
379
        $user = [
380
            'id' => $user_id,
381
            'code_user' => $userInfo['official_code'],
382
            'complete_name' => $userInfo['complete_name'],
383
            'username' => $userInfo['username'],
384
            'course' => self::returnCourseTracking($user_id),
385
            'avatar' => $avatar,
386
        ];
387
388
        $tpl->assign('item', $user);
389
        $templateName = $tpl->get_template('my_space/partials/tracking_user_overview.tpl');
390
        $content = $tpl->fetch($templateName);
391
392
        return $content;
393
    }
394
395
    /**
396
     * Display a sortable table that contains an overview off all the
397
     * reporting progress of all users and all courses the user is subscribed to.
398
     *
399
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
400
     *         Alex Aragon <[email protected]>, BeezNest, Perú
401
     *
402
     * @version Chamilo 1.11.8
403
     *
404
     * @since October 2008, Update April 2019
405
     */
406
    public static function display_tracking_user_overview()
407
    {
408
        self::display_user_overview_export_options();
409
410
        $params = ['view' => 'admin', 'display' => 'user'];
411
        $table = new SortableTable(
412
            'tracking_user_overview',
413
            ['MySpace', 'get_number_of_users_tracking_overview'],
414
            ['MySpace', 'get_user_data_tracking_overview'],
415
            0,
416
            20,
417
            'ASC',
418
            null, [
419
                'class' => 'table table-transparent',
420
            ]
421
        );
422
        $table->additional_parameters = $params;
423
424
        $table->set_column_filter(0, ['MySpace', 'returnTrackingUserOverviewFilter']);
425
        $tableContent = $table->return_table();
426
        $tpl = new Template('', false, false, false, false, false, false);
427
        $tpl->assign('table', $tableContent);
428
        $templateName = $tpl->get_template('my_space/user_summary.tpl');
429
        $tpl->display($templateName);
430
    }
431
432
    /**
433
     * @param $export_csv
434
     */
435
    public static function display_tracking_coach_overview($export_csv)
436
    {
437
        if ($export_csv) {
438
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
439
        } else {
440
            $is_western_name_order = api_is_western_name_order();
441
        }
442
        $sort_by_first_name = api_sort_by_first_name();
443
444
        if (isset($_GET['tracking_list_coaches_column'])) {
445
            $tracking_column = (int) $_GET['tracking_list_coaches_column'];
446
        } else {
447
            $tracking_column = ($is_western_name_order xor $sort_by_first_name) ? 1 : 0;
448
        }
449
450
        $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';
451
        // Prepare array for column order - when impossible, use some of user names.
452
        if ($is_western_name_order) {
453
            $order = [
454
                0 => 'firstname',
455
                1 => 'lastname',
456
                2 => $sort_by_first_name ? 'firstname' : 'lastname',
457
                3 => 'login_date',
458
                4 => $sort_by_first_name ? 'firstname' : 'lastname',
459
                5 => $sort_by_first_name ? 'firstname' : 'lastname',
460
            ];
461
        } else {
462
            $order = [
463
                0 => 'lastname',
464
                1 => 'firstname',
465
                2 => $sort_by_first_name ? 'firstname' : 'lastname',
466
                3 => 'login_date',
467
                4 => $sort_by_first_name ? 'firstname' : 'lastname',
468
                5 => $sort_by_first_name ? 'firstname' : 'lastname',
469
            ];
470
        }
471
        $table = new SortableTable(
472
            'tracking_list_coaches_myspace',
473
            ['MySpace', 'count_coaches'],
474
            null,
475
            ($is_western_name_order xor $sort_by_first_name) ? 1 : 0
476
        );
477
        $parameters['view'] = 'admin';
478
        $table->set_additional_parameters($parameters);
479
        if ($is_western_name_order) {
480
            $table->set_header(0, get_lang('FirstName'), true);
481
            $table->set_header(1, get_lang('LastName'), true);
482
        } else {
483
            $table->set_header(0, get_lang('LastName'), true);
484
            $table->set_header(1, get_lang('FirstName'), true);
485
        }
486
        $table->set_header(2, get_lang('TimeSpentOnThePlatform'), false);
487
        $table->set_header(3, get_lang('LastConnexion'), false);
488
        $table->set_header(4, get_lang('NbStudents'), false);
489
        $table->set_header(5, get_lang('CountCours'), false);
490
        $table->set_header(6, get_lang('NumberOfSessions'), false);
491
        $table->set_header(7, get_lang('Sessions'), false);
492
493
        if ($is_western_name_order) {
494
            $csv_header[] = [
495
                get_lang('FirstName'),
496
                get_lang('LastName'),
497
                get_lang('TimeSpentOnThePlatform'),
498
                get_lang('LastConnexion'),
499
                get_lang('NbStudents'),
500
                get_lang('CountCours'),
501
                get_lang('NumberOfSessions'),
502
            ];
503
        } else {
504
            $csv_header[] = [
505
                get_lang('LastName'),
506
                get_lang('FirstName'),
507
                get_lang('TimeSpentOnThePlatform'),
508
                get_lang('LastConnexion'),
509
                get_lang('NbStudents'),
510
                get_lang('CountCours'),
511
                get_lang('NumberOfSessions'),
512
            ];
513
        }
514
515
        $tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
516
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
517
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
518
        $tbl_sessions = Database::get_main_table(TABLE_MAIN_SESSION);
519
520
        $sqlCoachs = "SELECT DISTINCT
521
                        scu.user_id as id_coach,
522
                        u.id as user_id,
523
                        lastname,
524
                        firstname,
525
                        MAX(login_date) as login_date
526
                        FROM $tbl_user u, $tbl_session_course_user scu, $tbl_track_login
527
                        WHERE
528
                            scu.user_id = u.id AND scu.status=2 AND login_user_id=u.id
529
                        GROUP BY user_id ";
530
531
        if (api_is_multiple_url_enabled()) {
532
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
533
            $access_url_id = api_get_current_access_url_id();
534
            if ($access_url_id != -1) {
535
                $sqlCoachs = "SELECT DISTINCT
536
                                    scu.user_id as id_coach,
537
                                    u.id as user_id,
538
                                    lastname,
539
                                    firstname,
540
                                    MAX(login_date) as login_date
541
                                FROM $tbl_user u,
542
                                $tbl_session_course_user scu,
543
                                $tbl_track_login ,
544
                                $tbl_session_rel_access_url session_rel_url
545
                                WHERE
546
                                    scu.user_id = u.id AND
547
                                    scu.status = 2 AND
548
                                    login_user_id = u.id AND
549
                                    access_url_id = $access_url_id AND
550
                                    session_rel_url.session_id = scu.session_id
551
                                GROUP BY u.id";
552
            }
553
        }
554
        if (!empty($order[$tracking_column])) {
555
            $sqlCoachs .= " ORDER BY `".$order[$tracking_column]."` ".$tracking_direction;
556
        }
557
558
        $result_coaches = Database::query($sqlCoachs);
559
        $global_coaches = [];
560
        while ($coach = Database::fetch_array($result_coaches)) {
561
            $global_coaches[$coach['user_id']] = $coach;
562
        }
563
564
        $sql_session_coach = "SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
565
                                FROM $tbl_user u , $tbl_sessions as session, $tbl_track_login
566
                                WHERE id_coach = u.id AND login_user_id = u.id
567
                                GROUP BY u.id
568
                                ORDER BY login_date $tracking_direction";
569
570
        if (api_is_multiple_url_enabled()) {
571
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
572
            $access_url_id = api_get_current_access_url_id();
573
            if ($access_url_id != -1) {
574
                $sql_session_coach = "SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
575
					FROM $tbl_user u , $tbl_sessions as session, $tbl_track_login , $tbl_session_rel_access_url as session_rel_url
576
					WHERE
577
					    id_coach = u.id AND
578
					    login_user_id = u.id  AND
579
					    access_url_id = $access_url_id AND
580
					    session_rel_url.session_id = session.id
581
					GROUP BY  u.id
582
					ORDER BY login_date $tracking_direction";
583
            }
584
        }
585
586
        $result_sessions_coach = Database::query($sql_session_coach);
587
        //$total_no_coaches += Database::num_rows($result_sessions_coach);
588
        while ($coach = Database::fetch_array($result_sessions_coach)) {
589
            $global_coaches[$coach['user_id']] = $coach;
590
        }
591
592
        $all_datas = [];
593
        foreach ($global_coaches as $id_coach => $coaches) {
594
            $time_on_platform = api_time_to_hms(
595
                Tracking::get_time_spent_on_the_platform($coaches['user_id'])
596
            );
597
            $last_connection = Tracking::get_last_connection_date(
598
                $coaches['user_id']
599
            );
600
            $nb_students = count(
601
                Tracking::get_student_followed_by_coach($coaches['user_id'])
602
            );
603
            $nb_courses = count(
604
                Tracking::get_courses_followed_by_coach($coaches['user_id'])
605
            );
606
            $nb_sessions = count(
607
                Tracking::get_sessions_coached_by_user($coaches['user_id'])
608
            );
609
610
            $table_row = [];
611
            if ($is_western_name_order) {
612
                $table_row[] = $coaches['firstname'];
613
                $table_row[] = $coaches['lastname'];
614
            } else {
615
                $table_row[] = $coaches['lastname'];
616
                $table_row[] = $coaches['firstname'];
617
            }
618
            $table_row[] = $time_on_platform;
619
            $table_row[] = $last_connection;
620
            $table_row[] = $nb_students;
621
            $table_row[] = $nb_courses;
622
            $table_row[] = $nb_sessions;
623
            $table_row[] = '<a href="session.php?id_coach='.$coaches['user_id'].'">
624
                '.Display::return_icon('2rightarrow.png', get_lang('Details')).'
625
            </a>';
626
            $all_datas[] = $table_row;
627
628
            if ($is_western_name_order) {
629
                $csv_content[] = [
630
                    api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
631
                    api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
632
                    $time_on_platform,
633
                    $last_connection,
634
                    $nb_students,
635
                    $nb_courses,
636
                    $nb_sessions,
637
                ];
638
            } else {
639
                $csv_content[] = [
640
                    api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
641
                    api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
642
                    $time_on_platform,
643
                    $last_connection,
644
                    $nb_students,
645
                    $nb_courses,
646
                    $nb_sessions,
647
                ];
648
            }
649
        }
650
651
        if ($tracking_column != 3) {
652
            if ($tracking_direction == 'DESC') {
653
                usort($all_datas, ['MySpace', 'rsort_users']);
654
            } else {
655
                usort($all_datas, ['MySpace', 'sort_users']);
656
            }
657
        }
658
659
        if ($export_csv && $tracking_column != 3) {
660
            usort($csv_content, 'sort_users');
661
        }
662
        if ($export_csv) {
663
            $csv_content = array_merge($csv_header, $csv_content);
664
        }
665
666
        foreach ($all_datas as $row) {
667
            $table->addRow($row, 'align="right"');
668
        }
669
        $table->display();
670
    }
671
672
    /**
673
     * @return mixed
674
     */
675
    public static function count_coaches()
676
    {
677
        global $total_no_coaches;
678
679
        return $total_no_coaches;
680
    }
681
682
    public static function sort_users($a, $b)
683
    {
684
        $tracking = Session::read('tracking_column');
685
686
        return api_strcmp(
687
            trim(api_strtolower($a[$tracking])),
688
            trim(api_strtolower($b[$tracking]))
689
        );
690
    }
691
692
    public static function rsort_users($a, $b)
693
    {
694
        $tracking = Session::read('tracking_column');
695
696
        return api_strcmp(
697
            trim(api_strtolower($b[$tracking])),
698
            trim(api_strtolower($a[$tracking]))
699
        );
700
    }
701
702
    /**
703
     * Display a sortable table that contains an overview off all the progress of the user in a session.
704
     *
705
     * @deprecated ?
706
     *
707
     * @author César Perales <[email protected]>, Beeznest Team
708
     */
709
    public static function display_tracking_lp_progress_overview(
710
        $sessionId = '',
711
        $courseId = '',
712
        $date_from,
713
        $date_to
714
    ) {
715
        $course = api_get_course_info_by_id($courseId);
716
        /**
717
         * Column name
718
         * The order is important you need to check the $column variable in the model.ajax.php file.
719
         */
720
        $columns = [
721
            get_lang('Username'),
722
            get_lang('FirstName'),
723
            get_lang('LastName'),
724
        ];
725
        //add lessons of course
726
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
727
728
        //create columns array
729
        foreach ($lessons as $lesson_id => $lesson) {
730
            $columns[] = $lesson['name'];
731
        }
732
733
        $columns[] = get_lang('Total');
734
735
        /**
736
         * Column config.
737
         */
738
        $column_model = [
739
            [
740
                'name' => 'username',
741
                'index' => 'username',
742
                'align' => 'left',
743
                'search' => 'true',
744
                'wrap_cell' => "true",
745
            ],
746
            [
747
                'name' => 'firstname',
748
                'index' => 'firstname',
749
                'align' => 'left',
750
                'search' => 'true',
751
            ],
752
            [
753
                'name' => 'lastname',
754
                'index' => 'lastname',
755
                'align' => 'left',
756
                'search' => 'true',
757
            ],
758
        ];
759
760
        // Get dinamic column names
761
        foreach ($lessons as $lesson_id => $lesson) {
762
            $column_model[] = [
763
                'name' => $lesson['id'],
764
                'index' => $lesson['id'],
765
                'align' => 'left',
766
                'search' => 'true',
767
            ];
768
        }
769
770
        $column_model[] = [
771
            'name' => 'total',
772
            'index' => 'total',
773
            'align' => 'left',
774
            'search' => 'true',
775
        ];
776
777
        $action_links = '';
778
        // jqgrid will use this URL to do the selects
779
        $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_lp_progress&session_id='.$sessionId.'&course_id='.$courseId.'&date_to='.$date_to.'&date_from='.$date_from;
780
781
        // Table Id
782
        $tableId = 'lpProgress';
783
784
        // Autowidth
785
        $extra_params['autowidth'] = 'true';
786
787
        // height auto
788
        $extra_params['height'] = 'auto';
789
790
        $table = Display::grid_js(
791
            $tableId,
792
            $url,
793
            $columns,
794
            $column_model,
795
            $extra_params,
796
            [],
797
            $action_links,
798
            true
799
        );
800
801
        $return = '<script>$(function() {'.$table.
802
            'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
803
                jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
804
                       caption:"",
805
                       title:"'.get_lang('ExportExcel').'",
806
                       onClickButton : function () {
807
                           jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
808
                       }
809
                });
810
            });</script>';
811
        $return .= Display::grid_html($tableId);
812
813
        return $return;
814
    }
815
816
    /**
817
     * Display a sortable table that contains an overview off all the progress of the user in a session.
818
     *
819
     * @param int $sessionId  The session ID
820
     * @param int $courseId   The course ID
821
     * @param int $exerciseId The quiz ID
822
     * @param     $date_from
823
     * @param     $date_to
824
     *
825
     * @return string HTML array of results formatted for gridJS
826
     *
827
     * @deprecated ?
828
     *
829
     * @author César Perales <[email protected]>, Beeznest Team
830
     */
831
    public static function display_tracking_exercise_progress_overview(
832
        $sessionId = 0,
833
        $courseId = 0,
834
        $exerciseId = 0,
835
        $date_from = null,
836
        $date_to = null
837
    ) {
838
        $date_from = Security::remove_XSS($date_from);
839
        $date_to = Security::remove_XSS($date_to);
840
        /**
841
         * Column names
842
         * The column order is important. Check $column variable in the main/inc/ajax/model.ajax.php file.
843
         */
844
        $columns = [
845
            get_lang('Session'),
846
            get_lang('ExerciseId'),
847
            get_lang('ExerciseName'),
848
            get_lang('Username'),
849
            get_lang('LastName'),
850
            get_lang('FirstName'),
851
            get_lang('Time'),
852
            get_lang('QuestionId'),
853
            get_lang('QuestionTitle'),
854
            get_lang('WorkDescription'),
855
            get_lang('Answer'),
856
            get_lang('Correct'),
857
        ];
858
859
        /**
860
         * Column config.
861
         */
862
        $column_model = [
863
            ['name' => 'session', 'index' => 'session', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
864
            ['name' => 'exercise_id', 'index' => 'exercise_id', 'align' => 'left', 'search' => 'true'],
865
            ['name' => 'quiz_title', 'index' => 'quiz_title', 'align' => 'left', 'search' => 'true'],
866
            ['name' => 'username', 'index' => 'username', 'align' => 'left', 'search' => 'true'],
867
            ['name' => 'lastname', 'index' => 'lastname', 'align' => 'left', 'search' => 'true'],
868
            ['name' => 'firstname', 'index' => 'firstname', 'align' => 'left', 'search' => 'true'],
869
            ['name' => 'time', 'index' => 'time', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
870
            ['name' => 'question_id', 'index' => 'question_id', 'align' => 'left', 'search' => 'true'],
871
            ['name' => 'question', 'index' => 'question', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
872
            ['name' => 'description', 'index' => 'description', 'align' => 'left', 'width' => '550', 'search' => 'true', 'wrap_cell' => "true"],
873
            ['name' => 'answer', 'index' => 'answer', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
874
            ['name' => 'correct', 'index' => 'correct', 'align' => 'left', 'search' => 'true', 'wrap_cell' => "true"],
875
        ];
876
        //get dynamic column names
877
878
        // jqgrid will use this URL to do the selects
879
        $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_progress&session_id='.$sessionId.'&course_id='.$courseId.'&exercise_id='.$exerciseId.'&date_to='.$date_to.'&date_from='.$date_from;
880
881
        // Autowidth
882
        $extra_params['autowidth'] = 'true';
883
884
        // height auto
885
        $extra_params['height'] = 'auto';
886
887
        $tableId = 'exerciseProgressOverview';
888
        $table = Display::grid_js(
889
            $tableId,
890
            $url,
891
            $columns,
892
            $column_model,
893
            $extra_params,
894
            [],
895
            '',
896
            true
897
        );
898
899
        $return = '<script>$(function() {'.$table.
900
            'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
901
                jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
902
                       caption:"",
903
                       title:"'.get_lang('ExportExcel').'",
904
                       onClickButton : function () {
905
                           jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
906
                       }
907
                });
908
            });</script>';
909
        $return .= Display::grid_html($tableId);
910
911
        return $return;
912
    }
913
914
    /**
915
     * Displays a form with all the additionally defined user fields of the profile
916
     * and give you the opportunity to include these in the CSV export.
917
     *
918
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
919
     *
920
     * @version 1.8.6
921
     *
922
     * @since November 2008
923
     */
924
    public static function display_user_overview_export_options()
925
    {
926
        $message = '';
927
        $defaults = [];
928
        // include the user manager and formvalidator library
929
        if (isset($_GET['export']) && 'options' == $_GET['export']) {
930
            // get all the defined extra fields
931
            $extrafields = UserManager::get_extra_fields(
932
                0,
933
                50,
934
                5,
935
                'ASC',
936
                false,
937
                1
938
            );
939
940
            // creating the form with all the defined extra fields
941
            $form = new FormValidator(
942
                'exportextrafields',
943
                'post',
944
                api_get_self()."?view=".Security::remove_XSS($_GET['view']).'&display='.Security::remove_XSS($_GET['display']).'&export='.Security::remove_XSS($_GET['export'])
945
            );
946
947
            if (is_array($extrafields) && count($extrafields) > 0) {
948
                foreach ($extrafields as $key => $extra) {
949
                    $form->addElement('checkbox', 'extra_export_field'.$extra[0], '', $extra[3]);
950
                }
951
                $form->addButtonSave(get_lang('Ok'), 'submit');
952
953
                // setting the default values for the form that contains all the extra fields
954
                $exportFields = Session::read('additional_export_fields');
955
                if (is_array($exportFields)) {
956
                    foreach ($exportFields as $key => $value) {
957
                        $defaults['extra_export_field'.$value] = 1;
958
                    }
959
                }
960
                $form->setDefaults($defaults);
961
            } else {
962
                $form->addElement('html', Display::return_message(get_lang('ThereAreNotExtrafieldsAvailable'), 'warning'));
963
            }
964
965
            if ($form->validate()) {
966
                // exporting the form values
967
                $values = $form->exportValues();
968
969
                // re-initialising the session that contains the additional fields that need to be exported
970
                Session::write('additional_export_fields', []);
971
972
                // adding the fields that are checked to the session
973
                $message = '';
974
                $additionalExportFields = [];
975
                foreach ($values as $field_ids => $value) {
976
                    if ($value == 1 && strstr($field_ids, 'extra_export_field')) {
977
                        $additionalExportFields[] = str_replace('extra_export_field', '', $field_ids);
978
                    }
979
                }
980
                Session::write('additional_export_fields', $additionalExportFields);
981
982
                // adding the fields that will be also exported to a message string
983
                $additionalExportFields = Session::read('additional_export_fields');
984
                if (is_array($additionalExportFields)) {
985
                    foreach ($additionalExportFields as $key => $extra_field_export) {
986
                        $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
987
                    }
988
                }
989
990
                // Displaying a feedback message
991
                if (!empty($additionalExportFields)) {
992
                    echo Display::return_message(
993
                        get_lang('FollowingFieldsWillAlsoBeExported').': <br /><ul>'.$message.'</ul>',
994
                        'confirm',
995
                        false
996
                    );
997
                } else {
998
                    echo Display::return_message(
999
                        get_lang('NoAdditionalFieldsWillBeExported'),
1000
                        'confirm',
1001
                        false
1002
                    );
1003
                }
1004
            } else {
1005
                $form->display();
1006
            }
1007
        } else {
1008
            $additionalExportFields = Session::read('additional_export_fields');
1009
            if (!empty($additionalExportFields)) {
1010
                // get all the defined extra fields
1011
                $extrafields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
1012
1013
                foreach ($additionalExportFields as $key => $extra_field_export) {
1014
                    $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
1015
                }
1016
1017
                echo Display::return_message(
1018
                    get_lang('FollowingFieldsWillAlsoBeExported').': <br /><ul>'.$message.'</ul>',
1019
                    'normal',
1020
                    false
1021
                );
1022
            }
1023
        }
1024
    }
1025
1026
    /**
1027
     * Export to cvs a list of users who were enrolled in the lessons.
1028
     * It is necessary that in the extra field, a company is defined.
1029
     *
1030
     * @param string|null $startDate
1031
     * @param string|null $endDate
1032
     *
1033
     * @return array
1034
     */
1035
    public static function exportCompanyResumeCsv($startDate, $endDate)
1036
    {
1037
        $companys = self::getCompanyLearnpathSubscription($startDate, $endDate);
1038
        $csv_content = [];
1039
        // Printing table
1040
        $total = 0;
1041
        $displayText = get_lang('Company');
1042
        // the first line of the csv file with the column headers
1043
        $csv_row = [];
1044
        $csv_row[] = $displayText;
1045
1046
        $csv_row[] = get_lang('CountOfSubscribedUsers');
1047
        $csv_content[] = $csv_row;
1048
1049
        foreach ($companys as $entity => $student) {
1050
            $csv_row = [];
1051
            // user official code
1052
            $csv_row[] = $entity;
1053
            $csv_row[] = count($student);
1054
            $total += count($student);
1055
            $csv_content[] = $csv_row;
1056
        }
1057
1058
        $csv_row = [];
1059
        // user official code
1060
        $csv_row[] = get_lang('GeneralTotal');
1061
        $csv_row[] = $total;
1062
        $csv_content[] = $csv_row;
1063
        Export::arrayToCsv($csv_content, 'reporting_company_resume');
1064
        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...
1065
    }
1066
1067
    /**
1068
     * Generates a structure to show the links or names for the authors by lesson report.
1069
     *
1070
     * @param array $students
1071
     * @param array $studentRegistered
1072
     * @param       $lpCourseCode
1073
     */
1074
    public static function getStudentDataToReportByLp($students = [], $studentRegistered = [], $lpCourseCode)
1075
    {
1076
        $data = [];
1077
        $totalStudents = 0;
1078
        $data['csv'] = '';
1079
        $data['html'] = '';
1080
        $icon = Display::return_icon('statistics.png', get_lang('Stats'));
1081
        foreach ($students as $student) {
1082
            $lpSessionId = isset($student['session_id']) ? (int) $student['session_id'] : 0;
1083
            $studentId = (int) $student['id'];
1084
            if (!isset($studentRegistered[$studentId][$lpSessionId])) {
1085
                $url = api_get_path(WEB_CODE_PATH)."mySpace/myStudents.php?details=true&student=$studentId";
1086
                if (0 != $lpSessionId) {
1087
                    $url .= "&id_session=$lpSessionId";
1088
                }
1089
                $url .= "&course=$lpCourseCode";
1090
                $reportLink = Display::url(
1091
                    $icon,
1092
                    $url
1093
                );
1094
                $studentName = $student['complete_name']."(".$student['company'].")";
1095
                $studentRegistered[$studentId][$lpSessionId] = $student;
1096
                $data['csv'] .= $studentName.' / ';
1097
                $data['html'] .= "$reportLink <strong>$studentName</strong><br>";
1098
                $totalStudents++;
1099
            }
1100
        }
1101
        $data['student_registered'] = $studentRegistered;
1102
        $data['total_students'] = $totalStudents;
1103
1104
        return $data;
1105
    }
1106
1107
    /**
1108
     * * Generates a structure to show the names for the authors by lesson report by item.
1109
     *
1110
     * @param array  $students
1111
     * @param array  $studentProcessed
1112
     * @param string $typeReport
1113
     * @param false  $csv
1114
     */
1115
    public static function getStudentDataToReportByLpItem($students = [], $studentProcessed = [], $typeReport = '', $csv = false)
1116
    {
1117
        $totalStudent = count($students);
1118
        $sessionIcon = Display::return_icon(
1119
            'admin_star.png',
1120
            get_lang('StudentInSessionCourse'),
1121
            [],
1122
            ICON_SIZE_MEDIUM
1123
        );
1124
        $classIcon = Display::return_icon(
1125
            'group_summary.png',
1126
            get_lang('UsersInsideClass'),
1127
            '',
1128
            ICON_SIZE_MEDIUM
1129
        );
1130
        /* use 'for' to performance */
1131
        for ($i = 0; $i < $totalStudent; $i++) {
1132
            $student = $students[$i];
1133
            $studentId = $student['id'];
1134
            $lpItemIdStudent = $student['lp_item_id'];
1135
            $sessionId = isset($student['session_id']) ? (int) $student['session_id'] : 0;
1136
            $studentName = $student['complete_name'];
1137
            $studentCompany = $student['company'];
1138
            $studentName = "$studentName($studentCompany)";
1139
            $type = isset($student['type']) ? $student['type'] : null;
1140
            $icon = null;
1141
            if (0 != $sessionId) {
1142
                $icon = $sessionIcon;
1143
            }
1144
            if ('class' == $typeReport) {
1145
                $icon = $classIcon;
1146
            }
1147
            $studentString = "$icon $studentName";
1148
            if (0 != $sessionId) {
1149
                $studentString = "<strong>$studentString</strong>";
1150
            }
1151
            if ($csv == false) {
1152
                $studentProcessed[$lpItemIdStudent][$type][$studentId] = $studentString.'<br>';
1153
            } else {
1154
                $studentProcessed[$lpItemIdStudent][$type][$studentId] = "$studentName / ";
1155
            }
1156
        }
1157
1158
        return $studentProcessed;
1159
    }
1160
1161
    /**
1162
     * Displays a list as a table of users who were enrolled in the lessons.
1163
     * It is necessary that in the extra field, a company is defined.
1164
     *
1165
     * @param string|null $startDate
1166
     * @param string|null $endDate
1167
     */
1168
    public static function displayResumeCompany(
1169
        $startDate = null,
1170
        $endDate = null
1171
    ) {
1172
        $companys = self::getCompanyLearnpathSubscription($startDate, $endDate);
1173
        $tableHtml = '';
1174
        // Printing table
1175
        $total = 0;
1176
        $table = "<div class='table-responsive'><table class='table table-hover table-striped table-bordered data_table'>";
1177
1178
        $displayText = get_lang('Company');
1179
        $table .= "<thead><tr><th class='th-header'>$displayText</th><th class='th-header'> ".get_lang('CountOfSubscribedUsers')." </th></tr></thead><tbody>";
1180
1181
        foreach ($companys as $entity => $student) {
1182
            $table .= "<tr><td>$entity</td><td>".count($student)."</td></tr>";
1183
            $total += count($student);
1184
        }
1185
        $table .= "<tr><td>".get_lang('GeneralTotal')."</td><td>$total</td></tr>";
1186
        $table .= '</tbody></table></div>';
1187
1188
        if (!empty($startDate) or !empty($endDate)) {
1189
            $tableHtml = $table;
1190
        }
1191
1192
        $form = new FormValidator('searchDate', 'get');
1193
        $form->addHidden('display', 'company');
1194
        $today = new DateTime();
1195
        if (empty($startDate)) {
1196
            $startDate = api_get_local_time($today->modify('first day of this month')->format('Y-m-d'));
1197
        }
1198
        if (empty($endDate)) {
1199
            $endDate = api_get_local_time($today->modify('last day of this month')->format('Y-m-d'));
1200
        }
1201
        $form->addDatePicker(
1202
            'startDate',
1203
            get_lang('DateStart'),
1204
            [
1205
                'value' => $startDate,
1206
            ]);
1207
        $form->addDatePicker(
1208
            'endDate',
1209
            get_lang('DateEnd'),
1210
            [
1211
                'value' => $endDate,
1212
            ]);
1213
        $form->addButtonSearch(get_lang('Search'));
1214
        if (count($companys) != 0) {
1215
            //$form->addButtonSave(get_lang('Ok'), 'export');
1216
            $form
1217
                ->addButton(
1218
                    'export_csv',
1219
                    get_lang('ExportAsCSV'),
1220
                    'check',
1221
                    'primary',
1222
                    null,
1223
                    null,
1224
                    [
1225
                    ]
1226
                );
1227
        }
1228
1229
        $tableContent = $form->returnForm();
1230
        $tableContent .= $tableHtml;
1231
        // $tableContent .= $table->return_table();
1232
1233
        $tpl = new Template('', false, false, false, false, false, false);
1234
        $tpl->assign('table', $tableContent);
1235
        $templateName = $tpl->get_template('my_space/course_summary.tpl');
1236
        $tpl->display($templateName);
1237
    }
1238
1239
    /**
1240
     *  Displays a list as a table of teachers who are set authors by a extra_field authors.
1241
     *
1242
     * @param string|null $startDate
1243
     * @param string|null $endDate
1244
     * @param bool        $csv
1245
     */
1246
    public static function displayResumeLP(
1247
        $startDate = null,
1248
        $endDate = null,
1249
        $csv = false
1250
    ) {
1251
        $tblExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
1252
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
1253
        $tblExtraFieldValue = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
1254
        $tblLpItem = Database::get_course_table(TABLE_LP_ITEM);
1255
        $tblLp = Database::get_course_table(TABLE_LP_MAIN);
1256
        $tblAccessUrlCourse = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
1257
        $accessUrlFilter = '';
1258
        if (api_is_multiple_url_enabled()) {
1259
            $urlId = api_get_current_access_url_id();
1260
            $accessUrlFilter = " INNER JOIN $tblAccessUrlCourse aurc
1261
                      ON (c.id = aurc.c_id AND aurc.access_url_id = $urlId)";
1262
        }
1263
        $query = "
1264
        SELECT DISTINCT
1265
            lp.name,
1266
            lpi.title,
1267
            lp.id as lp_id,
1268
            lpi.id AS lp_item_id,
1269
            REPLACE (efv.value, ';', ',') AS users_id,
1270
            c.title AS course_title,
1271
            c.code AS course_code
1272
        FROM $tblExtraFieldValue AS efv
1273
        INNER JOIN $tblExtraField AS ef
1274
        ON (
1275
            efv.field_id = ef.id AND
1276
            ef.variable = 'authorlpitem' AND
1277
            efv.value != ''
1278
            )
1279
        INNER JOIN $tblLpItem AS lpi
1280
        ON (efv.item_id = lpi.iid)
1281
        INNER JOIN $tblLp AS lp
1282
        ON (lpi.lp_id = lp.iid AND lpi.c_id = lp.c_id)
1283
        INNER JOIN $tblCourse AS c
1284
        ON (lp.c_id = c.id)
1285
        $accessUrlFilter";
1286
        $queryResult = Database::query($query);
1287
        $dataTeachers = Database::store_result($queryResult, 'ASSOC');
1288
        $totalData = count($dataTeachers);
1289
        $lpItems = [];
1290
        $teachers = [];
1291
        $users = [];
1292
        $learningPaths = [];
1293
        $csvContent = [];
1294
        $htmlData = '';
1295
        /* use 'for' to performance */
1296
        for ($i = 0; $i < $totalData; $i++) {
1297
            $row = $dataTeachers[$i];
1298
            $lpId = $row['lp_id'];
1299
            $lpItems[] = $lpId;
1300
            $authorData = $row['users_id'];
1301
            $learningPaths[$lpId] = $row;
1302
            if (strpos($authorData, ",") === false) {
1303
                if (!isset($users[$authorData])) {
1304
                    $users[$authorData] = api_get_user_info($authorData);
1305
                }
1306
                $teachers[$authorData][$lpId] = $users[$authorData];
1307
                $learningPaths[$lpId]['teachers'][$authorData] = $users[$authorData];
1308
            } else {
1309
                $items = explode(',', $authorData);
1310
                $totalItems = count($items);
1311
                for ($j = 0; $j < $totalItems; $j++) {
1312
                    $authorData = $items[$j];
1313
                    if (!isset($users[$authorData])) {
1314
                        $users[$authorData] = api_get_user_info($authorData);
1315
                    }
1316
                    $teachers[$authorData][$lpId] = $users[$authorData];
1317
                    $learningPaths[$lpId]['teachers'][$authorData] = $users[$authorData];
1318
                }
1319
            }
1320
        }
1321
        $lpItems = array_unique($lpItems);
1322
        $whereInLp = implode(',', $lpItems);
1323
        if (count($lpItems) != 0) {
1324
            $registeredUsers = self::getCompanyLearnpathSubscription(
1325
                $startDate,
1326
                $endDate,
1327
                $whereInLp
1328
            );
1329
            foreach ($registeredUsers as $students) {
1330
                $totalStudents = count($students);
1331
                /* use 'for' to performance */
1332
                for ($i = 0; $i < $totalStudents; $i++) {
1333
                    $user = $students[$i];
1334
                    $lpId = $user['lp_item'];
1335
                    $studentId = $user['id'];
1336
                    $learningPaths[$lpId]['courseStudent'][$studentId] = $user;
1337
                }
1338
            }
1339
            $registeredUsersBySession = self::getSessionAddUserCourseFromTrackDefault(
1340
                $startDate,
1341
                $endDate,
1342
                $whereInLp
1343
            );
1344
            foreach ($registeredUsersBySession as $lpId => $student) {
1345
                $totalStudents = count($student);
1346
                /* use 'for' to performance */
1347
                for ($i = 0; $i < $totalStudents; $i++) {
1348
                    $user = $student[$i];
1349
                    $lpId = $user['lp'];
1350
                    $studentId = $user['id'];
1351
                    $learningPaths[$lpId]['sessionStudent'][$studentId] = $user;
1352
                    $learningPaths[$lpId]['sessionStudent'][$studentId]['session_id'] = $user;
1353
                }
1354
            }
1355
            $registeredUsersGroup = self::getCompanyLearnpathSubscription(
1356
                $startDate,
1357
                $endDate,
1358
                $whereInLp,
1359
                true
1360
            );
1361
            foreach ($registeredUsersGroup as $student) {
1362
                $totalStudents = count($student);
1363
                /* use 'for' to performance */
1364
                for ($i = 0; $i < $totalStudents; $i++) {
1365
                    $user = $student[$i];
1366
                    $lpId = $user['lp_item'];
1367
                    $studentId = $user['id'];
1368
                    $learningPaths[$lpId]['courseStudentGroup'][$studentId] = $user;
1369
                }
1370
            }
1371
1372
            $index = 0;
1373
            $iconAdd = Display::return_icon('add.png', get_lang('ShowOrHide'), '', ICON_SIZE_SMALL);
1374
            $iconRemove = Display::return_icon('error.png', get_lang('ShowOrHide'), '', ICON_SIZE_SMALL);
1375
            $htmlData = "<div class='table-responsive'>
1376
            <table class='table table-hover table-striped table-bordered data_table'>
1377
            <thead>
1378
                <tr>
1379
                    <th class='th-header'>".get_lang('Author')."</th>
1380
                    <th class='th-header'>".get_lang('LearningPathList')."</th>
1381
                    <th class='th-header'>".get_lang('CountOfSubscribedUsers')."</th>
1382
                    <th class='th-header'>".get_lang('StudentList')."</th>
1383
                </tr>
1384
            </thead>
1385
                <tbody>";
1386
            $lastTeacher = '';
1387
            /* csv */
1388
            $csv_row = [];
1389
            $csv_row[] = get_lang('Author');
1390
            $csv_row[] = get_lang('LearningPathList');
1391
            $csv_row[] = get_lang('CountOfSubscribedUsers');
1392
            $csv_row[] = get_lang('StudentList');
1393
            $csvContent[] = $csv_row;
1394
            $studentsName = '';
1395
            /* csv */
1396
            foreach ($teachers as $authorLId => $teacher) {
1397
                $totalStudents = 0;
1398
                foreach ($teacher as $lpId => $teacherData) {
1399
                    $lpSessionId = 0;
1400
                    $lpData = $learningPaths[$lpId];
1401
                    $printTeacherName = ($lastTeacher != $teacherData['complete_name']) ? $teacherData['complete_name'] : '';
1402
                    $htmlData .= "<tr><td>$printTeacherName</td>";
1403
                    $hiddenField = 'student_show_'.$index;
1404
                    $hiddenFieldLink = 'student_show_'.$index.'_';
1405
                    $lpCourseCode = $lpData['course_code'];
1406
                    $lpName = $lpData['name'];
1407
                    $courseStudent = isset($lpData['courseStudent']) ? $lpData['courseStudent'] : [];
1408
                    $courseStudentGroup = isset($lpData['courseStudentGroup']) ? $lpData['courseStudentGroup'] : [];
1409
                    $sessionStudent = isset($lpData['sessionStudent']) ? $lpData['sessionStudent'] : [];
1410
                    $htmlData .= "<td>$lpName</td><td>".count($courseStudent)." ( ".count($sessionStudent)." )</td><td>";
1411
                    $csv_row = [];
1412
                    $csv_row[] = $printTeacherName;
1413
                    $csv_row[] = $lpName;
1414
                    $csv_row[] = count($courseStudent).' ( '.count($sessionStudent)." )";
1415
                    if (!empty($courseStudent)
1416
                        || !empty($courseStudentGroup)
1417
                        || !empty($sessionStudent)
1418
                    ) {
1419
                        $htmlData .= "<a href='#!' id='$hiddenFieldLink' onclick='showHideStudent(\"$hiddenField\")'>
1420
                        <div class='icon_add'>$iconAdd</div>
1421
                        <div class='icon_remove hidden'>$iconRemove</div>
1422
                        </a>
1423
                        <div id='$hiddenField' class='hidden'>";
1424
                        $studentRegistered = [];
1425
1426
                        $tempArray = self::getStudentDataToReportByLp($courseStudent, $studentRegistered, $lpCourseCode);
1427
                        $studentsName .= $tempArray['csv'];
1428
                        $htmlData .= $tempArray['html'];
1429
                        $studentRegistered = $tempArray['student_registered'];
1430
                        $totalStudents += $tempArray['total_students'];
1431
1432
                        $tempArray = self::getStudentDataToReportByLp($sessionStudent, $studentRegistered, $lpCourseCode);
1433
                        $studentsName .= $tempArray['csv'];
1434
                        $htmlData .= $tempArray['html'];
1435
                        $studentRegistered = $tempArray['student_registered'];
1436
                        $totalStudents += $tempArray['total_students'];
1437
1438
                        $tempArray = self::getStudentDataToReportByLp($courseStudentGroup, $studentRegistered, $lpCourseCode);
1439
                        $studentsName .= $tempArray['csv'];
1440
                        $htmlData .= $tempArray['html'];
1441
                        $studentRegistered = $tempArray['student_registered'];
1442
                        $totalStudents += $tempArray['total_students'];
1443
1444
                        $htmlData .= "</div>";
1445
                    }
1446
                    $htmlData .= "</td></tr>";
1447
                    $index++;
1448
                    $csv_row[] = trim($studentsName, ' / ');
1449
                    $studentsName = '';
1450
                    $csvContent[] = $csv_row;
1451
                    $lastTeacher = $teacherData['complete_name'];
1452
                }
1453
                $htmlData .= "<tr>
1454
                <td></td>
1455
                <td><strong>".get_lang('LearnpathsTotal')." ".count($teacher)." </strong></td>
1456
                <td><strong>$totalStudents</strong></td>
1457
                <td></td>
1458
                </tr>";
1459
            }
1460
            $htmlData .= "</tbody>
1461
            </table>
1462
            </div>";
1463
        }
1464
        if (false == $csv) {
1465
            $form = new FormValidator('searchDate', 'get');
1466
            $form->addHidden('display', 'learningPath');
1467
            $today = new DateTime();
1468
            if (empty($startDate)) {
1469
                $startDate = $today->modify('first day of this month')->format('Y-m-d');
1470
            }
1471
            if (empty($endDate)) {
1472
                $endDate = $today->modify('last day of this month')->format('Y-m-d');
1473
            }
1474
            $form->addDatePicker(
1475
                'startDate',
1476
                get_lang('DateStart'),
1477
                [
1478
                    'value' => $startDate,
1479
                ]);
1480
            $form->addDatePicker(
1481
                'endDate',
1482
                get_lang('DateEnd'),
1483
                [
1484
                    'value' => $endDate,
1485
                ]);
1486
            $form->addButtonSearch(get_lang('Search'));
1487
            if (0 != count($csvContent)) {
1488
                $form
1489
                    ->addButton(
1490
                        'export_csv',
1491
                        get_lang('ExportAsCSV'),
1492
                        'check',
1493
                        'primary',
1494
                        null,
1495
                        null,
1496
                        [
1497
                        ]
1498
                    );
1499
            }
1500
            $tableContent = $form->returnForm();
1501
            if (!empty($startDate) || !empty($endDate)) {
1502
                $tableContent .= $htmlData;
1503
            }
1504
            $tpl = new Template('', false, false, false, false, false, false);
1505
            $tpl->assign('table', $tableContent);
1506
            $templateName = $tpl->get_template('my_space/course_summary.tpl');
1507
            $tpl->display($templateName);
1508
        } else {
1509
            if (count($csvContent) != 0) {
1510
                Export::arrayToCsv($csvContent, 'reporting_lp_by_authors');
1511
            }
1512
        }
1513
    }
1514
1515
    /**
1516
     *  Displays a list as a table of teachers who are set authors of lp's item by a extra_field authors.
1517
     *
1518
     * @param string|null $startDate
1519
     * @param string|null $endDate
1520
     * @param bool        $csv
1521
     */
1522
    public static function displayResumeLpByItem($startDate = null, $endDate = null, $csv = false)
1523
    {
1524
        $tableHtml = '';
1525
        $table = '';
1526
        $tblExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
1527
        $tblExtraFieldValue = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
1528
        $tblLpItem = Database::get_course_table(TABLE_LP_ITEM);
1529
        $tblLp = Database::get_course_table(TABLE_LP_MAIN);
1530
        $tblAccessUrlCourse = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
1531
        $accessUrlFilter = '';
1532
        if (api_is_multiple_url_enabled()) {
1533
            $urlId = api_get_current_access_url_id();
1534
            $accessUrlFilter = " INNER JOIN $tblAccessUrlCourse aurc
1535
                      ON (lp.c_id = aurc.c_id AND aurc.access_url_id = $urlId)";
1536
        }
1537
        $index = 0;
1538
        $cLpItems = [];
1539
        $cLpItemsAuthor = [];
1540
        $authorArray = [];
1541
        $studentArray = [];
1542
        $whereInLp = [];
1543
        $dataSet = [];
1544
        /** Get lp items only with authors */
1545
        $sql = " SELECT
1546
                efv.item_id AS lp_item_id,
1547
                efv.value AS author
1548
            FROM $tblExtraFieldValue AS efv
1549
            INNER JOIN $tblExtraField AS ef
1550
            ON (
1551
                ef.variable = 'authorlpitem' AND
1552
                efv.field_id = ef.id AND
1553
                efv.value != ''
1554
            )
1555
            ORDER BY efv.item_id ";
1556
        $queryResult = Database::query($sql);
1557
        $data = Database::store_result($queryResult, 'ASSOC');
1558
        $totalData = count($data);
1559
        /* use 'for' to performance */
1560
        for ($i = 0; $i < $totalData; $i++) {
1561
            $cLpItemsAuthor[$data[$i]['lp_item_id']] = $data[$i]['author'];
1562
        }
1563
        /** Get lp items only with price */
1564
        $sql = " SELECT
1565
               lp.iid AS lp_id,
1566
               lp.name AS lp_name,
1567
               efv.item_id AS lp_item_id,
1568
               lpi.title AS title,
1569
               efv.value AS price
1570
            FROM $tblExtraFieldValue AS efv
1571
            INNER JOIN $tblExtraField AS ef
1572
            ON (
1573
                ef.variable = 'price' AND
1574
                efv.field_id = ef.id AND
1575
                efv.value > 0
1576
            )
1577
            INNER JOIN $tblLpItem AS lpi
1578
            ON (lpi.iid = efv.item_id)
1579
            INNER JOIN $tblLp AS lp
1580
            ON (lpi.lp_id = lp.iid AND lpi.c_id = lp.c_id)
1581
            $accessUrlFilter";
1582
        $queryResult = Database::query($sql);
1583
        $data = Database::store_result($queryResult, 'ASSOC');
1584
        $totalData = count($data);
1585
        /* use 'for' to performance */
1586
        for ($i = 0; $i < $totalData; $i++) {
1587
            $item = $data[$i];
1588
            $lpItemId = (int) $item['lp_item_id'];
1589
            $whereInLp[] = $item['lp_id'];
1590
            $author = isset($cLpItemsAuthor[$lpItemId]) ? $cLpItemsAuthor[$lpItemId] : null;
1591
            $item['author'] = $author;
1592
            if (!empty($author)) {
1593
                $cLpItems[count($cLpItems)] = $item;
1594
            }
1595
        }
1596
        $totalLpItems = count($cLpItems);
1597
        $tableNoData = "<div class='table-responsive'>
1598
                <table class='table table-hover table-striped table-bordered data_table'>
1599
                <thead>
1600
                    <tr>
1601
                    <th class='th-header'>".get_lang('NoDataAvailable').'</th>
1602
                </tr>
1603
                </thead>
1604
                </tbody>
1605
                </tbody>
1606
                </table>
1607
                </div>';
1608
        if (0 == $totalLpItems) {
1609
            $tableHtml = $tableNoData;
1610
        } elseif (0 == count($whereInLp)) {
1611
            $tableHtml = $tableNoData;
1612
        } else {
1613
            $whereInLp = array_unique($whereInLp);
1614
            $whereInLp = implode(',', $whereInLp);
1615
            $registeredUsersBySession = self::getSessionAddUserCourseFromTrackDefault(
1616
                $startDate,
1617
                $endDate,
1618
                $whereInLp
1619
            );
1620
            $registeredUsersInCourse = self::getUserSubscribedInCourseByDateAndLp($startDate, $endDate, $whereInLp);
1621
            $registeredUsersInLp = self::getCompanyLearnpathSubscription(
1622
                $startDate,
1623
                $endDate,
1624
                $whereInLp
1625
            );
1626
            $registeredGroupsInLp = self::getCompanyLearnpathSubscription(
1627
                $startDate,
1628
                $endDate,
1629
                $whereInLp,
1630
                true
1631
            );
1632
            /* use 'for' to performance */
1633
            for ($i = 0; $i < $totalLpItems; $i++) {
1634
                $lpItem = $cLpItems[$i];
1635
                $lpItemId = $lpItem['lp_item_id'];
1636
                $author = str_replace(';', ',', $lpItem['author']);
1637
                $tempArrayAuthor = explode(',', $author);
1638
                $byCourse = $registeredUsersInLp[$lpItemId] ?? [];
1639
                $byCourseGroups = $registeredGroupsInLp[$lpItemId] ?? [];
1640
                $bySession = $registeredUsersBySession[$lpItemId] ?? [];
1641
                $byUserInCourse = $registeredUsersInCourse[$lpItemId] ?? [];
1642
                if (is_array($tempArrayAuthor)) {
1643
                    $totalAuthors = count($tempArrayAuthor);
1644
                    for ($j = 0; $j < $totalAuthors; $j++) {
1645
                        if (!isset($authorArray[$tempArrayAuthor[$j]])) {
1646
                            $authorArray[$tempArrayAuthor[$j]] = api_get_user_info($tempArrayAuthor[$j]);
1647
                        }
1648
                        $dataSet[$tempArrayAuthor[$j]][$lpItemId] = [
1649
                            'course' => $byCourse,
1650
                            'courseGroups' => $byCourseGroups,
1651
                            'session' => $bySession,
1652
                            'lp_item' => $lpItem,
1653
                            'course_user' => $byUserInCourse,
1654
                        ];
1655
                    }
1656
                } else {
1657
                    if (!isset($authorArray[$author])) {
1658
                        $authorArray[$author] = api_get_user_info($author);
1659
                    }
1660
                    $dataSet[$author][$lpItemId] = [
1661
                        'course' => $byCourse,
1662
                        'courseGroups' => $byCourseGroups,
1663
                        'session' => $bySession,
1664
                        'lp_item' => $lpItem,
1665
                        'course_user' => $byUserInCourse,
1666
                    ];
1667
                }
1668
            }
1669
        }
1670
        if ($csv == false) {
1671
            if (empty($tableHtml)) {
1672
                $table .= "<div class='table-responsive'>
1673
                    <table class='table table-hover table-striped table-bordered data_table'>
1674
                    <thead>
1675
                    <tr>
1676
                    <th class='th-header'>".get_lang('Author')."</th>
1677
                    <th class='th-header'>".get_lang('ContentList')."</th>
1678
                    <th class='th-header'>".get_lang('Tariff')."</th>
1679
                    <th class='th-header'>".get_lang('CountOfSubscribedUsers')."</th>
1680
                    <th class='th-header'>".get_lang('ToInvoice')."</th>
1681
                    <th class='th-header'>".get_lang('StudentList')."</th>
1682
                    </tr>
1683
                    </thead>
1684
                    <tbody>";
1685
                //Icon Constant
1686
                $iconAdd = Display::return_icon('add.png', get_lang('ShowOrHide'), '', ICON_SIZE_SMALL);
1687
                $iconRemove = Display::return_icon('error.png', get_lang('ShowOrHide'), '', ICON_SIZE_SMALL);
1688
1689
                $lastAuthor = '';
1690
                $total = 0;
1691
                foreach ($dataSet as $authorId => $lpItems) {
1692
                    $authorTemp = $authorArray[$authorId];
1693
                    $totalSudent = 0;
1694
                    foreach ($lpItems as $lpItem) {
1695
                        $totalStudents = 0;
1696
                        $itemLp = $lpItem['lp_item'];
1697
                        $title = $itemLp['title'];
1698
                        $price = $itemLp['price'];
1699
                        $byCourse = $lpItem['course'];
1700
                        $byCourseGroups = $lpItem['courseGroups'];
1701
                        $bySession = $lpItem['session'];
1702
                        $byUserInCourse = $lpItem['course_user'];
1703
                        $hide = "class='author_$authorId hidden' ";
1704
                        $tableTemp = '';
1705
                        if ($lastAuthor != $authorTemp) {
1706
                            $table .= "<tr><td>".$authorTemp['complete_name']."</td>";
1707
                        } else {
1708
                            $table .= "<tr $hide ><td></td>";
1709
                        }
1710
                        $table .= "<td>$title</td><td>$price</td>";
1711
                        $studentRegister = count($byCourse);
1712
                        $studentGroupsRegister = count($byCourseGroups);
1713
                        $studentRegisterBySession = count($bySession);
1714
                        $usersInCourseCount = count($byUserInCourse);
1715
1716
                        $hiddenField = 'student_show_'.$index;
1717
                        $hiddenFieldLink = 'student_show_'.$index.'_';
1718
                        if (0 != $studentRegister ||
1719
                            0 != $studentRegisterBySession ||
1720
                            0 != $studentGroupsRegister ||
1721
                            0 != $usersInCourseCount
1722
                        ) {
1723
                            $tableTemp .= "<td>
1724
                                <a href='#!' id='$hiddenFieldLink' onclick='showHideStudent(\"$hiddenField\")'>
1725
                                <div class='icon_add'>$iconAdd</div>
1726
                                <div class='icon_remove hidden'>$iconRemove</div>
1727
                                </a>
1728
                                <div id='$hiddenField' class='hidden'>";
1729
                            $studentProcessed = [];
1730
                            /* Student by course*/
1731
                            $studentProcessed = self::getStudentDataToReportByLpItem($byCourse, $studentProcessed);
1732
                            /* Student by Class*/
1733
                            $studentProcessed = self::getStudentDataToReportByLpItem($byCourseGroups, $studentProcessed, 'class');
1734
                            /* Student by sessions*/
1735
                            $studentProcessed = self::getStudentDataToReportByLpItem($bySession, $studentProcessed);
1736
                            // Students in course*/
1737
                            $studentProcessed = self::getStudentDataToReportByLpItem($byUserInCourse, $studentProcessed);
1738
                            $index++;
1739
                            foreach ($studentProcessed as $lpItemId => $item) {
1740
                                foreach ($item as $type => $student) {
1741
                                    foreach ($student as $userId => $text) {
1742
                                        if ('LearnpathSubscription' == $type) {
1743
                                            $tableTemp .= $text;
1744
                                            $totalStudents++;
1745
                                        } else {
1746
                                            if (!isset($studentProcessed[$lpItemId]['LearnpathSubscription'])) {
1747
                                                $tableTemp .= $text;
1748
                                                $totalStudents++;
1749
                                            }
1750
                                        }
1751
                                    }
1752
                                }
1753
                            }
1754
                            $tableTemp .= "</div></td>";
1755
                        } else {
1756
                            $tableTemp .= "<td></td>";
1757
                        }
1758
                        $table .= "<td>$totalStudents</td>";
1759
                        $invoicing = ($totalStudents * $price);
1760
                        $table .= "<td>$invoicing</td>";
1761
                        $total += $invoicing;
1762
                        $totalSudent += $totalStudents;
1763
                        $table .= $tableTemp."</tr>";
1764
                        $lastAuthor = $authorTemp;
1765
                    }
1766
                    $hiddenFieldLink = 'student__show_'.$index.'_';
1767
                    $index++;
1768
                    $table .= "<tr>
1769
                    <th class='th-header'></th>
1770
                    <th class='th-header'>
1771
                            <a href='#!' id='$hiddenFieldLink' onclick='ShowMoreAuthor(\"$authorId\")'>
1772
                                <div class='icon_add_author_$authorId'>$iconAdd</div>
1773
                                <div class='icon_remove_author_$authorId hidden'>$iconRemove</div>
1774
                            </a>
1775
                        </th>
1776
                    <th class='th-header'></th>
1777
                    <th class='th-header'>$totalSudent</th>
1778
                    <th class='th-header'>$total</th>
1779
                    <th class='th-header'></tr>";
1780
                    $total = 0;
1781
                }
1782
                $table .= "</tbody></table></div>";
1783
                $tableHtml = $table;
1784
            }
1785
1786
            $form = new FormValidator('searchDate', 'get');
1787
            $form->addHidden('display', 'learningPathByItem');
1788
            $today = new DateTime();
1789
            if (empty($startDate)) {
1790
                $startDate = $today->modify('first day of this month')->format('Y-m-d');
1791
            }
1792
            if (empty($endDate)) {
1793
                $endDate = $today->modify('last day of this month')->format('Y-m-d');
1794
            }
1795
            $form->addDatePicker(
1796
                'startDate',
1797
                get_lang('DateStart'),
1798
                [
1799
                    'value' => $startDate,
1800
                ]
1801
            );
1802
            $form->addDatePicker(
1803
                'endDate',
1804
                get_lang('DateEnd'),
1805
                [
1806
                    'value' => $endDate,
1807
                ]
1808
            );
1809
            $form->addButtonSearch(get_lang('Search'));
1810
1811
            if (count($dataSet) != 0) {
1812
                $form->addButton(
1813
                    'export_csv',
1814
                    get_lang('ExportAsCSV'),
1815
                    'check',
1816
                    'primary',
1817
                    null,
1818
                    null,
1819
                    [
1820
                    ]
1821
                );
1822
            }
1823
            $tableContent = $form->returnForm();
1824
            $tableContent .= $tableHtml;
1825
            $tpl = new Template('', false, false, false, false, false, false);
1826
            $tpl->assign('table', $tableContent);
1827
            $templateName = $tpl->get_template('my_space/course_summary.tpl');
1828
            $tpl->display($templateName);
1829
        } else {
1830
            $csv_content = [];
1831
            $csv_row = [];
1832
            $csv_row[] = get_lang('Author');
1833
            $csv_row[] = get_lang('ContentList');
1834
            $csv_row[] = get_lang('Tariff');
1835
            $csv_row[] = get_lang('CountOfSubscribedUsers');
1836
            $csv_row[] = get_lang('ToInvoice');
1837
            $csv_row[] = get_lang('StudentList');
1838
            $csv_content[] = $csv_row;
1839
            $total = 0;
1840
            foreach ($dataSet as $authorId => $lpItems) {
1841
                $authorTemp = $authorArray[$authorId];
1842
                $totalSudent = 0;
1843
                foreach ($lpItems as $lpItem) {
1844
                    $totalStudents = 0;
1845
                    $itemLp = $lpItem['lp_item'];
1846
                    $itemLpId = $itemLp['lp_item_id'];
1847
                    $title = $itemLp['title'];
1848
                    $price = $itemLp['price'];
1849
                    $byCourse = $lpItem['course'];
1850
                    $bySession = $lpItem['session'];
1851
                    $byCourseGroups = $lpItem['courseGroups'];
1852
                    $byUserInCourse = $lpItem['course_user'];
1853
1854
                    $csv_row = [];
1855
                    $csv_row[] = $authorTemp['complete_name'];
1856
                    $csv_row[] = $title;
1857
                    $csv_row[] = $price;
1858
1859
                    $studentRegister = count($byCourse);
1860
                    $studentRegisterBySession = count($bySession);
1861
                    $studentGroupsRegister = count($byCourseGroups);
1862
1863
                    $studentsName = '';
1864
                    if (0 != $studentRegister ||
1865
                        0 != $studentRegisterBySession ||
1866
                        0 != $studentGroupsRegister) {
1867
                        $studentProcessed = [];
1868
                        /* Student by course*/
1869
                        $studentProcessed = self::getStudentDataToReportByLpItem($byCourse, $studentProcessed, '', true);
1870
                        /* Student by Class*/
1871
                        $studentProcessed = self::getStudentDataToReportByLpItem($byCourseGroups, $studentProcessed, 'class', true);
1872
                        /* Student by sessions*/
1873
                        $studentProcessed = self::getStudentDataToReportByLpItem($bySession, $studentProcessed, '', true);
1874
                        // Students in course*/
1875
                        $studentProcessed = self::getStudentDataToReportByLpItem($byUserInCourse, $studentProcessed, '', true);
1876
1877
                        $index++;
1878
                        foreach ($studentProcessed as $lpItemId => $item) {
1879
                            foreach ($item as $type => $student) {
1880
                                foreach ($student as $userId => $text) {
1881
                                    if ('LearnpathSubscription' == $type) {
1882
                                        $studentsName .= $text;
1883
                                        $totalStudents++;
1884
                                    } else {
1885
                                        if (!isset($studentProcessed[$lpItemId]['LearnpathSubscription'])) {
1886
                                            $studentsName .= $text;
1887
                                            $totalStudents++;
1888
                                        }
1889
                                    }
1890
                                }
1891
                            }
1892
                        }
1893
                    }
1894
                    $csv_row[] = $totalStudents;
1895
                    $csv_row[] = $price * $totalStudents;
1896
                    $csv_row[] = trim($studentsName, " / ");
1897
                    $csv_content[] = $csv_row;
1898
                }
1899
            }
1900
            Export::arrayToCsv($csv_content, 'reporting_lp_by_authors');
1901
        }
1902
    }
1903
1904
    public static function getSessionAddUserCourseFromTrackDefault(
1905
        $startDate = null,
1906
        $endDate = null,
1907
        $whereInLp = null
1908
    ) {
1909
        $whereInLp = Database::escape_string($whereInLp);
1910
        $data = [];
1911
        $tblTrackDefault = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
1912
        $tblSessionRelCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1913
        $tblLp = Database::get_course_table(TABLE_LP_MAIN);
1914
        $tblLpItem = Database::get_course_table(TABLE_LP_ITEM);
1915
        $tblUser = Database::get_main_table(TABLE_MAIN_USER);
1916
        $tblAccessUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
1917
        $accessUrlFilter = '';
1918
        if (api_is_multiple_url_enabled()) {
1919
            $urlId = api_get_current_access_url_id();
1920
            $accessUrlFilter = " INNER JOIN $tblAccessUrlUser auru
1921
                      ON (u.id = auru.user_id AND auru.access_url_id = $urlId)";
1922
        }
1923
1924
        if (!empty($startDate)) {
1925
            $startDate = new DateTime($startDate);
1926
        } else {
1927
            $startDate = new DateTime();
1928
        }
1929
        if (!empty($endDate)) {
1930
            $endDate = new DateTime($endDate);
1931
        } else {
1932
            $endDate = new DateTime();
1933
        }
1934
        if (!empty($startDate) and !empty($endDate)) {
1935
            if ($startDate > $endDate) {
1936
                $dateTemp = $endDate;
1937
                $endDate = $startDate;
1938
                $startDate = $dateTemp;
1939
                unset($dateTemp);
1940
            }
1941
        }
1942
        $startDate = api_get_utc_datetime($startDate->setTime(0, 0, 0)->format('Y-m-d H:i:s'));
1943
        $endDate = api_get_utc_datetime($endDate->setTime(0, 0, 0)->format('Y-m-d H:i:s'));
1944
        $extra = '';
1945
        if (!empty($whereInLp)) {
1946
            $extra = " AND lpi.lp_id in ($whereInLp) ";
1947
        }
1948
1949
        $sql = "SELECT DISTINCT
1950
            lp.iid AS lp,
1951
            lpi.iid AS lp_item,
1952
            lpi.iid AS lp_item_id,
1953
            td.default_value AS id,
1954
            srcu.session_id AS session_id,
1955
            u.username AS username,
1956
            td.default_date AS default_date,
1957
            td.default_event_type AS type,
1958
            u.firstname as firstname,
1959
            u.lastname as lastname
1960
        FROM $tblTrackDefault AS td
1961
        INNER JOIN $tblSessionRelCourseUser AS srcu
1962
        ON (td.default_value = srcu.user_id AND td.c_id = srcu.c_id)
1963
        INNER JOIN $tblLp AS lp
1964
        ON (lp.c_id = srcu.c_id)
1965
        INNER JOIN $tblLpItem AS lpi
1966
        ON (
1967
            lpi.c_id = srcu.c_id AND
1968
            lp.id = lpi.lp_id AND
1969
            lpi.c_id = lp.c_id
1970
        )
1971
        INNER JOIN $tblUser AS u
1972
        ON (u.id = srcu.user_id)
1973
        $accessUrlFilter
1974
        WHERE
1975
            td.default_event_type = 'session_add_user_course' AND
1976
            td.default_date >= '$startDate' AND
1977
            td.default_date <= '$endDate'
1978
            $extra
1979
        ORDER BY td.default_value ";
1980
        $queryResult = Database::query($sql);
1981
        $dataTrack = Database::store_result($queryResult, 'ASSOC');
1982
        foreach ($dataTrack as $item) {
1983
            $item['complete_name'] = api_get_person_name($item['firstname'], $item['lastname']);
1984
            $item['company'] = self::getCompanyOfUser($item['id']);
1985
            $data[$item['lp_item_id']][] = $item;
1986
        }
1987
1988
        return $data;
1989
    }
1990
1991
    public static function getUserSubscribedInCourseByDateAndLp(
1992
        $startDate = null,
1993
        $endDate = null,
1994
        $whereInLp = null
1995
    ): array {
1996
        $whereInLp = Database::escape_string($whereInLp);
1997
        $tblTrackDefault = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
1998
        $tblCourseRelUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1999
        $tblLp = Database::get_course_table(TABLE_LP_MAIN);
2000
        $tblLpItem = Database::get_course_table(TABLE_LP_ITEM);
2001
        $tblUser = Database::get_main_table(TABLE_MAIN_USER);
2002
        $tblAccessUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
2003
        $accessUrlFilter = '';
2004
2005
        if (api_is_multiple_url_enabled()) {
2006
            $urlId = api_get_current_access_url_id();
2007
            $accessUrlFilter = " INNER JOIN $tblAccessUrlUser auru
2008
                ON (u.id = auru.user_id AND auru.access_url_id = $urlId)";
2009
        }
2010
2011
        $startDate = !empty($startDate) ? new DateTime($startDate) : new DateTime();
2012
        $endDate = !empty($endDate) ? new DateTime($endDate) : new DateTime();
2013
2014
        $startDate = api_get_utc_datetime($startDate->setTime(0, 0)->format('Y-m-d H:i:s'));
2015
        $endDate = api_get_utc_datetime($endDate->setTime(0, 0)->format('Y-m-d H:i:s'));
2016
2017
        $extra = '';
2018
2019
        if (!empty($whereInLp)) {
2020
            $extra = " AND lpi.lp_id in ($whereInLp) ";
2021
        }
2022
2023
        $sql = "SELECT DISTINCT
2024
                lp.iid AS lp,
2025
                lpi.iid AS lp_item,
2026
                lpi.iid AS lp_item_id,
2027
                u.id AS id,
2028
                u.username AS username,
2029
                td.default_date AS default_date,
2030
                td.default_event_type AS type,
2031
                u.firstname as firstname,
2032
                u.lastname as lastname
2033
            FROM $tblTrackDefault AS td
2034
            INNER JOIN $tblCourseRelUser AS cru ON td.c_id = cru.c_id
2035
            INNER JOIN $tblLp AS lp ON lp.c_id = cru.c_id
2036
            INNER JOIN $tblLpItem AS lpi
2037
                ON (lpi.c_id = cru.c_id AND lp.id = lpi.lp_id AND lpi.c_id = lp.c_id)
2038
            INNER JOIN $tblUser AS u ON u.id = cru.user_id
2039
            $accessUrlFilter
2040
            WHERE
2041
                td.default_event_type = '".LOG_SUBSCRIBE_USER_TO_COURSE."'
2042
                AND td.default_date >= '$startDate'
2043
                AND td.default_date <= '$endDate'
2044
                AND td.default_value LIKE CONCAT('%s:2:\\\\\\\\\\\"id\\\\\\\\\";i:', cru.user_id, ';%')
2045
                $extra
2046
            ORDER BY u.id";
2047
2048
        $result = Database::query($sql);
2049
2050
        $data = [];
2051
2052
        while ($item = Database::fetch_assoc($result)) {
2053
            $item['complete_name'] = api_get_person_name($item['firstname'], $item['lastname']);
2054
            $item['company'] = self::getCompanyOfUser($item['id']);
2055
2056
            $data[$item['lp_item_id']][] = $item;
2057
        }
2058
2059
        return $data;
2060
    }
2061
2062
    /**
2063
     * Display a sortable table that contains an overview of all the reporting progress of all courses.
2064
     */
2065
    public static function display_tracking_course_overview()
2066
    {
2067
        $params = ['view' => 'admin', 'display' => 'courseoverview'];
2068
        $table = new SortableTable(
2069
            'tracking_session_overview',
2070
            ['MySpace', 'get_total_number_courses'],
2071
            ['MySpace', 'get_course_data_tracking_overview'],
2072
            1,
2073
            20,
2074
            'ASC',
2075
            null, [
2076
                'class' => 'table table-transparent',
2077
            ]
2078
        );
2079
        $table->additional_parameters = $params;
2080
        $table->set_column_filter(0, ['MySpace', 'course_tracking_filter']);
2081
        $tableContent = $table->return_table();
2082
2083
        $tpl = new Template('', false, false, false, false, false, false);
2084
        $tpl->assign('table', $tableContent);
2085
        $templateName = $tpl->get_template('my_space/course_summary.tpl');
2086
        $tpl->display($templateName);
2087
    }
2088
2089
    /**
2090
     * Get the total number of courses.
2091
     *
2092
     * @return int Total number of courses
2093
     */
2094
    public static function get_total_number_courses()
2095
    {
2096
        return CourseManager::count_courses(api_get_current_access_url_id());
2097
    }
2098
2099
    /**
2100
     * Get data for the courses.
2101
     *
2102
     * @param int    $from        Inferior limit
2103
     * @param int    $numberItems Number of items to select
2104
     * @param string $column      Column to order on
2105
     * @param string $direction   Order direction
2106
     *
2107
     * @return array Results
2108
     */
2109
    public static function get_course_data_tracking_overview(
2110
        $from,
2111
        $numberItems,
2112
        $column,
2113
        $direction
2114
    ) {
2115
        switch ($column) {
2116
            default:
2117
            case 1:
2118
                $column = 'title';
2119
                break;
2120
        }
2121
2122
        $courses = CourseManager::get_courses_list(
2123
            $from,
2124
            $numberItems,
2125
            $column,
2126
            $direction,
2127
             -1,
2128
            '',
2129
            api_get_current_access_url_id()
2130
        );
2131
2132
        $list = [];
2133
        foreach ($courses as $course) {
2134
            $list[] = [
2135
                '0' => $course['code'],
2136
                'col0' => $course['code'],
2137
            ];
2138
        }
2139
2140
        return $list;
2141
    }
2142
2143
    /**
2144
     * Fills in course reporting data.
2145
     *
2146
     * @param int course code
2147
     * @param array $url_params additional url parameters
2148
     * @param array $row        the row information (the other columns)
2149
     *
2150
     * @return string html code
2151
     */
2152
    public static function course_tracking_filter($course_code, $url_params, $row)
2153
    {
2154
        $course_code = $row[0];
2155
        $courseInfo = api_get_course_info($course_code);
2156
        $courseId = $courseInfo['real_id'];
2157
2158
        $tpl = new Template('', false, false, false, false, false, false);
2159
        $data = null;
2160
2161
        // database table definition
2162
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2163
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2164
2165
        // getting all the courses of the user
2166
        $sql = "SELECT *
2167
                FROM $tbl_user AS u
2168
                INNER JOIN $tbl_course_rel_user AS cu
2169
                ON cu.user_id = u.user_id
2170
                WHERE cu.c_id = '".$courseId."'";
2171
        $result = Database::query($sql);
2172
        $time_spent = 0;
2173
        $progress = 0;
2174
        $nb_progress_lp = 0;
2175
        $score = 0;
2176
        $nb_score_lp = 0;
2177
        $nb_messages = 0;
2178
        $nb_assignments = 0;
2179
        $last_login_date = false;
2180
        $total_score_obtained = 0;
2181
        $total_score_possible = 0;
2182
        $total_questions_answered = 0;
2183
        while ($row = Database::fetch_object($result)) {
2184
            // get time spent in the course and session
2185
            $time_spent += Tracking::get_time_spent_on_the_course(
2186
                $row->user_id,
2187
                $courseInfo['real_id']
2188
            );
2189
            $progress_tmp = Tracking::get_avg_student_progress(
2190
                $row->user_id,
2191
                $course_code,
2192
                [],
2193
                null,
2194
                true
2195
            );
2196
2197
            if ($progress_tmp) {
2198
                $progress += $progress_tmp[0];
2199
                $nb_progress_lp += $progress_tmp[1];
2200
            }
2201
            $score_tmp = Tracking::get_avg_student_score(
2202
                $row->user_id,
2203
                $course_code,
2204
                [],
2205
                null,
2206
                true
2207
            );
2208
            if (is_array($score_tmp)) {
2209
                $score += $score_tmp[0];
2210
                $nb_score_lp += $score_tmp[1];
2211
            }
2212
            $nb_messages += Tracking::count_student_messages(
2213
                $row->user_id,
2214
                $course_code
2215
            );
2216
            $nb_assignments += Tracking::count_student_assignments(
2217
                $row->user_id,
2218
                $course_code
2219
            );
2220
            $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
2221
                $row->user_id,
2222
                $courseInfo,
2223
                null,
2224
                false
2225
            );
2226
            if ($last_login_date_tmp != false &&
2227
                $last_login_date == false
2228
            ) { // TODO: To be cleaned
2229
                $last_login_date = $last_login_date_tmp;
2230
            } elseif ($last_login_date_tmp != false && $last_login_date != false) {
2231
                // TODO: Repeated previous condition. To be cleaned.
2232
                // Find the max and assign it to first_login_date
2233
                if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
2234
                    $last_login_date = $last_login_date_tmp;
2235
                }
2236
            }
2237
2238
            $exercise_results_tmp = self::exercises_results($row->user_id, $course_code);
2239
            $total_score_obtained += $exercise_results_tmp['score_obtained'];
2240
            $total_score_possible += $exercise_results_tmp['score_possible'];
2241
            $total_questions_answered += $exercise_results_tmp['questions_answered'];
2242
        }
2243
        if ($nb_progress_lp > 0) {
2244
            $avg_progress = round($progress / $nb_progress_lp, 2);
2245
        } else {
2246
            $avg_progress = 0;
2247
        }
2248
        if ($nb_score_lp > 0) {
2249
            $avg_score = round($score / $nb_score_lp, 2);
2250
        } else {
2251
            $avg_score = '-';
2252
        }
2253
        if ($last_login_date) {
2254
            $last_login_date = api_convert_and_format_date(
2255
                $last_login_date,
2256
                DATE_FORMAT_SHORT,
2257
                date_default_timezone_get()
2258
            );
2259
        } else {
2260
            $last_login_date = '-';
2261
        }
2262
        if ($total_score_possible > 0) {
2263
            $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
2264
        } else {
2265
            $total_score_percentage = 0;
2266
        }
2267
        if ($total_score_percentage > 0) {
2268
            $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
2269
        } else {
2270
            $total_score = '-';
2271
        }
2272
2273
        $data = [
2274
            'course_code' => $course_code,
2275
            'id' => $courseId,
2276
            'image' => $courseInfo['course_image_large'],
2277
            'image_small' => $courseInfo['course_image'],
2278
            'title' => $courseInfo['title'],
2279
            'url' => $courseInfo['course_public_url'],
2280
            'category' => $courseInfo['categoryName'],
2281
            'time_spent' => api_time_to_hms($time_spent),
2282
            'avg_progress' => $avg_progress,
2283
            'avg_score' => $avg_score,
2284
            'number_message' => $nb_messages,
2285
            'number_assignments' => $nb_assignments,
2286
            'total_score' => $total_score,
2287
            'questions_answered' => $total_questions_answered,
2288
            'last_login' => $last_login_date,
2289
        ];
2290
2291
        $tpl->assign('data', $data);
2292
        $layout = $tpl->get_template('my_space/partials/tracking_course_overview.tpl');
2293
        $content = $tpl->fetch($layout);
2294
2295
        return $content;
2296
    }
2297
2298
    /**
2299
     * This function exports the table that we see in display_tracking_course_overview().
2300
     */
2301
    public static function export_tracking_course_overview()
2302
    {
2303
        // database table definition
2304
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2305
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2306
2307
        // the values of the sortable table
2308
        if ($_GET['tracking_course_overview_page_nr']) {
2309
            $from = $_GET['tracking_course_overview_page_nr'];
2310
        } else {
2311
            $from = 0;
2312
        }
2313
        if ($_GET['tracking_course_overview_column']) {
2314
            $orderby = $_GET['tracking_course_overview_column'];
2315
        } else {
2316
            $orderby = 0;
2317
        }
2318
2319
        if ($_GET['tracking_course_overview_direction']) {
2320
            $direction = $_GET['tracking_course_overview_direction'];
2321
        } else {
2322
            $direction = 'ASC';
2323
        }
2324
2325
        $course_data = self::get_course_data_tracking_overview(
2326
            $from,
2327
            1000,
2328
            $orderby,
2329
            $direction
2330
        );
2331
2332
        $csv_content = [];
2333
2334
        // the first line of the csv file with the column headers
2335
        $csv_row = [];
2336
        $csv_row[] = get_lang('Course');
2337
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse');
2338
        $csv_row[] = get_lang('AvgStudentsProgress');
2339
        $csv_row[] = get_lang('AvgCourseScore');
2340
        $csv_row[] = get_lang('TotalNumberOfMessages');
2341
        $csv_row[] = get_lang('TotalNumberOfAssignments');
2342
        $csv_row[] = get_lang('TotalExercisesScoreObtained');
2343
        $csv_row[] = get_lang('TotalExercisesScorePossible');
2344
        $csv_row[] = get_lang('TotalExercisesAnswered');
2345
        $csv_row[] = get_lang('TotalExercisesScorePercentage');
2346
        $csv_row[] = get_lang('LatestLogin');
2347
        $csv_content[] = $csv_row;
2348
2349
        // the other lines (the data)
2350
        foreach ($course_data as $key => $course) {
2351
            $course_code = $course[0];
2352
            $courseInfo = api_get_course_info($course_code);
2353
            $course_title = $courseInfo['title'];
2354
            $courseId = $courseInfo['real_id'];
2355
2356
            $csv_row = [];
2357
            $csv_row[] = $course_title;
2358
2359
            // getting all the courses of the session
2360
            $sql = "SELECT *
2361
                    FROM $tbl_user AS u
2362
                    INNER JOIN $tbl_course_rel_user AS cu
2363
                    ON cu.user_id = u.user_id
2364
                    WHERE cu.c_id = '".$courseId."'";
2365
            $result = Database::query($sql);
2366
            $time_spent = 0;
2367
            $progress = 0;
2368
            $nb_progress_lp = 0;
2369
            $score = 0;
2370
            $nb_score_lp = 0;
2371
            $nb_messages = 0;
2372
            $nb_assignments = 0;
2373
            $last_login_date = false;
2374
            $total_score_obtained = 0;
2375
            $total_score_possible = 0;
2376
            $total_questions_answered = 0;
2377
            while ($row = Database::fetch_object($result)) {
2378
                // get time spent in the course and session
2379
                $time_spent += Tracking::get_time_spent_on_the_course(
2380
                    $row->user_id,
2381
                    $courseId
2382
                );
2383
                $progress_tmp = Tracking::get_avg_student_progress(
2384
                    $row->user_id,
2385
                    $course_code,
2386
                    [],
2387
                    null,
2388
                    true
2389
                );
2390
                $progress += $progress_tmp[0];
2391
                $nb_progress_lp += $progress_tmp[1];
2392
                $score_tmp = Tracking::get_avg_student_score(
2393
                    $row->user_id,
2394
                    $course_code,
2395
                    [],
2396
                    null,
2397
                    true
2398
                );
2399
                if (is_array($score_tmp)) {
2400
                    $score += $score_tmp[0];
2401
                    $nb_score_lp += $score_tmp[1];
2402
                }
2403
                $nb_messages += Tracking::count_student_messages(
2404
                    $row->user_id,
2405
                    $course_code
2406
                );
2407
                $nb_assignments += Tracking::count_student_assignments(
2408
                    $row->user_id,
2409
                    $course_code
2410
                );
2411
2412
                $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
2413
                    $row->user_id,
2414
                    $courseInfo,
2415
                    null,
2416
                    false
2417
                );
2418
                if ($last_login_date_tmp != false && $last_login_date == false) {
2419
                    // TODO: To be cleaned.
2420
                    $last_login_date = $last_login_date_tmp;
2421
                } elseif ($last_login_date_tmp != false && $last_login_date == false) {
2422
                    // TODO: Repeated previous condition. To be cleaned.
2423
                    // Find the max and assign it to first_login_date
2424
                    if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
2425
                        $last_login_date = $last_login_date_tmp;
2426
                    }
2427
                }
2428
2429
                $exercise_results_tmp = self::exercises_results($row->user_id, $course_code);
2430
                $total_score_obtained += $exercise_results_tmp['score_obtained'];
2431
                $total_score_possible += $exercise_results_tmp['score_possible'];
2432
                $total_questions_answered += $exercise_results_tmp['questions_answered'];
2433
            }
2434
            if ($nb_progress_lp > 0) {
2435
                $avg_progress = round($progress / $nb_progress_lp, 2);
2436
            } else {
2437
                $avg_progress = 0;
2438
            }
2439
            if ($nb_score_lp > 0) {
2440
                $avg_score = round($score / $nb_score_lp, 2);
2441
            } else {
2442
                $avg_score = '-';
2443
            }
2444
            if ($last_login_date) {
2445
                $last_login_date = api_convert_and_format_date(
2446
                    $last_login_date,
2447
                    DATE_FORMAT_SHORT,
2448
                    date_default_timezone_get()
2449
                );
2450
            } else {
2451
                $last_login_date = '-';
2452
            }
2453
            if ($total_score_possible > 0) {
2454
                $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
2455
            } else {
2456
                $total_score_percentage = 0;
2457
            }
2458
            // time spent in the course
2459
            $csv_row[] = api_time_to_hms($time_spent);
2460
            // student progress in course
2461
            $csv_row[] = $avg_progress;
2462
            // student score
2463
            $csv_row[] = $avg_score;
2464
            // student messages
2465
            $csv_row[] = $nb_messages;
2466
            // student assignments
2467
            $csv_row[] = $nb_assignments;
2468
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
2469
            $csv_row[] = $total_score_obtained;
2470
            $csv_row[] = $total_score_possible;
2471
            $csv_row[] = $total_questions_answered;
2472
            $csv_row[] = $total_score_percentage;
2473
            // last connection
2474
            $csv_row[] = $last_login_date;
2475
            $csv_content[] = $csv_row;
2476
        }
2477
        Export::arrayToCsv($csv_content, 'reporting_course_overview');
2478
        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...
2479
    }
2480
2481
    /**
2482
     * Display a sortable table that contains an overview of all the reporting
2483
     * progress of all sessions and all courses the user is subscribed to.
2484
     *
2485
     * @author Guillaume Viguier <[email protected]>
2486
     */
2487
    public static function display_tracking_session_overview()
2488
    {
2489
        $head = '<table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
2490
        $head .= '<tr>';
2491
        $head .= '<th width="155px" style="border-left:0;border-bottom:0"><span>'.get_lang('Course').'</span></th>';
2492
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgTimeSpentInTheCourse'), 6, true).'</span></th>';
2493
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgStudentsProgress'), 6, true).'</span></th>';
2494
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgCourseScore'), 6, true).'</span></th>';
2495
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfMessages'), 6, true).'</span></th>';
2496
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfAssignments'), 6, true).'</span></th>';
2497
        $head .= '<th width="105px" style="border-bottom:0"><span>'.get_lang('TotalExercisesScoreObtained').'</span></th>';
2498
        $head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalExercisesAnswered'), 6, true).'</span></th>';
2499
        $head .= '<th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('LatestLogin').'</span></th>';
2500
        $head .= '</tr></table>';
2501
2502
        $params = ['view' => 'admin', 'display' => 'sessionoverview'];
2503
        $table = new SortableTable(
2504
            'tracking_session_overview',
2505
            ['MySpace', 'get_total_number_sessions'],
2506
            ['MySpace', 'get_session_data_tracking_overview'],
2507
            1
2508
        );
2509
        $table->additional_parameters = $params;
2510
2511
        $table->set_header(0, '', false, null, ['style' => 'display: none']);
2512
        $table->set_header(
2513
            1,
2514
            get_lang('Session'),
2515
            true,
2516
            ['style' => 'font-size:8pt'],
2517
            ['style' => 'font-size:8pt']
2518
        );
2519
        $table->set_header(
2520
            2,
2521
            $head,
2522
            false,
2523
            ['style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'],
2524
            ['style' => 'width:90%;padding:0;font-size:7.5pt;']
2525
        );
2526
        $table->set_column_filter(2, ['MySpace', 'session_tracking_filter']);
2527
        $table->display();
2528
    }
2529
2530
    /**
2531
     * Get the total number of sessions.
2532
     *
2533
     * @return int Total number of sessions
2534
     */
2535
    public static function get_total_number_sessions()
2536
    {
2537
        return SessionManager::count_sessions(api_get_current_access_url_id());
2538
    }
2539
2540
    /**
2541
     * Get data for the sessions.
2542
     *
2543
     * @param int    $from        Inferior limit
2544
     * @param int    $numberItems Number of items to select
2545
     * @param string $column      Column to order on
2546
     * @param string $direction   Order direction
2547
     *
2548
     * @return array Results
2549
     */
2550
    public static function get_session_data_tracking_overview(
2551
        $from,
2552
        $numberItems,
2553
        $column,
2554
        $direction
2555
    ) {
2556
        $from = (int) $from;
2557
        $numberItems = (int) $numberItems;
2558
        $direction = Database::escape_string($direction);
2559
        $columnName = 'name';
2560
        if ($column === 1) {
2561
            $columnName = 'id';
2562
        }
2563
2564
        $options = [
2565
            'order' => " $columnName $direction",
2566
            'limit' => " $from,$numberItems",
2567
        ];
2568
        $sessions = SessionManager::formatSessionsAdminForGrid($options);
2569
        $list = [];
2570
        foreach ($sessions as $session) {
2571
            $list[] = [
2572
                '0' => $session['id'],
2573
                'col0' => $session['id'],
2574
                '1' => strip_tags($session['name']),
2575
                'col1' => strip_tags($session['name']),
2576
            ];
2577
        }
2578
2579
        return $list;
2580
    }
2581
2582
    /**
2583
     * Fills in session reporting data.
2584
     *
2585
     * @param int   $session_id the id of the user
2586
     * @param array $url_params additonal url parameters
2587
     * @param array $row        the row information (the other columns)
2588
     *
2589
     * @return string html code
2590
     */
2591
    public static function session_tracking_filter($session_id, $url_params, $row)
2592
    {
2593
        $session_id = $row[0];
2594
        // the table header
2595
        $return = '<table class="table table-hover table-striped data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
2596
2597
        // database table definition
2598
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2599
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
2600
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2601
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2602
2603
        // getting all the courses of the user
2604
        $sql = "SELECT * FROM $tbl_course AS c
2605
                INNER JOIN $tbl_session_rel_course AS sc
2606
                ON sc.c_id = c.id
2607
                WHERE sc.session_id = '".$session_id."'";
2608
        $result = Database::query($sql);
2609
        while ($row = Database::fetch_object($result)) {
2610
            $courseId = $row->c_id;
2611
            $courseInfo = api_get_course_info_by_id($courseId);
2612
            $return .= '<tr>';
2613
            // course code
2614
            $return .= '    <td width="157px" >'.$row->title.'</td>';
2615
            // get the users in the course
2616
            $sql = "SELECT u.user_id
2617
                    FROM $tbl_user AS u
2618
                    INNER JOIN $tbl_session_rel_course_rel_user AS scu
2619
                    ON u.user_id = scu.user_id
2620
                    WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
2621
            $result_users = Database::query($sql);
2622
            $time_spent = 0;
2623
            $progress = 0;
2624
            $nb_progress_lp = 0;
2625
            $score = 0;
2626
            $nb_score_lp = 0;
2627
            $nb_messages = 0;
2628
            $nb_assignments = 0;
2629
            $last_login_date = false;
2630
            $total_score_obtained = 0;
2631
            $total_score_possible = 0;
2632
            $total_questions_answered = 0;
2633
            while ($row_user = Database::fetch_object($result_users)) {
2634
                // get time spent in the course and session
2635
                $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
2636
                $progress_tmp = Tracking::get_avg_student_progress($row_user->user_id, $row->code, [], $session_id, true);
2637
                $progress += $progress_tmp[0];
2638
                $nb_progress_lp += $progress_tmp[1];
2639
                $score_tmp = Tracking::get_avg_student_score($row_user->user_id, $row->code, [], $session_id, true);
2640
                if (is_array($score_tmp)) {
2641
                    $score += $score_tmp[0];
2642
                    $nb_score_lp += $score_tmp[1];
2643
                }
2644
                $nb_messages += Tracking::count_student_messages($row_user->user_id, $row->code, $session_id);
2645
                $nb_assignments += Tracking::count_student_assignments($row_user->user_id, $row->code, $session_id);
2646
                $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course(
2647
                    $row_user->user_id,
2648
                    $courseInfo,
2649
                    $session_id,
2650
                    false
2651
                );
2652
                if ($last_login_date_tmp != false && $last_login_date == false) {
2653
                    // TODO: To be cleaned.
2654
                    $last_login_date = $last_login_date_tmp;
2655
                } elseif ($last_login_date_tmp != false && $last_login_date != false) {
2656
                    // TODO: Repeated previous condition! To be cleaned.
2657
                    // Find the max and assign it to first_login_date
2658
                    if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
2659
                        $last_login_date = $last_login_date_tmp;
2660
                    }
2661
                }
2662
2663
                $exercise_results_tmp = self::exercises_results($row_user->user_id, $row->code, $session_id);
2664
                $total_score_obtained += $exercise_results_tmp['score_obtained'];
2665
                $total_score_possible += $exercise_results_tmp['score_possible'];
2666
                $total_questions_answered += $exercise_results_tmp['questions_answered'];
2667
            }
2668
            if ($nb_progress_lp > 0) {
2669
                $avg_progress = round($progress / $nb_progress_lp, 2);
2670
            } else {
2671
                $avg_progress = 0;
2672
            }
2673
            if ($nb_score_lp > 0) {
2674
                $avg_score = round($score / $nb_score_lp, 2);
2675
            } else {
2676
                $avg_score = '-';
2677
            }
2678
            if ($last_login_date) {
2679
                $last_login_date = api_convert_and_format_date(
2680
                    $last_login_date,
2681
                    DATE_FORMAT_SHORT,
2682
                    date_default_timezone_get()
2683
                );
2684
            } else {
2685
                $last_login_date = '-';
2686
            }
2687
            if ($total_score_possible > 0) {
2688
                $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
2689
            } else {
2690
                $total_score_percentage = 0;
2691
            }
2692
            if ($total_score_percentage > 0) {
2693
                $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
2694
            } else {
2695
                $total_score = '-';
2696
            }
2697
            // time spent in the course
2698
            $return .= '    <td><div>'.api_time_to_hms($time_spent).'</div></td>';
2699
            // student progress in course
2700
            $return .= '    <td><div>'.$avg_progress.'</div></td>';
2701
            // student score
2702
            $return .= '    <td><div>'.$avg_score.'</div></td>';
2703
            // student messages
2704
            $return .= '    <td><div>'.$nb_messages.'</div></td>';
2705
            // student assignments
2706
            $return .= '    <td><div>'.$nb_assignments.'</div></td>';
2707
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
2708
            $return .= '<td width="105px;">'.$total_score.'</td>';
2709
            $return .= '<td>'.$total_questions_answered.'</td>';
2710
            // last connection
2711
            $return .= '    <td><div>'.$last_login_date.'</div></td>';
2712
            $return .= '<tr>';
2713
        }
2714
        $return .= '</table>';
2715
2716
        return $return;
2717
    }
2718
2719
    /**
2720
     * This function exports the table that we see in display_tracking_session_overview().
2721
     */
2722
    public static function export_tracking_session_overview()
2723
    {
2724
        // database table definition
2725
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2726
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
2727
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2728
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2729
2730
        // the values of the sortable table
2731
        $from = 0;
2732
        if ($_GET['tracking_session_overview_page_nr']) {
2733
            $from = $_GET['tracking_session_overview_page_nr'];
2734
        }
2735
2736
        $orderby = 0;
2737
        if ($_GET['tracking_session_overview_column']) {
2738
            $orderby = $_GET['tracking_session_overview_column'];
2739
        }
2740
2741
        $direction = 'ASC';
2742
        if ($_GET['tracking_session_overview_direction']) {
2743
            $direction = $_GET['tracking_session_overview_direction'];
2744
        }
2745
2746
        $session_data = self::get_session_data_tracking_overview($from, 1000, $orderby, $direction);
2747
2748
        $csv_content = [];
2749
2750
        // the first line of the csv file with the column headers
2751
        $csv_row = [];
2752
        $csv_row[] = get_lang('Session');
2753
        $csv_row[] = get_lang('Course');
2754
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse');
2755
        $csv_row[] = get_lang('AvgStudentsProgress');
2756
        $csv_row[] = get_lang('AvgCourseScore');
2757
        $csv_row[] = get_lang('TotalNumberOfMessages');
2758
        $csv_row[] = get_lang('TotalNumberOfAssignments');
2759
        $csv_row[] = get_lang('TotalExercisesScoreObtained');
2760
        $csv_row[] = get_lang('TotalExercisesScorePossible');
2761
        $csv_row[] = get_lang('TotalExercisesAnswered');
2762
        $csv_row[] = get_lang('TotalExercisesScorePercentage');
2763
        $csv_row[] = get_lang('LatestLogin');
2764
        $csv_content[] = $csv_row;
2765
2766
        // the other lines (the data)
2767
        foreach ($session_data as $key => $session) {
2768
            $session_id = $session[0];
2769
            $session_title = $session[1];
2770
2771
            // getting all the courses of the session
2772
            $sql = "SELECT * FROM $tbl_course AS c
2773
                    INNER JOIN $tbl_session_rel_course AS sc
2774
                    ON sc.c_id = c.id
2775
                    WHERE sc.session_id = '".$session_id."';";
2776
            $result = Database::query($sql);
2777
            while ($row = Database::fetch_object($result)) {
2778
                $courseId = $row->c_id;
2779
                $courseInfo = api_get_course_info_by_id($courseId);
2780
                $csv_row = [];
2781
                $csv_row[] = $session_title;
2782
                $csv_row[] = $row->title;
2783
                // get the users in the course
2784
                $sql = "SELECT scu.user_id
2785
                        FROM $tbl_user AS u
2786
                        INNER JOIN $tbl_session_rel_course_rel_user AS scu
2787
                        ON u.user_id = scu.user_id
2788
                        WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
2789
                $result_users = Database::query($sql);
2790
                $time_spent = 0;
2791
                $progress = 0;
2792
                $nb_progress_lp = 0;
2793
                $score = 0;
2794
                $nb_score_lp = 0;
2795
                $nb_messages = 0;
2796
                $nb_assignments = 0;
2797
                $last_login_date = false;
2798
                $total_score_obtained = 0;
2799
                $total_score_possible = 0;
2800
                $total_questions_answered = 0;
2801
                while ($row_user = Database::fetch_object($result_users)) {
2802
                    // get time spent in the course and session
2803
                    $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
2804
                    $progress_tmp = Tracking::get_avg_student_progress(
2805
                        $row_user->user_id,
2806
                        $row->code,
2807
                        [],
2808
                        $session_id,
2809
                        true
2810
                    );
2811
                    $progress += $progress_tmp[0];
2812
                    $nb_progress_lp += $progress_tmp[1];
2813
                    $score_tmp = Tracking::get_avg_student_score(
2814
                        $row_user->user_id,
2815
                        $row->code,
2816
                        [],
2817
                        $session_id,
2818
                        true
2819
                    );
2820
                    if (is_array($score_tmp)) {
2821
                        $score += $score_tmp[0];
2822
                        $nb_score_lp += $score_tmp[1];
2823
                    }
2824
                    $nb_messages += Tracking::count_student_messages(
2825
                        $row_user->user_id,
2826
                        $row->code,
2827
                        $session_id
2828
                    );
2829
2830
                    $nb_assignments += Tracking::count_student_assignments(
2831
                        $row_user->user_id,
2832
                        $row->code,
2833
                        $session_id
2834
                    );
2835
2836
                    $last_login_date_tmp = Tracking:: get_last_connection_date_on_the_course(
2837
                        $row_user->user_id,
2838
                        $courseInfo,
2839
                        $session_id,
2840
                        false
2841
                    );
2842
                    if ($last_login_date_tmp != false && $last_login_date == false) {
2843
                        // TODO: To be cleaned.
2844
                        $last_login_date = $last_login_date_tmp;
2845
                    } elseif ($last_login_date_tmp != false && $last_login_date == false) {
2846
                        // TODO: Repeated previous condition. To be cleaned.
2847
                        // Find the max and assign it to first_login_date
2848
                        if (strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
2849
                            $last_login_date = $last_login_date_tmp;
2850
                        }
2851
                    }
2852
2853
                    $exercise_results_tmp = self::exercises_results($row_user->user_id, $row->code, $session_id);
2854
                    $total_score_obtained += $exercise_results_tmp['score_obtained'];
2855
                    $total_score_possible += $exercise_results_tmp['score_possible'];
2856
                    $total_questions_answered += $exercise_results_tmp['questions_answered'];
2857
                }
2858
                if ($nb_progress_lp > 0) {
2859
                    $avg_progress = round($progress / $nb_progress_lp, 2);
2860
                } else {
2861
                    $avg_progress = 0;
2862
                }
2863
                if ($nb_score_lp > 0) {
2864
                    $avg_score = round($score / $nb_score_lp, 2);
2865
                } else {
2866
                    $avg_score = '-';
2867
                }
2868
                if ($last_login_date) {
2869
                    $last_login_date = api_convert_and_format_date(
2870
                        $last_login_date,
2871
                        DATE_FORMAT_SHORT,
2872
                        date_default_timezone_get()
2873
                    );
2874
                } else {
2875
                    $last_login_date = '-';
2876
                }
2877
                if ($total_score_possible > 0) {
2878
                    $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
2879
                } else {
2880
                    $total_score_percentage = 0;
2881
                }
2882
                if ($total_score_percentage > 0) {
2883
                    $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
2884
                } else {
2885
                    $total_score = '-';
2886
                }
2887
                // time spent in the course
2888
                $csv_row[] = api_time_to_hms($time_spent);
2889
                // student progress in course
2890
                $csv_row[] = $avg_progress;
2891
                // student score
2892
                $csv_row[] = $avg_score;
2893
                // student messages
2894
                $csv_row[] = $nb_messages;
2895
                // student assignments
2896
                $csv_row[] = $nb_assignments;
2897
                // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
2898
                $csv_row[] = $total_score_obtained;
2899
                $csv_row[] = $total_score_possible;
2900
                $csv_row[] = $total_questions_answered;
2901
                $csv_row[] = $total_score_percentage;
2902
                // last connection
2903
                $csv_row[] = $last_login_date;
2904
                $csv_content[] = $csv_row;
2905
            }
2906
        }
2907
        Export::arrayToCsv($csv_content, 'reporting_session_overview');
2908
        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...
2909
    }
2910
2911
    /**
2912
     * Get general information about the exercise performance of the user
2913
     * the total obtained score (all the score on all the questions)
2914
     * the maximum score that could be obtained
2915
     * the number of questions answered
2916
     * the success percentage.
2917
     *
2918
     * @param int    $user_id     the id of the user
2919
     * @param string $course_code the course code
2920
     * @param int    $session_id
2921
     *
2922
     * @return array
2923
     *
2924
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
2925
     *
2926
     * @version Dokeos 1.8.6
2927
     *
2928
     * @since November 2008
2929
     */
2930
    public static function exercises_results($user_id, $course_code, $session_id = 0)
2931
    {
2932
        $user_id = (int) $user_id;
2933
        $courseId = api_get_course_int_id($course_code);
2934
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
2935
2936
        $sql = "SELECT exe_result, exe_weighting
2937
                FROM $table
2938
                WHERE
2939
                    c_id = $courseId AND
2940
                    exe_user_id = $user_id";
2941
2942
        $session_id = (int) $session_id;
2943
        if (!empty($session_id)) {
2944
            $sql .= " AND session_id = '".$session_id."' ";
2945
        }
2946
        $result = Database::query($sql);
2947
        $score_obtained = 0;
2948
        $score_possible = 0;
2949
        $questions_answered = 0;
2950
        while ($row = Database::fetch_array($result)) {
2951
            $score_obtained += $row['exe_result'];
2952
            $score_possible += $row['exe_weighting'];
2953
            $questions_answered++;
2954
        }
2955
2956
        $percentage = null;
2957
        if ($score_possible != 0) {
2958
            $percentage = round(($score_obtained / $score_possible * 100), 2);
2959
        }
2960
2961
        return [
2962
            'score_obtained' => $score_obtained,
2963
            'score_possible' => $score_possible,
2964
            'questions_answered' => $questions_answered,
2965
            'percentage' => $percentage,
2966
        ];
2967
    }
2968
2969
    /**
2970
     * This function exports the table that we see in display_tracking_user_overview().
2971
     *
2972
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
2973
     *
2974
     * @version Dokeos 1.8.6
2975
     *
2976
     * @since October 2008
2977
     */
2978
    public static function export_tracking_user_overview()
2979
    {
2980
        // database table definitions
2981
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2982
        $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
2983
2984
        // the values of the sortable table
2985
        if ($_GET['tracking_user_overview_page_nr']) {
2986
            $from = $_GET['tracking_user_overview_page_nr'];
2987
        } else {
2988
            $from = 0;
2989
        }
2990
        if ($_GET['tracking_user_overview_column']) {
2991
            $orderby = $_GET['tracking_user_overview_column'];
2992
        } else {
2993
            $orderby = 0;
2994
        }
2995
        if ($is_western_name_order != api_is_western_name_order() && ($orderby == 1 || $orderby == 2)) {
2996
            // Swapping the sorting column if name order for export is different than the common name order.
2997
            $orderby = 3 - $orderby;
2998
        }
2999
        if ($_GET['tracking_user_overview_direction']) {
3000
            $direction = $_GET['tracking_user_overview_direction'];
3001
        } else {
3002
            $direction = 'ASC';
3003
        }
3004
3005
        $user_data = self::get_user_data_tracking_overview(
3006
            $from,
3007
            1000,
3008
            $orderby,
3009
            $direction
3010
        );
3011
3012
        // the first line of the csv file with the column headers
3013
        $csv_row = [];
3014
        $csv_row[] = get_lang('OfficialCode');
3015
        if ($is_western_name_order) {
3016
            $csv_row[] = get_lang('FirstName');
3017
            $csv_row[] = get_lang('LastName');
3018
        } else {
3019
            $csv_row[] = get_lang('LastName');
3020
            $csv_row[] = get_lang('FirstName');
3021
        }
3022
        $csv_row[] = get_lang('LoginName');
3023
        $csv_row[] = get_lang('CourseCode');
3024
3025
        // the additional user defined fields (only those that were selected to be exported)
3026
        $fields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
3027
3028
        $additionalExportFields = Session::read('additional_export_fields');
3029
3030
        if (is_array($additionalExportFields)) {
3031
            foreach ($additionalExportFields as $key => $extra_field_export) {
3032
                $csv_row[] = $fields[$extra_field_export][3];
3033
                $field_names_to_be_exported[] = 'extra_'.$fields[$extra_field_export][1];
3034
            }
3035
        }
3036
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse', '');
3037
        $csv_row[] = get_lang('AvgStudentsProgress', '');
3038
        $csv_row[] = get_lang('AvgCourseScore', '');
3039
        $csv_row[] = get_lang('AvgExercisesScore', '');
3040
        $csv_row[] = get_lang('AvgMessages', '');
3041
        $csv_row[] = get_lang('AvgAssignments', '');
3042
        $csv_row[] = get_lang('TotalExercisesScoreObtained', '');
3043
        $csv_row[] = get_lang('TotalExercisesScorePossible', '');
3044
        $csv_row[] = get_lang('TotalExercisesAnswered', '');
3045
        $csv_row[] = get_lang('TotalExercisesScorePercentage', '');
3046
        $csv_row[] = get_lang('FirstLogin', '');
3047
        $csv_row[] = get_lang('LatestLogin', '');
3048
        $csv_content[] = $csv_row;
3049
3050
        // the other lines (the data)
3051
        foreach ($user_data as $key => $user) {
3052
            // getting all the courses of the user
3053
            $sql = "SELECT * FROM $tbl_course_user
3054
                    WHERE user_id = '".intval($user[4])."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
3055
            $result = Database::query($sql);
3056
            while ($row = Database::fetch_row($result)) {
3057
                $courseInfo = api_get_course_info($row['course_code']);
3058
                $courseId = $courseInfo['real_id'];
3059
3060
                $csv_row = [];
3061
                // user official code
3062
                $csv_row[] = $user[0];
3063
                // user first|last name
3064
                $csv_row[] = $user[1];
3065
                // user last|first name
3066
                $csv_row[] = $user[2];
3067
                // user login name
3068
                $csv_row[] = $user[3];
3069
                // course code
3070
                $csv_row[] = $row[0];
3071
                // the additional defined user fields
3072
                $extra_fields = self::get_user_overview_export_extra_fields($user[4]);
3073
3074
                if (is_array($field_names_to_be_exported)) {
3075
                    foreach ($field_names_to_be_exported as $key => $extra_field_export) {
3076
                        $csv_row[] = $extra_fields[$extra_field_export];
3077
                    }
3078
                }
3079
                // time spent in the course
3080
                $csv_row[] = api_time_to_hms(Tracking::get_time_spent_on_the_course($user[4], $courseId));
3081
                // student progress in course
3082
                $csv_row[] = round(Tracking::get_avg_student_progress($user[4], $row[0]), 2);
3083
                // student score
3084
                $csv_row[] = round(Tracking::get_avg_student_score($user[4], $row[0]), 2);
3085
                // student tes score
3086
                $csv_row[] = round(Tracking::get_avg_student_exercise_score($user[4], $row[0]), 2);
3087
                // student messages
3088
                $csv_row[] = Tracking::count_student_messages($user[4], $row[0]);
3089
                // student assignments
3090
                $csv_row[] = Tracking::count_student_assignments($user[4], $row[0]);
3091
                // student exercises results
3092
                $exercises_results = self::exercises_results($user[4], $row[0]);
3093
                $csv_row[] = $exercises_results['score_obtained'];
3094
                $csv_row[] = $exercises_results['score_possible'];
3095
                $csv_row[] = $exercises_results['questions_answered'];
3096
                $csv_row[] = $exercises_results['percentage'];
3097
                // first connection
3098
                $csv_row[] = Tracking::get_first_connection_date_on_the_course($user[4], $courseId);
3099
                // last connection
3100
                $csv_row[] = strip_tags(Tracking::get_last_connection_date_on_the_course($user[4], $courseInfo));
3101
3102
                $csv_content[] = $csv_row;
3103
            }
3104
        }
3105
        Export::arrayToCsv($csv_content, 'reporting_user_overview');
3106
        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...
3107
    }
3108
3109
    /**
3110
     * Get data for courses list in sortable with pagination.
3111
     *
3112
     * @return array
3113
     */
3114
    public static function get_course_data($from, $number_of_items, $column, $direction)
3115
    {
3116
        global $courses, $csv_content, $charset, $session_id;
3117
3118
        // definition database tables
3119
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3120
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
3121
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3122
3123
        $course_data = [];
3124
        $courses_code = array_keys($courses);
3125
3126
        foreach ($courses_code as &$code) {
3127
            $code = "'$code'";
3128
        }
3129
3130
        // get all courses with limit
3131
        $sql = "SELECT course.code as col1, course.title as col2
3132
                FROM $tbl_course course
3133
                WHERE course.code IN (".implode(',', $courses_code).")";
3134
3135
        if (!in_array($direction, ['ASC', 'DESC'])) {
3136
            $direction = 'ASC';
3137
        }
3138
3139
        $column = (int) $column;
3140
        $from = (int) $from;
3141
        $number_of_items = (int) $number_of_items;
3142
3143
        $sql .= " ORDER BY col$column $direction ";
3144
        $sql .= " LIMIT $from,$number_of_items";
3145
3146
        $res = Database::query($sql);
3147
        while ($row_course = Database::fetch_row($res)) {
3148
            $course_code = $row_course[0];
3149
            $courseInfo = api_get_course_info($course_code);
3150
            $courseId = $courseInfo['real_id'];
3151
            $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;
3152
3153
            // students directly subscribed to the course
3154
            if (empty($session_id)) {
3155
                $sql = "SELECT user_id
3156
                        FROM $tbl_course_user as course_rel_user
3157
                        WHERE
3158
                            course_rel_user.status='5' AND
3159
                            course_rel_user.c_id = '$courseId'";
3160
            } else {
3161
                $sql = "SELECT user_id FROM $tbl_session_course_user srcu
3162
                        WHERE
3163
                            c_id = '$courseId' AND
3164
                            session_id = '$session_id' AND
3165
                            status<>2";
3166
            }
3167
            $rs = Database::query($sql);
3168
            $users = [];
3169
            while ($row = Database::fetch_array($rs)) {
3170
                $users[] = $row['user_id'];
3171
            }
3172
3173
            if (count($users) > 0) {
3174
                $nb_students_in_course = count($users);
3175
                $avg_assignments_in_course = Tracking::count_student_assignments($users, $course_code, $session_id);
3176
                $avg_messages_in_course = Tracking::count_student_messages($users, $course_code, $session_id);
3177
                $avg_progress_in_course = Tracking::get_avg_student_progress($users, $course_code, [], $session_id);
3178
                $avg_score_in_course = Tracking::get_avg_student_score($users, $course_code, [], $session_id);
3179
                $avg_score_in_exercise = Tracking::get_avg_student_exercise_score($users, $course_code, 0, $session_id);
3180
                $avg_time_spent_in_course = Tracking::get_time_spent_on_the_course(
3181
                    $users,
3182
                    $courseInfo['real_id'],
3183
                    $session_id
3184
                );
3185
3186
                $avg_progress_in_course = round($avg_progress_in_course / $nb_students_in_course, 2);
3187
                if (is_numeric($avg_score_in_course)) {
3188
                    $avg_score_in_course = round($avg_score_in_course / $nb_students_in_course, 2);
3189
                }
3190
                $avg_time_spent_in_course = api_time_to_hms($avg_time_spent_in_course / $nb_students_in_course);
3191
            } else {
3192
                $avg_time_spent_in_course = null;
3193
                $avg_progress_in_course = null;
3194
                $avg_score_in_course = null;
3195
                $avg_score_in_exercise = null;
3196
                $avg_messages_in_course = null;
3197
                $avg_assignments_in_course = null;
3198
            }
3199
            $table_row = [];
3200
            $table_row[] = $row_course[1];
3201
            $table_row[] = $nb_students_in_course;
3202
            $table_row[] = $avg_time_spent_in_course;
3203
            $table_row[] = is_null($avg_progress_in_course) ? '' : $avg_progress_in_course.'%';
3204
            $table_row[] = is_null($avg_score_in_course) ? '' : $avg_score_in_course.'%';
3205
            $table_row[] = is_null($avg_score_in_exercise) ? '' : $avg_score_in_exercise.'%';
3206
            $table_row[] = $avg_messages_in_course;
3207
            $table_row[] = $avg_assignments_in_course;
3208
3209
            //set the "from" value to know if I access the Reporting by the chamilo tab or the course link
3210
            $table_row[] = '<center><a href="../../tracking/courseLog.php?cidReq='.$course_code.'&from=myspace&id_session='.$session_id.'">
3211
                             '.Display::return_icon('2rightarrow.png', get_lang('Details')).'
3212
                             </a>
3213
                            </center>';
3214
3215
            $scoreInCourse = null;
3216
            if (null !== $avg_score_in_course) {
3217
                if (is_numeric($avg_score_in_course)) {
3218
                    $scoreInCourse = $avg_score_in_course.'%';
3219
                } else {
3220
                    $scoreInCourse = $avg_score_in_course;
3221
                }
3222
            }
3223
3224
            $csv_content[] = [
3225
                api_html_entity_decode($row_course[1], ENT_QUOTES, $charset),
3226
                $nb_students_in_course,
3227
                $avg_time_spent_in_course,
3228
                is_null($avg_progress_in_course) ? null : $avg_progress_in_course.'%',
3229
                $scoreInCourse,
3230
                is_null($avg_score_in_exercise) ? null : $avg_score_in_exercise.'%',
3231
                $avg_messages_in_course,
3232
                $avg_assignments_in_course,
3233
            ];
3234
            $course_data[] = $table_row;
3235
        }
3236
3237
        return $course_data;
3238
    }
3239
3240
    /**
3241
     * Get the number of users of the platform.
3242
     *
3243
     * @return int
3244
     */
3245
    public static function get_number_of_users_tracking_overview()
3246
    {
3247
        return UserManager::get_number_of_users(0, api_get_current_access_url_id());
3248
    }
3249
3250
    /**
3251
     * Get all the data for the sortable table of the reporting progress of
3252
     * all users and all the courses the user is subscribed to.
3253
     *
3254
     * @param int    $from
3255
     * @param int    $numberItems
3256
     * @param int    $column
3257
     * @param string $direction
3258
     *
3259
     * @return array
3260
     */
3261
    public static function get_user_data_tracking_overview($from, $numberItems, $column, $direction)
3262
    {
3263
        $isWestern = api_is_western_name_order();
3264
3265
        switch ($column) {
3266
            case '0':
3267
                $column = $isWestern ? 'firstname' : 'lastname';
3268
                break;
3269
        }
3270
3271
        $order = [
3272
            " `$column` $direction",
3273
        ];
3274
        $userList = UserManager::get_user_list([], $order, $from, $numberItems);
3275
        $return = [];
3276
        foreach ($userList as $user) {
3277
            $return[] = [
3278
                '0' => $user['user_id'],
3279
                'col0' => $user['user_id'],
3280
            ];
3281
        }
3282
3283
        return $return;
3284
    }
3285
3286
    /**
3287
     * Get all information that the user with user_id = $user_data has
3288
     * entered in the additionally defined profile fields.
3289
     *
3290
     * @param int $user_id the id of the user
3291
     *
3292
     * @return array
3293
     *
3294
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
3295
     *
3296
     * @version Dokeos 1.8.6
3297
     *
3298
     * @since November 2008
3299
     */
3300
    public static function get_user_overview_export_extra_fields($user_id)
3301
    {
3302
        // include the user manager
3303
        $data = UserManager::get_extra_user_data($user_id, true);
3304
3305
        return $data;
3306
    }
3307
3308
    /**
3309
     * Checks if a username exist in the DB otherwise it create a "double"
3310
     * i.e. if we look into for jmontoya but the user's name already exist we create the user jmontoya2
3311
     * the return array will be array(username=>'jmontoya', sufix='2').
3312
     *
3313
     * @param string firstname
3314
     * @param string lastname
3315
     * @param string username
3316
     *
3317
     * @return array with the username, the sufix
3318
     *
3319
     * @author Julio Montoya
3320
     */
3321
    public static function make_username($firstname, $lastname, $username, $language = null, $encoding = null)
3322
    {
3323
        // if username exist
3324
        if (!UserManager::is_username_available($username) || empty($username)) {
3325
            $i = 0;
3326
            while (1) {
3327
                if ($i == 0) {
3328
                    $sufix = '';
3329
                } else {
3330
                    $sufix = $i;
3331
                }
3332
                $desired_username = UserManager::create_username(
3333
                    $firstname,
3334
                    $lastname
3335
                );
3336
                if (UserManager::is_username_available($desired_username.$sufix)) {
3337
                    break;
3338
                } else {
3339
                    $i++;
3340
                }
3341
            }
3342
            $username_array = ['username' => $desired_username, 'sufix' => $sufix];
3343
3344
            return $username_array;
3345
        } else {
3346
            $username_array = ['username' => $username, 'sufix' => ''];
3347
3348
            return $username_array;
3349
        }
3350
    }
3351
3352
    /**
3353
     * Checks if there are repeted users in a given array.
3354
     *
3355
     * @param array $usernames  list of the usernames in the uploaded file
3356
     * @param array $user_array $user_array['username'] and $user_array['sufix']
3357
     *                          where suffix is the number part in a login i.e -> jmontoya2
3358
     *
3359
     * @return array with the $usernames array and the $user_array array
3360
     *
3361
     * @author Julio Montoya
3362
     */
3363
    public static function check_user_in_array($usernames, $user_array)
3364
    {
3365
        $user_list = array_keys($usernames);
3366
        $username = $user_array['username'].$user_array['sufix'];
3367
3368
        if (in_array($username, $user_list)) {
3369
            $user_array['sufix'] += $usernames[$username];
3370
            $usernames[$username]++;
3371
        } else {
3372
            $usernames[$username] = 1;
3373
        }
3374
        $result_array = [$usernames, $user_array];
3375
3376
        return $result_array;
3377
    }
3378
3379
    /**
3380
     * Checks whether a username has been already subscribed in a session.
3381
     *
3382
     * @param string $username    a given username
3383
     * @param array  $course_list the array with the course list id
3384
     * @param int    $id_session  the session id
3385
     *
3386
     * @return int 0 if the user is not subscribed otherwise it returns the user_id of the given username
3387
     *
3388
     * @author Julio Montoya
3389
     */
3390
    public static function user_available_in_session($username, $course_list, $id_session)
3391
    {
3392
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
3393
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3394
        $id_session = (int) $id_session;
3395
        $username = Database::escape_string($username);
3396
        foreach ($course_list as $courseId) {
3397
            $courseId = (int) $courseId;
3398
            $sql = " SELECT u.user_id FROM $tbl_session_rel_course_rel_user rel
3399
                     INNER JOIN $table_user u
3400
                     ON (rel.user_id = u.user_id)
3401
                     WHERE
3402
                        rel.session_id='$id_session' AND
3403
                        u.status='5' AND
3404
                        u.username ='$username' AND
3405
                        rel.c_id='$courseId'";
3406
            $rs = Database::query($sql);
3407
            if (Database::num_rows($rs) > 0) {
3408
                return Database::result($rs, 0, 0);
3409
            }
3410
        }
3411
3412
        return 0;
3413
    }
3414
3415
    /**
3416
     * This function checks whether some users in the uploaded file
3417
     * repeated and creates unique usernames if necesary.
3418
     * A case: Within the file there is an user repeted twice (Julio Montoya / Julio Montoya)
3419
     * and the username fields are empty.
3420
     * Then, this function would create unique usernames based on the first and the last name.
3421
     * Two users wiould be created - jmontoya and jmontoya2.
3422
     * Of course, if in the database there is a user with the name jmontoya,
3423
     * the newly created two users registered would be jmontoya2 and jmontoya3.
3424
     *
3425
     * @param $users list of users
3426
     *
3427
     * @return array
3428
     *
3429
     * @author Julio Montoya Armas
3430
     */
3431
    public static function check_all_usernames($users, $course_list, $id_session)
3432
    {
3433
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
3434
        $usernames = [];
3435
        $new_users = [];
3436
        foreach ($users as $index => $user) {
3437
            $desired_username = [];
3438
            if (empty($user['UserName'])) {
3439
                $desired_username = self::make_username($user['FirstName'], $user['LastName'], '');
3440
                $pre_username = $desired_username['username'].$desired_username['sufix'];
3441
                $user['UserName'] = $pre_username;
3442
                $user['create'] = '1';
3443
            } else {
3444
                if (UserManager::is_username_available($user['UserName'])) {
3445
                    $desired_username = self::make_username($user['FirstName'], $user['LastName'], $user['UserName']);
3446
                    $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
3447
                    $user['create'] = '1';
3448
                } else {
3449
                    $is_session_avail = self::user_available_in_session($user['UserName'], $course_list, $id_session);
3450
                    if (0 == $is_session_avail) {
3451
                        $user_name = $user['UserName'];
3452
                        $sql_select = "SELECT user_id FROM $table_user WHERE username ='$user_name' ";
3453
                        $rs = Database::query($sql_select);
3454
                        $user['create'] = Database::result($rs, 0, 0);
3455
                    } else {
3456
                        $user['create'] = $is_session_avail;
3457
                    }
3458
                }
3459
            }
3460
            // Usernames is the current list of users in the file.
3461
            $result_array = self::check_user_in_array($usernames, $desired_username);
3462
            $usernames = $result_array[0];
3463
            $desired_username = $result_array[1];
3464
            $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
3465
            $new_users[] = $user;
3466
        }
3467
3468
        return $new_users;
3469
    }
3470
3471
    /**
3472
     * This functions checks whether there are users that are already
3473
     * registered in the DB by different creator than the current coach.
3474
     *
3475
     * @param array $users
3476
     *
3477
     * @return array
3478
     *
3479
     * @author Julio Montoya Armas
3480
     */
3481
    public static function get_user_creator($users)
3482
    {
3483
        $errors = [];
3484
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
3485
        foreach ($users as $index => $user) {
3486
            $username = Database::escape_string($user['UserName']);
3487
            $sql = "SELECT creator_id FROM $table_user WHERE username='$username' ";
3488
3489
            $rs = Database::query($sql);
3490
            $creator_id = Database::result($rs, 0, 0);
3491
            // check if we are the creators or not
3492
            if ($creator_id != '') {
3493
                if ($creator_id != api_get_user_id()) {
3494
                    $user['error'] = get_lang('UserAlreadyRegisteredByOtherCreator');
3495
                    $errors[] = $user;
3496
                }
3497
            }
3498
        }
3499
3500
        return $errors;
3501
    }
3502
3503
    /**
3504
     * Validates imported data.
3505
     *
3506
     * @param array $users list of users
3507
     */
3508
    public static function validate_data($users, $id_session = null)
3509
    {
3510
        $errors = [];
3511
        $new_users = [];
3512
        foreach ($users as $index => $user) {
3513
            // 1. Check whether mandatory fields are set.
3514
            $mandatory_fields = ['LastName', 'FirstName'];
3515
            if (api_get_setting('registration', 'email') == 'true') {
3516
                $mandatory_fields[] = 'Email';
3517
            }
3518
3519
            foreach ($mandatory_fields as $key => $field) {
3520
                if (!isset($user[$field]) || strlen($user[$field]) == 0) {
3521
                    $user['error'] = get_lang($field.'Mandatory');
3522
                    $errors[] = $user;
3523
                }
3524
            }
3525
            // 2. Check whether the username is too long.
3526
            if (UserManager::is_username_too_long($user['UserName'])) {
3527
                $user['error'] = get_lang('UserNameTooLong');
3528
                $errors[] = $user;
3529
            }
3530
3531
            $user['UserName'] = trim($user['UserName']);
3532
3533
            if (empty($user['UserName'])) {
3534
                $user['UserName'] = UserManager::create_username($user['FirstName'], $user['LastName']);
3535
            }
3536
            $new_users[] = $user;
3537
        }
3538
        $results = ['errors' => $errors, 'users' => $new_users];
3539
3540
        return $results;
3541
    }
3542
3543
    /**
3544
     * Adds missing user-information (which isn't required, like password, etc).
3545
     */
3546
    public static function complete_missing_data($user)
3547
    {
3548
        // 1. Generate a password if it is necessary.
3549
        if (!isset($user['Password']) || strlen($user['Password']) == 0) {
3550
            $user['Password'] = api_generate_password();
3551
        }
3552
3553
        return $user;
3554
    }
3555
3556
    /**
3557
     * Saves imported data.
3558
     */
3559
    public static function save_data($users, $course_list, $id_session)
3560
    {
3561
        $id_session = (int) $id_session;
3562
        $sendMail = $_POST['sendMail'] ? 1 : 0;
3563
3564
        // Adding users to the platform.
3565
        $new_users = [];
3566
        foreach ($users as $index => $user) {
3567
            $user = self::complete_missing_data($user);
3568
            // coach only will registered users
3569
            $default_status = STUDENT;
3570
            if ($user['create'] == COURSEMANAGER) {
3571
                $user['id'] = UserManager:: create_user(
3572
                    $user['FirstName'],
3573
                    $user['LastName'],
3574
                    $default_status,
3575
                    $user['Email'],
3576
                    $user['UserName'],
3577
                    $user['Password'],
3578
                    $user['OfficialCode'],
3579
                    api_get_setting('PlatformLanguage'),
3580
                    $user['PhoneNumber'],
3581
                    ''
3582
                );
3583
                $user['added_at_platform'] = 1;
3584
            } else {
3585
                $user['id'] = $user['create'];
3586
                $user['added_at_platform'] = 0;
3587
            }
3588
            $new_users[] = $user;
3589
        }
3590
        // Update user list.
3591
        $users = $new_users;
3592
3593
        // Inserting users.
3594
        SessionManager::insertUsersInCourses(
3595
            array_column($users, 'id'),
3596
            $course_list,
3597
            $id_session
3598
        );
3599
3600
        array_walk(
3601
            $users,
3602
            function (array &$user) {
3603
                $user['added_at_session'] = 1;
3604
            }
3605
        );
3606
3607
        $registered_users = get_lang('FileImported').'<br /> Import file results : <br />';
3608
        // Sending emails.
3609
        $addedto = '';
3610
        if ($sendMail) {
3611
            foreach ($users as $index => $user) {
3612
                $emailsubject = '['.api_get_setting('siteName').'] '.get_lang('YourReg').' '.api_get_setting('siteName');
3613
                $emailbody = get_lang('Dear').' '.
3614
                    api_get_person_name($user['FirstName'], $user['LastName']).",\n\n".
3615
                    get_lang('YouAreReg')." ".api_get_setting('siteName')." ".get_lang('WithTheFollowingSettings')."\n\n".
3616
                    get_lang('Username')." : $user[UserName]\n".
3617
                    get_lang('Pass')." : $user[Password]\n\n".
3618
                    get_lang('Address')." ".api_get_setting('siteName')." ".get_lang('Is')." : ".api_get_path(WEB_PATH)." \n\n".
3619
                    get_lang('Problem')."\n\n".
3620
                    get_lang('SignatureFormula').",\n\n".
3621
                    api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))."\n".
3622
                    get_lang('Manager')." ".api_get_setting('siteName')."\nT. ".
3623
                    api_get_setting('administratorTelephone')."\n".get_lang('Email')." : ".api_get_setting('emailAdministrator');
3624
3625
                MessageManager::send_message_simple($user['id'], $emailsubject, $emailbody);
3626
3627
                $userInfo = api_get_user_info($user['id']);
3628
3629
                if (($user['added_at_platform'] == 1 && $user['added_at_session'] == 1) || $user['added_at_session'] == 1) {
3630
                    if ($user['added_at_platform'] == 1) {
3631
                        $addedto = get_lang('UserCreatedPlatform');
3632
                    } else {
3633
                        $addedto = '          ';
3634
                    }
3635
3636
                    if ($user['added_at_session'] == 1) {
3637
                        $addedto .= get_lang('UserInSession');
3638
                    }
3639
                } else {
3640
                    $addedto = get_lang('UserNotAdded');
3641
                }
3642
3643
                $registered_users .= UserManager::getUserProfileLink($userInfo).' - '.$addedto.'<br />';
3644
            }
3645
        } else {
3646
            foreach ($users as $index => $user) {
3647
                $userInfo = api_get_user_info($user['id']);
3648
                if (($user['added_at_platform'] == 1 && $user['added_at_session'] == 1) || $user['added_at_session'] == 1) {
3649
                    if ($user['added_at_platform'] == 1) {
3650
                        $addedto = get_lang('UserCreatedPlatform');
3651
                    } else {
3652
                        $addedto = '          ';
3653
                    }
3654
3655
                    if ($user['added_at_session'] == 1) {
3656
                        $addedto .= ' '.get_lang('UserInSession');
3657
                    }
3658
                } else {
3659
                    $addedto = get_lang('UserNotAdded');
3660
                }
3661
                $registered_users .= "<a href=\"../user/userInfo.php?uInfo=".$user['id']."\">".
3662
                    Security::remove_XSS($userInfo['complete_user_name'])."</a> - ".$addedto.'<br />';
3663
            }
3664
        }
3665
        Display::addFlash(Display::return_message($registered_users, 'normal', false));
3666
        header('Location: course.php?id_session='.$id_session);
3667
        exit;
3668
    }
3669
3670
    /**
3671
     * Reads CSV-file.
3672
     *
3673
     * @param string $file Path to the CSV-file
3674
     *
3675
     * @return array All userinformation read from the file
3676
     */
3677
    public function parse_csv_data($file)
3678
    {
3679
        $users = Import::csvToArray($file);
3680
        foreach ($users as $index => $user) {
3681
            if (isset($user['Courses'])) {
3682
                $user['Courses'] = explode('|', trim($user['Courses']));
3683
            }
3684
            $users[$index] = $user;
3685
        }
3686
3687
        return $users;
3688
    }
3689
3690
    /**
3691
     * Reads XML-file.
3692
     *
3693
     * @param string $file Path to the XML-file
3694
     *
3695
     * @return array All userinformation read from the file
3696
     */
3697
    public static function parse_xml_data($file)
3698
    {
3699
        $crawler = Import::xml($file);
3700
        $crawler = $crawler->filter('Contacts > Contact ');
3701
        $array = [];
3702
        foreach ($crawler as $domElement) {
3703
            $row = [];
3704
            foreach ($domElement->childNodes as $node) {
3705
                if ($node->nodeName != '#text') {
3706
                    $row[$node->nodeName] = $node->nodeValue;
3707
                }
3708
            }
3709
            if (!empty($row)) {
3710
                $array[] = $row;
3711
            }
3712
        }
3713
3714
        return $array;
3715
    }
3716
3717
    /**
3718
     * @param int $courseId
3719
     * @param int $sessionId
3720
     * @param int $studentId
3721
     */
3722
    public static function displayTrackingAccessOverView(
3723
        $courseId,
3724
        $sessionId,
3725
        $studentId,
3726
        $perPage = 20,
3727
        $dates = null
3728
    ) {
3729
        $courseId = (int) $courseId;
3730
        $sessionId = (int) $sessionId;
3731
        $studentId = (int) $studentId;
3732
3733
        $courseList = [];
3734
        $sessionList = [];
3735
        $studentList = [];
3736
3737
        if (!empty($courseId)) {
3738
            $course = api_get_course_entity($courseId);
3739
            if ($course) {
3740
                $courseList[$course->getId()] = $course->getTitle();
3741
            }
3742
        }
3743
3744
        if (!empty($sessionId)) {
3745
            $session = api_get_session_entity($sessionId);
3746
            if ($session) {
3747
                $sessionList[$session->getId()] = $session->getName();
3748
            }
3749
        }
3750
3751
        if (!empty($studentId)) {
3752
            $student = api_get_user_entity($studentId);
3753
            if ($student) {
3754
                $studentList[$student->getId()] = UserManager::formatUserFullName($student);
3755
            }
3756
        }
3757
3758
        $form = new FormValidator('access_overview', 'GET');
3759
        $form->addElement(
3760
            'select_ajax',
3761
            'course_id',
3762
            get_lang('SearchCourse'),
3763
            $courseList,
3764
            [
3765
                'url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?'.http_build_query(
3766
                    [
3767
                        'a' => 'search_course_by_session_all',
3768
                        'session_id' => $sessionId,
3769
                        'course_id' => $courseId,
3770
                    ]
3771
                ),
3772
            ]
3773
        );
3774
3775
        $form->addElement(
3776
            'select_ajax',
3777
            'session_id',
3778
            get_lang('SearchSession'),
3779
            $sessionList,
3780
            [
3781
                'url_function' => "
3782
                    function () {
3783
                        var params = $.param({
3784
                            a: 'search_session_by_course',
3785
                            course_id: $('#access_overview_course_id').val() || 0
3786
                        });
3787
3788
                        return '".api_get_path(WEB_AJAX_PATH)."session.ajax.php?' + params;
3789
                    }
3790
                ",
3791
            ]
3792
        );
3793
3794
        $form->addSelect(
3795
            'profile',
3796
            get_lang('Profile'),
3797
            [
3798
                '' => get_lang('Select'),
3799
                STUDENT => get_lang('Student'),
3800
                COURSEMANAGER => get_lang('CourseManager'),
3801
                DRH => get_lang('Drh'),
3802
            ],
3803
            ['id' => 'profile']
3804
        );
3805
3806
        $form->addElement(
3807
            'select_ajax',
3808
            'student_id',
3809
            get_lang('SearchUsers'),
3810
            $studentList,
3811
            [
3812
                'placeholder' => get_lang('All'),
3813
                'url_function' => "
3814
                    function () {
3815
                        var params = $.param({
3816
                            a: 'search_user_by_course',
3817
                            session_id: $('#access_overview_session_id').val(),
3818
                            course_id: $('#access_overview_course_id').val()
3819
                        });
3820
3821
                        return '".api_get_path(WEB_AJAX_PATH)."course.ajax.php?' + params;
3822
                    }
3823
                ",
3824
            ]
3825
        );
3826
3827
        $form->addDateRangePicker(
3828
            'date',
3829
            get_lang('DateRange'),
3830
            true,
3831
            [
3832
                'id' => 'date_range',
3833
                'format' => 'YYYY-MM-DD HH:mm',
3834
                'timePicker' => 'true',
3835
                //'validate_format' => 'Y-m-d',
3836
            ]
3837
        );
3838
3839
        $form->addHidden('display', 'accessoverview');
3840
        $form->addRule('course_id', get_lang('Required'), 'required');
3841
        $form->addRule('profile', get_lang('Required'), 'required');
3842
        $form->addButton('submit', get_lang('Generate'), 'gear', 'primary');
3843
3844
        $table = null;
3845
        if (!empty($dates)) {
3846
            //if ($form->validate()) {
3847
            $table = new SortableTable(
3848
                'tracking_access_overview',
3849
                ['MySpace', 'getNumberOfTrackAccessOverview'],
3850
                ['MySpace', 'getUserDataAccessTrackingOverview'],
3851
                0,
3852
                $perPage
3853
            );
3854
            $table->set_additional_parameters(
3855
                [
3856
                    'course_id' => $courseId,
3857
                    'session_id' => $sessionId,
3858
                    'student_id' => $studentId,
3859
                    'date' => $dates,
3860
                    'tracking_access_overview_per_page' => $perPage,
3861
                    'display' => 'accessoverview',
3862
                ]
3863
            );
3864
            $table->set_header(0, get_lang('LoginDate'), true);
3865
            $table->set_header(1, get_lang('Username'), true);
3866
            if (api_is_western_name_order()) {
3867
                $table->set_header(2, get_lang('FirstName'), true);
3868
                $table->set_header(3, get_lang('LastName'), true);
3869
            } else {
3870
                $table->set_header(2, get_lang('LastName'), true);
3871
                $table->set_header(3, get_lang('FirstName'), true);
3872
            }
3873
            //$table->set_header(4, get_lang('Clicks'), false);
3874
            $table->set_header(4, get_lang('IP'), false);
3875
            $table->set_header(5, get_lang('TimeLoggedIn'), false);
3876
        }
3877
3878
        $template = new Template(
3879
            null,
3880
            false,
3881
            false,
3882
            false,
3883
            false,
3884
            false,
3885
            false
3886
        );
3887
        $template->assign('form', $form->returnForm());
3888
        $template->assign('table', $table ? $table->return_table() : null);
3889
3890
        echo $template->fetch(
3891
            $template->get_template('my_space/accessoverview.tpl')
3892
        );
3893
    }
3894
3895
    /**
3896
     * @return int
3897
     */
3898
    public static function getNumberOfTrackAccessOverview()
3899
    {
3900
        $user = Database::get_main_table(TABLE_MAIN_USER);
3901
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
3902
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
3903
3904
        $sql = "SELECT COUNT(course_access_id) count
3905
                FROM $trackCourseAccess a
3906
                INNER JOIN $user u
3907
                ON a.user_id = u.id
3908
                INNER JOIN $course c
3909
                ON a.c_id = c.id
3910
                ";
3911
        $sql = self::getDataAccessTrackingFilters($sql);
3912
3913
        $result = Database::query($sql);
3914
        $row = Database::fetch_assoc($result);
3915
3916
        if ($row) {
3917
            return $row['count'];
3918
        }
3919
3920
        return 0;
3921
    }
3922
3923
    /**
3924
     * @param $from
3925
     * @param $numberItems
3926
     * @param $column
3927
     * @param $orderDirection
3928
     *
3929
     * @return array
3930
     */
3931
    public static function getUserDataAccessTrackingOverview(
3932
        $from,
3933
        $numberItems,
3934
        $column,
3935
        $orderDirection
3936
    ) {
3937
        $from = (int) $from;
3938
        $numberItems = (int) $numberItems;
3939
        $column = (int) $column;
3940
        $orderDirection = Database::escape_string($orderDirection);
3941
        $orderDirection = !in_array(strtolower(trim($orderDirection)), ['asc', 'desc']) ? 'asc' : $orderDirection;
3942
3943
        $user = Database::get_main_table(TABLE_MAIN_USER);
3944
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
3945
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
3946
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
3947
3948
        global $export_csv;
3949
        $is_western_name_order = api_is_western_name_order();
3950
        if ($export_csv) {
3951
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
3952
        }
3953
3954
        //TODO add course name
3955
        $sql = "SELECT
3956
                a.login_course_date as col0,
3957
                u.username as col1,
3958
                ".(
3959
                    $is_western_name_order ? "
3960
                        u.firstname AS col2,
3961
                        u.lastname AS col3,
3962
                    " : "
3963
                        u.lastname AS col2,
3964
                        u.firstname AS col3,
3965
                "
3966
        )."
3967
                a.login_course_date,
3968
                a.logout_course_date,
3969
                c.title,
3970
                c.code,
3971
                u.id as user_id,
3972
                user_ip
3973
            FROM $trackCourseAccess a
3974
            INNER JOIN $user u
3975
            ON a.user_id = u.id
3976
            INNER JOIN $course c
3977
            ON a.c_id = c.id
3978
            WHERE 1=1 ";
3979
3980
        $sql = self::getDataAccessTrackingFilters($sql);
3981
3982
        $sql .= " ORDER BY col$column $orderDirection ";
3983
        $sql .= " LIMIT $from, $numberItems";
3984
3985
        $result = Database::query($sql);
3986
3987
        $data = [];
3988
        while ($user = Database::fetch_assoc($result)) {
3989
            $data[] = $user;
3990
        }
3991
3992
        $return = [];
3993
        //TODO: Dont use numeric index
3994
        foreach ($data as $key => $info) {
3995
            $return[] = [
3996
                api_get_local_time($info['login_course_date']),
3997
                $info['col1'],
3998
                $info['col2'],
3999
                $info['col3'],
4000
                $info['user_ip'],
4001
                gmdate('H:i:s', strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
4002
            ];
4003
        }
4004
4005
        return $return;
4006
    }
4007
4008
    /**
4009
     * Gets the connections to a course as an array of login and logout time.
4010
     *
4011
     * @param int    $user_id
4012
     * @param array  $course_info
4013
     * @param int    $sessionId
4014
     * @param string $start_date
4015
     * @param string $end_date
4016
     * @param bool   $addUserIp
4017
     *
4018
     * @author  Jorge Frisancho Jibaja
4019
     * @author  Julio Montoya <[email protected]> fixing the function
4020
     *
4021
     * @version OCT-22- 2010
4022
     *
4023
     * @return array
4024
     */
4025
    public static function get_connections_to_course_by_date(
4026
        $user_id,
4027
        $course_info,
4028
        $sessionId,
4029
        $start_date,
4030
        $end_date,
4031
        $addUserIp = false
4032
    ) {
4033
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
4034
        $user_id = (int) $user_id;
4035
        $connections = [];
4036
        if (!empty($course_info)) {
4037
            $courseId = (int) $course_info['real_id'];
4038
            $end_date = self::add_day_to($end_date);
4039
4040
            $start_date = Database::escape_string($start_date);
4041
            $end_date = Database::escape_string($end_date);
4042
            $sessionCondition = api_get_session_condition($sessionId);
4043
            $sql = "SELECT
4044
                        login_course_date,
4045
                        logout_course_date,
4046
                        TIMESTAMPDIFF(SECOND, login_course_date, logout_course_date) duration,
4047
                        user_ip
4048
                    FROM $table
4049
                    WHERE
4050
                        user_id = $user_id AND
4051
                        c_id = $courseId AND
4052
                        login_course_date BETWEEN '$start_date' AND '$end_date' AND
4053
                        logout_course_date BETWEEN '$start_date' AND '$end_date'
4054
                        $sessionCondition
4055
                    ORDER BY login_course_date ASC";
4056
            $rs = Database::query($sql);
4057
4058
            while ($row = Database::fetch_array($rs)) {
4059
                $item = [
4060
                    'login' => $row['login_course_date'],
4061
                    'logout' => $row['logout_course_date'],
4062
                    'duration' => $row['duration'],
4063
                ];
4064
                if ($addUserIp) {
4065
                    $item['user_ip'] = $row['user_ip'];
4066
                }
4067
                $connections[] = $item;
4068
            }
4069
        }
4070
4071
        return $connections;
4072
    }
4073
4074
    /**
4075
     * @param int   $user_id
4076
     * @param array $course_info
4077
     * @param int   $sessionId
4078
     * @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...
4079
     * @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...
4080
     *
4081
     * @return array
4082
     */
4083
    public static function getStats($user_id, $course_info, $sessionId, $start_date = null, $end_date = null)
4084
    {
4085
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
4086
        $result = [];
4087
        if (!empty($course_info)) {
4088
            $stringStartDate = '';
4089
            $stringEndDate = '';
4090
            if ($start_date != null && $end_date != null) {
4091
                $end_date = self::add_day_to($end_date);
4092
4093
                $start_date = Database::escape_string($start_date);
4094
                $end_date = Database::escape_string($end_date);
4095
4096
                $stringStartDate = "AND login_course_date BETWEEN '$start_date' AND '$end_date'";
4097
                $stringEndDate = "AND logout_course_date BETWEEN '$start_date' AND '$end_date'";
4098
            }
4099
            $user_id = (int) $user_id;
4100
            $courseId = (int) $course_info['real_id'];
4101
            $sessionCondition = api_get_session_condition($sessionId);
4102
            $sql = "SELECT
4103
                SEC_TO_TIME(AVG(time_to_sec(timediff(logout_course_date,login_course_date)))) as avrg,
4104
                SEC_TO_TIME(SUM(time_to_sec(timediff(logout_course_date,login_course_date)))) as total,
4105
                count(user_id) as times
4106
                FROM $table
4107
                WHERE
4108
                    user_id = $user_id AND
4109
                    c_id = $courseId $stringStartDate $stringEndDate
4110
                    $sessionCondition
4111
                ORDER BY login_course_date ASC";
4112
4113
            $rs = Database::query($sql);
4114
            if ($row = Database::fetch_array($rs)) {
4115
                $foo_avg = $row['avrg'];
4116
                $foo_total = $row['total'];
4117
                $foo_times = $row['times'];
4118
                $result = [
4119
                    'avg' => $foo_avg,
4120
                    'total' => $foo_total,
4121
                    'times' => $foo_times,
4122
                ];
4123
            }
4124
        }
4125
4126
        return $result;
4127
    }
4128
4129
    public static function add_day_to($end_date)
4130
    {
4131
        $foo_date = strtotime($end_date);
4132
        $foo_date = strtotime(' +1 day', $foo_date);
4133
        $foo_date = date('Y-m-d', $foo_date);
4134
4135
        return $foo_date;
4136
    }
4137
4138
    /**
4139
     * This function draw the graphic to be displayed on the user view as an image.
4140
     *
4141
     * @param array  $sql_result
4142
     * @param string $start_date
4143
     * @param string $end_date
4144
     * @param string $type
4145
     *
4146
     * @author Jorge Frisancho Jibaja
4147
     *
4148
     * @version OCT-22- 2010
4149
     *
4150
     * @return string
4151
     */
4152
    public static function grapher($sql_result, $start_date, $end_date, $type = '')
4153
    {
4154
        if (empty($start_date)) {
4155
            $start_date = '';
4156
        }
4157
        if (empty($end_date)) {
4158
            $end_date = '';
4159
        }
4160
        if ('' == $type) {
4161
            $type = 'day';
4162
        }
4163
        $main_year = $main_month_year = $main_day = [];
4164
4165
        $period = new DatePeriod(
4166
            new DateTime($start_date),
4167
            new DateInterval('P1D'),
4168
            new DateTime($end_date)
4169
        );
4170
4171
        foreach ($period as $date) {
4172
            $main_day[$date->format('d-m-Y')] = 0;
4173
        }
4174
4175
        $period = new DatePeriod(
4176
            new DateTime($start_date),
4177
            new DateInterval('P1M'),
4178
            new DateTime($end_date)
4179
        );
4180
4181
        foreach ($period as $date) {
4182
            $main_month_year[$date->format('m-Y')] = 0;
4183
        }
4184
4185
        $i = 0;
4186
        if (is_array($sql_result) && count($sql_result) > 0) {
4187
            foreach ($sql_result as $key => $data) {
4188
                $login = api_strtotime($data['login']);
4189
                $logout = api_strtotime($data['logout']);
4190
                //creating the main array
4191
                if (isset($main_month_year[date('m-Y', $login)])) {
4192
                    $main_month_year[date('m-Y', $login)] += (float) ($logout - $login) / 60;
4193
                }
4194
                if (isset($main_day[date('d-m-Y', $login)])) {
4195
                    $main_day[date('d-m-Y', $login)] += (float) ($logout - $login) / 60;
4196
                }
4197
                if ($i > 500) {
4198
                    break;
4199
                }
4200
                $i++;
4201
            }
4202
            switch ($type) {
4203
                case 'day':
4204
                    $main_date = $main_day;
4205
                    break;
4206
                case 'month':
4207
                    $main_date = $main_month_year;
4208
                    break;
4209
                case 'year':
4210
                    $main_date = $main_year;
4211
                    break;
4212
            }
4213
4214
            $labels = array_keys($main_date);
4215
            if (1 == count($main_date)) {
4216
                $labels = $labels[0];
4217
                $main_date = $main_date[$labels];
4218
            }
4219
4220
            /* Create and populate the pData object */
4221
            $myData = new pData();
4222
            $myData->addPoints($main_date, 'Serie1');
4223
            if (count($main_date) != 1) {
4224
                $myData->addPoints($labels, 'Labels');
4225
                $myData->setSerieDescription('Labels', 'Months');
4226
                $myData->setAbscissa('Labels');
4227
            }
4228
            $myData->setSerieWeight('Serie1', 1);
4229
            $myData->setSerieDescription('Serie1', get_lang('MyResults'));
4230
            $myData->setAxisName(0, get_lang('Minutes'));
4231
            $myData->loadPalette(api_get_path(SYS_CODE_PATH).'palettes/pchart/default.color', true);
4232
4233
            // Cache definition
4234
            $cachePath = api_get_path(SYS_ARCHIVE_PATH);
4235
            $myCache = new pCache(['CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)]);
4236
            $chartHash = $myCache->getHash($myData);
4237
4238
            if ($myCache->isInCache($chartHash)) {
4239
                //if we already created the img
4240
                $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
4241
                $myCache->saveFromCache($chartHash, $imgPath);
4242
                $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
4243
            } else {
4244
                /* Define width, height and angle */
4245
                $mainWidth = 760;
4246
                $mainHeight = 230;
4247
                $angle = 50;
4248
4249
                /* Create the pChart object */
4250
                $myPicture = new pImage($mainWidth, $mainHeight, $myData);
4251
4252
                /* Turn of Antialiasing */
4253
                $myPicture->Antialias = false;
4254
                /* Draw the background */
4255
                $settings = ["R" => 255, "G" => 255, "B" => 255];
4256
                $myPicture->drawFilledRectangle(0, 0, $mainWidth, $mainHeight, $settings);
4257
4258
                /* Add a border to the picture */
4259
                $myPicture->drawRectangle(
4260
                    0,
4261
                    0,
4262
                    $mainWidth - 1,
4263
                    $mainHeight - 1,
4264
                    ["R" => 0, "G" => 0, "B" => 0]
4265
                );
4266
4267
                /* Set the default font */
4268
                $myPicture->setFontProperties(
4269
                    [
4270
                        "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
4271
                        "FontSize" => 10, ]
4272
                );
4273
                /* Write the chart title */
4274
                $myPicture->drawText(
4275
                    $mainWidth / 2,
4276
                    30,
4277
                    get_lang('TimeSpentInTheCourse'),
4278
                    [
4279
                        "FontSize" => 12,
4280
                        "Align" => TEXT_ALIGN_BOTTOMMIDDLE,
4281
                    ]
4282
                );
4283
4284
                /* Set the default font */
4285
                $myPicture->setFontProperties(
4286
                    [
4287
                        "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
4288
                        "FontSize" => 8,
4289
                    ]
4290
                );
4291
4292
                /* Define the chart area */
4293
                $myPicture->setGraphArea(50, 40, $mainWidth - 40, $mainHeight - 80);
4294
4295
                /* Draw the scale */
4296
                $scaleSettings = [
4297
                    'XMargin' => 10,
4298
                    'YMargin' => 10,
4299
                    'Floating' => true,
4300
                    'GridR' => 200,
4301
                    'GridG' => 200,
4302
                    'GridB' => 200,
4303
                    'DrawSubTicks' => true,
4304
                    'CycleBackground' => true,
4305
                    'LabelRotation' => $angle,
4306
                    'Mode' => SCALE_MODE_ADDALL_START0,
4307
                ];
4308
                $myPicture->drawScale($scaleSettings);
4309
4310
                /* Turn on Antialiasing */
4311
                $myPicture->Antialias = true;
4312
4313
                /* Enable shadow computing */
4314
                $myPicture->setShadow(
4315
                    true,
4316
                    [
4317
                        "X" => 1,
4318
                        "Y" => 1,
4319
                        "R" => 0,
4320
                        "G" => 0,
4321
                        "B" => 0,
4322
                        "Alpha" => 10,
4323
                    ]
4324
                );
4325
4326
                /* Draw the line chart */
4327
                $myPicture->setFontProperties(
4328
                    [
4329
                        "FontName" => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
4330
                        "FontSize" => 10,
4331
                    ]
4332
                );
4333
                $myPicture->drawSplineChart();
4334
                $myPicture->drawPlotChart(
4335
                    [
4336
                        "DisplayValues" => true,
4337
                        "PlotBorder" => true,
4338
                        "BorderSize" => 1,
4339
                        "Surrounding" => -60,
4340
                        "BorderAlpha" => 80,
4341
                    ]
4342
                );
4343
4344
                /* Do NOT Write the chart legend */
4345
4346
                /* Write and save into cache */
4347
                $myCache->writeToCache($chartHash, $myPicture);
4348
                $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
4349
                $myCache->saveFromCache($chartHash, $imgPath);
4350
                $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
4351
            }
4352
4353
            return '<img src="'.$imgPath.'">';
4354
        } else {
4355
            return api_convert_encoding(
4356
                '<div id="messages" class="warning-message">'.get_lang('GraphicNotAvailable').'</div>',
4357
                'UTF-8'
4358
            );
4359
        }
4360
    }
4361
4362
    /*
4363
     * Gets the company name of a user based on the extra field 'company'.
4364
     *
4365
     * @param int $userId
4366
     *
4367
     * @return string
4368
     */
4369
    public static function getCompanyOfUser($userId = 0)
4370
    {
4371
        $userId = (int) $userId;
4372
        if (0 != $userId) {
4373
            $tblExtraFieldValue = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
4374
            $tblExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
4375
            $sql = "SELECT
4376
                    extra_field_value.item_id AS userId,
4377
                    extra_field_value.value AS company
4378
                FROM $tblExtraFieldValue AS extra_field_value
4379
                INNER JOIN $tblExtraField AS extra_field
4380
                ON (
4381
                    extra_field_value.field_id = extra_field.id AND
4382
                    extra_field.variable = 'company'
4383
                )
4384
                WHERE
4385
                    extra_field_value.value != '' AND
4386
                    extra_field_value.item_id = $userId ";
4387
            $queryResult = Database::query($sql);
4388
            $data = Database::store_result($queryResult, 'ASSOC');
4389
            $totalData = count($data);
4390
            /* use 'for' to performance */
4391
            for ($i = 0; $i < $totalData; $i++) {
4392
                $row = $data[$i];
4393
                if (isset($row['company']) && !empty($row['company'])) {
4394
                    return $row['company'];
4395
                }
4396
            }
4397
        }
4398
4399
        return get_lang('NoEntity');
4400
    }
4401
4402
    /**
4403
     * Gets a list of users who were enrolled in the lessons.
4404
     * It is necessary that in the extra field, a company is defined.
4405
     *
4406
     *  if lpId is different to 0, this search by lp id too
4407
     *
4408
     * Variable $withGroups determines the consultation of the enrollment in groups. The group in total will be taken
4409
     *
4410
     * @param string|null $startDate
4411
     * @param string|null $endDate
4412
     * @param int         $lpId
4413
     * @param bool        $withGroups
4414
     *
4415
     * @return array
4416
     */
4417
    protected static function getCompanyLearnpathSubscription(
4418
        $startDate = null,
4419
        $endDate = null,
4420
        $whereInLp = null,
4421
        $withGroups = false
4422
    ) {
4423
        $whereInLp = Database::escape_string($whereInLp);
4424
        $tblItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
4425
        $tblLp = Database::get_course_table(TABLE_LP_MAIN);
4426
        $tblLpItem = Database::get_course_table(TABLE_LP_ITEM);
4427
        $tblGroupUser = Database::get_course_table(TABLE_GROUP_USER);
4428
        $tblUser = Database::get_main_table(TABLE_MAIN_USER);
4429
        $tblAccessUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
4430
        $accessUrlFilter = '';
4431
        if (api_is_multiple_url_enabled()) {
4432
            $urlId = api_get_current_access_url_id();
4433
            $accessUrlFilter = " INNER JOIN $tblAccessUrlUser auru
4434
                      ON (u.id = auru.user_id AND auru.access_url_id = $urlId)";
4435
        }
4436
        $whereCondition = '';
4437
4438
        //Validating dates
4439
        if (!empty($startDate)) {
4440
            $startDate = new DateTime($startDate);
4441
        }
4442
        if (!empty($endDate)) {
4443
            $endDate = new DateTime($endDate);
4444
        }
4445
        if (!empty($startDate) && !empty($endDate)) {
4446
            if ($startDate > $endDate) {
4447
                $dateTemp = $endDate;
4448
                $endDate = $startDate;
4449
                $startDate = $dateTemp;
4450
                unset($dateTemp);
4451
            }
4452
        }
4453
4454
        // Settings condition and parametter GET to right date
4455
        if (!empty($startDate)) {
4456
            $startDate = api_get_utc_datetime($startDate->setTime(0, 0, 0)->format('Y-m-d H:i:s'));
4457
            $_GET['startDate'] = $startDate;
4458
            $whereCondition .= " AND ip.lastedit_date >= '$startDate' ";
4459
        }
4460
        if (!empty($endDate)) {
4461
            $endDate = api_get_utc_datetime($endDate->setTime(23, 59, 59)->format('Y-m-d H:i:s'));
4462
            $_GET['endDate'] = $endDate;
4463
            $whereCondition .= " AND ip.lastedit_date <= '$endDate' ";
4464
        }
4465
        if (!empty($whereInLp)) {
4466
            $whereCondition .= " AND ip.ref in ($whereInLp) ";
4467
        }
4468
        $datas = [];
4469
        if (!empty($startDate) or !empty($endDate)) {
4470
            $query = "
4471
            SELECT DISTINCT
4472
                ip.ref AS lp_item,
4473
                lpi.iid AS lp_item_id,
4474
                ip.session_id AS session_id,
4475
                ip.lastedit_type AS type,
4476
                u.username AS username,
4477
                ip.lastedit_date AS lastedit_date,
4478
                ip.to_user_id AS id,
4479
                u.firstname as firstname,
4480
                u.lastname as lastname
4481
            FROM $tblItemProperty AS ip
4482
            INNER JOIN $tblUser AS u
4483
            ON (u.id = ip.to_user_id)
4484
            INNER JOIN $tblLp AS lp
4485
            ON (lp.iid = ip.ref AND lp.c_id = ip.c_id)
4486
            INNER JOIN $tblLpItem AS lpi
4487
            ON (lp.id = lpi.lp_id AND lp.c_id = lpi.c_id)
4488
            $accessUrlFilter
4489
                    WHERE
4490
                ip.lastedit_type = 'LearnpathSubscription' ";
4491
            if (strlen($whereCondition) > 2) {
4492
                $query .= $whereCondition;
4493
            }
4494
            if ($withGroups) {
4495
                $query = "
4496
                SELECT DISTINCT
4497
                    ip.ref AS lp_item,
4498
                    lpi.iid AS lp_item_id,
4499
                    ip.session_id AS session_id,
4500
                    ip.lastedit_type AS type,
4501
                    ip.lastedit_date AS lastedit_date,
4502
                    ip.to_group_id AS group_id,
4503
                    ug.user_id AS id,
4504
                    u.firstname as firstname,
4505
                    u.lastname as lastname
4506
            FROM
4507
                    $tblItemProperty AS ip
4508
                INNER JOIN $tblGroupUser AS ug
4509
                ON (ug.group_id = ip.to_group_id AND ip.c_id = ug.c_id)
4510
                INNER JOIN $tblUser AS u
4511
                ON (u.id = ug.user_id)
4512
                INNER JOIN $tblLp AS lp
4513
                ON (lp.iid = ip.ref AND ug.c_id = lp.c_id)
4514
                INNER JOIN $tblLpItem AS lpi
4515
                ON (lp.id = lpi.lp_id AND lp.c_id = lpi.c_id)
4516
                $accessUrlFilter
4517
            WHERE
4518
                    ip.lastedit_type = 'LearnpathSubscription' AND
4519
                    ip.to_group_id != 0 ";
4520
                if (strlen($whereCondition) > 2) {
4521
                    $query .= $whereCondition;
4522
                }
4523
            }
4524
            $query .= ' ORDER BY ip.ref, ip.session_id ';
4525
            $queryResult = Database::query($query);
4526
            $data = Database::store_result($queryResult, 'ASSOC');
4527
            $totalData = count($data);
4528
            /* use 'for' to performance */
4529
            for ($i = 0; $i < $totalData; $i++) {
4530
                $row = $data[$i];
4531
                $row['complete_name'] = api_get_person_name($row['firstname'], $row['lastname']);
4532
                $row['company'] = self::getCompanyOfUser($row['id']);
4533
                $datas[$row['lp_item_id']][] = $row;
4534
            }
4535
        }
4536
4537
        return $datas;
4538
    }
4539
4540
    private static function getDataAccessTrackingFilters($sql)
4541
    {
4542
        if (isset($_GET['course_id']) && !empty($_GET['course_id'])) {
4543
            $courseId = (int) $_GET['course_id'];
4544
            $sql .= " AND c.id = ".$courseId;
4545
        }
4546
4547
        if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
4548
            $sessionId = (int) $_GET['session_id'];
4549
            $sql .= " AND a.session_id = ".$sessionId;
4550
        }
4551
4552
        if (isset($_GET['student_id']) && !empty($_GET['student_id'])) {
4553
            $userId = (int) $_GET['student_id'];
4554
            $sql .= " AND u.user_id = ".$userId;
4555
        }
4556
4557
        $sql .= " AND u.status <> ".ANONYMOUS;
4558
4559
        if (isset($_GET['date']) && !empty($_GET['date'])) {
4560
            $dateRangePicker = new DateRangePicker('date', '', ['timePicker' => 'true']);
4561
            $dates = $dateRangePicker->parseDateRange($_GET['date']);
4562
            if (isset($dates['start']) && !empty($dates['start'])) {
4563
                $dates['start'] = Database::escape_string(api_get_utc_datetime($dates['start']));
4564
                $sql .= " AND login_course_date >= '".$dates['start']."'";
4565
            }
4566
            if (isset($dates['end']) && !empty($dates['end'])) {
4567
                $dates['end'] = Database::escape_string(api_get_utc_datetime($dates['end']));
4568
                $sql .= " AND logout_course_date <= '".$dates['end']."'";
4569
            }
4570
        }
4571
4572
        return $sql;
4573
    }
4574
}
4575