Passed
Push — 1.11.x ( f19aa7...6b670b )
by Julito
11:19
created

getReport()   F

Complexity

Conditions 33
Paths > 20000

Size

Total Lines 231
Code Lines 161

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 33
eloc 161
nc 1533224
nop 4
dl 0
loc 231
rs 0
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
require_once __DIR__.'/../inc/global.inc.php';
6
7
api_block_anonymous_users();
8
9
$is_allowedToTrack = api_is_platform_admin(true, true) ||
10
    api_is_teacher() || api_is_course_tutor();
11
12
if (!$is_allowedToTrack) {
13
    api_not_allowed(true);
14
    exit;
15
}
16
17
// the section (for the tabs)
18
$this_section = SECTION_TRACKING;
19
$quote_simple = "'";
20
21
$userId = isset($_REQUEST['user_id']) ? (int) $_REQUEST['user_id'] : 0;
22
$userInfo = api_get_user_info($userId);
23
if (empty($userInfo)) {
24
    api_not_allowed(true);
25
}
26
27
/**
28
 * @param string $dateTime
29
 * @param bool   $showTime
30
 *
31
 * @return string
32
 */
33
function customDate($dateTime, $showTime = false)
34
{
35
    $format = 'd/m/Y';
36
    if ($showTime) {
37
        $format = 'd/m/Y H:i:s';
38
    }
39
    $dateTime = api_get_local_time(
40
        $dateTime,
41
        null,
42
        null,
43
        true,
44
        false,
45
        true,
46
        $format
47
    );
48
49
    return $dateTime;
50
}
51
52
$sessions = SessionManager::getSessionsFollowedByUser(
53
    $userId,
54
    null,
55
    null,
56
    null,
57
    false,
58
    false,
59
    false,
60
    'ORDER BY s.access_end_date'
61
);
62
63
$startDate = '';
64
$endDate = '';
65
if (!empty($sessions)) {
66
    foreach ($sessions as $session) {
67
        $startDate = customDate($session['access_start_date']);
68
        $endDate = customDate($session['access_end_date']);
69
    }
70
}
71
72
$form = new FormValidator(
73
    'myform',
74
    'get',
75
    api_get_self().'?user_id='.$userId,
76
    null,
77
    ['id' => 'myform']
78
);
79
$form->addElement('text', 'from', get_lang('From'));
80
$form->addElement('text', 'to', get_lang('Until'));
81
$form->addHidden('user_id', $userId);
82
$form->addRule('from', get_lang('ThisFieldIsRequired'), 'required');
83
$form->addRule('from', get_lang('ThisFieldIsRequired').' dd/mm/yyyy', 'callback', 'validateDate');
84
$form->addRule('to', get_lang('ThisFieldIsRequired'), 'required');
85
$form->addRule('to', get_lang('ThisFieldIsRequired').' dd/mm/yyyy', 'callback', 'validateDate');
86
$form->addButtonSearch(get_lang('GenerateReport'));
87
88
/**
89
 * @param string $value
90
 *
91
 * @return bool
92
 */
