Passed
Push — 1.11.x ( 0e014d...433f25 )
by Angel Fernando Quiroz
09:07 queued 13s
created

sort_by_order()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use ChamiloSession as Session;
6
7
require_once __DIR__.'/../inc/global.inc.php';
8
9
$current_course_tool = TOOL_TRACKING;
10
11
TrackingCourseLog::protectIfNotAllowed();
12
13
$courseInfo = api_get_course_info();
14
$sessionId = api_get_session_id();
15
16
//keep course_code form as it is loaded (global) by the table's get_user_data
17
$courseCode = $courseInfo['code'];
18
$courseId = $courseInfo['real_id'];
19
$parameters['cidReq'] = isset($_GET['cidReq']) ? Security::remove_XSS($_GET['cidReq']) : '';
20
$parameters['id_session'] = $sessionId;
21
$parameters['from'] = isset($_GET['myspace']) ? Security::remove_XSS($_GET['myspace']) : null;
22
$parameters['user_active'] = isset($_REQUEST['user_active']) && is_numeric($_REQUEST['user_active']) ? (int) $_REQUEST['user_active'] : null;
23
24
// PERSON_NAME_DATA_EXPORT is buggy
25
$sortByFirstName = api_sort_by_first_name();
26
$from_myspace = false;
27
$from = $_GET['from'] ?? null;
28
$origin = api_get_origin();
29
$lpShowMaxProgress = api_get_configuration_value('lp_show_max_progress_instead_of_average');
30
if (api_get_configuration_value('lp_show_max_progress_or_average_enable_course_level_redefinition')) {
31
    $lpShowProgressCourseSetting = api_get_course_setting('lp_show_max_or_average_progress');
32
    if (in_array($lpShowProgressCourseSetting, ['max', 'average'])) {
33
        $lpShowMaxProgress = ('max' === $lpShowProgressCourseSetting);
34
    }
35
}
36
37
// Starting the output buffering when we are exporting the information.
38
$export_csv = isset($_GET['export']) && 'csv' === $_GET['export'];
39
40
$htmlHeadXtra[] = api_get_js('chartjs/Chart.min.js');
41
$htmlHeadXtra[] = ' ';
42
43
$this_section = SECTION_COURSES;
44
if ('myspace' === $from) {
45
    $from_myspace = true;
46
    $this_section = 'session_my_space';
47
}
48
49
$additionalParams = '';
50
if (isset($_GET['additional_profile_field'])) {
51
    foreach ($_GET['additional_profile_field'] as $fieldId) {
52
        $additionalParams .= '&additional_profile_field[]='.(int) $fieldId;
53
    }
54
}
55
56
if (isset($parameters['user_active'])) {
57
    $additionalParams .= '&user_active='.(int) $parameters['user_active'];
58
}
59
60
if ($export_csv || isset($_GET['csv'])) {
61
    if (!empty($sessionId)) {
62
        Session::write('id_session', $sessionId);
63
    }
64
    ob_start();
65
}
66
$columnsToHideFromSetting = api_get_configuration_value('course_log_hide_columns');
67
$columnsToHide = [0, 8, 9, 10, 11];
68
if (!empty($columnsToHideFromSetting) && isset($columnsToHideFromSetting['columns'])) {
69
    $columnsToHide = $columnsToHideFromSetting['columns'];
70
}
71
$columnsToHide = json_encode($columnsToHide);
72
73
$visibleIcon = Display::return_icon(
74
    'visible.png',
75
    get_lang('HideColumn'),
76
    ['align' => 'absmiddle', 'hspace' => '3px']
77
);
78
79
$exportInactiveUsers = api_get_path(WEB_CODE_PATH).'tracking/courseLog.php?'.api_get_cidreq().'&'.$additionalParams;
80
81
// Scripts for reporting array hide/show columns
82
$js = "<script>
83
    // hide column and display the button to unhide it
84
    function foldup(id) {
85
        $('#reporting_table .data_table tr td:nth-child(' + (id + 1) + ')').toggleClass('hide');
86
        $('#reporting_table .data_table tr th:nth-child(' + (id + 1) + ')').toggleClass('hide');
87
        $('div#unhideButtons a:nth-child(' + (id + 1) + ')').toggleClass('hide');
88
    }
89
90
    // add the red cross on top of each column
91
    function init_hide() {
92
        $('#reporting_table .data_table tr th').each(
93
            function(index) {
94
                $(this).prepend(
95
                    '<div style=\"cursor:pointer\" onclick=\"foldup(' + index + ')\">".$visibleIcon."</div>'
96
                );
97
            }
98
        );
99
    }
100
101
    // hide some column at startup
102
    // be sure that these columns always exists
103
    // see headers = array();
104
    // tab of header texts
105
    $(function() {
106
        init_hide();
107
        var columnsToHide = ".$columnsToHide.";
108
        if (columnsToHide) {
109
            columnsToHide.forEach(function(id) {
110
                foldup(id);
111
            });
112
        }
113
        $('#download-csv').on('click', function (e) {
114
            e.preventDefault();
115
            location.href = '".$exportInactiveUsers.'&csv=1&since='."'+$('#reminder_form_since').val();
116
        });
117
    })
