MySpace::display_tracking_course_overview()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

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

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

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