93
function validateDate($value)
94
{
95
    $value = DateTime::createFromFormat('d/m/Y', $value);
96
97
    if ($value === false) {
98
        return false;
99
    }
100
101
    return true;
102
}
103
104
function getReport($userId, $from, $to, $addTime = false)
105
{
106
    $sessionCategories = UserManager::get_sessions_by_category($userId, false);
107
    $report = [];
108
    $minLogin = 0;
109
    $maxLogin = 0;
110
    $totalDuration = 0;
111
112
    foreach ($sessionCategories as $category) {
113
        foreach ($category['sessions'] as $session) {
114
            $sessionId = $session['session_id'];
115
            $courseList = $session['courses'];
116
            foreach ($courseList as $course) {
117
                $courseInfo = api_get_course_info_by_id($course['real_id']);
118
                $result = MySpace::get_connections_to_course_by_date(
119
                    $userId,
120
                    $courseInfo,
121
                    $sessionId,
122
                    $from,
123
                    $to
124
                );
125
126
                $partialMinLogin = 0;
127
                $partialMaxLogin = 0;
128
                $partialDuration = 0;
129
130
                foreach ($result as $item) {
131
                    $record = [
132
                        customDate($item['login'], true),
133
                        customDate($item['logout'], true),
134
                        api_format_time($item['duration'], 'js'),
135
                    ];
136
137
                    $totalDuration += $item['duration'];
138
139
                    if (empty($minLogin)) {
140
                        $minLogin = api_strtotime($item['login'], 'UTC');
141
                    }
142
                    if ($minLogin > api_strtotime($item['login'], 'UTC')) {
143
                        $minLogin = api_strtotime($item['login'], 'UTC');
144
                    }
145
                    if (api_strtotime($item['logout']) > $maxLogin) {
146
                        $maxLogin = api_strtotime($item['logout'], 'UTC');
147
                    }
148
149
                    // Partials
150
                    $partialDuration += $item['duration'];
151
                    if (empty($partialMinLogin)) {
152
                        $partialMinLogin = api_strtotime($item['login'], 'UTC');
153
                    }
154
                    if ($partialMinLogin > api_strtotime($item['login'], 'UTC')) {
155
                        $partialMinLogin = api_strtotime($item['login'], 'UTC');
156
                    }
157
                    if (api_strtotime($item['logout'], 'UTC') > $partialMaxLogin) {
158
                        $partialMaxLogin = api_strtotime($item['logout'], 'UTC');
159
                    }
160
161
                    $report[$sessionId]['courses'][$course['real_id']][] = $record;
162
                    $report[$sessionId]['name'][$course['real_id']] = $courseInfo['title'].'&nbsp; ('.$session['session_name'].')';
163
                }
164
165
                if (!empty($result)) {
166
                    $record = [
167
                        customDate($partialMinLogin, true),
168
                        customDate($partialMaxLogin, true),
169
                        api_format_time($partialDuration, 'js'),
170
                    ];
171
                    $report[$sessionId]['courses'][$course['real_id']][] = $record;
172
                    $report[$sessionId]['name'][$course['real_id']] = $courseInfo['title'].'&nbsp; ('.$session['session_name'].')';
173
                }
174
            }
175
        }
176
    }
177
178
    $courses = CourseManager::returnCourses($userId);
179
    $courses = array_merge($courses['in_category'], $courses['not_category']);
180
181
    if ($addTime) {
182
        $fromFirst = api_get_local_time($from.' 00:00:00');
183
        $toEnd = api_get_local_time($from.' 23:59:59');
184
185
        $from = api_get_utc_datetime($fromFirst);
186
        $to = api_get_utc_datetime($toEnd);
187
    }
188
189
    foreach ($courses as $course) {
190
        $result = MySpace::get_connections_to_course_by_date(
191
            $userId,
192
            $course,
193
            0,
194
            $from,
195
            $to
196
        );
197
        $partialMinLogin = 0;
198
        $partialMaxLogin = 0;
199
        $partialDuration = 0;
200
201
        foreach ($result as $item) {
202
            $record = [
203
                customDate($item['login'], true),
204
                customDate($item['logout'], true),
205
                api_format_time($item['duration'], 'js'),
206
            ];
207
            $report[0]['courses'][$course['course_id']][] = $record;
208
            $report[0]['name'][$course['course_id']] = $course['title'];
209
210
            $totalDuration += $item['duration'];
211
212
            if (empty($minLogin)) {
213
                $minLogin = api_strtotime($item['login'], 'UTC');
214
            }
215
            if ($minLogin > api_strtotime($item['login'], 'UTC')) {
216
                $minLogin = api_strtotime($item['login'], 'UTC');
217
            }
218
            if (api_strtotime($item['logout'], 'UTC') > $maxLogin) {
219
                $maxLogin = api_strtotime($item['logout'], 'UTC');
220
            }
221
222
            // Partials
223
            $partialDuration += $item['duration'];
224
            if (empty($partialMinLogin)) {
225
                $partialMinLogin = api_strtotime($item['login'], 'UTC');
226
            }
227
            if ($partialMinLogin > api_strtotime($item['login'], 'UTC')) {
228
                $partialMinLogin = api_strtotime($item['login'], 'UTC');
229
            }
230
            if (api_strtotime($item['logout'], 'UTC') > $partialMaxLogin) {
231
                $partialMaxLogin = api_strtotime($item['logout'], 'UTC');
232
            }
233
        }
234
235
        if (!empty($result)) {
236
            $record = [
237
                customDate($partialMinLogin, true),
238
                customDate($partialMaxLogin, true),
239
                api_format_time($partialDuration, 'js'),
240
            ];
241
242
            $report[0]['courses'][$course['course_id']][] = $record;
243
            $report[0]['name'][$course['course_id']] = $course['title'];
244
        }
245
    }
246
247
    $table = new HTML_Table(['class' => 'data_table']);
248
    $headers = [
249
        get_lang('MinStartDate'),
250
        get_lang('MaxEndDate'),
251
        get_lang('TotalDuration'),
252
    ];
253
    $row = 0;
254
    $column = 0;
255
    foreach ($headers as $header) {
256
        $table->setHeaderContents($row, $column, $header);
257
        $column++;
258
    }
259
    $row++;
260
    $column = 0;
261
    $table->setCellContents($row, $column++, customDate($minLogin));
262
    $table->setCellContents($row, $column++, customDate($maxLogin));
263
    $table->setRowAttributes($row, ['style' => 'font-weight:bold']);
264
    $table->setCellContents($row, $column++, api_format_time($totalDuration, 'js'));
265
266
    $first = $table->toHtml();
267
268
    $courseSessionTable = '';
269
    $courseSessionTableData = [];
270
    foreach ($report as $sessionId => $data) {
271
        foreach ($data['courses'] as $courseId => $courseData) {
272
            if (empty($courseData)) {
273
                continue;
274
            }
275
            $courseSessionTable .= Display::page_subheader3($data['name'][$courseId]);
276
            $table = new HTML_Table(['class' => 'data_table']);
277
            $headers = [
278
                get_lang('StartDate'),
279
                get_lang('EndDate'),
280
                get_lang('Duration'),
281
            ];
282
            $row = 0;
283
            $column = 0;
284
            foreach ($headers as $header) {
285
                $table->setHeaderContents($row, $column, $header);
286
                $column++;
287
            }
288
            $row++;
289
            $countData = count($courseData);
290
            foreach ($courseData as $record) {
291
                $column = 0;
292
                foreach ($record as $item) {
293
                    $table->setCellContents($row, $column++, $item);
294
                    if ($row == $countData) {
295
                        $courseSessionTableData[$data['name'][$courseId]] = $item;
296
                        $table->setRowAttributes($row, ['style' => 'font-weight:bold']);
297
                    }
298
                }
299
                $row++;
300
            }
301
            $courseSessionTable .= $table->toHtml();
302
        }
303
    }
304
    $totalCourseSessionTable = '';
305
306
    if ($courseSessionTableData) {
307
        $table = new HTML_Table(['class' => 'table data_table']);
308
        $headers = [
309
            get_lang('Course'),
310
            get_lang('TotalDuration'),
311
        ];
312
        $row = 0;
313
        $column = 0;
314
        foreach ($headers as $header) {
315
            $table->setHeaderContents($row, $column, $header);
316
            $column++;
317
        }
318
        $row++;
319
        foreach ($courseSessionTableData as $name => $duration) {
320
            $column = 0;
321
            $table->setCellContents($row, $column++, $name);
322
            $table->setCellContents($row, $column++, $duration);
323
            $row++;
324
        }
325
        $totalCourseSessionTable = $table->toHtml();
326
    }
327
328
    $result = [];
329
    $result['first'] = $first;
330
    $result['second'] = $courseSessionTable;
331
    $result['third'] = $totalCourseSessionTable;
332
    $result['total'] = $totalDuration;
333
334
    return $result;
335
}
336
337
if ($form->validate()) {
338
    $values = $form->getSubmitValues();
339
    $from = $values['from'];
340
    $to = $values['to'];
341
342
    $from = DateTime::createFromFormat('d/m/Y', $from);
343
    $to = DateTime::createFromFormat('d/m/Y', $to);
344
345
    $from = api_get_utc_datetime($from->format('Y-m-d'));
346
    $to = api_get_utc_datetime($to->format('Y-m-d'));
347
    $title = Display::page_subheader3(sprintf(get_lang('ExtractionFromX'), api_get_local_time()));
348
    $result = getReport($userId, $from, $to);
349
350
    $first = $result['first'];
351
    $courseSessionTable = $result['second'];
352
    $totalCourseSessionTable = $result['third'];
353
354
    $tpl = new Template('', false, false, false, true, false, false);
355
    $tpl->assign('title', get_lang('RealisationCertificate'));
356
    $tpl->assign('student', $userInfo['complete_name']);
357
    $tpl->assign('table_progress', $title.$first.$totalCourseSessionTable.'<pagebreak>'.$courseSessionTable);
358
359
    $content = $tpl->fetch($tpl->get_template('my_space/pdf_export_student.tpl'));
360
361
    $params = [
362
        'pdf_title' => get_lang('Resume'),
363
        'course_info' => '',
364
        'pdf_date' => '',
365
        'student_info' => $userInfo,
366
        'show_grade_generated_date' => true,
367
        'show_real_course_teachers' => false,
368
        'show_teacher_as_myself' => false,
369
        'orientation' => 'P',
370
    ];
371
372
    @$pdf = new PDF('A4', $params['orientation'], $params);
373
374
    @$pdf->setBackground($tpl->theme);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for setBackground(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

374
    /** @scrutinizer ignore-unhandled */ @$pdf->setBackground($tpl->theme);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
Are you sure the usage of $pdf->setBackground($tpl->theme) targeting PDF::setBackground() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
375
    @$pdf->content_to_pdf(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for content_to_pdf(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

375
    /** @scrutinizer ignore-unhandled */ @$pdf->content_to_pdf(

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
376
        $content,
377
        '',
378
        '',
379
        null,
380
        'D',
381
        false,
382
        null,
383
        false,
384
        true,
385
        false
386
    );
387
    exit;
388
}
389
390
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('AccessDetails')];
391
$userInfo = api_get_user_info($userId);
392
393
394
$form->setDefaults(['from' => $startDate, 'to' => $endDate]);
395
396
$formByDay = new FormValidator(
397
    'by_day',
398
    'get',
399
    api_get_self().'?user_id='.$userId,
400
    null,
401
    ['id' => 'by_day']
402
);
403
$formByDay->addElement('text', 'from', get_lang('From'));
404
$formByDay->addElement('text', 'to', get_lang('Until'));
405
$formByDay->addCheckBox('reduced', null, get_lang('ReducedReport'));
406
$formByDay->addHidden('user_id', $userId);
407
$formByDay->addRule('from', get_lang('ThisFieldIsRequired'), 'required');
408
$formByDay->addRule('from', get_lang('ThisFieldIsRequired').' dd/mm/yyyy', 'callback', 'validateDate');
409
$formByDay->addRule('to', get_lang('ThisFieldIsRequired'), 'required');
410
$formByDay->addRule('to', get_lang('ThisFieldIsRequired').' dd/mm/yyyy', 'callback', 'validateDate');
411
$formByDay->addButtonSearch(get_lang('GenerateReport'));
412
413
if ($formByDay->validate()) {
414
    $from = $formByDay->getSubmitValue('from');
415
    $to = $formByDay->getSubmitValue('to');
416
    $reduced = !empty($formByDay->getSubmitValue('reduced'));
417
418
    $fromObject = DateTime::createFromFormat('d/m/Y', $from);
419
    $toObject = DateTime::createFromFormat('d/m/Y', $to);
420
421
    $from = api_get_utc_datetime($fromObject->format('Y-m-d'));
422
    $to = api_get_utc_datetime($toObject->format('Y-m-d'));
423
424
    $list = Tracking::get_time_spent_on_the_platform($userId, 'custom', $from, $to, true);
425
    $newList = [];
426
    foreach ($list as $list) {
0 ignored issues
show
Bug introduced by
The expression $list of type integer is not traversable.
Loading history...
427
        $key = substr($list['login_date'], 0, 10);
428
        if (!isset($newList[$key])) {
429
            $newList[$key] = [
430
                'login_date' => $list['login_date'],
431
                'logout_date' => $list['logout_date'],
432
                'diff' => $list['diff'],
433
            ];
434
        } else {
435
            $newList[$key] = [
436
                'login_date' => $newList[$key]['login_date'],
437
                'logout_date' => $list['logout_date'],
438
                'diff' => $newList[$key]['diff'] + $list['diff'],
439
            ];
440
        }
441
    }
442
443
    $period = new DatePeriod(
444
        $fromObject,
0 ignored issues
show
Bug introduced by
It seems like $fromObject can also be of type false; however, parameter $start of DatePeriod::__construct() does only seem to accept DateTimeInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

444
        /** @scrutinizer ignore-type */ $fromObject,
Loading history...
445
        new DateInterval('P1D'),
446
        $toObject
0 ignored issues
show
Bug introduced by
It seems like $toObject can also be of type false; however, parameter $end of DatePeriod::__construct() does only seem to accept DateTimeInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

446
        /** @scrutinizer ignore-type */ $toObject
Loading history...
447
    );
448
449
    $tableList = '';
450
    foreach ($period as $value) {
451
        $dateToCheck = $value->format('Y-m-d');
452
        $data = isset($newList[$dateToCheck]) ? $newList[$dateToCheck] : [];
453
454
        if (empty($data)) {
455
            continue;
456
        }
457
458
        $table = new HTML_Table(['class' => ' data_table']);
459
        $headers = [
460
            get_lang('FirstConnection'),
461
            get_lang('LastConnection'),
462
            get_lang('Total'),
463
        ];
464
465
        /*$table->setHeaderContents(0, 0, $dateToCheck);
466
        $table->setCellAttributes(0,0,['colspan' => 3]);*/
467
468
        $row = 0;
469
        $column = 0;
470
        foreach ($headers as $header) {
471
            $table->setHeaderContents($row, $column, $header);
472
            $column++;
473
        }
474
475
        $row = 1;
476
        $column = 0;
477
        $table->setCellContents($row, $column++, customDate($data['login_date'], true));
478
        $table->setCellContents($row, $column++, customDate($data['logout_date'], true));
479
        $table->setCellContents($row, $column, api_format_time($data['diff'], 'js'));
480
481
        $result = getReport($userId, $dateToCheck, $dateToCheck, true);
482
        $first = $result['first'];
483
        $courseSessionTable = $result['second'];
484
        $totalCourseSessionTable = $result['third'];
485
        $total = $result['total'];
486
        $tableList .= '<div style="text-align:center">'.Display::page_subheader2($dateToCheck).'</div>'.$table->toHtml();
487
        //echo $tableList;exit;
488
489
        if (!$reduced && !empty($total)) {
490
            $diff = get_lang('NotInCourse').' '.api_format_time($data['diff'] - $total, 'js');
491
            $tableList .= $courseSessionTable;
492
            $tableList .= $totalCourseSessionTable;
493
            $tableList .= Display::page_subheader3($diff);
494
        }
495
    }
496
497
    $tpl = new Template('', false, false, false, true, false, false);
498
    $tpl->assign('title', get_lang('RealisationCertificate'));
499
    $tpl->assign('student', $userInfo['complete_name']);
500
    $totalTable = Display::page_subheader3(sprintf(get_lang('ExtractionFromX'), api_get_local_time()));
501
    $tpl->assign('table_progress', $totalTable.$tableList);
502
503
    $content = $tpl->fetch($tpl->get_template('my_space/pdf_export_student.tpl'));
504
505
    $params = [
506
        'pdf_title' => get_lang('Resume'),
507
        'course_info' => '',
508
        'pdf_date' => '',
509
        'student_info' => $userInfo,
510
        'show_grade_generated_date' => true,
511
        'show_real_course_teachers' => false,
512
        'show_teacher_as_myself' => false,
513
        'orientation' => 'P',
514
    ];
515
516
    @$pdf = new PDF('A4', $params['orientation'], $params);
517
    @$pdf->setBackground($tpl->theme);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $pdf->setBackground($tpl->theme) targeting PDF::setBackground() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
518
    @$pdf->content_to_pdf(
519
        $content,
520
        '',
521
        '',
522
        null,
523
        'D',
524
        false,
525
        null,
526
        false,
527
        true,
528
        false
529
    );
530
    exit;
531
}
532
533
$formByDay->setDefaults(['from' => $startDate, 'to' => $endDate]);
534
535
Display::display_header('');
536
echo Display::page_header(get_lang('DetailsStudentInCourse'));
537
echo Display::page_subheader(
538
    get_lang('User').': '.$userInfo['complete_name']
539
);
540
541
echo Display::tabs(
542
    [get_lang('CertificateOfAchievement'), get_lang('CertificateOfAchievementByDay')],
543
    [$form->returnForm(), $formByDay->returnForm()]
544
);
545
546
Display::display_footer();
547