118
</script>";
119
$htmlHeadXtra[] = $js;
120
121
// Database table definitions.
122
//@todo remove this calls
123
$TABLETRACK_EXERCISES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
124
$TABLECOURSE = Database::get_main_table(TABLE_MAIN_COURSE);
125
$table_user = Database::get_main_table(TABLE_MAIN_USER);
126
$TABLEQUIZ = Database::get_course_table(TABLE_QUIZ_TEST);
127
128
$userEditionExtraFieldToCheck = api_get_configuration_value('user_edition_extra_field_to_check');
129
130
$objExtrafieldUser = new ExtraField('user');
131
132
// Breadcrumbs.
133
if ('resume_session' === $origin) {
134
    $interbreadcrumb[] = [
135
        'url' => '../admin/index.php',
136
        'name' => get_lang('PlatformAdmin'),
137
    ];
138
    $interbreadcrumb[] = [
139
        'url' => '../session/session_list.php',
140
        'name' => get_lang('SessionList'),
141
    ];
142
    $interbreadcrumb[] = [
143
        'url' => '../session/resume_session.php?id_session='.$sessionId,
144
        'name' => get_lang('SessionOverview'),
145
    ];
146
}
147
148
$view = $_REQUEST['view'] ?? '';
149
$nameTools = get_lang('Tracking');
150
151
$tpl = new Template($nameTools);
152
// Getting all the students of the course
153
if (empty($sessionId)) {
154
    // Registered students in a course outside session.
155
    $studentList = CourseManager::get_student_list_from_course_code(
156
        $courseCode,
157
        false,
158
        0,
159
        null,
160
        null,
161
        true,
162
        0,
163
        false,
164
        0,
165
        0,
166
        $parameters['user_active']
167
    );
168
} else {
169
    // Registered students in session.
170
    $studentList = CourseManager::get_student_list_from_course_code(
171
        $courseCode,
172
        true,
173
        $sessionId,
174
        null,
175
        null,
176
        true,
177
        0,
178
        false,
179
        0,
180
        0,
181
        $parameters['user_active']
182
    );
183
}
184
185
$nbStudents = count($studentList);
186
$user_ids = array_keys($studentList);
187
$extra_info = [];
188
$userProfileInfo = [];
189
// Getting all the additional information of an additional profile field.
190
if (isset($_GET['additional_profile_field'])) {
191
    $user_array = [];
192
    foreach ($studentList as $key => $item) {
193
        $user_array[] = $key;
194
    }
195
196
    foreach ($_GET['additional_profile_field'] as $fieldId) {
197
        // Fetching only the user that are loaded NOT ALL user in the portal.
198
        $userProfileInfo[$fieldId] = TrackingCourseLog::getAdditionalProfileInformationOfFieldByUser(
199
            $fieldId,
200
            $user_array
201
        );
202
        $extra_info[$fieldId] = $objExtrafieldUser->getFieldInfoByFieldId($fieldId);
203
    }
204
}
205
206
Session::write('additional_user_profile_info', $userProfileInfo);
207
Session::write('extra_field_info', $extra_info);
208
209
$defaultExtraFields = [];
210
$defaultExtraFieldsFromSettings = [];
211
$defaultExtraFieldsFromSettings = api_get_configuration_value('course_log_default_extra_fields');
212
if (!empty($defaultExtraFieldsFromSettings) && isset($defaultExtraFieldsFromSettings['extra_fields'])) {
213
    $defaultExtraFields = $defaultExtraFieldsFromSettings['extra_fields'];
214
    $defaultExtraInfo = [];
215
    $defaultUserProfileInfo = [];
216
217
    foreach ($defaultExtraFields as $fieldName) {
218
        $extraFieldInfo = UserManager::get_extra_field_information_by_name($fieldName);
219
220
        if (!empty($extraFieldInfo)) {
221
            // Fetching only the user that are loaded NOT ALL user in the portal.
222
            $defaultUserProfileInfo[$extraFieldInfo['id']] = TrackingCourseLog::getAdditionalProfileInformationOfFieldByUser(
223
                $extraFieldInfo['id'],
224
                $user_ids
225
            );
226
            $defaultExtraInfo[$extraFieldInfo['id']] = $extraFieldInfo;
227
        }
228
    }
229
230
    Session::write('default_additional_user_profile_info', $defaultUserProfileInfo);
231
    Session::write('default_extra_field_info', $defaultExtraInfo);
232
}
233
234
Display::display_header($nameTools, 'Tracking');
235
236
$actionsLeft = TrackingCourseLog::actionsLeft('users', $sessionId);
237
238
$actionsRight = '<div class="pull-right">';
239
$actionsRight .= '<a href="javascript: void(0);" onclick="window.print();">'.
240
    Display::return_icon('printer.png', get_lang('Print'), '', ICON_SIZE_MEDIUM).'</a>';
241
242
$users_tracking_per_page = '';
243
if (isset($_GET['users_tracking_per_page'])) {
244
    $users_tracking_per_page = '&users_tracking_per_page='.intval($_GET['users_tracking_per_page']);
245
}
246
247
$actionsRight .= '<a
248
    href="'.api_get_self().'?'.api_get_cidreq().'&export=csv&'.$additionalParams.$users_tracking_per_page.'">
249
     '.Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a>';
