MySpace::complete_missing_data()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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