Test Setup Failed
Push — master ( ec638a...cb9435 )
by Julito
51:10
created

MySpace::user_available_in_session()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 18
nc 3
nop 3
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use CpChart\Chart\Cache as pCache;
5
use CpChart\Chart\Data as pData;
6
use CpChart\Chart\Image as pImage;
7
8
/**
9
 * Class MySpace
10
 * @package chamilo.reporting
11
 */
12
class MySpace
13
{
14
    /**
15
     * Get admin actions
16
     * @return string
17
     */
18
    public static function getAdminActions()
19
    {
20
        $actions = array(
21
            //array('url' => api_get_path(WEB_CODE_PATH).'mySpace/index.php', 'content' => get_lang('Home')),
22
            array(
23
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=coaches',
24
                'content' => get_lang('DisplayCoaches'),
25
            ),
26
            array(
27
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=user',
28
                'content' => get_lang('DisplayUserOverview'),
29
            ),
30
            array(
31
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=session',
32
                'content' => get_lang('DisplaySessionOverview'),
33
            ),
34
            array(
35
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=course',
36
                'content' => get_lang('DisplayCourseOverview'),
37
            ),
38
            array(
39
                'url' => api_get_path(WEB_CODE_PATH).'tracking/question_course_report.php?view=admin',
40
                'content' => get_lang('LPQuestionListResults'),
41
            ),
42
            array(
43
                'url' => api_get_path(WEB_CODE_PATH).'tracking/course_session_report.php?view=admin',
44
                'content' => get_lang('LPExerciseResultsBySession'),
45
            ),
46
            [
47
                'url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=accessoverview',
48
                'content' => get_lang('DisplayAccessOverview').' ('.get_lang('Beta').')',
49
            ],
50
        );
51
52
        return Display::actions($actions, null);
53
    }
54
55
    public static function getTopMenu()
56
    {
57
        $menu_items = array();
58
        $menu_items[] = Display::url(
59
            Display::return_icon('stats.png', get_lang('MyStats'), '', ICON_SIZE_MEDIUM),
60
            api_get_path(WEB_CODE_PATH)."auth/my_progress.php"
61
        );
62
        $menu_items[] = Display::url(
63
            Display::return_icon('teacher.png', get_lang('TeacherInterface'), array(), 32),
64
            api_get_path(WEB_CODE_PATH).'mySpace/?view=teacher'
65
        );
66
        $menu_items[] = Display::url(Display::return_icon('star_na.png', get_lang('AdminInterface'), array(), 32), '#');
67
        $menu_items[] = Display::url(
68
            Display::return_icon('quiz.png', get_lang('ExamTracking'), array(), 32),
69
            api_get_path(WEB_CODE_PATH).'tracking/exams.php'
70
        );
71
        $menu = null;
72
        foreach ($menu_items as $item) {
73
            $menu .= $item;
74
        }
75
        $menu .= '<br />';
76
77
        return $menu;
78
    }
79
80
    /**
81
     * This function serves exporting data in CSV format.
82
     * @param array $header         The header labels.
83
     * @param array $data           The data array.
84
     * @param string $file_name     The name of the file which contains exported data.
85
     * @return string mixed             Returns a message (string) if an error occurred.
86
     */
87
    public function export_csv($header, $data, $file_name = 'export.csv')
88
    {
89
        $archive_path = api_get_path(SYS_ARCHIVE_PATH);
90
        $archive_url = api_get_path(WEB_CODE_PATH).'course_info/download.php?archive_path=&archive=';
91
92
        if (!$open = fopen($archive_path.$file_name, 'w+')) {
93
            $message = get_lang('noOpen');
94
        } else {
95
            $info = '';
96
97
            foreach ($header as $value) {
98
                $info .= $value.';';
99
            }
100
            $info .= "\r\n";
101
102
            foreach ($data as $row) {
103
                foreach ($row as $value) {
104
                    $info .= $value.';';
105
                }
106
                $info .= "\r\n";
107
            }
108
109
            fwrite($open, $info);
110
            fclose($open);
111
            @chmod($file_name, api_get_permissions_for_new_files());
112
113
            header("Location:".$archive_url.$file_name);
114
        }
115
        return $message;
116
    }
117
118
    /**
119
     * Gets the connections to a course as an array of login and logout time
120
     *
121
     * @param   int     $userId User id
122
     * @param   int   $courseId
123
     * @param   int     $sessionId Session id (optional, default = 0)
124
     * @return  array   Connections
125
     */
126
    public static function get_connections_to_course($userId, $courseId, $sessionId = 0)
127
    {
128
        // Database table definitions
129
        $tbl_track_course = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
130
131
        // protect data
132
        $userId = (int) $userId;
133
        $courseId = (int) $courseId;
134
        $sessionId = (int) $sessionId;
135
136
        $sql = 'SELECT login_course_date, logout_course_date
137
                FROM ' . $tbl_track_course . '
138
                WHERE
139
                    user_id = '.$userId.' AND
140
                    c_id = '.$courseId.' AND
141
                    session_id = '.$sessionId.'
142
                ORDER BY login_course_date ASC';
143
        $rs = Database::query($sql);
144
        $connections = array();
145
146 View Code Duplication
        while ($row = Database::fetch_array($rs)) {
147
            $timestamp_login_date = api_strtotime($row['login_course_date'], 'UTC');
148
            $timestamp_logout_date = api_strtotime($row['logout_course_date'], 'UTC');
149
            $connections[] = array('login' => $timestamp_login_date, 'logout' => $timestamp_logout_date);
150
        }
151
152
        return $connections;
153
    }
154
155
    /**
156
     * @param $user_id
157
     * @param $course_list
158
     * @param int $session_id
159
     * @return array|bool
160
     */
161
    public static function get_connections_from_course_list(
162
        $user_id,
163
        $course_list,
164
        $session_id = 0
165
    ) {
166
        // Database table definitions
167
        $tbl_track_course = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
168
        if (empty($course_list)) {
169
            return false;
170
        }
171
172
        // protect data
173
        $user_id = intval($user_id);
174
        $session_id = intval($session_id);
175
        $new_course_list = array();
176
        foreach ($course_list as $course_item) {
177
            $courseInfo = api_get_course_info($course_item['code']);
178
            $courseId = $courseInfo['real_id'];
179
            $new_course_list[] =  '"'.$courseId.'"';
180
        }
181
        $course_list = implode(', ', $new_course_list);
182
183
        if (empty($course_list)) {
184
            return false;
185
        }
186
        $sql = 'SELECT login_course_date, logout_course_date, c_id
187
                FROM ' . $tbl_track_course . '
188
                WHERE
189
                    user_id = '.$user_id.' AND
190
                    c_id IN ('.$course_list.') AND
191
                    session_id = '.$session_id.'
192
                ORDER BY login_course_date ASC';
193
        $rs = Database::query($sql);
194
        $connections = array();
195
196 View Code Duplication
        while ($row = Database::fetch_array($rs)) {
197
            $timestamp_login_date = api_strtotime($row['login_course_date'], 'UTC');
198
            $timestamp_logout_date = api_strtotime($row['logout_course_date'], 'UTC');
199
            $connections[] = array(
200
                'login' => $timestamp_login_date,
201
                'logout' => $timestamp_logout_date,
202
                'c_id' => $row['c_id']
203
            );
204
        }
205
206
        return $connections;
207
    }
208
209
    /**
210
     * Creates a small table in the last column of the table with the user overview
211
     *
212
     * @param integer $user_id the id of the user
213
     * @param array $url_params additonal url parameters
214
     * @param array $row the row information (the other columns)
215
     * @return string html code
216
     */
217
    public static function course_info_tracking_filter($user_id, $url_params, $row)
218
    {
219
        // the table header
220
        $return = '<table class="data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
221
        // database table definition
222
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
223
224
        // getting all the courses of the user
225
        $sql = "SELECT * FROM $tbl_course_user
226
                WHERE
227
                    user_id = '".intval($user_id)."' AND
228
                    relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
229
        $result = Database::query($sql);
230
        while ($row = Database::fetch_array($result)) {
231
            $courseInfo = api_get_course_info_by_id($row['c_id']);
232
            if (empty($courseInfo)) {
233
                continue;
234
            }
235
236
            $courseCode = $courseInfo['code'];
237
            $courseId = $courseInfo['real_id'];
238
239
            $return .= '<tr>';
240
            // course code
241
            $return .= '    <td width="157px" >'.cut($courseCode, 20, true).'</td>';
242
            // time spent in the course
243
            $return .= '    <td><div>'.api_time_to_hms(Tracking::get_time_spent_on_the_course($user_id, $courseId)).'</div></td>';
244
            // student progress in course
245
            $return .= '    <td><div>'.round(Tracking::get_avg_student_progress($user_id, $courseCode), 2).'</div></td>';
246
            // student score
247
            $avg_score = Tracking::get_avg_student_score($user_id, $courseCode);
248
            if (is_numeric($avg_score)) {
249
                $avg_score = round($avg_score,2);
250
            } else {
251
                $$avg_score = '-';
252
            }
253
254
            $return .= '    <td><div>'.$avg_score.'</div></td>';
255
            // student tes score
256
            //$return .= '  <td><div style="width:40px">'.round(Tracking::get_avg_student_exercise_score ($user_id, $courseCode),2).'%</div></td>';
257
            // student messages
258
            $return .= '    <td><div>'.Tracking::count_student_messages($user_id, $courseCode).'</div></td>';
259
            // student assignments
260
            $return .= '    <td><div>'.Tracking::count_student_assignments($user_id, $courseCode).'</div></td>';
261
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
262
            $exercises_results = self::exercises_results($user_id, $courseCode);
263
            $return .= '    <td width="105px"><div>'.(is_null($exercises_results['percentage']) ? '' : $exercises_results['score_obtained'].'/'.$exercises_results['score_possible'].' ( '.$exercises_results['percentage'].'% )').'</div></td>';
264
            $return .= '    <td><div>'.$exercises_results['questions_answered'].'</div></td>';
265
            $return .= '    <td><div>'.Tracking::get_last_connection_date_on_the_course($user_id, $courseInfo).'</div></td>';
266
            $return .= '<tr>';
267
        }
268
        $return .= '</table>';
269
        return $return;
270
    }
271
272
    /**
273
     * Display a sortable table that contains an overview off all the
274
     * reporting progress of all users and all courses the user is subscribed to
275
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
276
     * @version Dokeos 1.8.6
277
     * @since October 2008
278
     */
279
    public static function display_tracking_user_overview()
280
    {
281
        self::display_user_overview_export_options();
282
        $t_head = '<table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
283
        $t_head .= '<tr>';
284
        $t_head .= '<th width="155px" style="border-left:0;border-bottom:0"><span>'.get_lang('Course').'</span></th>';
285
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgTimeSpentInTheCourse'), 6, true).'</span></th>';
286
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgStudentsProgress'), 6, true).'</span></th>';
287
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgCourseScore'), 6, true).'</span></th>';
288
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfMessages'), 6, true).'</span></th>';
289
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfAssignments'), 6, true).'</span></th>';
290
        $t_head .= '<th width="105px" style="border-bottom:0"><span>'.get_lang('TotalExercisesScoreObtained').'</span></th>';
291
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalExercisesAnswered'), 6, true).'</span></th>';
292
        $t_head .= '<th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('LatestLogin').'</span></th>';
293
        $t_head .= '</tr></table>';
294
        $addparams = array('view' => 'admin', 'display' => 'user');
295
        $table = new SortableTable(
296
            'tracking_user_overview',
297
            array('MySpace', 'get_number_of_users_tracking_overview'),
298
            array('MySpace', 'get_user_data_tracking_overview'),
299
            0
300
        );
301
        $table->additional_parameters = $addparams;
302
        $table->set_header(0, get_lang('OfficialCode'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
303
        if (api_is_western_name_order()) {
304
            $table->set_header(1, get_lang('FirstName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
305
            $table->set_header(2, get_lang('LastName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
306
        } else {
307
            $table->set_header(1, get_lang('LastName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
308
            $table->set_header(2, get_lang('FirstName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
309
        }
310
        $table->set_header(3, get_lang('LoginName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
311
        $table->set_header(4, $t_head, false, array('style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'), array('style' => 'width:90%;padding:0;font-size:7.5pt;'));
312
        $table->set_column_filter(4, array('MySpace','course_info_tracking_filter'));
313
        $table->display();
314
    }
315
316
    /**
317
     * @param $export_csv
318
     */
319
    public static function display_tracking_coach_overview($export_csv)
320
    {
321
        if ($export_csv) {
322
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
323
        } else {
324
            $is_western_name_order = api_is_western_name_order();
325
        }
326
        $sort_by_first_name = api_sort_by_first_name();
327
        $tracking_column = isset($_GET['tracking_list_coaches_column']) ? $_GET['tracking_list_coaches_column'] : ($is_western_name_order xor $sort_by_first_name) ? 1 : 0;
328
        $tracking_direction = (isset($_GET['tracking_list_coaches_direction']) && in_array(strtoupper($_GET['tracking_list_coaches_direction']), array('ASC', 'DESC', 'ASCENDING', 'DESCENDING', '0', '1'))) ? $_GET['tracking_list_coaches_direction'] : 'DESC';
329
        // Prepare array for column order - when impossible, use some of user names.
330
        if ($is_western_name_order) {
331
            $order = array(
332
                0 => 'firstname',
333
                1 => 'lastname',
334
                2 => ($sort_by_first_name ? 'firstname' : 'lastname'),
335
                3 => 'login_date',
336
                4 => ($sort_by_first_name ? 'firstname' : 'lastname'),
337
                5 => ($sort_by_first_name ? 'firstname' : 'lastname'),
338
            );
339
        } else {
340
            $order = array(
341
                0 => 'lastname',
342
                1 => 'firstname',
343
                2 => ($sort_by_first_name ? 'firstname' : 'lastname'),
344
                3 => 'login_date',
345
                4 => ($sort_by_first_name ? 'firstname' : 'lastname'),
346
                5 => ($sort_by_first_name ? 'firstname' : 'lastname'),
347
            );
348
        }
349
        $table = new SortableTable(
350
            'tracking_list_coaches_myspace',
351
            array('MySpace', 'count_coaches'),
352
            null,
353
            ($is_western_name_order xor $sort_by_first_name) ? 1 : 0
354
        );
355
        $parameters['view'] = 'admin';
356
        $table->set_additional_parameters($parameters);
357 View Code Duplication
        if ($is_western_name_order) {
358
            $table -> set_header(0, get_lang('FirstName'), true);
359
            $table -> set_header(1, get_lang('LastName'), true);
360
        } else {
361
            $table -> set_header(0, get_lang('LastName'), true);
362
            $table -> set_header(1, get_lang('FirstName'), true);
363
        }
364
        $table -> set_header(2, get_lang('TimeSpentOnThePlatform'), false);
365
        $table -> set_header(3, get_lang('LastConnexion'), false);
366
        $table -> set_header(4, get_lang('NbStudents'), false);
367
        $table -> set_header(5, get_lang('CountCours'), false);
368
        $table -> set_header(6, get_lang('NumberOfSessions'), false);
369
        $table -> set_header(7, get_lang('Sessions'), false);
370
371
        if ($is_western_name_order) {
372
            $csv_header[] = array (
373
                get_lang('FirstName'),
374
                get_lang('LastName'),
375
                get_lang('TimeSpentOnThePlatform'),
376
                get_lang('LastConnexion'),
377
                get_lang('NbStudents'),
378
                get_lang('CountCours'),
379
                get_lang('NumberOfSessions')
380
            );
381
        } else {
382
            $csv_header[] = array (
383
                get_lang('LastName'),
384
                get_lang('FirstName'),
385
                get_lang('TimeSpentOnThePlatform'),
386
                get_lang('LastConnexion'),
387
                get_lang('NbStudents'),
388
                get_lang('CountCours'),
389
                get_lang('NumberOfSessions')
390
            );
391
        }
392
393
        $tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
394
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
395
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
396
        $tbl_sessions = Database::get_main_table(TABLE_MAIN_SESSION);
397
398
        $sqlCoachs = "SELECT DISTINCT
399
                        scu.user_id as id_coach,
400
                        u.id as user_id,
401
                        lastname,
402
                        firstname,
403
                        MAX(login_date) as login_date
404
                        FROM $tbl_user u, $tbl_session_course_user scu, $tbl_track_login
405
                        WHERE
406
                            scu.user_id = u.id AND scu.status=2 AND login_user_id=u.id
407
                        GROUP BY user_id ";
408
409
        if (api_is_multiple_url_enabled()) {
410
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
411
            $access_url_id = api_get_current_access_url_id();
412
            if ($access_url_id != -1) {
413
                $sqlCoachs = "SELECT DISTINCT
414
                                    scu.user_id as id_coach,
415
                                    u.id as user_id,
416
                                    lastname,
417
                                    firstname,
418
                                    MAX(login_date) as login_date
419
                                FROM $tbl_user u,
420
                                $tbl_session_course_user scu,
421
                                $tbl_track_login ,
422
                                $tbl_session_rel_access_url session_rel_url
423
                                WHERE
424
                                    scu.user_id = u.id AND
425
                                    scu.status = 2 AND
426
                                    login_user_id = u.id AND
427
                                    access_url_id = $access_url_id AND
428
                                    session_rel_url.session_id = scu.session_id
429
                                GROUP BY u.id";
430
            }
431
        }
432
        if (!empty($order[$tracking_column])) {
433
            $sqlCoachs .= " ORDER BY ".$order[$tracking_column]." ".$tracking_direction;
434
        }
435
436
        $result_coaches = Database::query($sqlCoachs);
437
        $total_no_coaches = Database::num_rows($result_coaches);
438
        $global_coaches = array();
439
        while ($coach = Database::fetch_array($result_coaches)) {
440
            $global_coaches[$coach['user_id']] = $coach;
441
        }
442
443
        $sql_session_coach = 'SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
444
                                FROM '.$tbl_user.' u ,'.$tbl_sessions.' as session,'.$tbl_track_login.'
445
                                WHERE id_coach = u.id AND login_user_id = u.id
446
                                GROUP BY u.id
447
                                ORDER BY login_date '.$tracking_direction;
448
449
        if (api_is_multiple_url_enabled()) {
450
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
451
            $access_url_id = api_get_current_access_url_id();
452
            if ($access_url_id != -1) {
453
                $sql_session_coach = 'SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
454
					FROM '.$tbl_user.' u ,'.$tbl_sessions.' as session, '.$tbl_track_login.' , '.$tbl_session_rel_access_url.' as session_rel_url
455
					WHERE
456
					    id_coach = u.id AND
457
					    login_user_id = u.id  AND
458
					    access_url_id = '.$access_url_id.' AND
459
					    session_rel_url.session_id = session.id
460
					GROUP BY  u.id
461
					ORDER BY login_date '.$tracking_direction;
462
            }
463
        }
464
465
        $result_sessions_coach = Database::query($sql_session_coach);
466
        $total_no_coaches += Database::num_rows($result_sessions_coach);
467
        while ($coach = Database::fetch_array($result_sessions_coach)) {
468
            $global_coaches[$coach['user_id']] = $coach;
469
        }
470
471
        $all_datas = array();
472
        foreach ($global_coaches as $id_coach => $coaches) {
473
            $time_on_platform   = api_time_to_hms(Tracking::get_time_spent_on_the_platform($coaches['user_id']));
474
            $last_connection    = Tracking::get_last_connection_date($coaches['user_id']);
475
            $nb_students        = count(Tracking::get_student_followed_by_coach($coaches['user_id']));
476
            $nb_courses         = count(Tracking::get_courses_followed_by_coach($coaches['user_id']));
477
            $nb_sessions        = count(Tracking::get_sessions_coached_by_user($coaches['user_id']));
478
479
            $table_row = array();
480
            if ($is_western_name_order) {
481
                $table_row[] = $coaches['firstname'];
482
                $table_row[] = $coaches['lastname'];
483
            } else {
484
                $table_row[] = $coaches['lastname'];
485
                $table_row[] = $coaches['firstname'];
486
            }
487
            $table_row[] = $time_on_platform;
488
            $table_row[] = $last_connection;
489
            $table_row[] = $nb_students;
490
            $table_row[] = $nb_courses;
491
            $table_row[] = $nb_sessions;
492
            $table_row[] = '<a href="session.php?id_coach='.$coaches['user_id'].'">
493
                '.Display::return_icon('2rightarrow.png').'
494
            </a>';
495
            $all_datas[] = $table_row;
496
497
            if ($is_western_name_order) {
498
                $csv_content[] = array(
499
                    api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
500
                    api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
501
                    $time_on_platform,
502
                    $last_connection,
503
                    $nb_students,
504
                    $nb_courses,
505
                    $nb_sessions
506
                );
507
            } else {
508
                $csv_content[] = array(
509
                    api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
510
                    api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
511
                    $time_on_platform,
512
                    $last_connection,
513
                    $nb_students,
514
                    $nb_courses,
515
                    $nb_sessions
516
                );
517
            }
518
        }
519
520
        if ($tracking_column != 3) {
521
            if ($tracking_direction == 'DESC') {
522
                usort($all_datas, array('MySpace','rsort_users'));
523
            } else {
524
                usort($all_datas, array('MySpace','sort_users'));
525
            }
526
        }
527
528
        if ($export_csv && $tracking_column != 3) {
529
            usort($csv_content, 'sort_users');
530
        }
531
        if ($export_csv) {
532
            $csv_content = array_merge($csv_header, $csv_content);
533
        }
534
535
        foreach ($all_datas as $row) {
536
            $table -> addRow($row, 'align="right"');
537
        }
538
        $table -> display();
539
    }
540
541
    public static function count_coaches()
542
    {
543
        global $total_no_coaches;
544
        return $total_no_coaches;
545
    }
546
547
    public static function sort_users($a, $b)
548
    {
549
        return api_strcmp(trim(api_strtolower($a[$_SESSION['tracking_column']])), trim(api_strtolower($b[$_SESSION['tracking_column']])));
550
    }
551
552
    public static function rsort_users($a, $b)
553
    {
554
        return api_strcmp(trim(api_strtolower($b[$_SESSION['tracking_column']])), trim(api_strtolower($a[$_SESSION['tracking_column']])));
555
    }
556
557
    /**
558
     * Display a sortable table that contains an overview off all the progress of the user in a session
559
     * @author César Perales <[email protected]>, Beeznest Team
560
     */
561
    public static function display_tracking_lp_progress_overview($sessionId = '', $courseId = '', $date_from, $date_to)
562
    {
563
        $course = api_get_course_info_by_id($courseId);
564
        /**
565
         * Column name
566
         * The order is important you need to check the $column variable in the model.ajax.php file
567
         */
568
        $columns = array(
569
            get_lang('Username'),
570
            get_lang('FirstName'),
571
            get_lang('LastName'),
572
        );
573
        //add lessons of course
574
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
575
576
        //create columns array
577
        foreach ($lessons as $lesson_id => $lesson) {
578
            $columns[] = $lesson['name'];
579
        }
580
581
        $columns[] = get_lang('Total');
582
583
        /**
584
         * Column config
585
         */
586
        $column_model   = array(
587
            array(
588
                'name' => 'username',
589
                'index' => 'username',
590
                'align' => 'left',
591
                'search' => 'true',
592
                'wrap_cell' => "true",
593
            ),
594
            array(
595
                'name' => 'firstname',
596
                'index' => 'firstname',
597
                'align' => 'left',
598
                'search' => 'true',
599
            ),
600
            array(
601
                'name' => 'lastname',
602
                'index' => 'lastname',
603
                'align' => 'left',
604
                'search' => 'true',
605
            ),
606
        );
607
608
        // Get dinamic column names
609
        foreach ($lessons as $lesson_id => $lesson) {
610
            $column_model[] = array(
611
                'name' => $lesson['id'],
612
                'index' => $lesson['id'],
613
                'align' => 'left',
614
                'search' => 'true',
615
            );
616
        }
617
618
        $column_model[] = array(
619
            'name' => 'total',
620
            'index' => 'total',
621
            'align' => 'left',
622
            'search' => 'true',
623
        );
624
625
        $action_links = '';
626
        // jqgrid will use this URL to do the selects
627
        $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_lp_progress&session_id=' . $sessionId . '&course_id=' . $courseId . '&date_to=' . $date_to . '&date_from=' . $date_from;
628
629
        //Table Id
630
        $tableId = 'lpProgress';
631
632
        //Autowidth
633
        $extra_params['autowidth'] = 'true';
634
635
        //height auto
636
        $extra_params['height'] = 'auto';
637
638
        $table = Display::grid_js(
639
            $tableId,
640
            $url,
641
            $columns,
642
            $column_model,
643
            $extra_params,
644
            array(),
645
            $action_links,
646
            true
647
        );
648
649
        $return = '<script>$(function() {'. $table .
650
            'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
651
                jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
652
                       caption:"",
653
                       title:"' . get_lang('ExportExcel') . '",
654
                       onClickButton : function () {
655
                           jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
656
                       }
657
                });
658
            });</script>';
659
        $return .= Display::grid_html($tableId);
660
        return $return;
661
    }
662
663
    /**
664
     * Display a sortable table that contains an overview off all the progress of the user in a session
665
     * @param   int $sessionId  The session ID
666
     * @param   int $courseId   The course ID
667
     * @param   int $exerciseId The quiz ID
668
     * @param   int $answer Answer status (0 = incorrect, 1 = correct, 2 = both)
0 ignored issues
show
Bug introduced by
There is no parameter named $answer. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
669
     * @return  string  HTML array of results formatted for gridJS
670
     * @author César Perales <[email protected]>, Beeznest Team
671
     */
672
    public static function display_tracking_exercise_progress_overview(
673
        $sessionId = 0,
674
        $courseId = 0,
675
        $exerciseId = 0,
676
        $date_from = null,
677
        $date_to = null
678
    ) {
679
        $date_from = Security::remove_XSS($date_from);
680
        $date_to = Security::remove_XSS($date_to);
681
        /**
682
         * Column names
683
         * The column order is important. Check $column variable in the main/inc/ajax/model.ajax.php file
684
         */
685
        $columns = array(
686
            get_lang('Session'),
687
            get_lang('ExerciseId'),
688
            get_lang('ExerciseName'),
689
            get_lang('Username'),
690
            get_lang('LastName'),
691
            get_lang('FirstName'),
692
            get_lang('Time'),
693
            get_lang('QuestionId'),
694
            get_lang('QuestionTitle'),
695
            get_lang('WorkDescription'),
696
            get_lang('Answer'),
697
            get_lang('Correct')
698
        );
699
700
        /**
701
         * Column config
702
         */
703
        $column_model   = array(
704
            array('name'=>'session', 'index'=>'session', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
705
            array('name'=>'exercise_id', 'index'=>'exercise_id', 'align'=>'left', 'search' => 'true'),
706
            array('name'=>'quiz_title', 'index'=>'quiz_title', 'align'=>'left', 'search' => 'true'),
707
            array('name'=>'username', 'index'=>'username', 'align'=>'left', 'search' => 'true'),
708
            array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left', 'search' => 'true'),
709
            array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left', 'search' => 'true'),
710
            array('name'=>'time', 'index'=>'time', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
711
            array('name'=>'question_id', 'index'=>'question_id', 'align'=>'left', 'search' => 'true'),
712
            array('name'=>'question', 'index'=>'question', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
713
            array('name'=>'description', 'index'=>'description', 'align'=>'left', 'width' => '550', 'search' => 'true', 'wrap_cell' => "true"),
714
            array('name'=>'answer', 'index'=>'answer', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
715
            array('name'=>'correct', 'index'=>'correct', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
716
        );
717
        //get dynamic column names
718
719
        // jqgrid will use this URL to do the selects
720
        $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_progress&session_id=' . $sessionId . '&course_id=' . $courseId  . '&exercise_id=' . $exerciseId . '&date_to=' . $date_to . '&date_from=' . $date_from;
721
722
        // Autowidth
723
        $extra_params['autowidth'] = 'true';
724
725
        // height auto
726
        $extra_params['height'] = 'auto';
727
728
        $tableId = 'exerciseProgressOverview';
729
        $table = Display::grid_js($tableId, $url, $columns, $column_model, $extra_params, array(), '', true);
730
731
        $return = '<script>$(function() {'. $table .
732
            'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
733
                jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
734
                       caption:"",
735
                       title:"' . get_lang('ExportExcel') . '",
736
                       onClickButton : function () {
737
                           jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
738
                       }
739
                });
740
            });</script>';
741
        $return .= Display::grid_html($tableId);
742
        return $return;
743
    }
744
745
    /**
746
     * Displays a form with all the additionally defined user fields of the profile
747
     * and give you the opportunity to include these in the CSV export
748
     *
749
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
750
     * @version 1.8.6
751
     * @since November 2008
752
     */
753
    public static function display_user_overview_export_options()
754
    {
755
        $message = '';
756
        // include the user manager and formvalidator library
757
        if (isset($_GET['export']) && $_GET['export'] == 'options') {
758
            // get all the defined extra fields
759
            $extrafields = UserManager::get_extra_fields(
760
                0,
761
                50,
762
                5,
763
                'ASC',
764
                false,
765
                1
766
            );
767
768
            // creating the form with all the defined extra fields
769
            $form = new FormValidator(
770
                'exportextrafields',
771
                'post',
772
                api_get_self()."?view=".Security::remove_XSS($_GET['view']).'&display='.Security::remove_XSS($_GET['display']).'&export='.Security::remove_XSS($_GET['export'])
773
            );
774
775
            if (is_array($extrafields) && count($extrafields) > 0) {
776
                foreach ($extrafields as $key => $extra) {
777
                    $form->addElement('checkbox', 'extra_export_field'.$extra[0], '', $extra[3]);
778
                }
779
                $form->addButtonSave(get_lang('Ok'), 'submit');
780
781
                // setting the default values for the form that contains all the extra fields
782
                if (is_array($_SESSION['additional_export_fields'])) {
783
                    foreach ($_SESSION['additional_export_fields'] as $key => $value) {
784
                        $defaults['extra_export_field'.$value] = 1;
785
                    }
786
                }
787
                $form->setDefaults($defaults);
788
            } else {
789
                $form->addElement('html', Display::display_warning_message(get_lang('ThereAreNotExtrafieldsAvailable')));
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_warning_message() has been deprecated with message: use Display::addFlash(Display::return_message($message, 'warning'));

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
790
            }
791
792
            if ($form->validate()) {
793
                // exporting the form values
794
                $values = $form->exportValues();
795
796
                // re-initialising the session that contains the additional fields that need to be exported
797
                $_SESSION['additional_export_fields'] = array();
798
799
                // adding the fields that are checked to the session
800
                $message = '';
801
                foreach ($values as $field_ids => $value) {
802
                    if ($value == 1 && strstr($field_ids,'extra_export_field')) {
803
                        $_SESSION['additional_export_fields'][] = str_replace('extra_export_field', '', $field_ids);
804
                    }
805
                }
806
807
                // adding the fields that will be also exported to a message string
808
                if (is_array($_SESSION['additional_export_fields'])) {
809 View Code Duplication
                    foreach ($_SESSION['additional_export_fields'] as $key => $extra_field_export) {
810
                        $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
811
                    }
812
                }
813
814
                // Displaying a feedback message
815
                if (!empty($_SESSION['additional_export_fields'])) {
816
                    Display::display_confirmation_message(get_lang('FollowingFieldsWillAlsoBeExported').': <br /><ul>'.$message.'</ul>', false);
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_confirmation_message() has been deprecated with message: use Display::addFlash(Display::return_message($message, 'confirm'));

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
817
                } else  {
818
                    Display::display_confirmation_message(get_lang('NoAdditionalFieldsWillBeExported'), false);
0 ignored issues
show
Deprecated Code introduced by
The method Display::display_confirmation_message() has been deprecated with message: use Display::addFlash(Display::return_message($message, 'confirm'));

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
819
                }
820
            } else {
821
                $form->display();
822
            }
823
824
        } else {
825
            if (!empty($_SESSION['additional_export_fields'])) {
826
                // get all the defined extra fields
827
                $extrafields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
828
829 View Code Duplication
                foreach ($_SESSION['additional_export_fields'] as $key => $extra_field_export) {
830
                    $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
831
                }
832
833
                echo Display::return_message(get_lang('FollowingFieldsWillAlsoBeExported').': <br /><ul>'.$message.'</ul>', 'normal', false);
834
            }
835
        }
836
    }
837
838
    /**
839
     * Display a sortable table that contains an overview of all the reporting progress of all courses
840
     */
841
    public static function display_tracking_course_overview()
842
    {
843
        $t_head = '<table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
844
        $t_head .= '<tr>';
845
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgTimeSpentInTheCourse'), 6, true).'</span></th>';
846
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgStudentsProgress'), 6, true).'</span></th>';
847
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgCourseScore'), 6, true).'</span></th>';
848
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfMessages'), 6, true).'</span></th>';
849
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfAssignments'), 6, true).'</span></th>';
850
        $t_head .= '<th width="105px" style="border-bottom:0"><span>'.get_lang('TotalExercisesScoreObtained').'</span></th>';
851
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalExercisesAnswered'), 6, true).'</span></th>';
852
        $t_head .= '<th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('LatestLogin').'</span></th>';
853
        $t_head .= '</tr></table>';
854
        $addparams = array('view' => 'admin', 'display' => 'courseoverview');
855
        $table = new SortableTable(
856
            'tracking_session_overview',
857
            array('MySpace', 'get_total_number_courses'),
858
            array('MySpace', 'get_course_data_tracking_overview'),
859
            1
860
        );
861
        $table->additional_parameters = $addparams;
862
863
        $table->set_header(0, '', false, null, array('style' => 'display: none'));
864
        $table->set_header(1, get_lang('Course'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
865
        $table->set_header(2, $t_head, false, array('style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'), array('style' => 'width:90%;padding:0;font-size:7.5pt;'));
866
        $table->set_column_filter(2, array('MySpace','course_tracking_filter'));
867
        $table->display();
868
    }
869
870
    /**
871
     * Get the total number of courses
872
     *
873
     * @return integer Total number of courses
874
     */
875
    public static function get_total_number_courses()
876
    {
877
        return CourseManager::count_courses(api_get_current_access_url_id());
878
    }
879
880
    /**
881
     * Get data for the courses
882
     *
883
     * @param int $from Inferior limit
884
     * @param int $numberItems Number of items to select
885
     * @param string $column Column to order on
886
     * @param string $direction Order direction
887
     * @return array Results
888
     */
889
    public static function get_course_data_tracking_overview($from, $numberItems, $column, $direction)
890
    {
891
        $courses = CourseManager::get_courses_list(
892
            $from,
893
            $numberItems,
894
            $column,
895
            $direction,
896
             -1,
897
            '',
898
            api_get_current_access_url_id()
899
        );
900
901
        $list = [];
902
        foreach ($courses as $course) {
903
            $list[] = [
904
                '0' => $course['code'],
905
                'col0' => $course['code'],
906
                '1' => $course['title'],
907
                'col1' => $course['title']
908
            ];
909
        }
910
911
        return $list;
912
    }
913
914
    /**
915
     * Fills in course reporting data
916
     *
917
     * @param integer course code
918
     * @param array $url_params additional url parameters
919
     * @param array $row the row information (the other columns)
920
     * @return string html code
921
     */
922
    public static function course_tracking_filter($course_code, $url_params, $row)
923
    {
924
        $course_code = $row[0];
925
        $courseInfo = api_get_course_info($course_code);
926
        $courseId = $courseInfo['real_id'];
927
928
        // the table header
929
        $return = '<table class="data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
930
931
        // database table definition
932
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
933
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
934
935
        // getting all the courses of the user
936
        $sql = "SELECT *
937
                FROM $tbl_user AS u
938
                INNER JOIN $tbl_course_rel_user AS cu
939
                ON cu.user_id = u.user_id
940
                WHERE cu.c_id = '".$courseId."'";
941
        $result = Database::query($sql);
942
        $time_spent = 0;
943
        $progress = 0;
944
        $nb_progress_lp = 0;
945
        $score = 0;
946
        $nb_score_lp = 0;
947
        $nb_messages = 0;
948
        $nb_assignments = 0;
949
        $last_login_date = false;
950
        $total_score_obtained = 0;
951
        $total_score_possible = 0;
952
        $total_questions_answered = 0;
953 View Code Duplication
        while ($row = Database::fetch_object($result)) {
954
            // get time spent in the course and session
955
            $time_spent += Tracking::get_time_spent_on_the_course($row->user_id, $courseInfo['real_id']);
956
            $progress_tmp = Tracking::get_avg_student_progress($row->user_id, $course_code, array(), null, true);
957
            $progress += $progress_tmp[0];
958
            $nb_progress_lp += $progress_tmp[1];
959
            $score_tmp = Tracking::get_avg_student_score($row->user_id, $course_code, array(), null, true);
960
            if(is_array($score_tmp)) {
961
                $score += $score_tmp[0];
962
                $nb_score_lp += $score_tmp[1];
963
            }
964
            $nb_messages += Tracking::count_student_messages($row->user_id, $course_code);
965
            $nb_assignments += Tracking::count_student_assignments($row->user_id, $course_code);
966
            $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course($row->user_id, $courseInfo, null, false);
967
            if($last_login_date_tmp != false && $last_login_date == false) { // TODO: To be cleaned
968
                $last_login_date = $last_login_date_tmp;
969
            } else if($last_login_date_tmp != false && $last_login_date != false) { // TODO: Repeated previous condition. To be cleaned.
970
                // Find the max and assign it to first_login_date
971
                if(strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
972
                    $last_login_date = $last_login_date_tmp;
973
                }
974
            }
975
976
            $exercise_results_tmp = self::exercises_results($row->user_id, $course_code);
977
            $total_score_obtained += $exercise_results_tmp['score_obtained'];
978
            $total_score_possible += $exercise_results_tmp['score_possible'];
979
            $total_questions_answered += $exercise_results_tmp['questions_answered'];
980
        }
981 View Code Duplication
        if ($nb_progress_lp > 0) {
982
            $avg_progress = round($progress / $nb_progress_lp, 2);
983
        } else {
984
            $avg_progress = 0;
985
        }
986 View Code Duplication
        if ($nb_score_lp > 0) {
987
            $avg_score = round($score / $nb_score_lp, 2);
988
        } else {
989
            $avg_score = '-';
990
        }
991
        if ($last_login_date) {
992
            $last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT, date_default_timezone_get());
993
        } else {
994
            $last_login_date = '-';
995
        }
996 View Code Duplication
        if ($total_score_possible > 0) {
997
            $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
998
        } else {
999
            $total_score_percentage = 0;
1000
        }
1001 View Code Duplication
        if ($total_score_percentage > 0) {
1002
            $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
1003
        } else {
1004
            $total_score = '-';
1005
        }
1006
        $return .= '<tr>';
1007
        // time spent in the course
1008
        $return .= '    <td style="width:164px;">'.api_time_to_hms($time_spent).'</td>';
1009
        // student progress in course
1010
        $return .= '    <td>'.$avg_progress.'</td>';
1011
        // student score
1012
        $return .= '    <td>'.$avg_score.'</td>';
1013
        // student messages
1014
        $return .= '    <td>'.$nb_messages.'</td>';
1015
        // student assignments
1016
        $return .= '    <td>'.$nb_assignments.'</td>';
1017
        // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
1018
        $return .= '<td width="105px;">'.$total_score.'</td>';
1019
        $return .= '<td>'.$total_questions_answered.'</td>';
1020
        // last connection
1021
        $return .= '    <td>'.$last_login_date.'</td>';
1022
        $return .= '</tr>';
1023
        $return .= '</table>';
1024
        return $return;
1025
    }
1026
1027
    /**
1028
     * This function exports the table that we see in display_tracking_course_overview()
1029
     *
1030
     */
1031
    public static function export_tracking_course_overview()
1032
    {
1033
        // database table definition
1034
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1035
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1036
1037
        // the values of the sortable table
1038
        if ($_GET['tracking_course_overview_page_nr']) {
1039
            $from = $_GET['tracking_course_overview_page_nr'];
1040
        } else {
1041
            $from = 0;
1042
        }
1043
        if ($_GET['tracking_course_overview_column']) {
1044
            $orderby = $_GET['tracking_course_overview_column'];
1045
        } else {
1046
            $orderby = 0;
1047
        }
1048
1049
        if ($_GET['tracking_course_overview_direction']) {
1050
            $direction = $_GET['tracking_course_overview_direction'];
1051
        } else {
1052
            $direction = 'ASC';
1053
        }
1054
1055
        $course_data = self::get_course_data_tracking_overview($from, 1000, $orderby, $direction);
1056
1057
        $csv_content = array();
1058
1059
        // the first line of the csv file with the column headers
1060
        $csv_row = array();
1061
        $csv_row[] = get_lang('Course');
1062
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse');
1063
        $csv_row[] = get_lang('AvgStudentsProgress');
1064
        $csv_row[] = get_lang('AvgCourseScore');
1065
        $csv_row[] = get_lang('TotalNumberOfMessages');
1066
        $csv_row[] = get_lang('TotalNumberOfAssignments');
1067
        $csv_row[] = get_lang('TotalExercisesScoreObtained');
1068
        $csv_row[] = get_lang('TotalExercisesScorePossible');
1069
        $csv_row[] = get_lang('TotalExercisesAnswered');
1070
        $csv_row[] = get_lang('TotalExercisesScorePercentage');
1071
        $csv_row[] = get_lang('LatestLogin');
1072
        $csv_content[] = $csv_row;
1073
1074
        // the other lines (the data)
1075
        foreach ($course_data as $key => $course) {
1076
            $course_code = $course[0];
1077
            $courseInfo = api_get_course_info($course_code);
1078
            $course_title = $courseInfo['title'];
1079
            $courseId = $courseInfo['real_id'];
1080
1081
            $csv_row = array();
1082
            $csv_row[] = $course_title;
1083
1084
            // getting all the courses of the session
1085
            $sql = "SELECT *
1086
                    FROM $tbl_user AS u
1087
                    INNER JOIN $tbl_course_rel_user AS cu
1088
                    ON cu.user_id = u.user_id
1089
                    WHERE cu.c_id = '".$courseId."'";
1090
            $result = Database::query($sql);
1091
            $time_spent = 0;
1092
            $progress = 0;
1093
            $nb_progress_lp = 0;
1094
            $score = 0;
1095
            $nb_score_lp = 0;
1096
            $nb_messages = 0;
1097
            $nb_assignments = 0;
1098
            $last_login_date = false;
1099
            $total_score_obtained = 0;
1100
            $total_score_possible = 0;
1101
            $total_questions_answered = 0;
1102 View Code Duplication
            while ($row = Database::fetch_object($result)) {
1103
                // get time spent in the course and session
1104
                $time_spent += Tracking::get_time_spent_on_the_course($row->user_id, $courseId);
1105
                $progress_tmp = Tracking::get_avg_student_progress($row->user_id, $course_code, array(), null, true);
1106
                $progress += $progress_tmp[0];
1107
                $nb_progress_lp += $progress_tmp[1];
1108
                $score_tmp = Tracking::get_avg_student_score($row->user_id, $course_code, array(), null, true);
1109
                if(is_array($score_tmp)) {
1110
                    $score += $score_tmp[0];
1111
                    $nb_score_lp += $score_tmp[1];
1112
                }
1113
                $nb_messages += Tracking::count_student_messages($row->user_id, $course_code);
1114
                $nb_assignments += Tracking::count_student_assignments($row->user_id, $course_code);
1115
1116
                $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course($row->user_id, $courseInfo, null, false);
1117
                if($last_login_date_tmp != false && $last_login_date == false) { // TODO: To be cleaned.
1118
                    $last_login_date = $last_login_date_tmp;
1119
                } else if($last_login_date_tmp != false && $last_login_date == false) { // TODO: Repeated previous condition. To be cleaned.
1120
                    // Find the max and assign it to first_login_date
1121
                    if(strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1122
                        $last_login_date = $last_login_date_tmp;
1123
                    }
1124
                }
1125
1126
                $exercise_results_tmp = self::exercises_results($row->user_id, $course_code);
1127
                $total_score_obtained += $exercise_results_tmp['score_obtained'];
1128
                $total_score_possible += $exercise_results_tmp['score_possible'];
1129
                $total_questions_answered += $exercise_results_tmp['questions_answered'];
1130
            }
1131 View Code Duplication
            if($nb_progress_lp > 0) {
1132
                $avg_progress = round($progress / $nb_progress_lp, 2);
1133
            } else {
1134
                $avg_progress = 0;
1135
            }
1136 View Code Duplication
            if($nb_score_lp > 0) {
1137
                $avg_score = round($score / $nb_score_lp, 2);
1138
            } else {
1139
                $avg_score = '-';
1140
            }
1141
            if($last_login_date) {
1142
                $last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT, date_default_timezone_get());
1143
            } else {
1144
                $last_login_date = '-';
1145
            }
1146 View Code Duplication
            if($total_score_possible > 0) {
1147
                $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1148
            } else {
1149
                $total_score_percentage = 0;
1150
            }
1151
            // time spent in the course
1152
            $csv_row[] = api_time_to_hms($time_spent);
1153
            // student progress in course
1154
            $csv_row[] = $avg_progress;
1155
            // student score
1156
            $csv_row[] = $avg_score;
1157
            // student messages
1158
            $csv_row[] = $nb_messages;
1159
            // student assignments
1160
            $csv_row[] = $nb_assignments;
1161
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
1162
            $csv_row[] = $total_score_obtained;
1163
            $csv_row[] = $total_score_possible;
1164
            $csv_row[] = $total_questions_answered;
1165
            $csv_row[] = $total_score_percentage;
1166
            // last connection
1167
            $csv_row[] = $last_login_date;
1168
            $csv_content[] = $csv_row;
1169
        }
1170
        Export::arrayToCsv($csv_content, 'reporting_course_overview');
1171
        exit;
1172
    }
1173
1174
    /**
1175
     * Display a sortable table that contains an overview of all the reporting
1176
     * progress of all sessions and all courses the user is subscribed to
1177
     * @author Guillaume Viguier <[email protected]>
1178
     */
1179
    public static function display_tracking_session_overview()
1180
    {
1181
        $t_head = '<table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
1182
        $t_head .= '<tr>';
1183
        $t_head .= '<th width="155px" style="border-left:0;border-bottom:0"><span>'.get_lang('Course').'</span></th>';
1184
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgTimeSpentInTheCourse'), 6, true).'</span></th>';
1185
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgStudentsProgress'), 6, true).'</span></th>';
1186
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgCourseScore'), 6, true).'</span></th>';
1187
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfMessages'), 6, true).'</span></th>';
1188
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfAssignments'), 6, true).'</span></th>';
1189
        $t_head .= '<th width="105px" style="border-bottom:0"><span>'.get_lang('TotalExercisesScoreObtained').'</span></th>';
1190
        $t_head .= '<th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalExercisesAnswered'), 6, true).'</span></th>';
1191
        $t_head .= '<th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('LatestLogin').'</span></th>';
1192
        $t_head .= '</tr></table>';
1193
1194
        $addparams = array('view' => 'admin', 'display' => 'sessionoverview');
1195
        $table = new SortableTable(
1196
            'tracking_session_overview',
1197
            array('MySpace', 'get_total_number_sessions'),
1198
            array('MySpace', 'get_session_data_tracking_overview'),
1199
            1
1200
        );
1201
        $table->additional_parameters = $addparams;
1202
1203
        $table->set_header(0, '', false, null, array('style' => 'display: none'));
1204
        $table->set_header(1, get_lang('Session'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
1205
        $table->set_header(2, $t_head, false, array('style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'), array('style' => 'width:90%;padding:0;font-size:7.5pt;'));
1206
        $table->set_column_filter(2, array('MySpace', 'session_tracking_filter'));
1207
        $table->display();
1208
    }
1209
1210
    /**
1211
     * Get the total number of sessions
1212
     *
1213
     * @return integer Total number of sessions
1214
     */
1215
    public static function get_total_number_sessions()
1216
    {
1217
        return SessionManager::count_sessions(api_get_current_access_url_id());
1218
    }
1219
1220
    /**
1221
     * Get data for the sessions
1222
     *
1223
     * @param int $from Inferior limit
1224
     * @param int $numberItems Number of items to select
1225
     * @param string $column Column to order on
1226
     * @param string $direction Order direction
1227
     * @return array Results
1228
     */
1229
    public static function get_session_data_tracking_overview($from, $numberItems, $column, $direction)
1230
    {
1231
        $from = (int) $from;
1232
        $numberItems = (int) $numberItems;
1233
        $direction = Database::escape_string($direction);
1234
        $columnName = 'name';
1235
        if ($column === 1) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $column (string) and 1 (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
1236
            $columnName = 'id';
1237
        }
1238
1239
        $options = [
1240
            'order' => " $columnName $direction",
1241
            'limit' => " $from,$numberItems"
1242
        ];
1243
        $sessions = SessionManager::get_sessions_admin($options);
1244
        $list = [];
1245
        foreach ($sessions as $session) {
1246
            $list[] = [
1247
                '0' => $session['id'],
1248
                'col0' => $session['id'],
1249
                '1' => strip_tags($session['name']),
1250
                'col1' => strip_tags($session['name'])
1251
            ];
1252
        }
1253
1254
        return $list;
1255
    }
1256
1257
    /**
1258
     * Fills in session reporting data
1259
     *
1260
     * @param integer $user_id the id of the user
0 ignored issues
show
Bug introduced by
There is no parameter named $user_id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1261
     * @param array $url_params additonal url parameters
1262
     * @param array $row the row information (the other columns)
1263
     * @return string html code
1264
     */
1265
    public static function session_tracking_filter($session_id, $url_params, $row)
1266
    {
1267
        $session_id = $row[0];
1268
        // the table header
1269
        $return = '<table class="data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
1270
1271
        // database table definition
1272
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1273
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
1274
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1275
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1276
1277
        // getting all the courses of the user
1278
        $sql = "SELECT * FROM $tbl_course AS c
1279
                INNER JOIN $tbl_session_rel_course AS sc
1280
                ON sc.c_id = c.id
1281
                WHERE sc.session_id = '".$session_id."'";
1282
        $result = Database::query($sql);
1283
        while ($row = Database::fetch_object($result)) {
1284
            $courseId = $row->c_id;
1285
            $courseInfo = api_get_course_info_by_id($courseId);
1286
            $return .= '<tr>';
1287
            // course code
1288
            $return .= '    <td width="157px" >'.$row->title.'</td>';
1289
            // get the users in the course
1290
            $sql = "SELECT u.user_id
1291
                    FROM $tbl_user AS u
1292
                    INNER JOIN $tbl_session_rel_course_rel_user AS scu
1293
                    ON u.user_id = scu.user_id
1294
                    WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
1295
            $result_users = Database::query($sql);
1296
            $time_spent = 0;
1297
            $progress = 0;
1298
            $nb_progress_lp = 0;
1299
            $score = 0;
1300
            $nb_score_lp = 0;
1301
            $nb_messages = 0;
1302
            $nb_assignments = 0;
1303
            $last_login_date = false;
1304
            $total_score_obtained = 0;
1305
            $total_score_possible = 0;
1306
            $total_questions_answered = 0;
1307 View Code Duplication
            while ($row_user = Database::fetch_object($result_users)) {
1308
                // get time spent in the course and session
1309
                $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
1310
                $progress_tmp = Tracking::get_avg_student_progress($row_user->user_id, $row->code, array(), $session_id, true);
1311
                $progress += $progress_tmp[0];
1312
                $nb_progress_lp += $progress_tmp[1];
1313
                $score_tmp = Tracking::get_avg_student_score($row_user->user_id, $row->code, array(), $session_id, true);
1314
                if (is_array($score_tmp)) {
1315
                    $score += $score_tmp[0];
1316
                    $nb_score_lp += $score_tmp[1];
1317
                }
1318
                $nb_messages += Tracking::count_student_messages($row_user->user_id, $row->code, $session_id);
1319
                $nb_assignments += Tracking::count_student_assignments($row_user->user_id, $row->code, $session_id);
1320
                $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course($row_user->user_id, $courseInfo, $session_id, false);
1321
                if ($last_login_date_tmp != false && $last_login_date == false) {
1322
                    // TODO: To be cleaned.
1323
                    $last_login_date = $last_login_date_tmp;
1324
                } else if($last_login_date_tmp != false && $last_login_date != false) {
1325
                    // TODO: Repeated previous condition! To be cleaned.
1326
                    // Find the max and assign it to first_login_date
1327
                    if(strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1328
                        $last_login_date = $last_login_date_tmp;
1329
                    }
1330
                }
1331
1332
                $exercise_results_tmp = self::exercises_results($row_user->user_id, $row->code, $session_id);
1333
                $total_score_obtained += $exercise_results_tmp['score_obtained'];
1334
                $total_score_possible += $exercise_results_tmp['score_possible'];
1335
                $total_questions_answered += $exercise_results_tmp['questions_answered'];
1336
            }
1337 View Code Duplication
            if ($nb_progress_lp > 0) {
1338
                $avg_progress = round($progress / $nb_progress_lp, 2);
1339
            } else {
1340
                $avg_progress = 0;
1341
            }
1342 View Code Duplication
            if ($nb_score_lp > 0) {
1343
                $avg_score = round($score / $nb_score_lp, 2);
1344
            } else {
1345
                $avg_score = '-';
1346
            }
1347
            if ($last_login_date) {
1348
                $last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT, date_default_timezone_get());
1349
            } else {
1350
                $last_login_date = '-';
1351
            }
1352 View Code Duplication
            if ($total_score_possible > 0) {
1353
                $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1354
            } else {
1355
                $total_score_percentage = 0;
1356
            }
1357 View Code Duplication
            if ($total_score_percentage > 0) {
1358
                $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
1359
            } else {
1360
                $total_score = '-';
1361
            }
1362
            // time spent in the course
1363
            $return .= '    <td><div>'.api_time_to_hms($time_spent).'</div></td>';
1364
            // student progress in course
1365
            $return .= '    <td><div>'.$avg_progress.'</div></td>';
1366
            // student score
1367
            $return .= '    <td><div>'.$avg_score.'</div></td>';
1368
            // student messages
1369
            $return .= '    <td><div>'.$nb_messages.'</div></td>';
1370
            // student assignments
1371
            $return .= '    <td><div>'.$nb_assignments.'</div></td>';
1372
            // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
1373
            $return .= '<td width="105px;">'.$total_score.'</td>';
1374
            $return .= '<td>'.$total_questions_answered.'</td>';
1375
            // last connection
1376
            $return .= '    <td><div>'.$last_login_date.'</div></td>';
1377
            $return .= '<tr>';
1378
        }
1379
        $return .= '</table>';
1380
        return $return;
1381
    }
1382
1383
    /**
1384
     * This function exports the table that we see in display_tracking_session_overview()
1385
     *
1386
     */
1387
    public static function export_tracking_session_overview()
1388
    {
1389
        // database table definition
1390
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1391
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
1392
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1393
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1394
1395
        // the values of the sortable table
1396
        if ($_GET['tracking_session_overview_page_nr']) {
1397
            $from = $_GET['tracking_session_overview_page_nr'];
1398
        } else {
1399
            $from = 0;
1400
        }
1401
        if ($_GET['tracking_session_overview_column']) {
1402
            $orderby = $_GET['tracking_session_overview_column'];
1403
        } else {
1404
            $orderby = 0;
1405
        }
1406
1407
        if ($_GET['tracking_session_overview_direction']) {
1408
            $direction = $_GET['tracking_session_overview_direction'];
1409
        } else {
1410
            $direction = 'ASC';
1411
        }
1412
1413
        $session_data = self::get_session_data_tracking_overview($from, 1000, $orderby, $direction);
1414
1415
        $csv_content = array();
1416
1417
        // the first line of the csv file with the column headers
1418
        $csv_row = array();
1419
        $csv_row[] = get_lang('Session');
1420
        $csv_row[] = get_lang('Course');
1421
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse');
1422
        $csv_row[] = get_lang('AvgStudentsProgress');
1423
        $csv_row[] = get_lang('AvgCourseScore');
1424
        $csv_row[] = get_lang('TotalNumberOfMessages');
1425
        $csv_row[] = get_lang('TotalNumberOfAssignments');
1426
        $csv_row[] = get_lang('TotalExercisesScoreObtained');
1427
        $csv_row[] = get_lang('TotalExercisesScorePossible');
1428
        $csv_row[] = get_lang('TotalExercisesAnswered');
1429
        $csv_row[] = get_lang('TotalExercisesScorePercentage');
1430
        $csv_row[] = get_lang('LatestLogin');
1431
        $csv_content[] = $csv_row;
1432
1433
        // the other lines (the data)
1434
        foreach ($session_data as $key => $session) {
1435
            $session_id = $session[0];
1436
            $session_title = $session[1];
1437
1438
            // getting all the courses of the session
1439
            $sql = "SELECT * FROM $tbl_course AS c
1440
                    INNER JOIN $tbl_session_rel_course AS sc
1441
                    ON sc.c_id = c.id
1442
                    WHERE sc.session_id = '".$session_id."';";
1443
            $result = Database::query($sql);
1444
            while ($row = Database::fetch_object($result)) {
1445
                $courseId = $row->c_id;
1446
                $courseInfo = api_get_course_info_by_id($courseId);
1447
                $csv_row = array();
1448
                $csv_row[] = $session_title;
1449
                $csv_row[] = $row->title;
1450
                // get the users in the course
1451
                $sql = "SELECT scu.user_id
1452
                        FROM $tbl_user AS u
1453
                        INNER JOIN $tbl_session_rel_course_rel_user AS scu
1454
                        ON u.user_id = scu.user_id
1455
                        WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
1456
                $result_users = Database::query($sql);
1457
                $time_spent = 0;
1458
                $progress = 0;
1459
                $nb_progress_lp = 0;
1460
                $score = 0;
1461
                $nb_score_lp = 0;
1462
                $nb_messages = 0;
1463
                $nb_assignments = 0;
1464
                $last_login_date = false;
1465
                $total_score_obtained = 0;
1466
                $total_score_possible = 0;
1467
                $total_questions_answered = 0;
1468 View Code Duplication
                while($row_user = Database::fetch_object($result_users)) {
1469
                    // get time spent in the course and session
1470
                    $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
1471
                    $progress_tmp = Tracking::get_avg_student_progress($row_user->user_id, $row->code, array(), $session_id, true);
1472
                    $progress += $progress_tmp[0];
1473
                    $nb_progress_lp += $progress_tmp[1];
1474
                    $score_tmp = Tracking::get_avg_student_score($row_user->user_id, $row->code, array(), $session_id, true);
1475
                    if (is_array($score_tmp)) {
1476
                        $score += $score_tmp[0];
1477
                        $nb_score_lp += $score_tmp[1];
1478
                    }
1479
                    $nb_messages += Tracking::count_student_messages(
1480
                        $row_user->user_id,
1481
                        $row->code,
1482
                        $session_id
1483
                    );
1484
1485
                    $nb_assignments += Tracking::count_student_assignments(
1486
                        $row_user->user_id,
1487
                        $row->code,
1488
                        $session_id
1489
                    );
1490
1491
                    $last_login_date_tmp = Tracking:: get_last_connection_date_on_the_course(
1492
                        $row_user->user_id,
1493
                        $courseInfo,
1494
                        $session_id,
1495
                        false
1496
                    );
1497
                    if($last_login_date_tmp != false && $last_login_date == false) { // TODO: To be cleaned.
1498
                        $last_login_date = $last_login_date_tmp;
1499
                    } else if($last_login_date_tmp != false && $last_login_date == false) { // TODO: Repeated previous condition. To be cleaned.
1500
                        // Find the max and assign it to first_login_date
1501
                        if(strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
1502
                            $last_login_date = $last_login_date_tmp;
1503
                        }
1504
                    }
1505
1506
                    $exercise_results_tmp = self::exercises_results($row_user->user_id, $row->code, $session_id);
1507
                    $total_score_obtained += $exercise_results_tmp['score_obtained'];
1508
                    $total_score_possible += $exercise_results_tmp['score_possible'];
1509
                    $total_questions_answered += $exercise_results_tmp['questions_answered'];
1510
                }
1511 View Code Duplication
                if($nb_progress_lp > 0) {
1512
                    $avg_progress = round($progress / $nb_progress_lp, 2);
1513
                } else {
1514
                    $avg_progress = 0;
1515
                }
1516 View Code Duplication
                if($nb_score_lp > 0) {
1517
                    $avg_score = round($score / $nb_score_lp, 2);
1518
                } else {
1519
                    $avg_score = '-';
1520
                }
1521
                if($last_login_date) {
1522
                    $last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT, date_default_timezone_get());
1523
                } else {
1524
                    $last_login_date = '-';
1525
                }
1526 View Code Duplication
                if($total_score_possible > 0) {
1527
                    $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
1528
                } else {
1529
                    $total_score_percentage = 0;
1530
                }
1531 View Code Duplication
                if($total_score_percentage > 0) {
1532
                    $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
1533
                } else {
1534
                    $total_score = '-';
1535
                }
1536
                // time spent in the course
1537
                $csv_row[] = api_time_to_hms($time_spent);
1538
                // student progress in course
1539
                $csv_row[] = $avg_progress;
1540
                // student score
1541
                $csv_row[] = $avg_score;
1542
                // student messages
1543
                $csv_row[] = $nb_messages;
1544
                // student assignments
1545
                $csv_row[] = $nb_assignments;
1546
                // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
1547
                $csv_row[] = $total_score_obtained;
1548
                $csv_row[] = $total_score_possible;
1549
                $csv_row[] = $total_questions_answered;
1550
                $csv_row[] = $total_score_percentage;
1551
                // last connection
1552
                $csv_row[] = $last_login_date;
1553
                $csv_content[] = $csv_row;
1554
            }
1555
        }
1556
        Export::arrayToCsv($csv_content, 'reporting_session_overview');
1557
        exit;
1558
    }
1559
1560
    /**
1561
     * Get general information about the exercise performance of the user
1562
     * the total obtained score (all the score on all the questions)
1563
     * the maximum score that could be obtained
1564
     * the number of questions answered
1565
     * the success percentage
1566
     * @param integer $user_id the id of the user
1567
     * @param string $course_code the course code
1568
     * @return array
1569
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
1570
     * @version Dokeos 1.8.6
1571
     * @since November 2008
1572
     */
1573
    public static function exercises_results($user_id, $course_code, $session_id = false)
1574
    {
1575
        $courseId = api_get_course_int_id($course_code);
1576
        $sql = 'SELECT exe_result, exe_weighting
1577
                FROM '.Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES)."
1578
                WHERE 
1579
                    c_id = ' . $courseId . ' AND 
1580
                    exe_user_id = '".intval($user_id)."'";
1581
        if ($session_id !== false) {
1582
            $sql .= " AND session_id = '".$session_id."' ";
1583
        }
1584
        $result = Database::query($sql);
1585
        $score_obtained = 0;
1586
        $score_possible = 0;
1587
        $questions_answered = 0;
1588
        while ($row = Database::fetch_array($result)) {
1589
            $score_obtained += $row['exe_result'];
1590
            $score_possible += $row['exe_weighting'];
1591
            $questions_answered ++;
1592
        }
1593
1594
        if ($score_possible != 0) {
1595
            $percentage = round(($score_obtained / $score_possible * 100), 2);
1596
        } else {
1597
            $percentage = null;
1598
        }
1599
1600
        return array(
1601
            'score_obtained' => $score_obtained,
1602
            'score_possible' => $score_possible,
1603
            'questions_answered' => $questions_answered,
1604
            'percentage' => $percentage
1605
        );
1606
    }
1607
1608
    /**
1609
     * This function exports the table that we see in display_tracking_user_overview()
1610
     *
1611
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
1612
     * @version Dokeos 1.8.6
1613
     * @since October 2008
1614
     */
1615
    public static function export_tracking_user_overview()
1616
    {
1617
        // database table definitions
1618
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1619
        $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1620
1621
        // the values of the sortable table
1622
        if ($_GET['tracking_user_overview_page_nr']) {
1623
            $from = $_GET['tracking_user_overview_page_nr'];
1624
        } else {
1625
            $from = 0;
1626
        }
1627
        if ($_GET['tracking_user_overview_column']) {
1628
            $orderby = $_GET['tracking_user_overview_column'];
1629
        } else {
1630
            $orderby = 0;
1631
        }
1632
        if ($is_western_name_order != api_is_western_name_order() && ($orderby == 1 || $orderby == 2)) {
1633
            // Swapping the sorting column if name order for export is different than the common name order.
1634
            $orderby = 3 - $orderby;
1635
        }
1636
        if ($_GET['tracking_user_overview_direction']) {
1637
            $direction = $_GET['tracking_user_overview_direction'];
1638
        } else {
1639
            $direction = 'ASC';
1640
        }
1641
1642
        $user_data = self::get_user_data_tracking_overview($from, 1000, $orderby, $direction);
1643
1644
        // the first line of the csv file with the column headers
1645
        $csv_row = array();
1646
        $csv_row[] = get_lang('OfficialCode');
1647 View Code Duplication
        if ($is_western_name_order) {
1648
            $csv_row[] = get_lang('FirstName', '');
1649
            $csv_row[] = get_lang('LastName', '');
1650
        } else {
1651
            $csv_row[] = get_lang('LastName', '');
1652
            $csv_row[] = get_lang('FirstName', '');
1653
        }
1654
        $csv_row[] = get_lang('LoginName');
1655
        $csv_row[] = get_lang('CourseCode');
1656
        // the additional user defined fields (only those that were selected to be exported)
1657
1658
        $fields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
1659
1660
        if (is_array($_SESSION['additional_export_fields'])) {
1661
            foreach ($_SESSION['additional_export_fields'] as $key => $extra_field_export) {
1662
                $csv_row[] = $fields[$extra_field_export][3];
1663
                $field_names_to_be_exported[] = 'extra_'.$fields[$extra_field_export][1];
1664
            }
1665
        }
1666
        $csv_row[] = get_lang('AvgTimeSpentInTheCourse', '');
1667
        $csv_row[] = get_lang('AvgStudentsProgress', '');
1668
        $csv_row[] = get_lang('AvgCourseScore', '');
1669
        $csv_row[] = get_lang('AvgExercisesScore', '');
1670
        $csv_row[] = get_lang('AvgMessages', '');
1671
        $csv_row[] = get_lang('AvgAssignments', '');
1672
        $csv_row[] = get_lang('TotalExercisesScoreObtained', '');
1673
        $csv_row[] = get_lang('TotalExercisesScorePossible', '');
1674
        $csv_row[] = get_lang('TotalExercisesAnswered', '');
1675
        $csv_row[] = get_lang('TotalExercisesScorePercentage', '');
1676
        $csv_row[] = get_lang('FirstLogin', '');
1677
        $csv_row[] = get_lang('LatestLogin', '');
1678
        $csv_content[] = $csv_row;
1679
1680
        // the other lines (the data)
1681
        foreach ($user_data as $key => $user) {
1682
            // getting all the courses of the user
1683
            $sql = "SELECT * FROM $tbl_course_user
1684
                    WHERE user_id = '".intval($user[4])."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
1685
            $result = Database::query($sql);
1686
            while ($row = Database::fetch_row($result)) {
1687
                $courseInfo = api_get_course_info($row['course_code']);
1688
                $courseId = $courseInfo['real_id'];
1689
1690
                $csv_row = array();
1691
                // user official code
1692
                $csv_row[] = $user[0];
1693
                // user first|last name
1694
                $csv_row[] = $user[1];
1695
                // user last|first name
1696
                $csv_row[] = $user[2];
1697
                // user login name
1698
                $csv_row[] = $user[3];
1699
                // course code
1700
                $csv_row[] = $row[0];
1701
                // the additional defined user fields
1702
                $extra_fields = self::get_user_overview_export_extra_fields($user[4]);
1703
1704
                if (is_array($field_names_to_be_exported)) {
1705
                    foreach ($field_names_to_be_exported as $key => $extra_field_export) {
1706
                        $csv_row[] = $extra_fields[$extra_field_export];
1707
                    }
1708
                }
1709
                // time spent in the course
1710
                $csv_row[] = api_time_to_hms(Tracking::get_time_spent_on_the_course ($user[4], $courseId));
1711
                // student progress in course
1712
                $csv_row[] = round(Tracking::get_avg_student_progress ($user[4], $row[0]), 2);
1713
                // student score
1714
                $csv_row[] = round(Tracking::get_avg_student_score($user[4], $row[0]), 2);
1715
                // student tes score
1716
                $csv_row[] = round(Tracking::get_avg_student_exercise_score($user[4], $row[0]), 2);
1717
                // student messages
1718
                $csv_row[] = Tracking::count_student_messages($user[4], $row[0]);
1719
                // student assignments
1720
                $csv_row[] = Tracking::count_student_assignments ($user[4], $row[0]);
1721
                // student exercises results
1722
                $exercises_results = self::exercises_results($user[4], $row[0]);
1723
                $csv_row[] = $exercises_results['score_obtained'];
1724
                $csv_row[] = $exercises_results['score_possible'];
1725
                $csv_row[] = $exercises_results['questions_answered'];
1726
                $csv_row[] = $exercises_results['percentage'];
1727
                // first connection
1728
                $csv_row[] = Tracking::get_first_connection_date_on_the_course ($user[4], $courseId);
1729
                // last connection
1730
                $csv_row[] = strip_tags(Tracking::get_last_connection_date_on_the_course($user[4], $courseInfo));
1731
1732
                $csv_content[] = $csv_row;
1733
            }
1734
        }
1735
        Export::arrayToCsv($csv_content, 'reporting_user_overview');
1736
        exit;
1737
    }
1738
1739
    /**
1740
     * Get data for courses list in sortable with pagination
1741
     * @return array
1742
     */
1743
    public static function get_course_data($from, $number_of_items, $column, $direction)
1744
    {
1745
        global $courses, $csv_content, $charset, $session_id;
1746
1747
        // definition database tables
1748
        $tbl_course                 = Database::get_main_table(TABLE_MAIN_COURSE);
1749
        $tbl_course_user            = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1750
        $tbl_session_course_user    = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1751
1752
        $course_data = array();
1753
        $courses_code = array_keys($courses);
1754
1755
        foreach ($courses_code as &$code) {
1756
            $code = "'$code'";
1757
        }
1758
1759
        // get all courses with limit
1760
        $sql = "SELECT course.code as col1, course.title as col2
1761
                FROM $tbl_course course
1762
                WHERE course.code IN (".implode(',',$courses_code).")";
1763
1764
        if (!in_array($direction, array('ASC','DESC'))) $direction = 'ASC';
1765
1766
        $column = intval($column);
1767
        $from = intval($from);
1768
        $number_of_items = intval($number_of_items);
1769
        $sql .= " ORDER BY col$column $direction ";
1770
        $sql .= " LIMIT $from,$number_of_items";
1771
1772
        $res = Database::query($sql);
1773
        while ($row_course = Database::fetch_row($res)) {
1774
            $course_code = $row_course[0];
1775
            $courseInfo = api_get_course_info($course_code);
1776
            $courseId = $courseInfo['real_id'];
1777
            $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;
1778
1779
            // students directly subscribed to the course
1780
            if (empty($session_id)) {
1781
                $sql = "SELECT user_id
1782
                        FROM $tbl_course_user as course_rel_user
1783
                        WHERE
1784
                            course_rel_user.status='5' AND
1785
                            course_rel_user.c_id = '$courseId'";
1786
            } else {
1787
                $sql = "SELECT user_id FROM $tbl_session_course_user srcu
1788
                        WHERE
1789
                            c_id = '$courseId' AND
1790
                            session_id = '$session_id' AND
1791
                            status<>2";
1792
            }
1793
            $rs = Database::query($sql);
1794
            $users = array();
1795
            while ($row = Database::fetch_array($rs)) {
1796
                $users[] = $row['user_id'];
1797
            }
1798
1799
            if (count($users) > 0) {
1800
                $nb_students_in_course = count($users);
1801
                $avg_assignments_in_course  = Tracking::count_student_assignments($users, $course_code, $session_id);
1802
                $avg_messages_in_course     = Tracking::count_student_messages($users, $course_code, $session_id);
1803
                $avg_progress_in_course     = Tracking::get_avg_student_progress($users, $course_code, array(), $session_id);
1804
                $avg_score_in_course        = Tracking::get_avg_student_score($users, $course_code, array(), $session_id);
1805
                $avg_score_in_exercise      = Tracking::get_avg_student_exercise_score($users, $course_code, 0, $session_id);
1806
                $avg_time_spent_in_course   = Tracking::get_time_spent_on_the_course($users, $courseInfo['real_id'], $session_id);
1807
1808
                $avg_progress_in_course = round($avg_progress_in_course / $nb_students_in_course, 2);
1809
                if (is_numeric($avg_score_in_course)) {
1810
                    $avg_score_in_course = round($avg_score_in_course / $nb_students_in_course, 2);
1811
                }
1812
                $avg_time_spent_in_course = api_time_to_hms($avg_time_spent_in_course / $nb_students_in_course);
1813
1814
            } else {
1815
                $avg_time_spent_in_course = null;
1816
                $avg_progress_in_course = null;
1817
                $avg_score_in_course = null;
1818
                $avg_score_in_exercise = null;
1819
                $avg_messages_in_course = null;
1820
                $avg_assignments_in_course = null;
1821
            }
1822
            $table_row = array();
1823
            $table_row[] = $row_course[1];
1824
            $table_row[] = $nb_students_in_course;
1825
            $table_row[] = $avg_time_spent_in_course;
1826
            $table_row[] = is_null($avg_progress_in_course) ? '' : $avg_progress_in_course.'%';
1827
            $table_row[] = is_null($avg_score_in_course) ? '' : $avg_score_in_course.'%';
1828
            $table_row[] = is_null($avg_score_in_exercise) ? '' : $avg_score_in_exercise.'%';
1829
            $table_row[] = $avg_messages_in_course;
1830
            $table_row[] = $avg_assignments_in_course;
1831
1832
            //set the "from" value to know if I access the Reporting by the chamilo tab or the course link
1833
            $table_row[] = '<center><a href="../../tracking/courseLog.php?cidReq=' .$course_code.'&from=myspace&id_session='.$session_id.'">
1834
                             '.Display::return_icon('2rightarrow.png').'
1835
                             </a>
1836
                            </center>';
1837
            $csv_content[] = array(
1838
                api_html_entity_decode($row_course[1], ENT_QUOTES, $charset),
1839
                $nb_students_in_course,
1840
                $avg_time_spent_in_course,
1841
                is_null($avg_progress_in_course) ? null : $avg_progress_in_course.'%',
1842
                is_null($avg_score_in_course) ? null : is_numeric($avg_score_in_course) ? $avg_score_in_course.'%' : $avg_score_in_course ,
1843
                is_null($avg_score_in_exercise) ? null : $avg_score_in_exercise.'%',
1844
                $avg_messages_in_course,
1845
                $avg_assignments_in_course,
1846
            );
1847
            $course_data[] = $table_row;
1848
        }
1849
        return $course_data;
1850
    }
1851
1852
    /**
1853
     * Get the number of users of the platform
1854
     *
1855
     * @return integer
1856
     *
1857
     */
1858
    public static function get_number_of_users_tracking_overview()
1859
    {
1860
        return UserManager::get_number_of_users(0, api_get_current_access_url_id());
1861
    }
1862
1863
    /**
1864
     * Get all the data for the sortable table of the reporting progress of
1865
     * all users and all the courses the user is subscribed to.
1866
     *
1867
     * @param int $from
1868
     * @param int $numberItems
1869
     * @param int $column
1870
     * @param string $direction
1871
     */
1872
    public static function get_user_data_tracking_overview($from, $numberItems, $column, $direction)
1873
    {
1874
        $isWestern = api_is_western_name_order();
1875
        switch ($column) {
1876
            case '0':
1877
                $column = 'official_code';
1878
                break;
1879
            case '1':
1880
                $column = $isWestern ? 'firstname' : 'lastname';
1881
                break;
1882
            case '2':
1883
                $column = $isWestern ? 'lastname' : 'firstname';
1884
                break;
1885
            case '3':
1886
                $column = 'username';
1887
                break;
1888
            case '4':
1889
                $column = 'username';
1890
                break;
1891
        }
1892
1893
        $order = [
1894
            "$column $direction"
1895
        ];
1896
        $userList = UserManager::get_user_list([], $order, $from, $numberItems);
1897
        $return = [];
1898
        foreach ($userList as $user) {
1899
            $firstPosition = $user['lastname'];
1900
            $secondPosition = $user['firstname'];
1901
            if ($isWestern) {
1902
                $firstPosition = $user['firstname'];
1903
                $secondPosition = $user['lastname'];
1904
            }
1905
            $return[] = [
1906
                '0' => $user['official_code'],
1907
                'col0' => $user['official_code'],
1908
                '1' => $firstPosition,
1909
                'col1' => $firstPosition,
1910
                '2' => $secondPosition,
1911
                'col2' => $secondPosition,
1912
                '3' => $user['username'],
1913
                'col3' => $user['username'],
1914
                '4' => $user['user_id'],
1915
                'col4' => $user['user_id']
1916
            ];
1917
        }
1918
1919
        return $return;
1920
    }
1921
1922
    /**
1923
     * Get all information that the user with user_id = $user_data has
1924
     * entered in the additionally defined profile fields
1925
     * @param integer $user_id the id of the user
1926
     * @return array
1927
     * @author Patrick Cool <[email protected]>, Ghent University, Belgium
1928
     * @version Dokeos 1.8.6
1929
     * @since November 2008
1930
     */
1931
    public static function get_user_overview_export_extra_fields($user_id)
1932
    {
1933
        // include the user manager
1934
        $extra_data = UserManager::get_extra_user_data($user_id, true);
1935
        return $extra_data;
1936
    }
1937
    /**
1938
     * Checks if a username exist in the DB otherwise it create a "double"
1939
     * i.e. if we look into for jmontoya but the user's name already exist we create the user jmontoya2
1940
     * the return array will be array(username=>'jmontoya', sufix='2')
1941
     * @param string firstname
1942
     * @param string lastname
1943
     * @param string username
1944
     * @return array with the username, the sufix
1945
     * @author Julio Montoya Armas
1946
     */
1947
    public static function make_username($firstname, $lastname, $username, $language = null, $encoding = null)
1948
    {
1949
        // if username exist
1950
        if (!UserManager::is_username_available($username) || empty($username)) {
1951
            $i = 0;
1952
            while (1) {
1953
                if ($i == 0) {
1954
                    $sufix = '';
1955
                } else {
1956
                    $sufix = $i;
1957
                }
1958
                $desired_username = UserManager::create_username(
1959
                    $firstname,
1960
                    $lastname,
1961
                    $language,
1962
                    $encoding
1963
                );
1964
                if (UserManager::is_username_available($desired_username.$sufix)) {
1965
                    break;
1966
                } else {
1967
                    $i++;
1968
                }
1969
            }
1970
            $username_array = array('username' => $desired_username , 'sufix' => $sufix);
1971
            return $username_array;
1972
        } else {
1973
            $username_array = array('username' => $username, 'sufix' => '');
1974
            return $username_array;
1975
        }
1976
    }
1977
1978
    /**
1979
     * Checks if there are repeted users in a given array
1980
     * @param  array $usernames list of the usernames in the uploaded file
1981
     * @param  array $user_array['username'] and $user_array['sufix'] where sufix is the number part in a login i.e -> jmontoya2
0 ignored issues
show
Documentation introduced by
There is no parameter named $user_array['username']. Did you maybe mean $user_array?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1982
     * @return array with the $usernames array and the $user_array array
1983
     * @author Julio Montoya
1984
     */
1985
    public static function check_user_in_array($usernames, $user_array)
1986
    {
1987
        $user_list = array_keys($usernames);
1988
        $username = $user_array['username'].$user_array['sufix'];
1989
1990
        if (in_array($username, $user_list)) {
1991
            $user_array['sufix'] += $usernames[$username];
1992
            $usernames[$username]++;
1993
        } else {
1994
            $usernames[$username] = 1;
1995
        }
1996
        $result_array = array($usernames, $user_array);
1997
        return $result_array;
1998
    }
1999
2000
    /**
2001
     * Checks whether a username has been already subscribed in a session.
2002
     * @param string $username a given username
2003
     * @param array $course_list the array with the course list id
2004
     * @param int $id_session the session id
2005
     * @return int 0 if the user is not subscribed otherwise it returns the user_id of the given username
2006
     * @author Julio Montoya
2007
     */
2008
    public static function user_available_in_session($username, $course_list, $id_session)
2009
    {
2010
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2011
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2012
        $id_session = intval($id_session);
2013
        $username = Database::escape_string($username);
2014
        foreach ($course_list as $courseId) {
2015
            $courseId = intval($courseId);
2016
            $sql = " SELECT u.user_id FROM $tbl_session_rel_course_rel_user rel
2017
                     INNER JOIN $table_user u
2018
                     ON (rel.user_id = u.user_id)
2019
                     WHERE
2020
                        rel.session_id='$id_session' AND
2021
                        u.status='5' AND
2022
                        u.username ='$username' AND
2023
                        rel.c_id='$courseId'";
2024
            $rs = Database::query($sql);
2025
            if (Database::num_rows($rs) > 0) {
2026
                return Database::result($rs, 0, 0);
2027
            } else {
2028
                return 0;
2029
            }
2030
        }
2031
        return 0;
2032
    }
2033
2034
    /**
2035
     * This function checks whether some users in the uploaded file
2036
     * repeated and creates unique usernames if necesary.
2037
     * A case: Within the file there is an user repeted twice (Julio Montoya / Julio Montoya)
2038
     * and the username fields are empty.
2039
     * Then, this function would create unique usernames based on the first and the last name.
2040
     * Two users wiould be created - jmontoya and jmontoya2.
2041
     * Of course, if in the database there is a user with the name jmontoya,
2042
     * the newly created two users registered would be jmontoya2 and jmontoya3.
2043
     * @param $users list of users
2044
     * @return array
2045
     * @author Julio Montoya Armas
2046
     */
2047
    function check_all_usernames($users, $course_list, $id_session)
2048
    {
2049
        $table_user = Database::get_main_table(TABLE_MAIN_USER);
2050
        $usernames = array();
2051
        $new_users = array();
2052
        foreach ($users as $index => $user) {
2053
            $desired_username = array();
2054
            if (empty($user['UserName'])) {
2055
                $desired_username = self::make_username($user['FirstName'], $user['LastName'], '');
2056
                $pre_username = $desired_username['username'].$desired_username['sufix'];
2057
                $user['UserName'] = $pre_username;
2058
                $user['create'] = '1';
2059
            } else {
2060
                if (UserManager::is_username_available($user['UserName'])) {
2061
                    $desired_username = self::make_username($user['FirstName'], $user['LastName'], $user['UserName']);
2062
                    $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
2063
                    $user['create'] = '1';
2064 View Code Duplication
                } else {
2065
                    $is_session_avail = self::user_available_in_session($user['UserName'], $course_list, $id_session);
2066
                    if ($is_session_avail == 0) {
2067
                        $user_name = $user['UserName'];
2068
                        $sql_select = "SELECT user_id FROM $table_user WHERE username ='$user_name' ";
2069
                        $rs = Database::query($sql_select);
2070
                        $user['create'] = Database::result($rs, 0, 0); // This should be the ID because the user exists.
2071
                    } else {
2072
                        $user['create'] = $is_session_avail;
2073
                    }
2074
                }
2075
            }
2076
            // Usernames is the current list of users in the file.
2077
            $result_array = self::check_user_in_array($usernames, $desired_username);
2078
            $usernames = $result_array[0];
2079
            $desired_username = $result_array[1];
2080
            $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
2081
            $new_users[] = $user;
2082
        }
2083
        return $new_users;
2084
    }
2085
2086
    /**
2087
     * This functions checks whether there are users that are already
2088
     * registered in the DB by different creator than the current coach.
2089
     * @param string a given username
2090
     * @param array $users the array with the course list ids
2091
     * @return array
2092
     * @author Julio Montoya Armas
2093
     */
2094
    public function get_user_creator($users)
2095
    {
2096
        $errors = array();
2097
        foreach ($users as $index => $user) {
2098
            // database table definition
2099
            $table_user = Database::get_main_table(TABLE_MAIN_USER);
2100
            $username = Database::escape_string($user['UserName']);
2101
            $sql = "SELECT creator_id FROM $table_user WHERE username='$username' ";
2102
2103
            $rs = Database::query($sql);
2104
            $creator_id = Database::result($rs, 0, 0);
2105
            // check if we are the creators or not
2106
            if ($creator_id != '') {
2107
                if ($creator_id != api_get_user_id()) {
2108
                    $user['error'] = get_lang('UserAlreadyRegisteredByOtherCreator');
2109
                    $errors[] = $user;
2110
                }
2111
            }
2112
        }
2113
2114
        return $errors;
2115
    }
2116
2117
    /**
2118
     * Validates imported data.
2119
     * @param list of users
2120
     */
2121
    function validate_data($users, $id_session = null)
2122
    {
2123
        $errors = array();
2124
        $new_users = array();
2125
        foreach ($users as $index => $user) {
2126
            // 1. Check whether mandatory fields are set.
2127
            $mandatory_fields = array('LastName', 'FirstName');
2128
            if (api_get_setting('registration', 'email') == 'true') {
2129
                $mandatory_fields[] = 'Email';
2130
            }
2131
2132
            foreach ($mandatory_fields as $key => $field) {
2133
                if (!isset ($user[$field]) || strlen($user[$field]) == 0) {
2134
                    $user['error'] = get_lang($field.'Mandatory');
2135
                    $errors[] = $user;
2136
                }
2137
            }
2138
            // 2. Check whether the username is too long.
2139 View Code Duplication
            if (UserManager::is_username_too_long($user['UserName'])) {
2140
                $user['error'] = get_lang('UserNameTooLong');
2141
                $errors[] = $user;
2142
            }
2143
2144
            $user['UserName'] = trim($user['UserName']);
2145
2146
            if (empty($user['UserName'])) {
2147
                $user['UserName'] = UserManager::create_username($user['FirstName'], $user['LastName']);
2148
            }
2149
            $new_users[] = $user;
2150
        }
2151
        $results = array('errors' => $errors, 'users' => $new_users);
2152
        return $results;
2153
    }
2154
2155
    /**
2156
     * Adds missing user-information (which isn't required, like password, etc).
2157
     */
2158
    function complete_missing_data($user)
2159
    {
2160
        // 1. Generate a password if it is necessary.
2161 View Code Duplication
        if (!isset ($user['Password']) || strlen($user['Password']) == 0) {
2162
            $user['Password'] = api_generate_password();
2163
        }
2164
2165
        return $user;
2166
    }
2167
2168
    /**
2169
     * Saves imported data.
2170
     */
2171
    public function save_data($users, $course_list, $id_session)
2172
    {
2173
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2174
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2175
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2176
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2177
2178
        $id_session = intval($id_session);
2179
        $sendMail = $_POST['sendMail'] ? 1 : 0;
2180
2181
        // Adding users to the platform.
2182
        $new_users = array();
2183
        foreach ($users as $index => $user) {
2184
            $user = self::complete_missing_data($user);
2185
            // coach only will registered users
2186
            $default_status = STUDENT;
2187
            if ($user['create'] == COURSEMANAGER) {
2188
                $user['id'] = UserManager:: create_user(
2189
                    $user['FirstName'],
2190
                    $user['LastName'],
2191
                    $default_status,
2192
                    $user['Email'],
2193
                    $user['UserName'],
2194
                    $user['Password'],
2195
                    $user['OfficialCode'],
2196
                    api_get_setting('PlatformLanguage'),
2197
                    $user['PhoneNumber'],
2198
                    ''
2199
                );
2200
                $user['added_at_platform'] = 1;
2201
            } else {
2202
                $user['id'] = $user['create'];
2203
                $user['added_at_platform'] = 0;
2204
            }
2205
            $new_users[] = $user;
2206
        }
2207
        // Update user list.
2208
        $users = $new_users;
2209
2210
        // Inserting users.
2211
        $super_list = array();
2212
        foreach ($course_list as $enreg_course) {
2213
            $nbr_users = 0;
2214
            $new_users = array();
2215
            $enreg_course = Database::escape_string($enreg_course);
2216
            foreach ($users as $index => $user) {
2217
                $userid = intval($user['id']);
2218
                $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user(session_id, c_id, user_id)
2219
                        VALUES('$id_session','$enreg_course','$userid')";
2220
                $course_session = array('course' => $enreg_course, 'added' => 1);
2221
2222
                $result = Database::query($sql);
2223
                if (Database::affected_rows($result)) {
2224
                    $nbr_users++;
2225
                }
2226
                $new_users[] = $user;
2227
            }
2228
            $super_list[] = $new_users;
2229
2230
            //update the nbr_users field
2231
            $sql_select = "SELECT COUNT(user_id) as nbUsers FROM $tbl_session_rel_course_rel_user
2232
                           WHERE session_id='$id_session' AND c_id='$enreg_course'";
2233
            $rs = Database::query($sql_select);
2234
            list($nbr_users) = Database::fetch_array($rs);
2235
            $sql_update = "UPDATE $tbl_session_rel_course SET nbr_users=$nbr_users
2236
                           WHERE session_id='$id_session' AND c_id='$enreg_course'";
2237
            Database::query($sql_update);
2238
2239
            $sql_update = "UPDATE $tbl_session SET nbr_users= '$nbr_users' WHERE id='$id_session'";
2240
            Database::query($sql_update);
2241
        }
2242
2243
        $new_users = array();
2244
        foreach ($users as $index => $user) {
2245
            $userid = $user['id'];
2246
            $sql_insert = "INSERT IGNORE INTO $tbl_session_rel_user(session_id, user_id, registered_at)
2247
                           VALUES ('$id_session','$userid', '" . api_get_utc_datetime() . "')";
2248
            Database::query($sql_insert);
2249
            $user['added_at_session'] = 1;
2250
            $new_users[] = $user;
2251
        }
2252
2253
        $users = $new_users;
2254
        $registered_users = get_lang('FileImported').'<br /> Import file results : <br />';
2255
        // Sending emails.
2256
        $addedto = '';
2257
        if ($sendMail) {
2258
            $i = 0;
2259
            foreach ($users as $index => $user) {
2260
                $emailsubject = '['.api_get_setting('siteName').'] '.get_lang('YourReg').' '.api_get_setting('siteName');
2261
                $emailbody = get_lang('Dear').' '.
2262
                    api_get_person_name($user['FirstName'], $user['LastName']).",\n\n".
2263
                    get_lang('YouAreReg')." ".api_get_setting('siteName')." ".get_lang('WithTheFollowingSettings')."\n\n".
2264
                    get_lang('Username')." : $user[UserName]\n".
2265
                    get_lang('Pass')." : $user[Password]\n\n".
2266
                    get_lang('Address')." ".api_get_setting('siteName')." ".get_lang('Is')." : ".api_get_path(WEB_PATH)." \n\n".
2267
                    get_lang('Problem')."\n\n".
2268
                    get_lang('SignatureFormula').",\n\n".
2269
                    api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))."\n".
2270
                    get_lang('Manager')." ".api_get_setting('siteName')."\nT. ".
2271
                    api_get_setting('administratorTelephone')."\n".get_lang('Email')." : ".api_get_setting('emailAdministrator');
2272
2273
                api_mail_html(
2274
                    api_get_person_name($user['FirstName'], $user['LastName'], null, PERSON_NAME_EMAIL_ADDRESS),
2275
                    $user['Email'],
2276
                    $emailsubject,
2277
                    $emailbody
2278
                );
2279
                $userInfo = api_get_user_info($user['id']);
2280
2281 View Code Duplication
                if (($user['added_at_platform'] == 1  && $user['added_at_session'] == 1) || $user['added_at_session'] == 1) {
2282
                    if ($user['added_at_platform'] == 1) {
2283
                        $addedto = get_lang('UserCreatedPlatform');
2284
                    } else  {
2285
                        $addedto = '          ';
2286
                    }
2287
2288
                    if ($user['added_at_session'] == 1) {
2289
                        $addedto .= get_lang('UserInSession');
2290
                    }
2291
                } else {
2292
                    $addedto = get_lang('UserNotAdded');
2293
                }
2294
2295
                $registered_users .= UserManager::getUserProfileLink($userInfo)." - ".$addedto.'<br />';
0 ignored issues
show
Security Bug introduced by
It seems like $userInfo defined by api_get_user_info($user['id']) on line 2279 can also be of type false; however, UserManager::getUserProfileLink() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
2296
            }
2297
        } else {
2298
            $i = 0;
2299
            foreach ($users as $index => $user) {
2300
                $userInfo = api_get_user_info($user['id']);
2301 View Code Duplication
                if (($user['added_at_platform'] == 1 && $user['added_at_session'] == 1) || $user['added_at_session'] == 1) {
2302
                    if ($user['added_at_platform'] == 1) {
2303
                        $addedto = get_lang('UserCreatedPlatform');
2304
                    } else {
2305
                        $addedto = '          ';
2306
                    }
2307
2308
                    if ($user['added_at_session'] == 1) {
2309
                        $addedto .= ' '.get_lang('UserInSession');
2310
                    }
2311
                } else {
2312
                    $addedto = get_lang('UserNotAdded');
2313
                }
2314
                $registered_users .= "<a href=\"../user/userInfo.php?uInfo=".$user['id']."\">".api_get_person_name($user['FirstName'], $user['LastName'])."</a> - ".$addedto.'<br />';
2315
            }
2316
        }
2317
        Display::addFlash(Display::return_message($registered_users));
2318
        header('Location: course.php?id_session='.$id_session);
2319
        exit;
2320
    }
2321
2322
    /**
2323
     * Reads CSV-file.
2324
     * @param string $file Path to the CSV-file
2325
     * @return array All userinformation read from the file
2326
     */
2327 View Code Duplication
    function parse_csv_data($file)
2328
    {
2329
        $users = Import::csvToArray($file);
0 ignored issues
show
Deprecated Code introduced by
The method Import::csvToArray() has been deprecated with message: use cvs_reader instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
2330
        foreach ($users as $index => $user) {
2331
            if (isset ($user['Courses'])) {
2332
                $user['Courses'] = explode('|', trim($user['Courses']));
2333
            }
2334
            $users[$index] = $user;
2335
        }
2336
        return $users;
2337
    }
2338
2339
    /**
2340
     * XML-parser: the handler at the beginning of element.
2341
     */
2342 View Code Duplication
    function element_start($parser, $data)
2343
    {
2344
        $data = api_utf8_decode($data);
2345
        global $user;
2346
        global $current_tag;
2347
        switch ($data) {
2348
            case 'Contact' :
2349
                $user = array ();
2350
                break;
2351
            default:
2352
                $current_tag = $data;
2353
        }
2354
    }
2355
2356
    /**
2357
     * XML-parser: the handler at the end of element.
2358
     */
2359
    function element_end($parser, $data) {
2360
        $data = api_utf8_decode($data);
2361
        global $user;
2362
        global $users;
2363
        global $current_value;
2364
        global $purification_option_for_usernames;
2365
        $user[$data] = $current_value;
2366
        switch ($data) {
2367
            case 'Contact' :
2368
                $user['UserName'] = UserManager::purify_username($user['UserName'], $purification_option_for_usernames);
2369
                $users[] = $user;
2370
                break;
2371
            default:
2372
                $user[$data] = $current_value;
2373
                break;
2374
        }
2375
    }
2376
2377
    /**
2378
     * XML-parser: the handler for character data.
2379
     */
2380
    function character_data($parser, $data) {
2381
        $data = trim(api_utf8_decode($data));
2382
        global $current_value;
2383
        $current_value = $data;
2384
    }
2385
2386
    /**
2387
     * Reads XML-file.
2388
     * @param string $file Path to the XML-file
2389
     * @return array All userinformation read from the file
2390
     */
2391
    function parse_xml_data($file) {
2392
        global $current_tag;
2393
        global $current_value;
2394
        global $user;
2395
        global $users;
2396
        $users = array ();
2397
        $parser = xml_parser_create('UTF-8');
2398
        xml_set_element_handler($parser, array('MySpace','element_start'), array('MySpace','element_end'));
2399
        xml_set_character_data_handler($parser, "character_data");
2400
        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
2401
        xml_parse($parser, api_utf8_encode_xml(file_get_contents($file)));
2402
        xml_parser_free($parser);
2403
        return $users;
2404
    }
2405
2406
    public static function displayTrackingAccessOverView($courseId, $sessionId, $studentId)
2407
    {
2408
        $courseId = intval($courseId);
2409
        $sessionId = intval($sessionId);
2410
        $studentId = intval($studentId);
2411
2412
        $em = Database::getManager();
2413
        $sessionRepo = $em->getRepository('ChamiloCoreBundle:Session');
2414
2415
        $courseList = [];
2416
        $sessionList = [];
2417
        $studentList = [];
2418
2419
        if (!empty($courseId)) {
2420
            $course = $em->find('ChamiloCoreBundle:Course', $courseId);
2421
2422
            $courseList[$course->getId()] = $course->getTitle();
2423
        }
2424
2425
        if (!empty($sessionId)) {
2426
            $session = $em->find('ChamiloCoreBundle:Session', $sessionId);
2427
2428
            $sessionList[$session->getId()] = $session->getName();
2429
        }
2430
2431
        if (!empty($studentId)) {
2432
            $student = $em->find('ChamiloUserBundle:User', $studentId);
2433
2434
            $studentList[$student->getId()] = $student->getCompleteName();
2435
        }
2436
2437
        $form = new FormValidator('access_overview', 'GET');
2438
        $form->addElement(
2439
            'select_ajax',
2440
            'course_id',
2441
            get_lang('SearchCourse'),
2442
            $courseList,
2443
            [
2444
                'url' => api_get_path(WEB_AJAX_PATH) . 'course.ajax.php?' . http_build_query([
2445
                    'a' => 'search_course_by_session_all',
2446
                    'session_id' => $sessionId
2447
                ])
2448
            ]
2449
        );
2450
        $form->addElement(
2451
            'select_ajax',
2452
            'session_id',
2453
            get_lang('SearchSession'),
2454
            $sessionList,
2455
            [
2456
                'url_function' => "
2457
                    function () {
2458
                        var params = $.param({
2459
                            a: 'search_session_by_course',
2460
                            course_id: $('#course_id').val() || 0
2461
                        });
2462
2463
                        return '" . api_get_path(WEB_AJAX_PATH) . "session.ajax.php?' + params;
2464
                    }
2465
                "
2466
            ]
2467
        );
2468
        $form->addSelect(
2469
            'profile',
2470
            get_lang('Profile'),
2471
            [
2472
                '' => get_lang('Select'),
2473
                STUDENT => get_lang('Student'),
2474
                COURSEMANAGER => get_lang('CourseManager'),
2475
                DRH => get_lang('Drh')
2476
            ],
2477
            ['id' => 'profile']
2478
        );
2479
        $form->addElement(
2480
            'select_ajax',
2481
            'student_id',
2482
            get_lang('SearchUsers'),
2483
            $studentList,
2484
            [
2485
                'placeholder' => get_lang('All'),
2486
                'url_function' => "
2487
                    function () {
2488
                        var params = $.param({
2489
                            a: 'search_user_by_course',
2490
                            session_id: $('#session_id').val(),
2491
                            course_id: $('#course_id').val()
2492
                        });
2493
2494
                        return '" . api_get_path(WEB_AJAX_PATH) . "course.ajax.php?' + params;
2495
                    }
2496
                "
2497
            ]
2498
        );
2499
        $form->addDateRangePicker(
2500
            'date',
2501
            get_lang('DateRange'),
2502
            true,
2503
            [
2504
                'id' => 'date_range',
2505
                'format' => 'YYYY-MM-DD',
2506
                'timePicker' => 'false',
2507
                'validate_format' => 'Y-m-d'
2508
            ]
2509
        );
2510
        $form->addHidden('display', 'accessoverview');
2511
        $form->addRule('course_id', get_lang('Required'), 'required');
2512
        $form->addRule('profile', get_lang('Required'), 'required');
2513
        $form->addButton('submit', get_lang('Generate'), 'gear', 'primary');
2514
2515
        $table = null;
2516
2517
        if ($form->validate()) {
2518
            $table = new SortableTable(
2519
                'tracking_access_overview',
2520
                ['MySpace', 'getNumberOfTrackAccessOverview'],
2521
                ['MySpace', 'getUserDataAccessTrackingOverview'],
2522
                0
2523
            );
2524
            $table->additional_parameters = $form->exportValues();
2525
2526
            $table->set_header(0, get_lang('LoginDate'), true);
2527
            $table->set_header(1, get_lang('Username'), true);
2528 View Code Duplication
            if (api_is_western_name_order()) {
2529
                $table->set_header(2, get_lang('FirstName'), true);
2530
                $table->set_header(3, get_lang('LastName'), true);
2531
            } else {
2532
                $table->set_header(2, get_lang('LastName'), true);
2533
                $table->set_header(3, get_lang('FirstName'), true);
2534
            }
2535
            $table->set_header(4, get_lang('Clicks'), false);
2536
            $table->set_header(5, get_lang('IP'), false);
2537
            $table->set_header(6, get_lang('TimeLoggedIn'), false);
2538
        }
2539
2540
        $template = new Template(null, false, false, false, false, false, false);
2541
        $template->assign('form', $form->returnForm());
2542
        $template->assign('table', $table ? $table->return_table() : null);
2543
2544
        echo $template->fetch(
2545
            $template->get_template('my_space/accessoverview.tpl')
2546
        );
2547
    }
2548
2549
    /**
2550
     * @return int
2551
     */
2552 View Code Duplication
    public static function getNumberOfTrackAccessOverview()
2553
    {
2554
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2555
        $sql = "SELECT COUNT(course_access_id) count FROM $table";
2556
        $result = Database::query($sql);
2557
        $row = Database::fetch_assoc($result);
2558
2559
        return $row['count'];
2560
    }
2561
2562
    /**
2563
     * @param $from
2564
     * @param $numberItems
2565
     * @param $column
2566
     * @param $orderDirection
2567
     * @return array
2568
     */
2569
    public static function getUserDataAccessTrackingOverview($from, $numberItems, $column, $orderDirection)
2570
    {
2571
        $user = Database::get_main_table(TABLE_MAIN_USER);
2572
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
2573
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
2574
        $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2575
2576
        global $export_csv;
2577
2578
        if ($export_csv) {
2579
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
2580
        } else {
2581
            $is_western_name_order = api_is_western_name_order();
2582
        }
2583
2584
        //TODO add course name
2585
        $sql = "SELECT
2586
                a.login_course_date as col0,
2587
                u.username as col1,
2588
                " . (
2589
                    $is_western_name_order ? "
2590
                        u.firstname AS col2,
2591
                        u.lastname AS col3,
2592
                    " : "
2593
                        u.lastname AS col2,
2594
                        u.firstname AS col3,
2595
                " ) . "
2596
                a.logout_course_date,
2597
                c.title,
2598
                c.code,
2599
                u.user_id
2600
            FROM $track_e_course_access a
2601
            INNER JOIN $user u ON a.user_id = u.user_id
2602
            INNER JOIN $course c ON a.c_id = c.id";
2603
2604
        if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
2605
            $sessionId = intval($_GET['session_id']);
2606
            $sql .= " WHERE a.session_id = " . $sessionId;
2607
        }
2608
2609
        $sql .= " ORDER BY col$column $orderDirection ";
2610
        $sql .= " LIMIT $from,$numberItems";
2611
        $result = Database::query($sql);
2612
2613
        //$clicks = Tracking::get_total_clicks_by_session();
2614
        $data = array();
2615
        while ($user = Database::fetch_assoc($result)) {
2616
            $data[] = $user;
2617
        }
2618
2619
        $return = [];
2620
        //TODO: Dont use numeric index
2621
        foreach ($data as $key => $info) {
2622
            $start_date = $info['col0'];
2623
2624
            $end_date = $info['logout_course_date'];
2625
2626
            $return[$info['user_id']] = array(
2627
                $start_date,
2628
                $info['col1'],
2629
                $info['col2'],
2630
                $info['col3'],
2631
                $info['user_id'],
2632
                'ip',
2633
                //TODO is not correct/precise, it counts the time not logged between two loggins
2634
                gmdate("H:i:s", strtotime($end_date) - strtotime($start_date))
2635
            );
2636
        }
2637
2638
        foreach ($return as $key => $info) {
2639
            $ipResult = Database::select(
2640
                'user_ip',
2641
                $track_e_login,
2642
                ['where' => [
2643
                    '? BETWEEN login_date AND logout_date' => $info[0]
2644
                ]],
2645
                'first'
2646
            );
2647
2648
            $return[$key][5] = $ipResult['user_ip'];
2649
        }
2650
2651
        return $return;
2652
    }
2653
2654
    /**
2655
     * Gets the connections to a course as an array of login and logout time
2656
     *
2657
     * @param   int       $user_id
2658
     * @param   int    $courseId
2659
     * @author  Jorge Frisancho Jibaja
2660
     * @author  Julio Montoya <[email protected]> fixing the function
2661
     * @version OCT-22- 2010
2662
     * @return  array
2663
     */
2664
    public static function get_connections_to_course_by_date($user_id, $courseId, $start_date, $end_date)
2665
    {
2666
        // Database table definitions
2667
        $tbl_track_course = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2668
        $course_info = api_get_course_info_by_id($courseId);
2669
        $user_id = intval($user_id);
2670
        $courseId = intval($courseId);
2671
        $connections = array();
2672
2673
        if (!empty($course_info)) {
2674
            $end_date = add_day_to($end_date);
2675
            $sql = "SELECT login_course_date, logout_course_date
2676
                FROM $tbl_track_course
2677
                WHERE
2678
                    user_id = $user_id AND
2679
                    c_id = $courseId AND
2680
                    login_course_date BETWEEN '$start_date' AND '$end_date' AND
2681
                    logout_course_date BETWEEN '$start_date' AND '$end_date'
2682
                ORDER BY login_course_date ASC";
2683
            $rs = Database::query($sql);
2684
2685
            while ($row = Database::fetch_array($rs)) {
2686
                $login_date = $row['login_course_date'];
2687
                $logout_date = $row['logout_course_date'];
2688
                $timestamp_login_date = strtotime($login_date);
2689
                $timestamp_logout_date = strtotime($logout_date);
2690
                $connections[] = array(
2691
                    'login' => $timestamp_login_date,
2692
                    'logout' => $timestamp_logout_date
2693
                );
2694
            }
2695
        }
2696
        return $connections;
2697
    }
2698
}
2699
2700
/**
2701
 * @param $user_id
2702
 * @param int $courseId
2703
 * @param null $start_date
2704
 * @param null $end_date
2705
 * @return array
2706
 */
2707
function get_stats($user_id, $courseId, $start_date = null, $end_date = null)
2708
{
2709
    // Database table definitions
2710
    $tbl_track_course   = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2711
2712
    $course_info = api_get_course_info_by_id($courseId);
2713
    if (!empty($course_info)) {
2714
        $strg_sd = '';
2715
        $strg_ed = '';
2716
        if ($start_date != null && $end_date != null){
2717
            $end_date = add_day_to($end_date);
2718
            $strg_sd = "AND login_course_date BETWEEN '$start_date' AND '$end_date'";
2719
            $strg_ed = "AND logout_course_date BETWEEN '$start_date' AND '$end_date'";
2720
        }
2721
        $sql = 'SELECT
2722
                SEC_TO_TIME(avg(time_to_sec(timediff(logout_course_date,login_course_date)))) as avrg,
2723
                SEC_TO_TIME(sum(time_to_sec(timediff(logout_course_date,login_course_date)))) as total,
2724
                count(user_id) as times
2725
                FROM ' . $tbl_track_course . '
2726
                WHERE
2727
                    user_id = ' . intval($user_id) . ' AND
2728
                    c_id = ' . intval($courseId) . ' '.$strg_sd.' '.$strg_ed.' '.'
2729
                ORDER BY login_course_date ASC';
2730
2731
        $rs = Database::query($sql);
2732
        $result = array();
2733
2734
        if ($row = Database::fetch_array($rs)) {
2735
            $foo_avg    = $row['avrg'];
2736
            $foo_total  = $row['total'];
2737
            $foo_times  = $row['times'];
2738
            $result = array('avg' => $foo_avg, 'total' => $foo_total, 'times' => $foo_times);
2739
        }
2740
    }
2741
2742
    return $result;
2743
}
2744
2745
function add_day_to($end_date) {
2746
    $foo_date = strtotime( $end_date );
2747
    $foo_date = strtotime(" +1 day", $foo_date);
2748
    $foo_date = date("Y-m-d", $foo_date);
2749
    return $foo_date;
2750
}
2751
2752
/**
2753
 *
2754
 * @param array
2755
 * @author Jorge Frisancho Jibaja
2756
 * @version OCT-22- 2010
2757
 * @return array
2758
 */
2759 View Code Duplication
function convert_to_array($sql_result)
2760
{
2761
    $result_to_print = '<table>';
2762
    foreach ($sql_result as $key => $data) {
2763
        $result_to_print .= '<tr><td>'.date('d-m-Y (H:i:s)', $data['login']).'</td><td>'.api_time_to_hms($data['logout'] - $data['login']).'</tr></td>'."\n";
2764
    }
2765
    $result_to_print .= '</table>';
2766
    $result_to_print = array("result"=>$result_to_print);
2767
    return $result_to_print;
2768
}
2769
2770
2771
/**
2772
 * Converte an array to a table in html
2773
 *
2774
 * @param array $sql_result
2775
 * @author Jorge Frisancho Jibaja
2776
 * @version OCT-22- 2010
2777
 * @return string
2778
 */
2779 View Code Duplication
function convert_to_string($sql_result)
2780
{
2781
    $result_to_print = '<table>';
2782
    if (!empty($sql_result)) {
2783
        foreach ($sql_result as $key => $data) {
2784
            $result_to_print .= '<tr><td>'.date('d-m-Y (H:i:s)', $data['login']).'</td><td>'.api_time_to_hms($data['logout'] - $data['login']).'</tr></td>'."\n";
2785
        }
2786
    }
2787
    $result_to_print .= '</table>';
2788
    return $result_to_print;
2789
}
2790
2791
2792
/**
2793
 * This function draw the graphic to be displayed on the user view as an image
2794
 *
2795
 * @param array $sql_result
2796
 * @param string $start_date
2797
 * @param string $end_date
2798
 * @param string $type
2799
 * @author Jorge Frisancho Jibaja
2800
 * @version OCT-22- 2010
2801
 * @return string
2802
 */
2803
function grapher($sql_result, $start_date, $end_date, $type = "")
2804
{
2805
    if (empty($start_date)) { $start_date =""; }
2806
    if (empty($end_date)) { $end_date =""; }
2807
    if ($type == ""){ $type = 'day'; }
2808
    $main_year  = $main_month_year = $main_day = [];
2809
2810
    $period = new DatePeriod(
2811
        new DateTime($start_date),
2812
        new DateInterval('P1D'),
2813
        new DateTime($end_date)
2814
    );
2815
2816
    foreach ($period as $date) {
2817
        $main_day[$date->format('d-m-Y')] = 0;
2818
    }
2819
2820
    $period = new DatePeriod(
2821
        new DateTime($start_date),
2822
        new DateInterval('P1M'),
2823
        new DateTime($end_date)
2824
    );
2825
2826
    foreach ($period as $date) {
2827
        $main_month_year[$date->format('m-Y')] = 0;
2828
    }
2829
2830
    $i = 0;
2831
    if (is_array($sql_result) && count($sql_result) > 0) {
2832
        foreach ($sql_result as $key => $data) {
2833
            //creating the main array
2834 View Code Duplication
            if (isset($main_month_year[date('m-Y', $data['login'])])) {
2835
                $main_month_year[date('m-Y', $data['login'])] += float_format(($data['logout'] - $data['login']) / 60, 0);
2836
            }
2837 View Code Duplication
            if (isset($main_day[date('d-m-Y', $data['login'])])) {
2838
                $main_day[date('d-m-Y', $data['login'])] += float_format(($data['logout'] - $data['login']) / 60, 0);
2839
            }
2840
            if ($i > 500) {
2841
                break;
2842
            }
2843
            $i++;
2844
        }
2845
        switch ($type) {
2846
            case 'day':
2847
                $main_date = $main_day;
2848
                break;
2849
            case 'month':
2850
                $main_date = $main_month_year;
2851
                break;
2852
            case 'year':
2853
                $main_date = $main_year;
2854
                break;
2855
        }
2856
2857
        // the nice graphics :D
2858
        $labels = array_keys($main_date);
2859
        if (count($main_date) == 1) {
2860
            $labels = $labels[0];
2861
            $main_date = $main_date[$labels];
2862
        }
2863
2864
        /* Create and populate the pData object */
2865
        $myData = new pData();
2866
        $myData->addPoints($main_date, 'Serie1');
2867
        if (count($main_date)!= 1) {
2868
            $myData->addPoints($labels, 'Labels');
2869
            $myData->setSerieDescription('Labels', 'Months');
2870
            $myData->setAbscissa('Labels');
2871
        }
2872
        $myData->setSerieWeight('Serie1', 1);
2873
        $myData->setSerieDescription('Serie1', get_lang('MyResults'));
2874
        $myData->setAxisName(0, get_lang('Minutes'));
2875
        $myData->loadPalette(api_get_path(SYS_CODE_PATH) . 'palettes/pchart/default.color', true);
2876
2877
        // Cache definition
2878
        $cachePath = api_get_path(SYS_ARCHIVE_PATH);
2879
        $myCache = new pCache(array('CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)));
2880
        $chartHash = $myCache->getHash($myData);
2881
2882
        if ($myCache->isInCache($chartHash)) {
2883
            //if we already created the img
2884
            $imgPath = api_get_path(SYS_ARCHIVE_PATH) . $chartHash;
2885
            $myCache->saveFromCache($chartHash, $imgPath);
2886
            $imgPath = api_get_path(WEB_ARCHIVE_PATH) . $chartHash;
2887
        } else {
2888
            /* Define width, height and angle */
2889
            $mainWidth = 760;
2890
            $mainHeight = 230;
2891
            $angle = 50;
2892
2893
            /* Create the pChart object */
2894
            $myPicture = new pImage($mainWidth, $mainHeight, $myData);
2895
2896
            /* Turn of Antialiasing */
2897
            $myPicture->Antialias = false;
2898
2899
            /* Draw the background */
2900
            $settings = array("R" => 255, "G" => 255, "B" => 255);
2901
            $myPicture->drawFilledRectangle(0, 0, $mainWidth, $mainHeight, $settings);
2902
2903
            /* Add a border to the picture */
2904
            $myPicture->drawRectangle(
2905
                0,
2906
                0,
2907
                $mainWidth - 1,
2908
                $mainHeight - 1,
2909
                array("R" => 0, "G" => 0, "B" => 0)
2910
            );
2911
2912
            /* Set the default font */
2913
            $myPicture->setFontProperties(
2914
                array(
2915
                    "FontName" => api_get_path(SYS_FONTS_PATH) . 'opensans/OpenSans-Regular.ttf',
2916
                    "FontSize" => 10)
2917
            );
2918
            /* Write the chart title */
2919
            $myPicture->drawText(
2920
                $mainWidth / 2,
2921
                30,
2922
                get_lang('TimeSpentInTheCourse'),
2923
                array(
2924
                    "FontSize" => 12,
2925
                    "Align" => TEXT_ALIGN_BOTTOMMIDDLE
2926
                )
2927
            );
2928
2929
            /* Set the default font */
2930
            $myPicture->setFontProperties(
2931
                array(
2932
                    "FontName" => api_get_path(SYS_FONTS_PATH) . 'opensans/OpenSans-Regular.ttf',
2933
                    "FontSize" => 8
2934
                )
2935
            );
2936
2937
            /* Define the chart area */
2938
            $myPicture->setGraphArea(50, 40, $mainWidth - 40, $mainHeight - 80);
2939
2940
            /* Draw the scale */
2941
            $scaleSettings = array(
2942
                'XMargin' => 10,
2943
                'YMargin' => 10,
2944
                'Floating' => true,
2945
                'GridR' => 200,
2946
                'GridG' => 200,
2947
                'GridB' => 200,
2948
                'DrawSubTicks' => true,
2949
                'CycleBackground' => true,
2950
                'LabelRotation' => $angle,
2951
                'Mode' => SCALE_MODE_ADDALL_START0,
2952
            );
2953
            $myPicture->drawScale($scaleSettings);
2954
2955
            /* Turn on Antialiasing */
2956
            $myPicture->Antialias = true;
2957
2958
            /* Enable shadow computing */
2959
            $myPicture->setShadow(
2960
                true,
2961
                array(
2962
                    "X" => 1,
2963
                    "Y" => 1,
2964
                    "R" => 0,
2965
                    "G" => 0,
2966
                    "B" => 0,
2967
                    "Alpha" => 10
2968
                )
2969
            );
2970
2971
            /* Draw the line chart */
2972
            $myPicture->setFontProperties(
2973
                array(
2974
                    "FontName" => api_get_path(SYS_FONTS_PATH) . 'opensans/OpenSans-Regular.ttf',
2975
                    "FontSize" => 10
2976
                )
2977
            );
2978
            $myPicture->drawSplineChart();
2979
            $myPicture->drawPlotChart(
2980
                array(
2981
                    "DisplayValues" => true,
2982
                    "PlotBorder" => true,
2983
                    "BorderSize" => 1,
2984
                    "Surrounding" => -60,
2985
                    "BorderAlpha" => 80
2986
                )
2987
            );
2988
2989
            /* Do NOT Write the chart legend */
2990
2991
            /* Write and save into cache */
2992
            $myCache->writeToCache($chartHash, $myPicture);
2993
            $imgPath = api_get_path(SYS_ARCHIVE_PATH) . $chartHash;
2994
            $myCache->saveFromCache($chartHash, $imgPath);
2995
            $imgPath = api_get_path(WEB_ARCHIVE_PATH) . $chartHash;
2996
        }
2997
        $html = '<img src="' . $imgPath . '">';
2998
2999
        return $html;
3000
    } else {
3001
        $foo_img = api_convert_encoding('<div id="messages" class="warning-message">'.get_lang('GraphicNotAvailable').'</div>','UTF-8');
3002
3003
        return $foo_img;
3004
    }
3005
}
3006