250
$actionsRight .= '</div>';
251
// Create a search-box.
252
$form_search = new FormValidator(
253
    'search_simple',
254
    'GET',
255
    api_get_path(WEB_CODE_PATH).'tracking/courseLog.php?'.api_get_cidreq(),
256
    '',
257
    [],
258
    FormValidator::LAYOUT_INLINE
259
);
260
$renderer = $form_search->defaultRenderer();
261
$form_search->addHidden('from', Security::remove_XSS($from));
262
$form_search->addHidden('session_id', $sessionId);
263
$form_search->addHidden('id_session', $sessionId);
264
$form_search->addHidden('cidReq', $courseCode);
265
$form_search->addElement('text', 'user_keyword');
266
$form_search->addButtonSearch(get_lang('SearchUsers'));
267
echo Display::toolbarAction(
268
    'toolbar-courselog',
269
    [$actionsLeft, $form_search->returnForm(), $actionsRight],
270
    [4, 6, 2]
271
);
272
echo Display::page_header(
273
    Display::return_icon('course.png', get_lang('Course')).PHP_EOL
274
        .$courseInfo['name'],
275
    $sessionId
276
        ? Display::return_icon('session.png', get_lang('Session')).PHP_EOL
277
            .Security::remove_XSS(api_get_session_name($sessionId))
278
        : null
279
);
280
281
$html = TrackingCourseLog::getTeachersOrCoachesHtmlHeader(
282
    $courseInfo['code'],
283
    $courseInfo['real_id'],
284
    $sessionId,
285
    true
286
);
287
288
$showReporting = api_get_configuration_value('hide_reporting_session_list') === false;
289
if ($showReporting) {
290
    $sessionList = SessionManager::get_session_by_course($courseInfo['real_id']);
291
    if (!empty($sessionList)) {
292
        $html .= Display::page_subheader2(get_lang('SessionList'));
293
        $icon = Display::return_icon(
294
            'session.png',
295
            null,
296
            null,
297
            ICON_SIZE_TINY
298
        );
299
300
        $html .= '<ul class="session-list">';
301
        $urlWebCode = api_get_path(WEB_CODE_PATH);
302
        $isAdmin = api_is_platform_admin();
303
        foreach ($sessionList as $session) {
304
            if (!$isAdmin) {
305
                // Check session visibility
306
                $visibility = api_get_session_visibility($session['id'], api_get_course_int_id());
307
                if (SESSION_INVISIBLE == $visibility) {
308
                    continue;
309
                }
310
311
                // Check if is coach
312
                $isCoach = api_is_coach($session['id'], api_get_course_int_id());
313
                if (!$isCoach) {
314
                    continue;
315
                }
316
            }
317
            $url = $urlWebCode.'mySpace/course.php?session_id='.$session['id'].'&cidReq='.$courseInfo['code'];
318
            $html .= Display::tag('li', $icon.' '.Display::url(Security::remove_XSS($session['name']), $url));
319
        }
320
        $html .= '</ul>';
321
    }
322
}
323
324
$trackingColumn = $_GET['users_tracking_column'] ?? null;
325
$trackingDirection = $_GET['users_tracking_direction'] ?? null;
326
$hideReports = (int) api_get_configuration_value('hide_course_report_graph');
327
328
$groupList = GroupManager::get_group_list(null, $courseInfo, 1, $sessionId);
329
330
$class = new UserGroup();
331
$classes = $class->get_all();
332
333
$bestScoreLabel = get_lang('Score').' - '.get_lang('BestAttempt');
334
335
// Show the charts part only if there are students subscribed to this course/session
336
if ($nbStudents > 0 || isset($parameters['user_active'])) {
337
    // Classes
338
    $formClass = new FormValidator(
339
        'classes',
340
        'get',
341
        api_get_self().'?'.api_get_cidreq().'&'.$additionalParams
342
    );
343
    $formClass->addHidden('cidReq', $courseCode);
344
    $formClass->addHidden('id_session', $sessionId);
345
    $groupIdList = ['--'];
346
    $select = $formClass->addSelect('class_id', get_lang('Class').'/'.get_lang('Group'), $groupIdList);
347
    $groupIdList = [];
348
    foreach ($classes as $class) {
349
        $groupIdList[] = ['text' => $class['name'], 'value' => 'class_'.$class['id']];
350
    }
351
    $select->addOptGroup($groupIdList, get_lang('Class'));
352
    $groupIdList = [];
353
    foreach ($groupList as $group) {
354
        $groupIdList[] = ['text' => $group['name'], 'value' => 'group_'.$group['id']];
355
    }
356
    $select->addOptGroup($groupIdList, get_lang('Group'));
357
    $formClass->addButtonSearch(get_lang('Search'));
358
359
    // Filter by ex learners
360
    if (false !== $userEditionExtraFieldToCheck) {
361
        $formExLearners = new FormValidator(
362
            'form_exlearners',
363
            'get',
364
            api_get_self().'?'.api_get_cidreq().'&'.$additionalParams
365
        );
366
        $group = [];
367
        $group[] = $formExLearners->createElement('radio', 'opt_exlearner', 'id="opt_exlearner1"', get_lang('Yes'), 1);
368
        $group[] = $formExLearners->createElement('radio', 'opt_exlearner', 'id="opt_exlearner0"', get_lang('No'), 0);
369
        $formExLearners->addGroup($group, 'exlearner', get_lang('ToHideExlearners'));
370
        $formExLearners->addHidden('cidReq', $courseCode);
371
        $formExLearners->addHidden('id_session', $sessionId);
372
        $formExLearners->addButtonSearch(get_lang('Search'));
373
    }
374
375
    // Groups
376
    /*$formGroup = new FormValidator(
377
        'groups',
378
        'get',
379
        api_get_self().'?'.api_get_cidreq().'&'.$additionalParams
380
    );
381
    $formGroup->addHidden('cidReq', $courseCode);
382
    $formGroup->addHidden('id_session', $sessionId);
383
    $groupIdList = ['--'];
384
    foreach ($groupList as $group) {
385
        $groupIdList[$group['id']] = $group['name'];
386
    }
387
    $formGroup->addSelect('group_id', get_lang('Group'), $groupIdList);
388
    $formGroup->addButtonSearch(get_lang('Search'));*/
389
390
    if (isset($_GET['additional_profile_field'])) {
391
        // Extra fields
392
        $formExtraField = new FormValidator(
393
            'extra_fields',
394
            'get',
395
            api_get_self().'?'.api_get_cidreq().'&'.$additionalParams
396
        );
397
        $formExtraField->addHidden('cidReq', $courseCode);
398
        $formExtraField->addHidden('id_session', $sessionId);
399
400
        foreach ($_GET['additional_profile_field'] as $fieldId) {
401
            $fieldId = Security::remove_XSS($fieldId);
402
            $formExtraField->addHidden('additional_profile_field[]', $fieldId);
403
            $formClass->addHidden('additional_profile_field[]', $fieldId);
404
        }
405
406
        $objExtrafieldUser->addElements($formExtraField, 0, [], true);
407
        $formExtraField->addButtonSearch(get_lang('Search'));
408
    }
409
410
    // Filter by active users
411
    $formActiveUsers = new FormValidator(
412
        'active_users',
413
        'get',
414
        api_get_self().'?'.api_get_cidreq().'&'.$additionalParams
415
    );
416
    // Filter by active users
417
    $group = [];
418
    $group[] = $formActiveUsers->createElement('radio', 'user_active', 'id="user_active1"', get_lang('Yes'), 1);
419
    $group[] = $formActiveUsers->createElement('radio', 'user_active', 'id="user_active0"', get_lang('No'), 0);
420
    $formActiveUsers->addGroup($group, '', get_lang('AccountActive'));
421
    $formActiveUsers->addButtonSearch(get_lang('Search'));
422
423
    if (isset($parameters['user_active'])) {
424
        $formActiveUsers->setDefaults(['user_active' => $parameters['user_active']]);
425
    }
426
427
    $conditions = [];
428
    $fields = [];
429
430
    if ($formClass->validate()) {
431
        $classId = null;
432
        $groupId = null;
433
434
        $part = $formClass->getSubmitValue('class_id');
435
        $item = explode('_', $part);
436
        if (isset($item[0]) && isset($item[1])) {
437
            if ('class' === $item[0]) {
438
                $classId = (int) $item[1];
439
            } else {
440
                $groupId = (int) $item[1];
441
            }
442
        }
443
444
        if (!empty($classId)) {
445
            $whereCondition = " AND gu.usergroup_id = $classId ";
446
            $tableGroup = Database::get_main_table(TABLE_USERGROUP_REL_USER);
447
            $joins = " INNER JOIN $tableGroup gu ON (user.id = gu.user_id) ";
448
            $conditions = ['where' => $whereCondition, 'inject_joins' => $joins];
449
        }
450
451
        if (!empty($groupId)) {
452
            $whereCondition = " AND gu.group_id = $groupId ";
453
            $tableGroup = Database::get_course_table(TABLE_GROUP_USER);
454
            $joins = " INNER JOIN $tableGroup gu ON (user.id = gu.user_id) ";
455
            $conditions = ['where' => $whereCondition, 'inject_joins' => $joins];
456
        }
457
    }
458
    if (false !== $userEditionExtraFieldToCheck) {
459
        if ($formExLearners->validate()) {
460
            $formValue = $formExLearners->getSubmitValue('exlearner');
461
            if (isset($formValue['opt_exlearner']) && 1 == $formValue['opt_exlearner']) {
462
                $sessionId = api_get_session_id();
463
                if (!empty($sessionId)) {
464
                    $tableSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
465
                    $joins = " INNER JOIN $tableSessionCourseUser scu ON scu.user_id = user.id ";
466
                    $whereCondition = " AND scu.status !=  ".COURSE_EXLEARNER." AND scu.c_id = '".api_get_course_int_id()."' AND scu.session_id = $sessionId";
467
                } else {
468
                    $tableCourseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
469
                    $joins = " INNER JOIN $tableCourseUser cu ON cu.user_id = user.id ";
470
                    $whereCondition = " AND cu.relation_type !=  ".COURSE_EXLEARNER." AND cu.c_id = '".api_get_course_int_id()."'";
471
                }
472
                $conditions = ['where' => $whereCondition, 'inject_joins' => $joins];
473
            }
474
        }
475
    }
476
477
    if ($formActiveUsers->validate()) {
478
        $userActive = $formActiveUsers->getSubmitValue('user_active');
479
        if (isset($userActive) && is_numeric($userActive)) {
480
            $active = (int) $userActive;
481
            $whereCondition = " AND user.active = $active ";
482
            $conditions = ['where' => $whereCondition, 'inject_joins' => ''];
483
        }
484
    }
485
486
    /*if ($formGroup->validate()) {
487
        $groupId = (int) $formGroup->getSubmitValue('group_id');
488
        if (!empty($groupId)) {
489
            $whereCondition = " AND gu.group_id = $groupId ";
490
            $tableGroup = Database::get_course_table(TABLE_GROUP_USER);
491
            $joins = " INNER JOIN $tableGroup gu ON (user.id = gu.user_id) ";
492
            $conditions = ['where' => $whereCondition, 'inject_joins' => $joins];
493
        }
494
    }*/
495
496
    if (isset($formExtraField) && $formExtraField->validate()) {
497
        $extraResult = $objExtrafieldUser->processExtraFieldSearch($_REQUEST, $formExtraField, 'user');
498
        if (!empty($extraResult)) {
499
            $conditions = $extraResult['condition'];
500
            $fields = $extraResult['fields'];
501
        }
502
    }
503
504
    if (TrackingCourseLog::HIDE_COURSE_REPORT_GRAPH_HIDDEN !== $hideReports) {
505
        Session::write(
506
            'course_log_args',
507
            [
508
                'parameters' => $parameters,
509
                'conditions' => $conditions,
510
            ]
511
        );
512
513
        echo '<script>
514
            $(function () {
515
                function loadGraphs () {
516
                    $("#tracking-course-summary-wrapper")
517
                        .html("<p><span class=\"fa fa-spinner fa-spin fa-2x\" aria-hidden=\"true\"></span></p>")
518
                        .load(_p.web_ajax + "course_log.ajax.php?a=graph");
519
                }
520
        ';
521
522
        if (TrackingCourseLog::HIDE_COURSE_REPORT_GRAPH_SHOWN === $hideReports) {
523
            echo 'loadGraphs();';
524
        }
525
526
        if (TrackingCourseLog::HIDE_COURSE_REPORT_GRAPH_CLICK_SHOW === $hideReports) {
527
            echo '$("#tracking-course-summary-loader").click(function () {
528
                $(this).remove();
529
                    loadGraphs();
530
                });
531
            ';
532
        }
533
534
        echo '});
535
            </script>
536
            <div id="tracking-course-summary-wrapper"></div>
537
        ';
538
539
        if (TrackingCourseLog::HIDE_COURSE_REPORT_GRAPH_CLICK_SHOW === $hideReports) {
540
            echo '<p>
541
                    <button type="button" class="btn btn-info" id="tracking-course-summary-loader">'
542
                .get_lang('ClickToShowGraphs')
543
                .'</button>
544
                </p>
545
            ';
546
        }
547
    }
548
549
    $html .= Display::page_subheader2(get_lang('StudentList'));
550
551
    $mainForm = new FormValidator(
552
        'filter',
553
        'get',
554
        api_get_self().'?'.api_get_cidreq().'&'.$additionalParams
555
    );
556
    $mainForm->addButtonAdvancedSettings(
557
        'advanced_search',
558
        [get_lang('AdvancedSearch')]
559
    );
560
    $html .= $mainForm->returnForm();
561
562
    $html .= '<div id="advanced_search_options" style="display:none;">';
563
    $html .= $formClass->returnForm();
564
    $html .= isset($formExtraField) ? $formExtraField->returnForm() : '';
565
    $html .= false !== $userEditionExtraFieldToCheck ? $formExLearners->returnForm() : '';
566
    $html .= $formActiveUsers->returnForm();
567
    $html .= '</div>';
568
    $html .= '<hr>';
569
570
    $getLangXDays = get_lang('XDays');
571
    $form = new FormValidator(
572
        'reminder_form',
573
        'get',
574
        api_get_path(WEB_CODE_PATH).'announcements/announcements.php?'.api_get_cidreq(),
575
        null,
576
        ['style' => 'margin-bottom: 10px']
577
    );
578
    $options = [
579
        2 => sprintf($getLangXDays, 2),
580
        3 => sprintf($getLangXDays, 3),
581
        4 => sprintf($getLangXDays, 4),
582
        5 => sprintf($getLangXDays, 5),
583
        6 => sprintf($getLangXDays, 6),
584
        7 => sprintf($getLangXDays, 7),
585
        15 => sprintf($getLangXDays, 15),
586
        30 => sprintf($getLangXDays, 30),
587
        'never' => get_lang('Never'),
588
    ];
589
    $el = $form->addSelect(
590
        'since',
591
        Display::returnFontAwesomeIcon('warning').get_lang('RemindInactivesLearnersSince'),
592
        $options,
593
        ['disable_js' => true, 'class' => 'col-sm-3']
594
    );
595
    $el->setSelected(7);
596
    $form->addElement('hidden', 'action', 'add');
597
    $form->addElement('hidden', 'remindallinactives', 'true');
598
    $form->addElement('hidden', 'cidReq', $courseInfo['code']);
599
    $form->addElement('hidden', 'id_session', api_get_session_id());
600
    $form->addButtonSend(get_lang('SendNotification'));
601
    $form->addLabel(get_lang('Export'), '<a id="download-csv" href="#!" class=" btn btn-default " > '.
602
        Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '').
603
        get_lang('ExportAsCSV')
604
    .' </a>');
605
    $extraFieldSelect = TrackingCourseLog::displayAdditionalProfileFields($defaultExtraFields);
606
    if (!empty($extraFieldSelect)) {
607
        $html .= $extraFieldSelect;
608
    }
609
610
    $html .= $form->returnForm();
611
612
    if ($export_csv) {
613
        //override the SortableTable "per page" limit if CSV
614
        $_GET['users_tracking_per_page'] = 1000000;
615
    }
616
617
    $conditions['include_invited_users'] = true;
618
    $table = new SortableTable(
619
        'users_tracking',
620
        ['TrackingCourseLog', 'getNumberOfUsers'],
621
        ['TrackingCourseLog', 'getUserData'],
622
        1,
623
        20
624
    );
625
    $table->setDataFunctionParams($conditions);
626
627
    $headerCounter = 0;
628
    $headers = [];
629
    // tab of header texts
630
    $table->set_header($headerCounter++, get_lang('OfficialCode'));
631
    $headers['official_code'] = get_lang('OfficialCode');
632
    if ($sortByFirstName) {
633
        $table->set_header($headerCounter++, get_lang('FirstName'));
634
        $table->set_header($headerCounter++, get_lang('LastName'));
635
        $headers['firstname'] = get_lang('FirstName');
636
        $headers['lastname'] = get_lang('LastName');
637
    } else {
638
        $table->set_header($headerCounter++, get_lang('LastName'));
639
        $table->set_header($headerCounter++, get_lang('FirstName'));
640
        $headers['lastname'] = get_lang('LastName');
641
        $headers['firstname'] = get_lang('FirstName');
642
    }
643
    $table->set_header($headerCounter++, get_lang('Login'), false);
644
    $headers['login'] = get_lang('Login');
645
646
    $table->set_header(
647
        $headerCounter++,
648
        get_lang('TrainingTime').'&nbsp;'.
649
        Display::return_icon('info3.gif', get_lang('CourseTimeInfo'), [], ICON_SIZE_TINY),
650
        false
651
    );
652
    $headers['training_time'] = get_lang('TrainingTime');
653
654
    $courseProgressHeadTitle = ($lpShowMaxProgress ? get_lang('ScormAndLPMaxProgress') : get_lang('ScormAndLPProgressTotalAverage'));
655
    $table->set_header(
656
        $headerCounter++,
657
        get_lang('CourseProgress').'&nbsp;'.
658
        Display::return_icon('info3.gif', $courseProgressHeadTitle, [], ICON_SIZE_TINY),
659
        false
660
    );
661
    $headers['course_progress'] = get_lang('CourseProgress');
662
663
    $table->set_header(
664
        $headerCounter++,
665
        get_lang('ExerciseProgress').'&nbsp;'.
666
        Display::return_icon('info3.gif', get_lang('ExerciseProgressInfo'), [], ICON_SIZE_TINY),
667
        false
668
    );
669
    $headers['exercise_progress'] = get_lang('ExerciseProgress');
670
    $table->set_header(
671
        $headerCounter++,
672
        get_lang('ExerciseAverage').'&nbsp;'.
673
        Display::return_icon('info3.gif', get_lang('ExerciseAverageInfo'), [], ICON_SIZE_TINY),
674
        false
675
    );
676
    $headers['exercise_average'] = get_lang('ExerciseAverage');
677
678
    $table->set_header(
679
        $headerCounter++,
680
        get_lang('Score').'&nbsp;'.
681
        Display::return_icon('info3.gif', get_lang('ScormAndLPTestTotalAverage'), [], ICON_SIZE_TINY),
682
        false
683
    );
684
    $headers['score'] = get_lang('Score');
685
686
    $table->set_header(
687
        $headerCounter++,
688
        $bestScoreLabel.'&nbsp;'.
689
        Display::return_icon('info3.gif', get_lang('ScormAndLPTestTotalAverage'), [], ICON_SIZE_TINY),
690
        false
691
    );
692
    $headers['score_best'] = $bestScoreLabel;
693
694
    $addExerciseOption = api_get_configuration_value('add_exercise_best_attempt_in_report');
695
    $exerciseResultHeaders = [];
696
    if (!empty($addExerciseOption) && isset($addExerciseOption['courses']) &&
697
        isset($addExerciseOption['courses'][$courseCode])
698
    ) {
699
        foreach ($addExerciseOption['courses'][$courseCode] as $exerciseId) {
700
            $exercise = new Exercise();
701
            $exercise->read($exerciseId);
702
            if ($exercise->iid) {
703
                $title = get_lang('Exercise').': '.$exercise->get_formated_title();
704
                $table->set_header(
705
                    $headerCounter++,
706
                    $title,
707
                    false
708
                );
709
                $exerciseResultHeaders[] = $title;
710
                $headers['exercise_'.$exercise->iid] = $title;
711
            }
712
        }
713
    }
714
715
    $table->set_header($headerCounter++, get_lang('Student_publication'), false);
716
    $headers['student_publication'] = get_lang('Student_publication');
717
    $table->set_header($headerCounter++, get_lang('Messages'), false);
718
    $headers['messages'] = get_lang('Messages');
719
    $table->set_header($headerCounter++, get_lang('Classes'), false);
720
    $headers['classes'] = get_lang('Classes');
721
722
    if (empty($sessionId)) {
723
        $table->set_header($headerCounter++, get_lang('Survey'), false);
724
        $headers['survey'] = get_lang('Survey');
725
    } else {
726
        $table->set_header($headerCounter++, get_lang('RegisteredDate'), false);
727
        $headers['registered_at'] = get_lang('RegisteredDate');
728
    }
729
    $table->set_header($headerCounter++, get_lang('FirstLoginInCourse'), false);
730
    $headers['first_login'] = get_lang('FirstLoginInCourse');
731
    $table->set_header($headerCounter++, get_lang('LatestLoginInCourse'), false);
732
    $headers['latest_login'] = get_lang('LatestLoginInCourse');
733
734
    $counter = $headerCounter;
735
    if (api_get_setting('show_email_addresses') === 'true') {
736
        $table->set_header($counter, get_lang('Email'), false);
737
        $headers['email'] = get_lang('Email');
738
        $counter++;
739
    }
740
    if (isset($_GET['additional_profile_field'])) {
741
        foreach ($_GET['additional_profile_field'] as $fieldId) {
742
            $table->set_header($counter, $extra_info[$fieldId]['display_text'], false);
743
            $headers[$extra_info[$fieldId]['variable']] = $extra_info[$fieldId]['display_text'];
744
            $counter++;
745
            $parameters['additional_profile_field'] = $fieldId;
746
        }
747
    }
748
    if (isset($defaultExtraFields)) {
749
        if (!empty($defaultExtraInfo)) {
750
            foreach ($defaultExtraInfo as $field) {
751
                $table->set_header($counter, $field['display_text'], false);
752
                $headers[$field['variable']] = $field['display_text'];
753
                $counter++;
754
            }
755
        }
756
    }
757
    $table->set_header($counter, get_lang('Details'), false);
758
    $headers['Details'] = get_lang('Details');
759
760
    if (!empty($fields)) {
761
        foreach ($fields as $key => $value) {
762
            $key = Security::remove_XSS($key);
763
            $value = Security::remove_XSS($value);
764
            $parameters[$key] = $value;
765
        }
766
    }
767
    $table->set_additional_parameters($parameters);
768
    // display buttons to un hide hidden columns
769
    $html .= '<div id="unhideButtons" class="btn-toolbar">';
770
    $index = 0;
771
    $getLangDisplayColumn = get_lang('DisplayColumn');
772
    foreach ($headers as $header) {
773
        $html .= Display::toolbarButton(
774
            $header,
775
            '#',
776
            'arrow-right',
777
            'default',
778
            [
779
                'title' => htmlentities("$getLangDisplayColumn \"$header\"", ENT_QUOTES),
780
                'class' => 'hide',
781
                'onclick' => "foldup($index); return false;",
782
            ]
783
        );
784
        $index++;
785
    }
786
    $html .= '</div>';
787
788
    $html .= '<div id="reporting_table">';
789
    $html .= $table->return_table();
790
    $html .= '</div>';
791
} else {
792
    $html .= Display::return_message(get_lang('NoUsersInCourse'), 'warning');
793
}
794
795
$groupContent = '';
796
echo Display::panel($html);
797
798
$groupTable = new HTML_Table(['class' => 'table table-hover table-striped table-bordered data_table']);
799
$column = 0;
800
$groupTable->setHeaderContents(0, $column++, get_lang('Name'));
801
$groupTable->setHeaderContents(0, $column++, get_lang('TrainingTime'));
802
$groupTable->setHeaderContents(0, $column++, get_lang('AverageTrainingTime'));
803
$groupTable->setHeaderContents(0, $column++, get_lang('CourseProgress'));
804
$groupTable->setHeaderContents(0, $column++, get_lang('ExerciseAverage'));
805
806
$exerciseList = ExerciseLib::get_all_exercises(
807
    $courseInfo,
808
    $sessionId,
809
    false,
810
    null,
811
    false,
812
    3
813
);
814
815
if (!empty($groupList)) {
816
    $totalTime = null;
817
    $totalLpProgress = null;
818
    $totalScore = null;
819
    $totalAverageTime = null;
820
    $totalBestScoreAverageNotInLP = 0;
821
    $row = 1;
822
    foreach ($groupList as $groupInfo) {
823
        $column = 0;
824
        $groupTable->setCellContents($row, $column++, $groupInfo['name']);
825
        $usersInGroup = GroupManager::getStudents($groupInfo['iid']);
826
827
        $time = null;
828
        $lpProgress = null;
829
        $score = null;
830
        $averageTime = null;
831
        $bestScoreAverageNotInLP = null;
832
        if (!empty($usersInGroup)) {
833
            $usersInGroup = array_column($usersInGroup, 'user_id');
834
            $userInGroupCount = count($usersInGroup);
835
            $timeInSeconds = Tracking::get_time_spent_on_the_course(
836
                $usersInGroup,
837
                $courseId,
838
                $sessionId
839
            );
840
            $totalTime += $timeInSeconds;
841
            if (!empty($timeInSeconds)) {
842
                $time = api_time_to_hms($timeInSeconds);
843
                $averageTime = $timeInSeconds / $userInGroupCount;
844
                $totalAverageTime += $averageTime;
845
                $averageTime = api_time_to_hms($averageTime);
846
            }
847
848
            $totalGroupLpProgress = 0;
849
            foreach ($usersInGroup as $studentId) {
850
                $lpProgress = Tracking::get_avg_student_progress(
851
                    $usersInGroup,
852
                    $courseCode,
853
                    [],
854
                    $sessionId
855
                );
856
                $totalGroupLpProgress += $lpProgress;
857
            }
858
859
            if (empty($totalGroupLpProgress)) {
860
                $totalGroupLpProgress = '';
861
            } else {
862
                $lpProgress = $totalGroupLpProgress / $userInGroupCount;
863
                $totalLpProgress += $totalGroupLpProgress;
864
            }
865
866
            $bestScoreAverageNotInLP = TrackingCourseLog::calcBestScoreAverageNotInLP(
867
                $exerciseList,
868
                $usersInGroup,
869
                (int) $courseInfo['real_id']
870
            );
871
872
            $totalBestScoreAverageNotInLP += $bestScoreAverageNotInLP;
873
        }
874
875
        $groupTable->setCellContents($row, $column++, $time);
876
        $groupTable->setCellContents($row, $column++, $averageTime);
877
        $groupTable->setCellContents($row, $column++, $lpProgress);
878
        $groupTable->setCellContents($row, $column++, $bestScoreAverageNotInLP);
879
        $row++;
880
    }
881
882
    $column = 0;
883
    $totalTime = api_time_to_hms($totalTime);
884
    $totalAverageTime = api_time_to_hms($totalAverageTime);
885
    $groupTable->setCellContents($row, $column++, get_lang('Total'));
886
    $groupTable->setCellContents($row, $column++, $totalTime);
887
    $groupTable->setCellContents($row, $column++, $totalAverageTime);
888
    $groupTable->setCellContents($row, $column++, round($totalLpProgress / count($groupList), 2).'% ');
889
    $groupTable->setCellContents($row, $column++, round($totalBestScoreAverageNotInLP / count($groupList), 2).'% ');
890
} else {
891
    $userIdList = Session::read('user_id_list');
892
893
    if (!empty($userIdList)) {
894
        $studentIdList = $userIdList;
895
    } else {
896
        $studentIdList = array_column($studentList, 'user_id');
897
    }
898
    $nbStudents = count($studentIdList);
899
900
    $timeInSeconds = Tracking::get_time_spent_on_the_course(
901
        $studentIdList,
902
        $courseId,
903
        $sessionId
904
    );
905
    $time = api_time_to_hms($timeInSeconds);
906
    $averageTime = api_time_to_hms($timeInSeconds / $nbStudents);
907
    $totalLpProgress = 0;
908
    foreach ($studentIdList as $studentId) {
909
        $lpProgress = Tracking::get_avg_student_progress(
910
            $studentId,
911
            $courseCode,
912
            [],
913
            $sessionId
914
        );
915
        $totalLpProgress += $lpProgress;
916
    }
917
918
    if (empty($nbStudents)) {
919
        $lpProgress = '0 %';
920
    } else {
921
        $lpProgress = round($totalLpProgress / $nbStudents, 2).' %';
922
    }
923
    $totalBestScoreAverageNotInLP = 0;
924
    $bestScoreAverageNotInLP = (string) TrackingCourseLog::calcBestScoreAverageNotInLP(
925
        $exerciseList,
926
        $studentIdList,
927
        (int) $courseInfo['real_id'],
928
        $sessionId,
929
        true
930
    );
931
932
    $row = 1;
933
    $column = 0;
934
    $groupTable->setCellContents($row, $column++, get_lang('Total'));
935
    $groupTable->setCellContents($row, $column++, $time);
936
    $groupTable->setCellContents($row, $column++, $averageTime);
937
    $groupTable->setCellContents($row, $column++, $lpProgress);
938
    $groupTable->setCellContents($row, $column++, $bestScoreAverageNotInLP);
939
}
940
941
echo Display::panel($groupTable->toHtml());
942
943
// Send the csv file if asked.
944
if ($export_csv) {
945
    $csv_headers = [];
946
    $csv_headers[] = get_lang('OfficialCode');
947
    if ($sortByFirstName) {
948
        $csv_headers[] = get_lang('FirstName');
949
        $csv_headers[] = get_lang('LastName');
950
    } else {
951
        $csv_headers[] = get_lang('LastName');
952
        $csv_headers[] = get_lang('FirstName');
953
    }
954
    $csv_headers[] = get_lang('Login');
955
    $csv_headers[] = get_lang('TrainingTime');
956
    $csv_headers[] = get_lang('CourseProgress');
957
    $csv_headers[] = get_lang('ExerciseProgress');
958
    $csv_headers[] = get_lang('ExerciseAverage');
959
    $csv_headers[] = get_lang('Score');
960
    $csv_headers[] = $bestScoreLabel;
961
    if (!empty($exerciseResultHeaders)) {
962
        foreach ($exerciseResultHeaders as $exerciseLabel) {
963
            $csv_headers[] = $exerciseLabel;
964
        }
965
    }
966
    $csv_headers[] = get_lang('Student_publication');
967
    $csv_headers[] = get_lang('Messages');
968
    $csv_headers[] = get_lang('Classes');
969
970
    if (empty($sessionId)) {
971
        $csv_headers[] = get_lang('Survey');
972
    } else {
973
        $csv_headers[] = get_lang('RegistrationDate');
974
    }
975
976
    $csv_headers[] = get_lang('FirstLoginInCourse');
977
    $csv_headers[] = get_lang('LatestLoginInCourse');
978
979
    if (isset($_GET['additional_profile_field'])) {
980
        foreach ($_GET['additional_profile_field'] as $fieldId) {
981
            $csv_headers[] = $extra_info[$fieldId]['display_text'];
982
        }
983
    }
984
    ob_end_clean();
985
986
    $csvContentInSession = Session::read('csv_content', []);
987
988
    // Adding headers before the content.
989
    array_unshift($csvContentInSession, $csv_headers);
990
991
    if ($sessionId) {
992
        $sessionInfo = api_get_session_info($sessionId);
993
        $sessionDates = SessionManager::parseSessionDates($sessionInfo);
994
995
        array_unshift($csvContentInSession, [get_lang('Date'), $sessionDates['access']]);
996
        array_unshift($csvContentInSession, [get_lang('SessionName'), Security::remove_XSS($sessionInfo['name'])]);
997
    }
998
999
    Export::arrayToCsv($csvContentInSession, 'reporting_student_list');
1000
    exit;
1001
}
1002
if (isset($_GET['csv']) && $_GET['csv'] == 1) {
1003
    $since = 6;
1004
    if (isset($_GET['since'])) {
1005
        if ($_GET['since'] === 'never') {
1006
            $since = 'never';
1007
        } else {
1008
            $since = (int) $_GET['since'];
1009
        }
1010
    }
1011
    $users = Tracking::getInactiveStudentsInCourse(
1012
        api_get_course_int_id(),
1013
        $since,
1014
        $sessionId,
1015
        $parameters['user_active']
1016
    );
1017
1018
    if (count($users) != 0) {
1019
        $csv_content = [];
1020
        $csv_headers = [get_lang('NamesAndLastNames'), get_lang('Classes')];
1021
1022
        $userProfileInfo = [];
1023
        if (isset($_GET['additional_profile_field'])) {
1024
            foreach ($_GET['additional_profile_field'] as $fieldId) {
1025
                $csv_headers[] = $extra_info[$fieldId]['display_text'];
1026
                $userProfileInfo[$fieldId] = TrackingCourseLog::getAdditionalProfileInformationOfFieldByUser(
1027
                    $fieldId,
1028
                    $users
1029
                );
1030
                $extra_info[$fieldId] = $objExtrafieldUser->getFieldInfoByFieldId($fieldId);
1031
            }
1032
        }
1033
        $csv_content[] = $csv_headers;
1034
        $userGroupManager = new UserGroup();
1035
1036
        foreach ($users as $userId) {
1037
            $user = api_get_user_info($userId);
1038
            $classes = implode(
1039
                ', ',
1040
                $userGroupManager->getNameListByUser($userId, UserGroup::NORMAL_CLASS)
1041
            );
1042
            $row = [$user['complete_name'], $classes];
1043
1044
            foreach ($_GET['additional_profile_field'] as $fieldId) {
1045
                $extraFieldInfo = $extra_info[$fieldId];
1046
                if (isset($userProfileInfo[$fieldId]) && isset($userProfileInfo[$fieldId][$userId])) {
1047
                    if (is_array($userProfileInfo[$fieldId][$userId])) {
1048
                        $row[] = implode(
1049
                            ', ',
1050
                            $userProfileInfo[$fieldId][$userId]
1051
                        );
1052
                    } else {
1053
                        $row[] = $userProfileInfo[$fieldId][$userId];
1054
                    }
1055
                } else {
1056
                    $row[] = '';
1057
                }
1058
            }
1059
            $csv_content[] = $row;
1060
        }
1061
        ob_end_clean();
1062
        Export::arrayToCsv($csv_content, 'reporting_inactive_users');
1063
        exit;
1064
    }
1065
}
1066
Display::display_footer();
1067