Completed
Push — master ( 1fcdba...966b12 )
by Julito
12:06
created

Attendance::get_attendance_calendar()   F

Complexity

Conditions 17
Paths 896

Size

Total Lines 97
Code Lines 63

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 63
nc 896
nop 8
dl 0
loc 97
rs 1.1943
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\ResourceLink;
6
use Chamilo\CoreBundle\Framework\Container;
7
use Chamilo\CourseBundle\Entity\CAttendance;
8
9
class Attendance
10
{
11
    // constants
12
    public const DONE_ATTENDANCE_LOG_TYPE = 'done_attendance_sheet';
13
    public const UPDATED_ATTENDANCE_LOG_TYPE = 'updated_attendance_sheet';
14
    public const LOCKED_ATTENDANCE_LOG_TYPE = 'locked_attendance_sheet';
15
    public $category_id;
16
    private $session_id;
17
    private $course_id;
18
    private $date_time;
19
    private $name;
20
    private $description;
21
    private $attendance_qualify_title;
22
    private $attendance_weight;
23
    private $course_int_id;
24
25
    /**
26
     * Get the total number of attendance inside current course and current session.
27
     *
28
     * @param int $active
29
     *
30
     * @return int
31
     *
32
     * @see SortableTable#get_total_number_of_items()
33
     */
34
    public static function getNumberOfAttendances()
35
    {
36
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
37
        $session_id = api_get_session_id();
38
        $condition_session = api_get_session_condition($session_id);
39
        $course_id = api_get_course_int_id();
40
41
        $active_plus = '';
42
        if ((isset($_GET['isStudentView']) && 'true' == $_GET['isStudentView']) ||
43
            !api_is_allowed_to_edit(null, true)
44
        ) {
45
            $active_plus = ' AND att.active = 1';
46
        }
47
48
        $sql = "SELECT COUNT(att.id) AS total_number_of_items
49
                FROM $tbl_attendance att
50
                WHERE
51
                      c_id = $course_id AND
52
                      active <> 2 $active_plus $condition_session  ";
53
        /*$active = (int) $active;
54
        if ($active === 1 || $active === 0) {
55
            $sql .= "AND att.active = $active";
56
        }*/
57
        $res = Database::query($sql);
58
        $obj = Database::fetch_object($res);
59
60
        return (int) $obj->total_number_of_items;
61
    }
62
63
    /**
64
     * Get attendance list only the id, name and attendance_qualify_max fields.
65
     *
66
     * @param int $course_id  course db name (optional)
67
     * @param int $session_id session id (optional)
68
     *
69
     * @return array attendances list
70
     */
71
    public function get_attendances_list($course_id = 0, $session_id = 0)
72
    {
73
        $table = Database::get_course_table(TABLE_ATTENDANCE);
74
        $course_id = (int) $course_id;
75
        if (empty($course_id)) {
76
            $course_id = api_get_course_int_id();
77
        }
78
79
        $session_id = !empty($session_id) ? (int) $session_id : api_get_session_id();
80
        $condition_session = api_get_session_condition($session_id);
81
82
        // Get attendance data
83
        $sql = "SELECT id, name, attendance_qualify_max
84
                FROM $table
85
                WHERE c_id = $course_id AND active = 1 $condition_session ";
86
        $result = Database::query($sql);
87
        $data = [];
88
        if (Database::num_rows($result) > 0) {
89
            while ($row = Database::fetch_array($result, 'ASSOC')) {
90
                $data[$row['id']] = $row;
91
            }
92
        }
93
94
        return $data;
95
    }
96
97
    /**
98
     * Get the attendances to display on the current page (fill the sortable-table).
99
     *
100
     * @param   int     offset of first user to recover
101
     * @param   int     Number of users to get
102
     * @param   int     Column to sort on
103
     * @param   string  Order (ASC,DESC)
104
     *
105
     * @see SortableTable#get_table_data($from)
106
     *
107
     * @return array
108
     */
109
    public static function get_attendance_data(
110
        $from,
111
        $number_of_items,
112
        $column,
113
        $direction
114
    ) {
115
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
116
        $course_id = api_get_course_int_id();
117
        $session_id = api_get_session_id();
118
        $condition_session = api_get_session_condition($session_id);
119
        $column = (int) $column;
120
        $from = (int) $from;
121
        $number_of_items = (int) $number_of_items;
122
123
        if (!in_array($direction, ['ASC', 'DESC'])) {
124
            $direction = 'ASC';
125
        }
126
127
        $active_plus = '';
128
        if ((isset($_GET['isStudentView']) && 'true' == $_GET['isStudentView']) ||
129
            !api_is_allowed_to_edit(null, true)
130
        ) {
131
            $active_plus = ' AND att.active = 1';
132
        }
133
134
        $sql = "SELECT
135
                    att.id AS col0,
136
                    att.name AS col1,
137
                    att.description AS col2,
138
                    att.attendance_qualify_max AS col3,
139
                    att.locked AS col4,
140
                    att.active AS col5,
141
                    att.session_id
142
                FROM $tbl_attendance att
143
                WHERE
144
                    att.active <> 2 AND
145
                    c_id = $course_id $active_plus $condition_session
146
                ORDER BY col$column $direction
147
                LIMIT $from,$number_of_items ";
148
149
        $res = Database::query($sql);
150
        $attendances = [];
151
        $user_info = api_get_user_info();
152
        $allowDelete = api_get_setting('allow_delete_attendance');
153
154
        $student_param = '';
155
        $studentRequestId = isset($_GET['student_id']) ? (int) $_GET['student_id'] : 0;
156
        if (api_is_drh() && !empty($studentRequestId)) {
157
            $student_param = '&student_id='.$studentRequestId;
158
        }
159
160
        while ($attendance = Database::fetch_row($res)) {
161
            $session_star = '';
162
            if ($session_id == $attendance[6]) {
163
                $session_star = api_get_session_image($session_id, $user_info['status']);
164
            }
165
166
            if (1 == $attendance[5]) {
167
                $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
168
                    api_get_user_id(),
169
                    api_get_course_info()
170
                ) || api_is_drh();
171
                if (api_is_allowed_to_edit(null, true) || $isDrhOfCourse) {
172
                    // Link to edit
173
                    $attendance[1] = '<a href="index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendance[0].$student_param.'">'.$attendance[1].'</a>'.$session_star;
174
                } else {
175
                    // Link to view
176
                    $attendance[1] = '<a href="index.php?'.api_get_cidreq().'&action=attendance_sheet_list_no_edit&attendance_id='.$attendance[0].$student_param.'">'.$attendance[1].'</a>'.$session_star;
177
                }
178
            } else {
179
                $attendance[1] = '<a class="muted" href="index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendance[0].$student_param.'">'.$attendance[1].'</a>'.$session_star;
180
            }
181
182
            if (1 == $attendance[5]) {
183
                $attendance[3] = '<center>'.$attendance[3].'</center>';
184
            } else {
185
                $attendance[3] = '<center><span class="muted">'.$attendance[3].'</span></center>';
186
            }
187
188
            $attendance[3] = '<center>'.$attendance[3].'</center>';
189
            if (api_is_allowed_to_edit(null, true)) {
190
                $actions = '';
191
                $actions .= '<center>';
192
193
                if (api_is_platform_admin()) {
194
                    $actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_edit&attendance_id='.$attendance[0].'">'.
195
                        Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL).'</a>&nbsp;';
196
                    // Visible
197
                    if (1 == $attendance[5]) {
198
                        $actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_set_invisible&attendance_id='.$attendance[0].'">'.
199
                            Display::return_icon('visible.png', get_lang('Hide'), [], ICON_SIZE_SMALL).'</a>';
200
                    } else {
201
                        $actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_set_visible&attendance_id='.$attendance[0].'">'.
202
                            Display::return_icon('invisible.png', get_lang('Show'), [], ICON_SIZE_SMALL).'</a>';
203
                        $attendance[2] = '<span class="muted">'.$attendance[2].'</span>';
204
                    }
205
                    if ('true' === $allowDelete) {
206
                        $actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_delete&attendance_id='.$attendance[0].'">'.
207
                            Display::return_icon('delete.png', get_lang('Delete'), [], ICON_SIZE_SMALL).'</a>';
208
                    }
209
                } else {
210
                    $is_locked_attendance = self::is_locked_attendance($attendance[0]);
211
                    if ($is_locked_attendance) {
212
                        $actions .= Display::return_icon('edit_na.png', get_lang('Edit')).'&nbsp;';
213
                        $actions .= Display::return_icon('visible.png', get_lang('Hide'));
214
                    } else {
215
                        $actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_edit&attendance_id='.$attendance[0].'">'.
216
                            Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL).'</a>&nbsp;';
217
218
                        if (1 == $attendance[5]) {
219
                            $actions .= ' <a href="index.php?'.api_get_cidreq().'&action=attendance_set_invisible&attendance_id='.$attendance[0].'">'.
220
                                Display::return_icon('visible.png', get_lang('Hide'), [], ICON_SIZE_SMALL).'</a>';
221
                        } else {
222
                            $actions .= ' <a href="index.php?'.api_get_cidreq().'&action=attendance_set_visible&attendance_id='.$attendance[0].'">'.
223
                                Display::return_icon('invisible.png', get_lang('Show'), [], ICON_SIZE_SMALL).'</a>';
224
                            $attendance[2] = '<span class="muted">'.$attendance[2].'</span>';
225
                        }
226
                        if ('true' === $allowDelete) {
227
                            $actions .= ' <a href="index.php?'.api_get_cidreq().'&action=attendance_delete&attendance_id='.$attendance[0].'">'.
228
                                Display::return_icon('delete.png', get_lang('Delete'), [], ICON_SIZE_SMALL).'</a>';
229
                        }
230
                    }
231
                }
232
233
                // display lock/unlock icon
234
                $is_done_all_calendar = self::is_all_attendance_calendar_done($attendance[0]);
235
236
                if ($is_done_all_calendar) {
237
                    $locked = $attendance[4];
238
                    if (0 == $locked) {
239
                        if (api_is_platform_admin()) {
240
                            $message_alert = get_lang('Are you sure you want to lock the attendance?');
241
                        } else {
242
                            $message_alert = get_lang('The attendance is not locked, which means your teacher is still able to modify it.');
243
                        }
244
                        $actions .= '&nbsp;<a
245
                            onclick="javascript:if(!confirm(\''.$message_alert.'\')) return false;"
246
                            href="index.php?'.api_get_cidreq().'&action=lock_attendance&attendance_id='.$attendance[0].'">'.
247
                            Display::return_icon('unlock.png', get_lang('Lock attendance')).'</a>';
248
                    } else {
249
                        if (api_is_platform_admin()) {
250
                            $actions .= '&nbsp;<a
251
                            onclick="javascript:if(!confirm(\''.get_lang('Are you sure you want to unlock the attendance?').'\')) return false;"
252
                            href="index.php?'.api_get_cidreq().'&action=unlock_attendance&attendance_id='.$attendance[0].'">'.
253
                                    Display::return_icon('locked.png', get_lang('Unlock attendance')).'</a>';
254
                        } else {
255
                            $actions .= '&nbsp;'.Display::return_icon('locked_na.png', get_lang('Locked attendance'));
256
                        }
257
                    }
258
                }
259
                $actions .= '</center>';
260
261
                $attendances[] = [
262
                    $attendance[0],
263
                    $attendance[1],
264
                    $attendance[2],
265
                    $attendance[3],
266
                    $actions,
267
                ];
268
            } else {
269
                $attendance[0] = '&nbsp;';
270
                $attendances[] = [
271
                    $attendance[0],
272
                    $attendance[1],
273
                    $attendance[2],
274
                    $attendance[3],
275
                ];
276
            }
277
        }
278
279
        return $attendances;
280
    }
281
282
    /**
283
     * Get the attendances by id to display on the current page.
284
     *
285
     * @param int $attendanceId
286
     *
287
     * @return array attendance data
288
     */
289
    public function get_attendance_by_id($attendanceId)
290
    {
291
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
292
        $attendanceId = (int) $attendanceId;
293
        $course_id = api_get_course_int_id();
294
        $attendance_data = [];
295
        $sql = "SELECT * FROM $tbl_attendance
296
                WHERE c_id = $course_id AND id = '$attendanceId'";
297
        $res = Database::query($sql);
298
        if (Database::num_rows($res) > 0) {
299
            while ($row = Database::fetch_array($res)) {
300
                $attendance_data = $row;
301
            }
302
        }
303
304
        return $attendance_data;
305
    }
306
307
    /**
308
     * Add attendances sheet inside table. This is the *list of* dates, not
309
     * a specific date in itself.
310
     *
311
     * @param  bool   true for adding link in gradebook or false otherwise (optional)
312
     *
313
     * @return int last attendance id
314
     */
315
    public function attendance_add($link_to_gradebook = false)
316
    {
317
        $_course = api_get_course_info();
318
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
319
        $table_link = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
320
        $session_id = api_get_session_id();
321
        $course_code = $_course['code'];
322
        $course_id = $_course['real_id'];
323
        $title_gradebook = $this->attendance_qualify_title;
324
        $value_calification = 0;
325
        $weight_calification = api_float_val($this->attendance_weight);
326
327
        $attendance = new CAttendance();
328
        $attendance
329
            ->setCId($course_id)
330
            ->setName($this->name)
331
            ->setDescription($this->description)
332
            ->setSessionId($session_id)
333
            ->setAttendanceQualifyTitle($title_gradebook)
334
            ->setAttendanceWeight($weight_calification)
335
        ;
336
337
        $repo = Container::getAttendanceRepository();
338
        $em = $repo->getEntityManager();
339
340
        $em->persist($attendance);
341
342
        $repo->addResourceToCourse(
343
            $attendance,
344
            ResourceLink::VISIBILITY_PUBLISHED,
345
            api_get_user_entity(api_get_user_id()),
346
            api_get_course_entity(),
347
            api_get_session_entity(),
348
            api_get_group_entity()
349
        );
350
        $em->flush();
351
352
        $last_id = $attendance->getIid();
353
354
        if (!empty($last_id)) {
355
            $sql = "UPDATE $tbl_attendance SET id = iid WHERE iid = $last_id";
356
            Database::query($sql);
357
358
            /*api_item_property_update(
359
                $_course,
360
                TOOL_ATTENDANCE,
361
                $last_id,
362
                "AttendanceAdded",
363
                $user_id
364
            );*/
365
        }
366
367
        // add link to gradebook
368
        if ($link_to_gradebook && !empty($this->category_id)) {
369
            $description = '';
370
            $link_info = GradebookUtils::isResourceInCourseGradebook(
371
                $course_code,
372
                7,
373
                $last_id,
374
                $session_id
375
            );
376
            $link_id = $link_info['id'];
377
            if (!$link_info) {
378
                GradebookUtils::add_resource_to_course_gradebook(
379
                    $this->category_id,
380
                    $course_code,
381
                    7,
382
                    $last_id,
383
                    $title_gradebook,
384
                    $weight_calification,
385
                    $value_calification,
386
                    $description,
387
                    1,
388
                    $session_id
389
                );
390
            } else {
391
                Database::query('UPDATE '.$table_link.' SET weight='.$weight_calification.' WHERE id='.$link_id.'');
392
            }
393
        }
394
395
        return $last_id;
396
    }
397
398
    /**
399
     * edit attendances inside table.
400
     *
401
     * @param CAttendance $attendance
402
     * @param bool true for adding link in gradebook or false otherwise (optional)
403
     *
404
     * @return int last id
405
     */
406
    public function attendance_edit($attendance, $link_to_gradebook = false)
407
    {
408
        $_course = api_get_course_info();
409
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
410
        $table_link = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
411
412
        $session_id = api_get_session_id();
413
        $user_id = api_get_user_id();
414
        $attendanceId = $attendance->getIid();
415
        $course_code = $_course['code'];
416
        $course_id = $_course['real_id'];
417
        $title_gradebook = $this->attendance_qualify_title;
418
        $value_calification = 0;
419
        $weight_calification = api_float_val($this->attendance_weight);
420
421
        if ($attendance) {
0 ignored issues
show
introduced by
$attendance is of type Chamilo\CourseBundle\Entity\CAttendance, thus it always evaluated to true.
Loading history...
422
            $attendanceId = $attendance->getIid();
423
            $attendance
424
                ->setName($this->name)
425
                ->setDescription($this->description)
426
                ->setAttendanceQualifyTitle($title_gradebook)
427
                ->setAttendanceWeight($weight_calification)
428
            ;
429
430
            $repo = Container::getAttendanceRepository();
431
            $repo->getEntityManager()->persist($attendance);
432
            $repo->getEntityManager()->flush();
433
434
            /*$params = [
435
                'name' => $this->name,
436
                'description' => $this->description,
437
                'attendance_qualify_title' => $title_gradebook,
438
                'attendance_weight' => $weight_calification,
439
            ];
440
            Database::update(
441
                $tbl_attendance,
442
                $params,
443
                ['c_id = ? AND id = ?' => [$course_id, $attendanceId]]
444
            );
445
            api_item_property_update(
446
                $_course,
447
                TOOL_ATTENDANCE,
448
                $attendanceId,
449
                "AttendanceUpdated",
450
                $user_id
451
            );*/
452
453
            // add link to gradebook
454
            if ($link_to_gradebook && !empty($this->category_id)) {
455
                $description = '';
456
                $link_info = GradebookUtils::isResourceInCourseGradebook(
457
                    $course_code,
458
                    7,
459
                    $attendanceId,
460
                    $session_id
461
                );
462
                if (!$link_info) {
463
                    GradebookUtils::add_resource_to_course_gradebook(
464
                        $this->category_id,
465
                        $course_code,
466
                        7,
467
                        $attendanceId,
468
                        $title_gradebook,
469
                        $weight_calification,
470
                        $value_calification,
471
                        $description,
472
                        1,
473
                        $session_id
474
                    );
475
                } else {
476
                    Database::query('UPDATE '.$table_link.' SET weight='.$weight_calification.' WHERE id='.$link_info['id']);
477
                }
478
            }
479
480
            return $attendanceId;
481
        }
482
483
        return null;
484
    }
485
486
    /**
487
     * Restore attendance.
488
     *
489
     * @param int|array one or many attendances id
490
     *
491
     * @return int affected rows
492
     */
493
    public function attendance_restore($attendanceId)
494
    {
495
        $_course = api_get_course_info();
496
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
497
        $user_id = api_get_user_id();
498
        $course_id = $_course['real_id'];
499
        if (is_array($attendanceId)) {
500
            foreach ($attendanceId as $id) {
501
                $id = (int) $id;
502
                $sql = "UPDATE $tbl_attendance SET active = 1
503
                        WHERE c_id = $course_id AND id = '$id'";
504
                $result = Database::query($sql);
505
                $affected_rows = Database::affected_rows($result);
506
                if (!empty($affected_rows)) {
507
                    // update row item property table
508
                    api_item_property_update(
509
                        $_course,
510
                        TOOL_ATTENDANCE,
511
                        $id,
512
                        'restore',
513
                        $user_id
514
                    );
515
                }
516
            }
517
        } else {
518
            $attendanceId = (int) $attendanceId;
519
            $sql = "UPDATE $tbl_attendance SET active = 1
520
                    WHERE c_id = $course_id AND id = '$attendanceId'";
521
            $result = Database::query($sql);
522
            $affected_rows = Database::affected_rows($result);
523
            if (!empty($affected_rows)) {
524
                // update row item property table
525
                api_item_property_update(
526
                    $_course,
527
                    TOOL_ATTENDANCE,
528
                    $attendanceId,
529
                    'restore',
530
                    $user_id
531
                );
532
            }
533
        }
534
535
        return $affected_rows;
536
    }
537
538
    /**
539
     * Delete attendances.
540
     *
541
     * @param CAttendance $attendance one or many attendances id
542
     *
543
     * @return bool
544
     */
545
    public function attendance_delete(CAttendance $attendance)
546
    {
547
        $allowDeleteAttendance = api_get_setting('allow_delete_attendance');
548
        if ('true' !== $allowDeleteAttendance) {
549
            return false;
550
        }
551
552
        $repo = Container::getAttendanceRepository();
553
        $attendance->setActive(2);
554
        $repo->getEntityManager()->persist($attendance);
555
        $repo->getEntityManager()->flush();
556
557
        Skill::deleteSkillsFromItem($attendance->getIid(), ITEM_TYPE_ATTENDANCE);
558
559
        return true;
560
561
        /*$_course = api_get_course_info();
562
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
563
        $user_id = api_get_user_id();
564
        $course_id = $_course['real_id'];
565
566
        $attendanceId = (int) $attendanceId;
567
        $sql = "UPDATE $tbl_attendance SET active = 2
568
                WHERE c_id = $course_id AND id = '$attendanceId'";
569
570
        $result = Database::query($sql);
571
        $affected_rows = Database::affected_rows($result);
572
        if (!empty($affected_rows)) {
573
            // update row item property table
574
            api_item_property_update(
575
                $_course,
576
                TOOL_ATTENDANCE,
577
                $attendanceId,
578
                "delete",
579
                $user_id
580
            );
581
        }return $affected_rows;
582
        */
583
    }
584
585
    /**
586
     * Changes visibility.
587
     *
588
     * @param CAttendance $attendance one or many attendances id
589
     * @param int         $status
590
     *
591
     * @return int affected rows
592
     */
593
    public function changeVisibility(CAttendance $attendance, $status = 1)
594
    {
595
        $status = (int) $status;
596
597
        $repo = Container::getAttendanceRepository();
598
        $em = $repo->getEntityManager();
599
        $attendance->setActive($status);
600
        $em->persist($attendance);
601
        $em->flush();
602
603
        return true;
604
        /*
605
606
        $attendanceId = (int) $attendanceId;
607
        $sql = "UPDATE $tbl_attendance SET active = $status
608
                WHERE c_id = $course_id AND id = '$attendanceId'";
609
        $result = Database::query($sql);
610
        $affected_rows = Database::affected_rows($result);
611
        if (!empty($affected_rows)) {
612
            // update row item property table
613
            api_item_property_update(
614
                $_course,
615
                TOOL_ATTENDANCE,
616
                $attendanceId,
617
                $action,
618
                $user_id
619
            );
620
        }
621
622
        return $affected_rows;
623
        */
624
    }
625
626
    /**
627
     * Lock or unlock an attendance.
628
     *
629
     * @param bool    True to lock or false otherwise
630
     *
631
     * @return bool
632
     */
633
    public function lock(CAttendance $attendance, $lock = true)
634
    {
635
        $repo = Container::getAttendanceRepository();
636
        $em = $repo->getEntityManager();
637
        $attendance->setLocked($lock);
638
        $em->persist($attendance);
639
        $em->flush();
640
641
        return true;
642
643
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
0 ignored issues
show
Unused Code introduced by
$tbl_attendance = Databa...table(TABLE_ATTENDANCE) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
644
        $course_id = api_get_course_int_id();
645
        $attendanceId = (int) $attendanceId;
646
        $locked = $lock ? 1 : 0;
647
        $upd = "UPDATE $tbl_attendance SET locked = $locked
648
                WHERE c_id = $course_id AND id = $attendanceId";
649
        $result = Database::query($upd);
650
        $affected_rows = Database::affected_rows($result);
651
        if ($affected_rows && $lock) {
652
            // Save attendance sheet log
653
            $this->saveAttendanceSheetLog(
654
                $attendanceId,
655
                api_get_utc_datetime(),
656
                self::LOCKED_ATTENDANCE_LOG_TYPE,
657
                api_get_user_id()
658
            );
659
        }
660
661
        return $affected_rows;
662
    }
663
664
    /**
665
     * Get registered users inside current course.
666
     *
667
     * @param int $attendanceId attendance id for showing attendance result field (optional)
668
     * @param int $groupId
669
     *
670
     * @return array users data
671
     */
672
    public function get_users_rel_course($attendanceId = 0, $groupId = 0)
673
    {
674
        $current_session_id = api_get_session_id();
675
        $current_course_id = api_get_course_id();
676
        $currentCourseIntId = api_get_course_int_id();
677
        $studentInGroup = [];
678
679
        if (!empty($current_session_id)) {
680
            $a_course_users = CourseManager:: get_user_list_from_course_code(
681
                $current_course_id,
682
                $current_session_id,
683
                '',
684
                'lastname'
685
            );
686
        } else {
687
            $a_course_users = CourseManager:: get_user_list_from_course_code(
688
                $current_course_id,
689
                0,
690
                '',
691
                'lastname'
692
            );
693
        }
694
695
        if (!empty($groupId)) {
696
            $groupInfo = GroupManager::get_group_properties($groupId);
697
            $students = GroupManager::getStudents($groupInfo['iid']);
698
            if (!empty($students)) {
699
                foreach ($students as $student) {
700
                    $studentInGroup[$student['user_id']] = true;
701
                }
702
            }
703
        }
704
705
        // get registered users inside current course
706
        $a_users = [];
707
        foreach ($a_course_users as $key => $user_data) {
708
            $value = [];
709
            $uid = $user_data['user_id'];
710
            $userInfo = api_get_user_info($uid);
711
            $status = $user_data['status'];
712
713
            if (!empty($groupId)) {
714
                if (!isset($studentInGroup[$uid])) {
715
                    continue;
716
                }
717
            }
718
719
            $user_status_in_session = null;
720
            $user_status_in_course = null;
721
722
            if (api_get_session_id()) {
723
                $user_status_in_session = SessionManager::get_user_status_in_course_session(
724
                    $uid,
725
                    $currentCourseIntId,
726
                    $current_session_id
727
                );
728
            } else {
729
                $user_status_in_course = CourseManager::getUserInCourseStatus(
730
                    $uid,
731
                    $currentCourseIntId
732
                );
733
            }
734
735
            // Not taking into account DRH or COURSEMANAGER
736
            if ($uid <= 1 ||
737
                DRH == $status ||
738
                COURSEMANAGER == $user_status_in_course ||
739
                2 == $user_status_in_session
740
            ) {
741
                continue;
742
            }
743
744
            if (!empty($attendanceId)) {
745
                $user_faults = $this->get_faults_of_user(
746
                    $uid,
747
                    $attendanceId,
748
                    $groupId
749
                );
750
                $value['attendance_result'] = $user_faults['faults'].'/'.$user_faults['total'].' ('.$user_faults['faults_porcent'].'%)';
751
                $value['result_color_bar'] = $user_faults['color_bar'];
752
            }
753
754
            $photo = Display::img(
755
                $userInfo['avatar_small'],
756
                $userInfo['complete_name'],
757
                [],
758
                false
759
            );
760
761
            $value['photo'] = $photo;
762
            $value['firstname'] = $user_data['firstname'];
763
            $value['lastname'] = $user_data['lastname'];
764
            $value['username'] = $user_data['username'];
765
            $value['user_id'] = $uid;
766
767
            // Sending only 5 items in the array instead of 60
768
            $a_users[$key] = $value;
769
        }
770
771
        return $a_users;
772
    }
773
774
    /**
775
     * add attendances sheet inside table.
776
     *
777
     * @param int   $calendar_id   attendance calendar id
778
     * @param array $users_present present users during current class
779
     * @param int   $attendanceId
780
     *
781
     * @return int affected rows
782
     */
783
    public function attendance_sheet_add($calendar_id, $users_present, $attendanceId)
784
    {
785
        $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET);
786
        $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
787
788
        $calendar_id = (int) $calendar_id;
789
        $attendanceId = (int) $attendanceId;
790
        $users = $this->get_users_rel_course();
791
        $course_id = api_get_course_int_id();
792
793
        $user_ids = array_keys($users);
794
        $users_absent = array_diff($user_ids, $users_present);
795
        $affected_rows = 0;
796
797
        // get last edit type
798
        $calendar_data = $this->get_attendance_calendar_by_id($calendar_id);
799
        $lastedit_type = self::DONE_ATTENDANCE_LOG_TYPE;
800
        if ($calendar_data['done_attendance']) {
801
            $lastedit_type = self::UPDATED_ATTENDANCE_LOG_TYPE;
802
        }
803
804
        // save users present in class
805
        foreach ($users_present as $user_present) {
806
            $uid = (int) $user_present;
807
            // check if user already was registered with the $calendar_id
808
            $sql = "SELECT user_id FROM $tbl_attendance_sheet
809
                    WHERE c_id = $course_id AND user_id='$uid' AND attendance_calendar_id = '$calendar_id'";
810
            $rs = Database::query($sql);
811
            if (0 == Database::num_rows($rs)) {
812
                $sql = "INSERT INTO $tbl_attendance_sheet SET
813
                        c_id = $course_id,
814
                        user_id = '$uid',
815
                        attendance_calendar_id = '$calendar_id',
816
                        presence = 1";
817
                $result = Database::query($sql);
818
819
                $affected_rows += Database::affected_rows($result);
820
            } else {
821
                $sql = "UPDATE $tbl_attendance_sheet SET presence = 1
822
                        WHERE
823
                            c_id = $course_id AND
824
                            user_id ='$uid' AND
825
                            attendance_calendar_id = '$calendar_id'
826
                        ";
827
                $result = Database::query($sql);
828
                $affected_rows += Database::affected_rows($result);
829
            }
830
        }
831
832
        // save users absent in class
833
        foreach ($users_absent as $user_absent) {
834
            $uid = (int) $user_absent;
835
            // check if user already was registered with the $calendar_id
836
            $sql = "SELECT user_id FROM $tbl_attendance_sheet
837
                    WHERE c_id = $course_id AND user_id='$uid' AND attendance_calendar_id = '$calendar_id'";
838
            $rs = Database::query($sql);
839
            if (0 == Database::num_rows($rs)) {
840
                $sql = "INSERT INTO $tbl_attendance_sheet SET
841
                        c_id = $course_id,
842
                        user_id ='$uid',
843
                        attendance_calendar_id = '$calendar_id',
844
                        presence = 0";
845
                $result = Database::query($sql);
846
                $affected_rows += Database::affected_rows($result);
847
            } else {
848
                $sql = "UPDATE $tbl_attendance_sheet SET presence = 0
849
                        WHERE
850
                            c_id = $course_id AND
851
                            user_id ='$uid' AND
852
                            attendance_calendar_id = '$calendar_id'";
853
                $result = Database::query($sql);
854
                $affected_rows += Database::affected_rows($result);
855
            }
856
        }
857
858
        // update done_attendance inside attendance calendar table
859
        $sql = "UPDATE $tbl_attendance_calendar SET done_attendance = 1
860
                WHERE  c_id = $course_id AND id = '$calendar_id'";
861
        Database::query($sql);
862
863
        // save users' results
864
        $this->updateUsersResults($user_ids, $attendanceId);
865
866
        if ($affected_rows) {
867
            //save attendance sheet log
868
            $this->saveAttendanceSheetLog(
869
                $attendanceId,
870
                api_get_utc_datetime(),
871
                $lastedit_type,
872
                api_get_user_id(),
873
                $calendar_data['date_time']
874
            );
875
        }
876
877
        return $affected_rows;
878
    }
879
880
    /**
881
     * update users' attendance results.
882
     *
883
     * @param array $user_ids     registered users inside current course
884
     * @param int   $attendanceId
885
     */
886
    public function updateUsersResults($user_ids, $attendanceId)
887
    {
888
        $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET);
889
        $tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT);
890
        $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
891
        $course_id = api_get_course_int_id();
892
        $attendanceId = (int) $attendanceId;
893
        // fill results about presence of students
894
        $attendance_calendar = $this->get_attendance_calendar(
895
            $attendanceId,
896
            'all',
897
            null,
898
            null,
899
            true
900
        );
901
        $calendar_ids = [];
902
        // get all dates from calendar by current attendance
903
        foreach ($attendance_calendar as $cal) {
904
            $calendar_ids[] = $cal['id'];
905
        }
906
907
        // get count of presences by users inside current attendance and save like results
908
        if (count($user_ids) > 0) {
909
            foreach ($user_ids as $uid) {
910
                $uid = (int) $uid;
911
                $count_presences = 0;
912
                if (count($calendar_ids) > 0) {
913
                    $sql = "SELECT count(presence) as count_presences
914
                            FROM $tbl_attendance_sheet
915
                            WHERE
916
                                c_id = $course_id AND
917
                                user_id = '$uid' AND
918
                                attendance_calendar_id IN (".implode(',', $calendar_ids).') AND
919
                                presence = 1';
920
                    $rs_count = Database::query($sql);
921
                    $row_count = Database::fetch_array($rs_count);
922
                    $count_presences = $row_count['count_presences'];
923
                }
924
925
                // save results
926
                $sql = "SELECT id FROM $tbl_attendance_result
927
                        WHERE
928
                            c_id = $course_id AND
929
                            user_id = '$uid' AND
930
                            attendance_id = '$attendanceId' ";
931
                $rs_check_result = Database::query($sql);
932
933
                if (Database::num_rows($rs_check_result) > 0) {
934
                    // update result
935
                    $sql = "UPDATE $tbl_attendance_result SET
936
                            score = '$count_presences'
937
                            WHERE
938
                                c_id = $course_id AND
939
                                user_id='$uid' AND
940
                                attendance_id='$attendanceId'";
941
                    Database::query($sql);
942
                } else {
943
                    // insert new result
944
                    $sql = "INSERT INTO $tbl_attendance_result SET
945
                            c_id = $course_id ,
946
                            user_id			= '$uid',
947
                            attendance_id 	= '$attendanceId',
948
                            score			= '$count_presences'";
949
                    Database::query($sql);
950
951
                    $insertId = Database::insert_id();
952
                    if ($insertId) {
953
                        $sql = "UPDATE $tbl_attendance_result SET id = iid WHERE iid = $insertId";
954
                        Database::query($sql);
955
                    }
956
                }
957
            }
958
        }
959
960
        // update attendance qualify max
961
        $count_done_calendar = self::get_done_attendance_calendar($attendanceId);
962
        $sql = "UPDATE $tbl_attendance SET
963
                    attendance_qualify_max = '$count_done_calendar'
964
                WHERE c_id = $course_id AND id = '$attendanceId'";
965
        Database::query($sql);
966
    }
967
968
    /**
969
     * update attendance_sheet_log table, is used as history of an attendance sheet.
970
     *
971
     * @param   int     Attendance id
972
     * @param   string  Last edit datetime
973
     * @param   string  Event type ('locked_attendance', 'done_attendance_sheet' ...)
974
     * @param   int     Last edit user id
975
     * @param   string  Calendar datetime value (optional, when event type is 'done_attendance_sheet')
976
     *
977
     * @return int Affected rows
978
     */
979
    public function saveAttendanceSheetLog(
980
        $attendanceId,
981
        $lastedit_date,
982
        $lastedit_type,
983
        $lastedit_user_id,
984
        $calendar_date_value = null
985
    ) {
986
        $course_id = api_get_course_int_id();
987
988
        // define table
989
        $tbl_attendance_sheet_log = Database::get_course_table(TABLE_ATTENDANCE_SHEET_LOG);
990
991
        // protect data
992
        $attendanceId = (int) $attendanceId;
993
        $lastedit_user_id = (int) $lastedit_user_id;
994
995
        if (isset($calendar_date_value)) {
996
            $calendar_date_value = $calendar_date_value;
997
        } else {
998
            $calendar_date_value = '';
999
        }
1000
1001
        // save data
1002
        $params = [
1003
            'c_id' => $course_id,
1004
            'attendance_id' => $attendanceId,
1005
            'lastedit_date' => $lastedit_date,
1006
            'lastedit_type' => $lastedit_type,
1007
            'lastedit_user_id' => $lastedit_user_id,
1008
            'calendar_date_value' => $calendar_date_value,
1009
        ];
1010
        $insertId = Database::insert($tbl_attendance_sheet_log, $params);
1011
        if ($insertId) {
1012
            $sql = "UPDATE $tbl_attendance_sheet_log SET id = iid WHERE iid = $insertId";
1013
            Database::query($sql);
1014
        }
1015
1016
        return $insertId;
1017
    }
1018
1019
    /**
1020
     * Get number of done attendances inside current sheet.
1021
     *
1022
     * @param int attendance id
1023
     *
1024
     * @return int number of done attendances
1025
     */
1026
    public static function get_done_attendance_calendar($attendanceId)
1027
    {
1028
        $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1029
        $attendanceId = (int) $attendanceId;
1030
        $course_id = api_get_course_int_id();
1031
        $sql = "SELECT count(done_attendance) as count
1032
                FROM $table
1033
                WHERE
1034
                    c_id = $course_id AND
1035
                    attendance_id = '$attendanceId' AND
1036
                    done_attendance = 1
1037
                ";
1038
        $rs = Database::query($sql);
1039
        $row = Database::fetch_array($rs);
1040
        $count = $row['count'];
1041
1042
        return $count;
1043
    }
1044
1045
    /**
1046
     * Get results of faults (absents) by user.
1047
     *
1048
     * @param int $user_id
1049
     * @param int $attendanceId
1050
     * @param int $groupId
1051
     *
1052
     * @return array results containing number of faults, total done attendance,
1053
     *               percent of faults and color depend on result (red, orange)
1054
     */
1055
    public function get_faults_of_user($user_id, $attendanceId, $groupId = null)
1056
    {
1057
        $user_id = (int) $user_id;
1058
        $attendanceId = (int) $attendanceId;
1059
        $results = [];
1060
        $calendar_count = self::get_number_of_attendance_calendar(
1061
            $attendanceId,
1062
            $groupId,
1063
            null,
1064
            $user_id
1065
        );
1066
        // $total_done_attendance 	= $attendance_data['attendance_qualify_max'];
1067
        $total_done_attendance = self::get_number_of_attendance_calendar(
1068
            $attendanceId,
1069
            $groupId,
1070
            true,
1071
            $user_id
1072
        );
1073
        $attendance_user_score = $this->get_user_score(
1074
            $user_id,
1075
            $attendanceId,
1076
            $groupId
1077
        );
1078
1079
        //This is the main change of the BT#1381
1080
        //$total_done_attendance = $calendar_count;
1081
1082
        // calculate results
1083
        $faults = $total_done_attendance - $attendance_user_score;
1084
1085
        if (empty($calendar_count)) {
1086
            $faults = 0;
1087
        }
1088
1089
        $faults = $faults > 0 ? $faults : 0;
1090
        $faults_porcent = $calendar_count > 0 ? round(($faults * 100) / $calendar_count, 0) : 0;
1091
        $results['faults'] = $faults;
1092
        $results['total'] = $calendar_count;
1093
        $results['faults_porcent'] = $faults_porcent;
1094
        $color_bar = '';
1095
1096
        if ($faults_porcent > 25) {
1097
            $color_bar = '#f28989';
1098
        } elseif ($faults_porcent > 10) {
1099
            $color_bar = '#F90';
1100
        }
1101
        $results['color_bar'] = $color_bar;
1102
1103
        return $results;
1104
    }
1105
1106
    /**
1107
     * Get results of faults average for all courses by user.
1108
     *
1109
     * @param int $user_id
1110
     *
1111
     * @return array results containing number of faults, total done attendance,
1112
     *               percentage of faults and color depend on result (red, orange)
1113
     */
1114
    public function get_faults_average_inside_courses($user_id)
1115
    {
1116
        // get all courses of current user
1117
        $courses = CourseManager::get_courses_list_by_user_id($user_id, true);
1118
        $user_id = (int) $user_id;
1119
        $results = [];
1120
        $total_faults = $total_weight = $porcent = 0;
1121
        foreach ($courses as $course) {
1122
            //$course_code = $course['code'];
1123
            //$course_info = api_get_course_info($course_code);
1124
            $course_id = $course['real_id'];
1125
            $tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT);
1126
            $attendances_by_course = $this->get_attendances_list($course_id);
1127
1128
            foreach ($attendances_by_course as $attendance) {
1129
                // get total faults and total weight
1130
                $total_done_attendance = $attendance['attendance_qualify_max'];
1131
                $sql = "SELECT score
1132
                        FROM $tbl_attendance_result
1133
                        WHERE
1134
                            c_id = $course_id AND
1135
                            user_id = $user_id AND
1136
                            attendance_id = ".$attendance['id'];
1137
                $rs = Database::query($sql);
1138
                $score = 0;
1139
                if (Database::num_rows($rs) > 0) {
1140
                    $row = Database::fetch_array($rs);
1141
                    $score = $row['score'];
1142
                }
1143
                $faults = $total_done_attendance - $score;
1144
                $faults = $faults > 0 ? $faults : 0;
1145
                $total_faults += $faults;
1146
                $total_weight += $total_done_attendance;
1147
            }
1148
        }
1149
1150
        $porcent = $total_weight > 0 ? round(($total_faults * 100) / $total_weight, 0) : 0;
1151
        $results['faults'] = $total_faults;
1152
        $results['total'] = $total_weight;
1153
        $results['porcent'] = $porcent;
1154
1155
        return $results;
1156
    }
1157
1158
    /**
1159
     * Get results of faults average by course.
1160
     *
1161
     * @param int    $user_id
1162
     * @param string $course_code
1163
     * @param int Session id (optional)
1164
     *
1165
     * @return array results containing number of faults,
1166
     *               total done attendance, porcent of faults and color depend on result (red, orange)
1167
     */
1168
    public function get_faults_average_by_course(
1169
        $user_id,
1170
        $course_code,
1171
        $session_id = null
1172
    ) {
1173
        // Database tables and variables
1174
        $course_info = api_get_course_info($course_code);
1175
        $tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT);
1176
        $user_id = (int) $user_id;
1177
        $results = [];
1178
        $total_faults = $total_weight = $porcent = 0;
1179
        $attendances_by_course = $this->get_attendances_list(
1180
            $course_info['real_id'],
1181
            $session_id
1182
        );
1183
1184
        foreach ($attendances_by_course as $attendance) {
1185
            // Get total faults and total weight
1186
            $total_done_attendance = $attendance['attendance_qualify_max'];
1187
            $sql = "SELECT score FROM $tbl_attendance_result
1188
                    WHERE
1189
                        c_id = {$course_info['real_id']} AND
1190
                        user_id = $user_id AND
1191
                        attendance_id=".$attendance['id'];
1192
            $rs = Database::query($sql);
1193
            $score = 0;
1194
            if (Database::num_rows($rs) > 0) {
1195
                $row = Database::fetch_array($rs);
1196
                $score = $row['score'];
1197
            }
1198
            $faults = $total_done_attendance - $score;
1199
            $faults = $faults > 0 ? $faults : 0;
1200
            $total_faults += $faults;
1201
            $total_weight += $total_done_attendance;
1202
        }
1203
1204
        $porcent = $total_weight > 0 ? round(($total_faults * 100) / $total_weight, 0) : 0;
1205
        $results['faults'] = $total_faults;
1206
        $results['total'] = $total_weight;
1207
        $results['porcent'] = $porcent;
1208
1209
        return $results;
1210
    }
1211
1212
    /**
1213
     * Get registered users' attendance sheet inside current course.
1214
     *
1215
     * @param int $attendanceId
1216
     * @param int $user_id      for showing data for only one user (optional)
1217
     * @param int $groupId
1218
     *
1219
     * @return array users attendance sheet data
1220
     */
1221
    public function get_users_attendance_sheet(
1222
        $attendanceId,
1223
        $user_id = 0,
1224
        $groupId = 0,
1225
        $course_id = 0,
1226
        DateTime $startDate = null,
1227
        DateTime $endDate = null
1228
    ) {
1229
        //Get actual course or by course_id
1230
        $course_id = (0 == $course_id) ? api_get_course_int_id() : (int) $course_id;
1231
        $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET);
1232
        $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1233
        $attendance_calendar = $this->get_attendance_calendar(
1234
            $attendanceId,
1235
            'all',
1236
            null,
1237
            $groupId,
1238
            true,
1239
            $course_id,
1240
            $startDate,
1241
            $endDate
1242
        );
1243
        $calendar_ids = [];
1244
        // get all dates from calendar by current attendance
1245
        foreach ($attendance_calendar as $cal) {
1246
            $calendar_ids[] = $cal['id'];
1247
        }
1248
1249
        $whereDate = '';
1250
        if (!empty($startDate)) {
1251
            $whereDate .= " AND cal.date_time >= '".$startDate->format('Y-m-d H:i:s')."'";
1252
        }
1253
        if (!empty($endDate)) {
1254
            $whereDate .= " AND cal.date_time <= '".$endDate->format('Y-m-d H:i:s')."'";
1255
        }
1256
1257
        // moved at start of this function
1258
        // $course_id = api_get_course_int_id();
1259
1260
        $data = [];
1261
        if (empty($user_id)) {
1262
            // get all registered users inside current course
1263
            $users = $this->get_users_rel_course();
1264
            $user_ids = array_keys($users);
1265
            if (count($calendar_ids) > 0 && count($user_ids) > 0) {
1266
                foreach ($user_ids as $uid) {
1267
                    $uid = (int) $uid;
1268
                    $sql = "SELECT * FROM $tbl_attendance_sheet
1269
                            WHERE
1270
                                c_id = $course_id AND
1271
                                user_id = '$uid' AND
1272
                                attendance_calendar_id IN(".implode(',', $calendar_ids).')
1273
                            ';
1274
                    $res = Database::query($sql);
1275
                    if (Database::num_rows($res) > 0) {
1276
                        while ($row = Database::fetch_array($res)) {
1277
                            $data[$uid][$row['attendance_calendar_id']]['presence'] = $row['presence'];
1278
                        }
1279
                    }
1280
                }
1281
            }
1282
        } else {
1283
            // Get attendance for current user
1284
            $user_id = (int) $user_id;
1285
            if (count($calendar_ids) > 0) {
1286
                $sql = "SELECT cal.date_time, att.presence
1287
                        FROM $tbl_attendance_sheet att
1288
                        INNER JOIN  $tbl_attendance_calendar cal
1289
                        ON cal.id = att.attendance_calendar_id
1290
                        WHERE
1291
                            att.c_id = $course_id AND
1292
                            cal.c_id =  $course_id AND
1293
                            att.user_id = '$user_id' AND
1294
                            att.attendance_calendar_id IN (".implode(',', $calendar_ids).")
1295
                            $whereDate
1296
                        ORDER BY date_time";
1297
                $res = Database::query($sql);
1298
                if (Database::num_rows($res) > 0) {
1299
                    while ($row = Database::fetch_array($res)) {
1300
                        $row['date_time'] = api_convert_and_format_date($row['date_time'], null, date_default_timezone_get());
1301
                        $data[$user_id][] = $row;
1302
                    }
1303
                }
1304
            }
1305
        }
1306
1307
        return $data;
1308
    }
1309
1310
    /**
1311
     * Get next attendance calendar without presences (done attendances).
1312
     *
1313
     * @param int    attendance id
1314
     *
1315
     * @return int attendance calendar id
1316
     */
1317
    public function get_next_attendance_calendar_id($attendanceId)
1318
    {
1319
        $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1320
        $attendanceId = (int) $attendanceId;
1321
        $course_id = api_get_course_int_id();
1322
1323
        $sql = "SELECT id FROM $table
1324
                WHERE
1325
                    c_id = $course_id AND
1326
                    attendance_id = '$attendanceId' AND
1327
                    done_attendance = 0
1328
                ORDER BY date_time
1329
                LIMIT 1";
1330
        $rs = Database::query($sql);
1331
        $next_calendar_id = 0;
1332
        if (Database::num_rows($rs) > 0) {
1333
            $row = Database::fetch_array($rs);
1334
            $next_calendar_id = $row['id'];
1335
        }
1336
1337
        return $next_calendar_id;
1338
    }
1339
1340
    /**
1341
     * Get next attendance calendar datetime without presences (done attendances).
1342
     *
1343
     * @param int    attendance id
1344
     *
1345
     * @return int UNIX time format datetime
1346
     */
1347
    public function getNextAttendanceCalendarDatetime($attendanceId)
1348
    {
1349
        $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1350
        $course_id = api_get_course_int_id();
1351
        $attendanceId = (int) $attendanceId;
1352
        $sql = "SELECT id, date_time FROM $table
1353
                WHERE
1354
                    c_id = $course_id AND
1355
                    attendance_id = '$attendanceId' AND
1356
                    done_attendance = 0
1357
                ORDER BY date_time
1358
                LIMIT 1";
1359
        $rs = Database::query($sql);
1360
        $next_calendar_datetime = 0;
1361
        if (Database::num_rows($rs) > 0) {
1362
            $row = Database::fetch_array($rs);
1363
            $next_calendar_datetime = api_get_local_time($row['date_time']);
1364
        }
1365
1366
        return $next_calendar_datetime;
1367
    }
1368
1369
    /**
1370
     * Get user's score from current attendance.
1371
     *
1372
     * @param int $user_id
1373
     * @param int $attendanceId
1374
     * @param int $groupId
1375
     *
1376
     * @return int score
1377
     */
1378
    public function get_user_score($user_id, $attendanceId, $groupId = 0)
1379
    {
1380
        $tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT);
1381
        $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET);
1382
        $tbl_attendance_cal_rel_group = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP);
1383
        $tbl_attendance_cal = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1384
        $user_id = (int) $user_id;
1385
        $attendanceId = (int) $attendanceId;
1386
        $groupId = (int) $groupId;
1387
        $course_id = api_get_course_int_id();
1388
1389
        if (empty($groupId)) {
1390
            $sql = "SELECT score FROM $tbl_attendance_result
1391
                    WHERE
1392
                        c_id = $course_id AND
1393
                        user_id='$user_id' AND
1394
                        attendance_id='$attendanceId'";
1395
        } else {
1396
            $sql = "SELECT count(presence) as score FROM $tbl_attendance_sheet
1397
                    WHERE
1398
                        c_id = $course_id AND
1399
                        user_id='$user_id' AND
1400
                        presence = 1 AND
1401
                        attendance_calendar_id IN (
1402
                            SELECT calendar_id FROM $tbl_attendance_cal_rel_group crg
1403
                            INNER JOIN $tbl_attendance_cal c
1404
                            ON (crg.calendar_id = c.id)
1405
                            WHERE
1406
                                crg.c_id = $course_id AND
1407
                                crg.group_id = $groupId AND
1408
                                c.attendance_id = $attendanceId
1409
                        )
1410
                    ";
1411
        }
1412
        $rs = Database::query($sql);
1413
        $score = 0;
1414
        if (Database::num_rows($rs) > 0) {
1415
            $row = Database::fetch_array($rs);
1416
            $score = $row['score'];
1417
        }
1418
1419
        return $score;
1420
    }
1421
1422
    /**
1423
     * Get attendance calendar data by id.
1424
     *
1425
     * @param int    attendance calendar id
1426
     *
1427
     * @return array attendance calendar data
1428
     */
1429
    public function get_attendance_calendar_by_id($calendar_id)
1430
    {
1431
        $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1432
        $calendar_id = (int) $calendar_id;
1433
        $course_id = api_get_course_int_id();
1434
        $sql = "SELECT * FROM $table
1435
                WHERE c_id = $course_id AND id = '$calendar_id' ";
1436
        $rs = Database::query($sql);
1437
        $data = [];
1438
        if (Database::num_rows($rs) > 0) {
1439
            while ($row = Database::fetch_array($rs)) {
1440
                $row['date_time'] = api_get_local_time($row['date_time']);
1441
                $data = $row;
1442
            }
1443
        }
1444
1445
        return $data;
1446
    }
1447
1448
    /**
1449
     * Get all attendance calendar data inside current attendance.
1450
     *
1451
     * @param int    $attendanceId
1452
     * @param string $type
1453
     * @param int    $calendar_id
1454
     * @param int    $groupId
1455
     * @param bool   $showAll      = false show group calendar items or not
1456
     * @param int      $course_id
1457
     * @param DateTime $startDate    Filter calendar with a start date
1458
     * @param DateTime $endDate      Filter calendar with a end date
1459
     *
1460
     * @return array attendance calendar data
1461
     */
1462
    public function get_attendance_calendar(
1463
        $attendanceId,
1464
        $type = 'all',
1465
        $calendar_id = null,
1466
        $groupId = 0,
1467
        $showAll = false,
1468
        $course_id = 0,
1469
        DateTime $startDate = null,
1470
        DateTime $endDate = null
1471
    ) {
1472
        $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1473
        $tbl_acrg = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP);
1474
        $attendanceId = (int) $attendanceId;
1475
        $course_id = (0 == $course_id) ? api_get_course_int_id() : (int) $course_id;
1476
        $whereDate = '';
1477
        if (!empty($startDate)) {
1478
            $whereDate .= " AND c.date_time >= '".$startDate->format('Y-m-d H:i:s')."'";
1479
        }
1480
        if (!empty($endDate)) {
1481
            $whereDate .= " AND c.date_time <= '".$endDate->format('Y-m-d H:i:s')."'";
1482
        }
1483
        if ($showAll) {
1484
            $sql = "SELECT * FROM $tbl_attendance_calendar c
1485
                    WHERE c_id = $course_id
1486
                      AND attendance_id = '$attendanceId'
1487
                        $whereDate";
1488
        } else {
1489
            $sql = "SELECT * FROM $tbl_attendance_calendar c
1490
                    WHERE
1491
                        c_id = $course_id AND
1492
                        attendance_id = '$attendanceId' AND
1493
                        id NOT IN (
1494
                            SELECT calendar_id FROM $tbl_acrg
1495
                            WHERE c_id = $course_id AND group_id != 0 AND group_id IS NOT NULL
1496
                        )
1497
                        $whereDate
1498
                    ";
1499
        }
1500
1501
        if (!empty($groupId)) {
1502
            $groupId = (int) $groupId;
1503
            $sql = "SELECT c.* FROM $tbl_attendance_calendar c
1504
                    INNER JOIN $tbl_acrg g
1505
                    ON c.c_id = g.c_id AND c.id = g.calendar_id
1506
                    WHERE
1507
                        c.c_id = $course_id AND
1508
                        g.group_id = '$groupId' AND
1509
                        c.attendance_id = '$attendanceId'
1510
                   ";
1511
        }
1512
1513
        if (!in_array($type, ['today', 'all', 'all_done', 'all_not_done', 'calendar_id'])) {
1514
            $type = 'all';
1515
        }
1516
1517
        switch ($type) {
1518
            case 'calendar_id':
1519
                $calendar_id = (int) $calendar_id;
1520
                if (!empty($calendar_id)) {
1521
                    $sql .= " AND c.id = $calendar_id";
1522
                }
1523
                break;
1524
            case 'today':
1525
                //$sql .= ' AND DATE_FORMAT(date_time,"%d-%m-%Y") = DATE_FORMAT("'.api_get_utc_datetime().'", "%d-%m-%Y" )';
1526
                break;
1527
            case 'all_done':
1528
                $sql .= ' AND done_attendance = 1 ';
1529
                break;
1530
            case 'all_not_done':
1531
                $sql .= ' AND done_attendance = 0 ';
1532
                break;
1533
            case 'all':
1534
            default:
1535
                break;
1536
        }
1537
        $sql .= ' ORDER BY date_time ';
1538
1539
        $rs = Database::query($sql);
1540
        $data = [];
1541
        if (Database::num_rows($rs) > 0) {
1542
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
1543
                $row['db_date_time'] = $row['date_time'];
1544
                $row['date_time'] = api_get_local_time($row['date_time']);
1545
                $row['date'] = api_format_date($row['date_time'], DATE_FORMAT_SHORT);
1546
                $row['time'] = api_format_date($row['date_time'], TIME_NO_SEC_FORMAT);
1547
                $row['groups'] = $this->getGroupListByAttendanceCalendar($row['id'], $course_id);
1548
                if ('today' === $type) {
1549
                    if (date('d-m-Y', api_strtotime($row['date_time'], 'UTC')) == date('d-m-Y', time())) {
1550
                        $data[] = $row;
1551
                    }
1552
                } else {
1553
                    $data[] = $row;
1554
                }
1555
            }
1556
        }
1557
1558
        return $data;
1559
    }
1560
1561
    /**
1562
     * Get number of attendance calendar inside current attendance.
1563
     *
1564
     * @param int $attendanceId
1565
     * @param int $groupId
1566
     * @param $done_attendance
1567
     * @param int $userId
1568
     *
1569
     * @return int number of dates in attendance calendar
1570
     */
1571
    public static function get_number_of_attendance_calendar(
1572
        $attendanceId,
1573
        $groupId = 0,
1574
        $done_attendance = null,
1575
        $userId = 0
1576
    ) {
1577
        $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1578
        $calendarRelGroup = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP);
1579
        $tbl_groupRelUser = Database::get_course_table(TABLE_GROUP_USER);
1580
        $attendanceId = (int) $attendanceId;
1581
        $groupId = (int) $groupId;
1582
        $course_id = api_get_course_int_id();
1583
1584
        $where_attendance = '';
1585
        if ($done_attendance) {
1586
            $where_attendance = ' done_attendance = 1 AND ';
1587
        }
1588
        if (empty($userId)) {
1589
            if (empty($groupId)) {
1590
                $sql = "SELECT count(a.id)
1591
                        FROM $tbl_attendance_calendar a
1592
                        WHERE
1593
                            c_id = $course_id AND
1594
                            $where_attendance
1595
                            attendance_id = '$attendanceId' AND
1596
                            id NOT IN (
1597
                                SELECT calendar_id FROM $calendarRelGroup
1598
                                WHERE
1599
                                    c_id = $course_id AND
1600
                                    group_id != 0 AND
1601
                                    group_id IS NOT NULL
1602
                            )
1603
                        ";
1604
            } else {
1605
                $sql = "SELECT count(a.id)
1606
                        FROM $tbl_attendance_calendar a
1607
                        INNER JOIN $calendarRelGroup g
1608
                        ON (a.id = g.calendar_id AND a.c_id = g.c_id)
1609
                        WHERE
1610
                            a.c_id = $course_id AND
1611
                            $where_attendance
1612
                            attendance_id = '$attendanceId' AND
1613
                            group_id = $groupId
1614
                        ";
1615
            }
1616
        } else {
1617
            if (empty($groupId)) {
1618
                $sql = "SELECT count(a.id)
1619
                        FROM $tbl_attendance_calendar a
1620
                        WHERE
1621
                            c_id = $course_id AND
1622
                            $where_attendance
1623
                            attendance_id = '$attendanceId' AND
1624
                            id NOT IN (
1625
                                SELECT calendar_id FROM $calendarRelGroup
1626
                                WHERE
1627
                                    c_id = $course_id AND
1628
                                    group_id != 0 AND
1629
                                    group_id IS NOT NULL AND
1630
                                    group_id NOT IN (
1631
                                        SELECT group_id
1632
                                        FROM $tbl_groupRelUser
1633
                                        WHERE user_id = $userId
1634
                                    )
1635
                            )
1636
                        ";
1637
            } else {
1638
                $sql = "SELECT count(a.id)
1639
                        FROM $tbl_attendance_calendar a
1640
                        INNER JOIN $calendarRelGroup g
1641
                        ON (a.id = g.calendar_id AND a.c_id = g.c_id)
1642
                        WHERE
1643
                            a.c_id = $course_id AND
1644
                            $where_attendance
1645
                            attendance_id = '$attendanceId' AND
1646
                            group_id = $groupId
1647
                        ";
1648
            }
1649
        }
1650
1651
        $rs = Database::query($sql);
1652
        $row = Database::fetch_row($rs);
1653
1654
        return $row[0];
1655
    }
1656
1657
    /**
1658
     * Get count dates inside attendance calendar by attendance id.
1659
     *
1660
     * @param int $attendanceId
1661
     *
1662
     * @return int count of dates
1663
     */
1664
    public static function get_count_dates_inside_attendance_calendar($attendanceId)
1665
    {
1666
        $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1667
        $attendanceId = (int) $attendanceId;
1668
        $course_id = api_get_course_int_id();
1669
        $sql = "SELECT count(id) FROM $tbl_attendance_calendar
1670
                WHERE
1671
                    c_id = $course_id AND
1672
                    attendance_id = '$attendanceId'";
1673
        $rs = Database::query($sql);
1674
        $count = 0;
1675
        if (Database::num_rows($rs) > 0) {
1676
            $row = Database::fetch_row($rs);
1677
            $count = $row[0];
1678
        }
1679
1680
        return $count;
1681
    }
1682
1683
    /**
1684
     * check if all calendar of an attendance is done.
1685
     *
1686
     * @param int $attendanceId
1687
     *
1688
     * @return bool True if all calendar is done, otherwise false
1689
     */
1690
    public static function is_all_attendance_calendar_done($attendanceId)
1691
    {
1692
        $attendanceId = (int) $attendanceId;
1693
        $done_calendar = self::get_done_attendance_calendar($attendanceId);
1694
        $count_dates_in_calendar = self::get_count_dates_inside_attendance_calendar($attendanceId);
1695
        $number_of_dates = self::get_number_of_attendance_calendar($attendanceId);
1696
1697
        $result = false;
1698
        if ($number_of_dates && intval($count_dates_in_calendar) == intval($done_calendar)) {
1699
            $result = true;
1700
        }
1701
1702
        return $result;
1703
    }
1704
1705
    /**
1706
     * check if an attendance is locked.
1707
     *
1708
     * @param int $attendanceId
1709
     * @param bool
1710
     *
1711
     * @return bool
1712
     */
1713
    public static function is_locked_attendance($attendanceId)
1714
    {
1715
        //  Use gradebook lock
1716
        return api_resource_is_locked_by_gradebook($attendanceId, LINK_ATTENDANCE);
1717
    }
1718
1719
    /**
1720
     * Add new datetime inside attendance calendar table.
1721
     *
1722
     * @param CAttendance $attendance
1723
     * @param array       $groupList
1724
     *
1725
     * @return int affected rows
1726
     */
1727
    public function attendance_calendar_add($attendance, $groupList = [])
1728
    {
1729
        $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1730
        $affected_rows = 0;
1731
        $attendanceId = $attendance->getIid();
1732
        $course_id = api_get_course_int_id();
1733
        // check if datetime already exists inside the table
1734
        /*$sql = "SELECT id FROM $tbl_attendance_calendar
1735
                WHERE
1736
                    c_id = $course_id AND
1737
                    date_time='".Database::escape_string($this->date_time)."' AND
1738
                    attendance_id = '$attendanceId'";
1739
        $rs = Database::query($sql);
1740
        if (Database::num_rows($rs) == 0) {*/
1741
        $params = [
1742
            'c_id' => $course_id,
1743
            'date_time' => $this->date_time,
1744
            'attendance_id' => $attendanceId,
1745
            'done_attendance' => 0,
1746
        ];
1747
        $id = Database::insert($tbl_attendance_calendar, $params);
1748
1749
        if ($id) {
1750
            $sql = "UPDATE $tbl_attendance_calendar SET id = iid WHERE iid = $id";
1751
            Database::query($sql);
1752
            $affected_rows++;
1753
        }
1754
        $this->addAttendanceCalendarToGroup($id, $course_id, $groupList);
1755
        //}
1756
1757
        // update locked attendance
1758
        $is_all_calendar_done = $this->is_all_attendance_calendar_done($attendanceId);
1759
        if (!$is_all_calendar_done) {
1760
            $this->lock($attendance, false);
1761
        } else {
1762
            $this->lock($attendance);
1763
        }
1764
1765
        return $affected_rows;
1766
    }
1767
1768
    /**
1769
     * @param int   $calendarId
1770
     * @param int   $courseId
1771
     * @param array $groupList
1772
     *
1773
     * @return bool
1774
     */
1775
    public function addAttendanceCalendarToGroup($calendarId, $courseId, $groupList)
1776
    {
1777
        if (empty($groupList)) {
1778
            return false;
1779
        }
1780
1781
        $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP);
1782
        foreach ($groupList as $groupId) {
1783
            if (empty($groupId)) {
1784
                continue;
1785
            }
1786
1787
            $result = $this->getAttendanceCalendarGroup(
1788
                $calendarId,
1789
                $courseId,
1790
                $groupId
1791
            );
1792
1793
            if (empty($result)) {
1794
                $params = [
1795
                    'calendar_id' => $calendarId,
1796
                    'c_id' => $courseId,
1797
                    'group_id' => $groupId,
1798
                ];
1799
                Database::insert($table, $params);
1800
            }
1801
        }
1802
1803
        return true;
1804
    }
1805
1806
    /**
1807
     * @param int $calendarId
1808
     * @param int $courseId
1809
     *
1810
     * @return array
1811
     */
1812
    public function getGroupListByAttendanceCalendar($calendarId, $courseId)
1813
    {
1814
        $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP);
1815
1816
        return Database::select(
1817
            '*',
1818
            $table,
1819
            [
1820
                'where' => [
1821
                    'calendar_id = ? AND c_id = ?' => [$calendarId, $courseId],
1822
                ],
1823
            ]
1824
        );
1825
    }
1826
1827
    /**
1828
     * @param int $calendarId
1829
     * @param int $courseId
1830
     * @param int $groupId
1831
     *
1832
     * @return array
1833
     */
1834
    public function getAttendanceCalendarGroup($calendarId, $courseId, $groupId)
1835
    {
1836
        $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP);
1837
1838
        return Database::select(
1839
            '*',
1840
            $table,
1841
            [
1842
                'where' => [
1843
                    'calendar_id = ? AND c_id = ? AND group_id = ?' => [$calendarId, $courseId, $groupId],
1844
                ],
1845
            ]
1846
        );
1847
    }
1848
1849
    /**
1850
     * @param int $calendarId
1851
     * @param int $courseId
1852
     */
1853
    public function deleteAttendanceCalendarGroup($calendarId, $courseId)
1854
    {
1855
        $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP);
1856
        Database::delete(
1857
            $table,
1858
            [
1859
                'calendar_id = ? AND c_id = ?' => [$calendarId, $courseId],
1860
            ]
1861
        );
1862
    }
1863
1864
    /**
1865
     * save repeated date inside attendance calendar table.
1866
     *
1867
     * @param CAttendance $attendance
1868
     * @param int         $start_date  start date in tms
1869
     * @param int         $end_date    end date in tms
1870
     * @param string      $repeat_type daily, weekly, monthlyByDate
1871
     * @param array       $groupList
1872
     */
1873
    public function attendance_repeat_calendar_add(
1874
        $attendance,
1875
        $start_date,
1876
        $end_date,
1877
        $repeat_type,
1878
        $groupList = []
1879
    ) {
1880
        $attendanceId = $attendance->getIid();
1881
        // save start date
1882
        $this->set_date_time(api_get_utc_datetime($start_date));
1883
        $this->attendance_calendar_add($attendance, $groupList);
1884
1885
        // 86400 = 24 hours in seconds
1886
        // 604800 = 1 week in seconds
1887
        // Saves repeated dates
1888
        switch ($repeat_type) {
1889
            case 'daily':
1890
                $j = 1;
1891
                for ($i = $start_date + 86400; ($i <= $end_date); $i += 86400) {
1892
                    $this->set_date_time(api_get_utc_datetime($i));
1893
                    $this->attendance_calendar_add($attendance, $groupList);
1894
                    $j++;
1895
                }
1896
                break;
1897
            case 'weekly':
1898
                $j = 1;
1899
                for ($i = $start_date + 604800; ($i <= $end_date); $i += 604800) {
1900
                    $this->set_date_time(api_get_utc_datetime($i));
1901
                    $this->attendance_calendar_add($attendance, $groupList);
1902
                    $j++;
1903
                }
1904
                break;
1905
            case 'monthlyByDate':
1906
                $j = 1;
1907
                //@todo fix bug with february
1908
                for ($i = $start_date + 2419200; ($i <= $end_date); $i += 2419200) {
1909
                    $this->set_date_time(api_get_utc_datetime($i));
1910
                    $this->attendance_calendar_add($attendanceId, $groupList);
1911
                    $j++;
1912
                }
1913
                break;
1914
        }
1915
    }
1916
1917
    /**
1918
     * edit a datetime inside attendance calendar table.
1919
     *
1920
     * @param int         $calendar_id
1921
     * @param CAttendance $attendance
1922
     *
1923
     * @return int affected rows
1924
     */
1925
    public function attendance_calendar_edit($calendar_id, $attendance)
1926
    {
1927
        $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1928
        $affected_rows = 0;
1929
        $attendanceId = $attendance->getIid();
1930
1931
        $course_id = api_get_course_int_id();
1932
        // check if datetime already exists inside the table
1933
        $sql = "SELECT id FROM $tbl_attendance_calendar
1934
                WHERE
1935
                    c_id = $course_id AND
1936
                    date_time = '".Database::escape_string($this->date_time)."' AND
1937
                    attendance_id = '$attendanceId'";
1938
        $rs = Database::query($sql);
1939
1940
        if (0 == Database::num_rows($rs)) {
1941
            $sql = "UPDATE $tbl_attendance_calendar
1942
                    SET date_time='".Database::escape_string($this->date_time)."'
1943
                    WHERE c_id = $course_id AND id = '".intval($calendar_id)."'";
1944
            Database::query($sql);
1945
        }
1946
1947
        // update locked attendance
1948
        $is_all_calendar_done = self::is_all_attendance_calendar_done($attendanceId);
1949
        if (!$is_all_calendar_done) {
1950
            $this->lock($attendance, false);
1951
        } else {
1952
            $this->lock($attendance);
1953
        }
1954
1955
        return $affected_rows;
1956
    }
1957
1958
    /**
1959
     * delete a datetime from attendance calendar table.
1960
     *
1961
     * @param	int		attendance calendar id
1962
     * @param	int		attendance id
1963
     * @param	bool true for removing all calendar inside current attendance, false for removing by calendar id
1964
     *
1965
     * @return int affected rows
1966
     */
1967
    public function attendance_calendar_delete(
1968
        $calendar_id,
1969
        $attendanceId,
1970
        $all_delete = false
1971
    ) {
1972
        $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
1973
        $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET);
1974
1975
        $attendanceId = (int) $attendanceId;
1976
        $calendar_id = (int) $calendar_id;
1977
1978
        // get all registered users inside current course
1979
        $users = $this->get_users_rel_course();
1980
        $user_ids = array_keys($users);
1981
        $course_id = api_get_course_int_id();
1982
        $affected_rows = 0;
1983
        if ($all_delete) {
1984
            $attendance_calendar = $this->get_attendance_calendar($attendanceId);
1985
            // get all dates from calendar by current attendance
1986
            if (!empty($attendance_calendar)) {
1987
                foreach ($attendance_calendar as $cal) {
1988
                    // delete all data from attendance sheet
1989
                    $sql = "DELETE FROM $tbl_attendance_sheet
1990
                            WHERE c_id = $course_id AND attendance_calendar_id = '".intval($cal['id'])."'";
1991
                    Database::query($sql);
1992
                    // delete data from attendance calendar
1993
                    $sql = "DELETE FROM $tbl_attendance_calendar
1994
                            WHERE c_id = $course_id AND id = '".intval($cal['id'])."'";
1995
                    Database::query($sql);
1996
1997
                    $this->deleteAttendanceCalendarGroup($cal['id'], $course_id);
1998
                    $affected_rows++;
1999
                }
2000
            }
2001
        } else {
2002
            // delete just one row from attendance sheet by the calendar id
2003
            $sql = "DELETE FROM $tbl_attendance_sheet
2004
                    WHERE c_id = $course_id AND attendance_calendar_id = '".$calendar_id."'";
2005
            Database::query($sql);
2006
            // delete data from attendance calendar
2007
            $sql = "DELETE FROM $tbl_attendance_calendar
2008
                    WHERE c_id = $course_id AND id = '".$calendar_id."'";
2009
            Database::query($sql);
2010
2011
            $this->deleteAttendanceCalendarGroup($calendar_id, $course_id);
2012
            $affected_rows++;
2013
        }
2014
2015
        // update users' results
2016
        $this->updateUsersResults($user_ids, $attendanceId);
2017
2018
        return $affected_rows;
2019
    }
2020
2021
    public function set_session_id($sessionId)
2022
    {
2023
        $this->session_id = $sessionId;
2024
    }
2025
2026
    public function set_course_id($course_id)
2027
    {
2028
        $this->course_id = $course_id;
2029
    }
2030
2031
    public function set_date_time($datetime)
2032
    {
2033
        $this->date_time = $datetime;
2034
    }
2035
2036
    public function set_name($name)
2037
    {
2038
        $this->name = $name;
2039
    }
2040
2041
    public function set_description($description)
2042
    {
2043
        $this->description = $description;
2044
    }
2045
2046
    public function set_attendance_qualify_title($attendance_qualify_title)
2047
    {
2048
        $this->attendance_qualify_title = $attendance_qualify_title;
2049
    }
2050
2051
    public function set_attendance_weight($attendance_weight)
2052
    {
2053
        $this->attendance_weight = $attendance_weight;
2054
    }
2055
2056
    /** Getters for fields of attendances tables */
2057
    public function get_session_id()
2058
    {
2059
        return $this->session_id;
2060
    }
2061
2062
    public function get_course_id()
2063
    {
2064
        return $this->course_id;
2065
    }
2066
2067
    public function get_date_time()
2068
    {
2069
        return $this->date_time;
2070
    }
2071
2072
    public function get_name()
2073
    {
2074
        return $this->name;
2075
    }
2076
2077
    public function get_description()
2078
    {
2079
        return $this->description;
2080
    }
2081
2082
    public function get_attendance_qualify_title()
2083
    {
2084
        return $this->attendance_qualify_title;
2085
    }
2086
2087
    public function get_attendance_weight()
2088
    {
2089
        return $this->attendance_weight;
2090
    }
2091
2092
    /**
2093
     * @param string $startDate in UTC time
2094
     * @param string $endDate   in UTC time
2095
     *
2096
     * @return array
2097
     */
2098
    public function getAttendanceLogin($startDate, $endDate)
2099
    {
2100
        if (empty($startDate) ||
2101
            '0000-00-00' === $startDate ||
2102
            '0000-00-00 00:00:00' === $startDate ||
2103
            empty($endDate) ||
2104
            '0000-00-00' === $endDate ||
2105
            '0000-00-00 00:00:00' === $endDate
2106
        ) {
2107
            return false;
2108
        }
2109
2110
        $sessionId = api_get_session_id();
2111
        $courseCode = api_get_course_id();
2112
        $courseId = api_get_course_int_id();
2113
2114
        if (!empty($sessionId)) {
2115
            $users = CourseManager::get_user_list_from_course_code(
2116
                $courseCode,
2117
                $sessionId,
2118
                '',
2119
                'lastname',
2120
                0
2121
            );
2122
        } else {
2123
            $users = CourseManager::get_user_list_from_course_code(
2124
                $courseCode,
2125
                0,
2126
                '',
2127
                'lastname',
2128
                STUDENT
2129
            );
2130
        }
2131
2132
        $dateTimeStartOriginal = new DateTime($startDate);
2133
        $dateTimeStart = new DateTime($startDate);
2134
        $dateTimeEnd = new DateTime($endDate);
2135
        $interval = $dateTimeStart->diff($dateTimeEnd);
2136
        $days = (int) $interval->format('%a');
2137
2138
        $dateList = [$dateTimeStart->format('Y-m-d')];
2139
        $headers = [
2140
            get_lang('User'),
2141
            $dateTimeStart->format('Y-m-d'),
2142
        ];
2143
2144
        for ($i = 0; $i < $days; $i++) {
2145
            $dateTimeStart = $dateTimeStart->add(new DateInterval('P1D'));
2146
            $date = $dateTimeStart->format('Y-m-d');
2147
            $dateList[] = $date;
2148
            $headers[] = $date;
2149
        }
2150
2151
        $accessData = CourseManager::getCourseAccessPerCourseAndSession(
2152
            $courseId,
2153
            $sessionId,
2154
            $dateTimeStartOriginal->format('Y-m-d H:i:s'),
2155
            $dateTimeEnd->format('Y-m-d H:i:s')
2156
        );
2157
2158
        $results = [];
2159
        if (!empty($accessData)) {
2160
            foreach ($accessData as $data) {
2161
                $onlyDate = substr($data['login_course_date'], 0, 10);
2162
                $results[$data['user_id']][$onlyDate] = true;
2163
            }
2164
        }
2165
2166
        return [
2167
            'users' => $users,
2168
            'dateList' => $dateList,
2169
            'headers' => $headers,
2170
            'results' => $results,
2171
        ];
2172
    }
2173
2174
    /**
2175
     * @param string $startDate in UTC time
2176
     * @param string $endDate   in UTC time
2177
     *
2178
     * @return string
2179
     */
2180
    public function getAttendanceLoginTable($startDate, $endDate)
2181
    {
2182
        $data = $this->getAttendanceLogin($startDate, $endDate);
2183
        if (!$data) {
2184
            return null;
2185
        }
2186
2187
        $headers = $data['headers'];
2188
        $dateList = $data['dateList'];
2189
        $users = $data['users'];
2190
        $results = $data['results'];
2191
2192
        $table = new HTML_Table(['class' => 'data_table']);
2193
        $row = 0;
2194
        $column = 0;
2195
        foreach ($headers as $header) {
2196
            $table->setHeaderContents($row, $column, $header);
2197
            $column++;
2198
        }
2199
        $row = 1;
2200
        foreach ($users as $user) {
2201
            $table->setCellContents(
2202
                $row,
2203
                0,
2204
                $user['lastname'].' '.$user['firstname'].' ('.$user['username'].')'
2205
            );
2206
            $row++;
2207
        }
2208
2209
        $column = 1;
2210
        $row = 1;
2211
        foreach ($users as $user) {
2212
            foreach ($dateList as $date) {
2213
                $status = null;
2214
                if (isset($results[$user['user_id']]) &&
2215
                    isset($results[$user['user_id']][$date])
2216
                ) {
2217
                    $status = 'X';
2218
                }
2219
                $table->setCellContents($row, $column, $status);
2220
                $column++;
2221
            }
2222
            $row++;
2223
            $column = 1;
2224
        }
2225
2226
        return $table->toHtml();
2227
    }
2228
2229
    /**
2230
     * @param string $startDate in UTC time
2231
     * @param string $endDate   in UTC time
2232
     *
2233
     * @return string
2234
     */
2235
    public function exportAttendanceLogin($startDate, $endDate)
2236
    {
2237
        $data = $this->getAttendanceLogin($startDate, $endDate);
2238
2239
        if (!$data) {
2240
            return null;
2241
        }
2242
        $users = $data['users'];
2243
        $results = $data['results'];
2244
2245
        $table = new HTML_Table(['class' => 'data_table']);
2246
        $table->setHeaderContents(0, 0, get_lang('User'));
2247
        $table->setHeaderContents(0, 1, get_lang('Date'));
2248
2249
        $row = 1;
2250
        foreach ($users as $user) {
2251
            $table->setCellContents(
2252
                $row,
2253
                0,
2254
                $user['lastname'].' '.$user['firstname'].' ('.$user['username'].')'
2255
            );
2256
            $row++;
2257
        }
2258
        $table->setColAttributes(0, ['style' => 'width:28%']);
2259
2260
        $row = 1;
2261
        foreach ($users as $user) {
2262
            if (isset($results[$user['user_id']]) &&
2263
                !empty($results[$user['user_id']])
2264
            ) {
2265
                $dates = implode(', ', array_keys($results[$user['user_id']]));
2266
                $table->setCellContents($row, 1, $dates);
2267
            }
2268
            $row++;
2269
        }
2270
2271
        $tableToString = $table->toHtml();
2272
        $params = [
2273
            'filename' => get_lang('Attendance').'_'.api_get_utc_datetime(),
2274
            'pdf_title' => get_lang('Attendance'),
2275
            'course_code' => api_get_course_id(),
2276
            'show_real_course_teachers' => true,
2277
        ];
2278
        $pdf = new PDF('A4', null, $params);
2279
        $pdf->html_to_pdf_with_template($tableToString);
2280
    }
2281
2282
    public function setAttendanceForm(FormValidator $form, CAttendance $attendance = null)
2283
    {
2284
        $skillList = [];
2285
        $header = get_lang('Create a new attendance list');
2286
        if ($attendance) {
2287
            $header = get_lang('Edit');
2288
            $form->addHidden('attendance_id', $attendance->getIid());
2289
        }
2290
        $form->addHeader($header);
2291
2292
        //$form->addElement('hidden', 'sec_token', $token);
2293
        $form->addText('title', get_lang('Title'), true);
2294
        $form->applyFilter('title', 'html_filter');
2295
        $form->addHtmlEditor(
2296
            'description',
2297
            get_lang('Description'),
2298
            false,
2299
            false,
2300
            ['ToolbarSet' => 'Basic', 'Width' => '100%', 'Height' => '150']
2301
        );
2302
2303
        $sessionId = api_get_session_id();
2304
2305
        // Advanced Parameters
2306
        if ((0 != $sessionId && Gradebook::is_active()) || 0 == $sessionId) {
2307
            $form->addButtonAdvancedSettings('id_qualify');
2308
            $form->addElement('html', '<div id="id_qualify_options" style="display:none">');
2309
2310
            // Qualify Attendance for gradebook option
2311
            $form->addElement(
2312
                'checkbox',
2313
                'attendance_qualify_gradebook',
2314
                '',
2315
                get_lang('Grade the attendance list in the assessment tool'),
2316
                'onclick="javascript: if(this.checked){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
2317
            );
2318
            $form->addElement('html', '<div id="options_field" style="display:none">');
2319
2320
            GradebookUtils::load_gradebook_select_in_tool($form);
2321
2322
            $form->addElement('text', 'attendance_qualify_title', get_lang('Column header in Competences Report'));
2323
            $form->applyFilter('attendance_qualify_title', 'html_filter');
2324
            $form->addElement(
2325
                'text',
2326
                'attendance_weight',
2327
                get_lang('Weight in Report'),
2328
                'value="0.00" Style="width:40px" onfocus="javascript: this.select();"'
2329
            );
2330
            $form->applyFilter('attendance_weight', 'html_filter');
2331
            $form->addElement('html', '</div>');
2332
2333
            $skillList = Skill::addSkillsToForm($form, ITEM_TYPE_ATTENDANCE, $attendance ? $attendance->getIid() : 0);
2334
2335
            $form->addElement('html', '</div>');
2336
        }
2337
2338
        if ($attendance) {
2339
            $form->addButtonUpdate(get_lang('Update'));
2340
        } else {
2341
            $form->addButtonCreate(get_lang('Save'));
2342
        }
2343
2344
        if ($attendance) {
2345
            $default = [];
2346
            $default['title'] = Security::remove_XSS($attendance->getName());
2347
            $default['description'] = Security::remove_XSS($attendance->getDescription(), STUDENT);
2348
            $default['attendance_qualify_title'] = $attendance->getAttendanceQualifyTitle();
2349
            $default['attendance_weight'] = $attendance->getAttendanceWeight();
2350
            $default['skills'] = array_keys($skillList);
2351
2352
            $link_info = GradebookUtils::isResourceInCourseGradebook(
2353
                api_get_course_id(),
2354
                7,
2355
                $attendance->getIid(),
2356
                $sessionId
2357
            );
2358
            if ($link_info) {
2359
                $default['category_id'] = $link_info['category_id'];
2360
            }
2361
            $form->setDefaults($default);
2362
        }
2363
2364
        return $form;
2365
    }
2366
2367
    public function getCalendarSheet($edit, $attendanceId, $student_id)
2368
    {
2369
        $content = '';
2370
        $groupId = isset($_REQUEST['group_id']) ? $_REQUEST['group_id'] : null;
2371
        $filter_type = 'today';
2372
        if (!empty($_REQUEST['filter'])) {
2373
            $filter_type = $_REQUEST['filter'];
2374
        }
2375
2376
        $users_in_course = $this->get_users_rel_course($attendanceId, $groupId);
2377
        $is_locked_attendance = $this->is_locked_attendance($attendanceId);
2378
2379
        $attendant_calendar_all = $this->get_attendance_calendar(
2380
            $attendanceId,
2381
            'all',
2382
            null,
2383
            $groupId
2384
        );
2385
        $attendant_calendar = $this->get_attendance_calendar(
2386
            $attendanceId,
2387
            $filter_type,
2388
            null,
2389
            $groupId
2390
        );
2391
2392
        $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
2393
                api_get_user_id(),
2394
                api_get_course_info()
2395
            ) || api_is_drh();
2396
        if (true == $edit) {
2397
            if (api_is_allowed_to_edit(null, true) || $isDrhOfCourse) {
2398
                $data['users_presence'] = $this->get_users_attendance_sheet(
2399
                    $attendanceId,
2400
                    0,
2401
                    $groupId
2402
                );
2403
            }
2404
        } else {
2405
            if (!empty($student_id)) {
2406
                $user_id = (int) $student_id;
2407
            } else {
2408
                $user_id = api_get_user_id();
2409
            }
2410
2411
            if (api_is_allowed_to_edit(null, true) ||
2412
                api_is_coach(api_get_session_id(), api_get_course_int_id()) ||
2413
                $isDrhOfCourse
2414
            ) {
2415
                $users_presence = $this->get_users_attendance_sheet(
2416
                    $attendanceId,
2417
                    0,
2418
                    $groupId
2419
                );
2420
            } else {
2421
                $users_presence = $this->get_users_attendance_sheet(
2422
                    $attendanceId,
2423
                    $user_id,
2424
                    $groupId
2425
                );
2426
            }
2427
2428
            $faults = $this->get_faults_of_user($user_id, $attendanceId, $groupId);
2429
        }
2430
2431
        $next_attendance_calendar_id = $this->get_next_attendance_calendar_id($attendanceId);
2432
        $next_attendance_calendar_datetime = $this->getNextAttendanceCalendarDatetime($attendanceId);
2433
2434
        if (api_is_allowed_to_edit(null, true) ||
2435
            api_is_coach(api_get_session_id(), api_get_course_int_id()) ||
2436
            $isDrhOfCourse
2437
        ) {
2438
            $groupId = isset($_REQUEST['group_id']) ? (int) ($_REQUEST['group_id']) : null;
2439
            $form = new FormValidator(
2440
                'filter',
2441
                'post',
2442
                'index.php?action=attendance_sheet_list&'.api_get_cidreq().'&attendance_id='.$attendanceId,
2443
                null,
2444
                [],
2445
                'inline'
2446
            );
2447
2448
            $values = [
2449
                'all' => get_lang('All'),
2450
                'today' => get_lang('Today'),
2451
                'all_done' => get_lang('All done'),
2452
                'all_not_done' => get_lang('All not done'),
2453
            ];
2454
            $today = api_convert_and_format_date(null, DATE_FORMAT_SHORT);
2455
            $exists_attendance_today = false;
2456
2457
            if (!empty($attendant_calendar_all)) {
2458
                $values[''] = '---------------';
2459
                foreach ($attendant_calendar_all as $attendance_date) {
2460
                    $includeCalendar = true;
2461
                    if (isset($attendance_date['groups']) && !empty($groupId)) {
2462
                        foreach ($attendance_date['groups'] as $group) {
2463
                            if ($groupId == $group['group_id']) {
2464
                                $includeCalendar = true;
2465
2466
                                break;
2467
                            } else {
2468
                                $includeCalendar = false;
2469
                            }
2470
                        }
2471
                    }
2472
2473
                    if ($today == $attendance_date['date']) {
2474
                        $exists_attendance_today = true;
2475
                    }
2476
                    if ($includeCalendar) {
2477
                        $values[$attendance_date['id']] = $attendance_date['date_time'];
2478
                    }
2479
                }
2480
            }
2481
2482
            if (!$exists_attendance_today) {
2483
                $content .= Display::return_message(
2484
                    get_lang('There is no class scheduled today, try picking another day or add your attendance entry yourself using the action icons.'),
2485
                    'warning'
2486
                );
2487
            }
2488
2489
            $form->addSelect(
2490
                'filter',
2491
                get_lang('Filter'),
2492
                $values,
2493
                ['id' => 'filter_id', 'onchange' => 'submit();']
2494
            );
2495
2496
            $groupList = GroupManager::get_group_list(null, null, 1);
2497
            $groupIdList = ['--'];
2498
            foreach ($groupList as $group) {
2499
                $groupIdList[$group['id']] = $group['name'];
2500
            }
2501
2502
            if (!empty($groupList)) {
2503
                $form->addSelect('group_id', get_lang('Group'), $groupIdList);
2504
            }
2505
2506
            if (isset($_REQUEST['filter'])) {
2507
                if (in_array($_REQUEST['filter'], array_keys($values))) {
2508
                    $default_filter = $_REQUEST['filter'];
2509
                }
2510
            } else {
2511
                $default_filter = 'today';
2512
            }
2513
2514
            $renderer = $form->defaultRenderer();
2515
            $renderer->setCustomElementTemplate(
2516
                '<div class="col-md-2">{label}</div><div class="col-md-10"> {element} </div>'
2517
            );
2518
2519
            $form->setDefaults(
2520
                [
2521
                    'filter' => $default_filter,
2522
                    'group_id' => $groupId,
2523
                ]
2524
            );
2525
2526
            if (!$is_locked_attendance || api_is_platform_admin()) {
2527
                $actionsLeft = '<a style="float:left;" href="index.php?'.api_get_cidreq().'&action=calendar_list&attendance_id='.$attendanceId.'">'.
2528
                    Display::return_icon('attendance_calendar.png', get_lang('Attendance calendar'), '', ICON_SIZE_MEDIUM).'</a>';
2529
                $actionsLeft .= '<a id="pdf_export" style="float:left;"  href="index.php?'.api_get_cidreq().'&action=attendance_sheet_export_to_pdf&attendance_id='.$attendanceId.'&filter='.$default_filter.'&group_id='.$groupId.'">'.
2530
                    Display::return_icon('pdf.png', get_lang('Export to PDF'), '', ICON_SIZE_MEDIUM).'</a>';
2531
2532
                $actionsRight = $form->returnForm();
2533
                $content .= Display::toolbarAction('toolbar-attendance', [$actionsLeft, $actionsRight]);
2534
            }
2535
2536
            $message_information = get_lang('The attendance sheets allow you to specify a list of dates in which you will report attendance to your courses');
2537
            if (!empty($message_information)) {
2538
                $message = '<strong>'.get_lang('Information').'</strong><br />';
2539
                $message .= $message_information;
2540
                $content .= Display::return_message($message, 'normal', false);
2541
            }
2542
2543
            if ($is_locked_attendance) {
2544
                $content .= Display::return_message(get_lang('The attendance sheet is locked.'), 'warning', false);
2545
            }
2546
2547
            $param_filter = '&filter='.Security::remove_XSS($default_filter).'&group_id='.$groupId;
2548
2549
            if (count($users_in_course) > 0) {
2550
                $form = '
2551
                <form method="post" action="index.php?action=attendance_sheet_add&'.api_get_cidreq().$param_filter.'&attendance_id='.$attendanceId.'">
2552
                    <div class="attendance-sheet-content" style="width:100%;background-color:#E1E1E1;margin-top:20px;">
2553
                        <div class="divTableWithFloatingHeader attendance-users-table" style="width:45%;float:left;margin:0px;padding:0px;">
2554
                            <table class="tableWithFloatingHeader data_table" width="100%">
2555
                                <thead>
2556
                                <tr class="tableFloatingHeader" style="position: absolute; top: 0px; left: 0px; visibility: hidden; margin:0px;padding:0px" >
2557
                                    <th width="10px">#</th>
2558
                                    <th width="10px">'.get_lang('Photo').'</th>
2559
                                    <th width="100px">'.get_lang('Last name').'</th>
2560
                                    <th width="100px">'.get_lang('First name').'</th>
2561
                                    <th width="100px">'.get_lang('Not attended').'</th>
2562
                                </tr>
2563
                                <tr class="tableFloatingHeaderOriginal" >
2564
                                    <th width="10px">#</th>
2565
                                    <th width="10px">'.get_lang('Photo').'</th>
2566
                                    <th width="150px">'.get_lang('Last name').'</th>
2567
                                    <th width="140px">'.get_lang('First name').'</th>
2568
                                    <th width="100px">'.get_lang('Not attended').'</th>
2569
                                </tr>
2570
                                </thead>
2571
                                <tbody>';
2572
2573
                $i = 1;
2574
                $class = '';
2575
                foreach ($users_in_course as $data) {
2576
                    $faults = 0;
2577
                    if (0 == $i % 2) {
2578
                        $class = 'row_odd';
2579
                    } else {
2580
                        $class = 'row_even';
2581
                    }
2582
                    $username = api_htmlentities(
2583
                        sprintf(get_lang('Login: %s'), $data['username']),
2584
                        ENT_QUOTES
2585
                    );
2586
2587
                    $form .= '<tr class="'.$class.'">
2588
                                <td><center>'.$i.'</center></td>
2589
                                <td>'.$data['photo'].'</td>
2590
                                <td><span title="'.$username.'">'.$data['lastname'].'</span></td>
2591
                                <td>'.$data['firstname'].'</td>
2592
                                <td>
2593
                                    <div class="attendance-faults-bar"
2594
                                    style="background-color:'.(!empty($data['result_color_bar']) ? $data['result_color_bar'] : 'none').'">
2595
                                        '.$data['attendance_result'].'
2596
                                    </div>
2597
                                </td>
2598
                            </tr>';
2599
2600
                    $i++;
2601
                }
2602
                $form .= '</tbody>
2603
                            </table>
2604
                        </div>';
2605
2606
                $form .= '<div
2607
                    class="divTableWithFloatingHeader attendance-calendar-table"
2608
                    style="margin:0px;padding:0px;float:left;width:55%;overflow:auto;overflow-y:hidden;">';
2609
                $form .= '<table class="tableWithFloatingHeader data_table" width="100%">';
2610
                $form .= '<thead>';
2611
                $result = null;
2612
2613
                if (count($attendant_calendar) > 0) {
2614
                    foreach ($attendant_calendar as $calendar) {
2615
                        $date = $calendar['date'];
2616
                        $time = $calendar['time'];
2617
                        $datetime = '<div class="grey">'.$date.' - '.$time.'</div>';
2618
2619
                        $img_lock = Display::return_icon(
2620
                            'lock-closed.png',
2621
                            get_lang('Unlock date'),
2622
                            ['class' => 'img_lock', 'id' => 'datetime_column_'.$calendar['id']]
2623
                        );
2624
2625
                        if (!empty($calendar['done_attendance'])) {
2626
                            $datetime = '<div class="blue">'.$date.' - '.$time.'</div>';
2627
                        }
2628
                        $disabled_check = 'disabled = "true"';
2629
                        $input_hidden = '<input type="hidden" id="hidden_input_'.$calendar['id'].'" name="hidden_input[]" value="" disabled />';
2630
                        if ($next_attendance_calendar_id == $calendar['id']) {
2631
                            $input_hidden = '<input type="hidden" id="hidden_input_'.$calendar['id'].'" name="hidden_input[]" value="'.$calendar['id'].'" />';
2632
                            $disabled_check = '';
2633
                            $img_lock = Display::return_icon('lock-closed.png', get_lang('Lock date'), ['class' => 'img_unlock', 'id' => 'datetime_column_'.$calendar['id']]);
2634
                        }
2635
2636
                        $result .= '<th>';
2637
                        $result .= '<div class="date-attendance">'.$datetime.'&nbsp;';
2638
                        if (api_is_allowed_to_edit(null, true)) {
2639
                            $result .= '<span id="attendance_lock" style="cursor:pointer">'.(!$is_locked_attendance || api_is_platform_admin() ? $img_lock : '').'</span>';
2640
                        }
2641
2642
                        if (false == $is_locked_attendance) {
2643
                            if (api_is_allowed_to_edit(null, true)) {
2644
                                $result .= '<input type="checkbox" class="checkbox_head_'.$calendar['id'].'" id="checkbox_head_'.$calendar['id'].'" '.$disabled_check.' checked="checked" />'.$input_hidden.'</div></th>';
2645
                            }
2646
                        }
2647
                    }
2648
                } else {
2649
                    $result = '<th width="2000px"><span>
2650
                    <a href="index.php?'.api_get_cidreq().'&action=calendar_list&attendance_id='.$attendanceId.'">';
2651
                    $result .= Display::return_icon(
2652
                            'attendance_calendar.png',
2653
                            get_lang('Attendance calendar'),
2654
                            '',
2655
                            ICON_SIZE_MEDIUM
2656
                        ).' '.get_lang('Go to the attendance calendar');
2657
                    $result .= '</a></span></th>';
2658
                }
2659
2660
                $form .= '<tr
2661
                        class="tableFloatingHeader row_odd"
2662
                        style="position: absolute; top: 0px; left: 0px; visibility: hidden; margin:0px;padding:0px">';
2663
                $form .= $result;
2664
                $form .= '</tr>';
2665
                $form .= '<tr class="tableWithFloatingHeader row_odd tableFloatingHeaderOriginal">';
2666
                $form .= $result;
2667
                $form .= '</tr>';
2668
                $form .= '</thead>';
2669
                $form .= '<tbody>';
2670
                $i = 0;
2671
                foreach ($users_in_course as $user) {
2672
                    $class = '';
2673
                    if (0 == $i % 2) {
2674
                        $class = 'row_even';
2675
                    } else {
2676
                        $class = 'row_odd';
2677
                    }
2678
                    $form .= '<tr class="'.$class.'">';
2679
2680
                    if (count($attendant_calendar) > 0) {
2681
                        foreach ($attendant_calendar as $calendar) {
2682
                            $checked = 'checked';
2683
                            $presence = -1;
2684
2685
                            if (isset($users_presence[$user['user_id']][$calendar['id']]['presence'])) {
2686
                                $presence = $users_presence[$user['user_id']][$calendar['id']]['presence'];
2687
                                if (1 == (int) $presence) {
2688
                                    $checked = 'checked';
2689
                                } else {
2690
                                    $checked = '';
2691
                                }
2692
                            } else {
2693
                                //if the user wasn't registered at that time, consider unchecked
2694
                                if (0 == $next_attendance_calendar_datetime ||
2695
                                    $calendar['date_time'] < $next_attendance_calendar_datetime
2696
                                ) {
2697
                                    $checked = '';
2698
                                }
2699
                            }
2700
                            $disabled = 'disabled';
2701
                            $style_td = '';
2702
2703
                            if ($next_attendance_calendar_id == $calendar['id']) {
2704
                                if (0 == $i % 2) {
2705
                                    $style_td = 'background-color:#eee;';
2706
                                } else {
2707
                                    $style_td = 'background-color:#dcdcdc;';
2708
                                }
2709
                                $disabled = '';
2710
                            }
2711
2712
                            $form .= '<td style="'.$style_td.'" class="checkboxes_col_'.$calendar['id'].'">';
2713
                            $form .= '<div class="check">';
2714
2715
                            if (api_is_allowed_to_edit(null, true)) {
2716
                                if (!$is_locked_attendance || api_is_platform_admin()) {
2717
                                    $form .= '<input type="checkbox" name="check_presence['.$calendar['id'].'][]" value="'.$user['user_id'].'" '.$disabled.' '.$checked.' />';
2718
                                    $form .= '<span class="anchor_'.$calendar['id'].'"></span>';
2719
                                } else {
2720
                                    $form .= $presence ? Display::return_icon('checkbox_on.png', get_lang('Assistance'), null, ICON_SIZE_TINY) : Display::return_icon('checkbox_off.png', get_lang('Assistance'), null, ICON_SIZE_TINY);
2721
                                }
2722
                            } else {
2723
                                switch ($presence) {
2724
                                    case 1:
2725
                                        $form .= Display::return_icon('accept.png', get_lang('Attended'));
2726
2727
                                        break;
2728
                                    case 0:
2729
                                        $form .= Display::return_icon('exclamation.png', get_lang('Not attended'));
2730
2731
                                        break;
2732
                                    case -1:
2733
                                        break;
2734
                                }
2735
                            }
2736
2737
                            $form .= '</div>';
2738
                            $form .= '</td>';
2739
                        }
2740
                    } else {
2741
                        $calendarClass = null;
2742
                        if (isset($calendar)) {
2743
                            $calendarClass = 'checkboxes_col_'.$calendar['id'];
2744
                        }
2745
                        $form .= '<td class="'.$calendarClass.'">';
2746
                        $form .= '<div>';
2747
                        $form .= '<center>&nbsp;</center>
2748
                                </div>
2749
                                </td>';
2750
                    }
2751
                    echo '</tr>';
2752
                    $i++;
2753
                }
2754
                $form .= '</tbody></table>';
2755
                $form .= '</div></div>';
2756
2757
                $form .= '<div class="row">
2758
                            <div class="col-md-12">';
2759
                if (!$is_locked_attendance || api_is_platform_admin()) {
2760
                    if (api_is_allowed_to_edit(null, true)) {
2761
                        $form .= '<button type="submit" class="btn btn-primary">'.get_lang('Save').'</button>';
2762
                    }
2763
                }
2764
                $form .= '</div>
2765
                        </div>
2766
                </form>';
2767
                $content .= $form;
2768
            } else {
2769
                $content .= Display::return_message(
2770
                    '<a href="'.api_get_path(WEB_CODE_PATH).'user/user.php?'.api_get_cidreq().'">'.
2771
                    get_lang('There are no registered learners inside the course').'</a>',
2772
                    'warning',
2773
                    false
2774
                );
2775
            }
2776
        } else {
2777
            $content .= Display::page_header(get_lang('Report of attendance sheets'));
2778
            if (!empty($users_presence)) {
2779
                $content .= '
2780
                <div>
2781
                    <table width="250px;">
2782
                        <tr>
2783
                            <td>'.get_lang('To attend').': </td>
2784
                            <td>
2785
                                <center>
2786
                                <div
2787
                                    class="attendance-faults-bar"
2788
                                    style="background-color:'.(!empty($faults['color_bar']) ? $faults['color_bar'] : 'none').'">
2789
                                        '.$faults['faults'].'/'.$faults['total'].' ('.$faults['faults_porcent'].'%)
2790
                                </div>
2791
                                </center>
2792
                            </td>
2793
                        </tr>
2794
                    </table>
2795
                </div>';
2796
            }
2797
2798
            $content .= '<table class="data_table">
2799
                <tr class="row_odd" >
2800
                    <th>'.get_lang('Attendance').'</th>
2801
                </tr>';
2802
2803
            if (!empty($users_presence)) {
2804
                $i = 0;
2805
                foreach ($users_presence[$user_id] as $presence) {
2806
                    $class = '';
2807
                    if (0 == $i % 2) {
2808
                        $class = 'row_even';
2809
                    } else {
2810
                        $class = 'row_odd';
2811
                    }
2812
2813
                    $check = $presence['presence'] ? Display::return_icon('checkbox_on.png', get_lang('Assistance'), null, ICON_SIZE_TINY) : Display::return_icon('checkbox_off.png', get_lang('Assistance'), null, ICON_SIZE_TINY);
2814
                    $content .= '<tr class="'.$class.'">
2815
                            <td>
2816
                                '.$check.'&nbsp; '.$presence['date_time'].'
2817
                            </td>
2818
                        </tr>';
2819
                }
2820
            } else {
2821
                $content .= '
2822
                        <tr>
2823
                            <td>
2824
                            <center>'.get_lang('You do not have attendances').'</center>
2825
                            </td>
2826
                        </tr>';
2827
            }
2828
            $content .= ' </table>';
2829
        }
2830
2831
        return $content;
2832
    }
2833
2834
    /**
2835
     * It's used to print attendance sheet.
2836
     *
2837
     * @param string $action
2838
     * @param int    $attendance_id
2839
     */
2840
    public function attendance_sheet_export_to_pdf(
2841
        $attendance_id,
2842
        $student_id = 0,
2843
        $course_id = ''
2844
    ) {
2845
        $courseInfo = api_get_course_info($course_id);
2846
        $this->set_course_id($courseInfo['code']);
2847
        $groupId = isset($_REQUEST['group_id']) ? $_REQUEST['group_id'] : null;
2848
        $data_array = [];
2849
        $data_array['attendance_id'] = $attendance_id;
2850
        $data_array['users_in_course'] = $this->get_users_rel_course($attendance_id, $groupId);
2851
2852
        $filter_type = 'today';
2853
2854
        if (!empty($_REQUEST['filter'])) {
2855
            $filter_type = $_REQUEST['filter'];
2856
        }
2857
2858
        $my_calendar_id = null;
2859
        if (is_numeric($filter_type)) {
2860
            $my_calendar_id = $filter_type;
2861
            $filter_type = 'calendar_id';
2862
        }
2863
2864
        $data_array['attendant_calendar'] = $this->get_attendance_calendar(
2865
            $attendance_id,
2866
            $filter_type,
2867
            $my_calendar_id,
2868
            $groupId
2869
        );
2870
2871
        if (api_is_allowed_to_edit(null, true) || api_is_drh()) {
2872
            $data_array['users_presence'] = $this->get_users_attendance_sheet($attendance_id, 0, $groupId);
2873
        } else {
2874
            if (!empty($student_id)) {
2875
                $user_id = (int) $student_id;
2876
            } else {
2877
                $user_id = api_get_user_id();
2878
            }
2879
            $data_array['users_presence'] = $this->get_users_attendance_sheet($attendance_id, $user_id, $groupId);
2880
            $data_array['faults'] = $this->get_faults_of_user($user_id, $attendance_id, $groupId);
2881
            $data_array['user_id'] = $user_id;
2882
        }
2883
2884
        $data_array['next_attendance_calendar_id'] = $this->get_next_attendance_calendar_id($attendance_id);
2885
2886
        // Set headers pdf.
2887
        $courseCategory = CourseManager::get_course_category($courseInfo['categoryCode']);
2888
        $teacherInfo = CourseManager::get_teacher_list_from_course_code($courseInfo['code']);
2889
        $teacherName = null;
2890
        foreach ($teacherInfo as $teacherData) {
2891
            if (null != $teacherName) {
2892
                $teacherName .= ' / ';
2893
            }
2894
            $teacherName .= api_get_person_name($teacherData['firstname'], $teacherData['lastname']);
2895
        }
2896
2897
        // Get data table
2898
        $data_table = [];
2899
        $head_table = ['#', get_lang('Name')];
2900
        foreach ($data_array['attendant_calendar'] as $class_day) {
2901
            $head_table[] =
2902
                api_format_date($class_day['date_time'], DATE_FORMAT_NUMBER_NO_YEAR).' '.
2903
                api_format_date($class_day['date_time'], TIME_NO_SEC_FORMAT);
2904
        }
2905
        $data_table[] = $head_table;
2906
        $data_attendant_calendar = $data_array['attendant_calendar'];
2907
        $data_users_presence = $data_array['users_presence'];
2908
        $count = 1;
2909
2910
        if (!empty($data_array['users_in_course'])) {
2911
            foreach ($data_array['users_in_course'] as $user) {
2912
                $cols = 1;
2913
                $result = [];
2914
                $result['count'] = $count;
2915
                $result['full_name'] = api_get_person_name($user['firstname'], $user['lastname']);
2916
                foreach ($data_array['attendant_calendar'] as $class_day) {
2917
                    if (1 == $class_day['done_attendance']) {
2918
                        if (1 == $data_users_presence[$user['user_id']][$class_day['id']]['presence']) {
2919
                            $result[$class_day['id']] = get_lang('P');
2920
                        } else {
2921
                            $result[$class_day['id']] = '<span style="color:red">'.get_lang('NP').'</span>';
2922
                        }
2923
                    } else {
2924
                        $result[$class_day['id']] = ' ';
2925
                    }
2926
                    $cols++;
2927
                }
2928
                $count++;
2929
                $data_table[] = $result;
2930
            }
2931
        }
2932
        $max_cols_per_page = 12; //10 dates + 2 name and number
2933
        $max_dates_per_page = $max_dates_per_page_original = $max_cols_per_page - 2; //10
2934
        $rows = count($data_table);
2935
2936
        if ($cols > $max_cols_per_page) {
2937
            $number_tables = round(($cols - 2) / $max_dates_per_page);
2938
            $headers = $data_table[0];
2939
            $all = [];
2940
            $tables = [];
2941
            $changed = 1;
2942
2943
            for ($i = 0; $i <= $rows; $i++) {
2944
                $row = isset($data_table[$i]) ? $data_table[$i] : null;
2945
                $key = 1;
2946
                $max_dates_per_page = 10;
2947
                $item = isset($data_table[$i]) ? $data_table[$i] : null;
2948
                $count_j = 0;
2949
2950
                if (!empty($item)) {
2951
                    foreach ($item as $value) {
2952
                        if ($count_j >= $max_dates_per_page) {
2953
                            $key++;
2954
                            $max_dates_per_page = $max_dates_per_page_original * $key;
2955
                            //magic hack
2956
                            $tables[$key][$i][] = $tables[1][$i][0];
2957
                            $tables[$key][$i][] = $tables[1][$i][1];
2958
                        }
2959
                        $tables[$key][$i][] = $value;
2960
                        $count_j++;
2961
                    }
2962
                }
2963
            }
2964
2965
            $content = null;
2966
            if (!empty($tables)) {
2967
                foreach ($tables as $sub_table) {
2968
                    $content .= Export::convert_array_to_html($sub_table).'<br /><br />';
2969
                }
2970
            }
2971
        } else {
2972
            $content = Export::convert_array_to_html(
2973
                $data_table,
2974
                ['header_attributes' => ['align' => 'center']]
2975
            );
2976
        }
2977
2978
        $params = [
2979
            'filename' => get_lang('Attendance').'-'.api_get_local_time(),
2980
            'pdf_title' => $courseInfo['title'],
2981
            'course_code' => $courseInfo['code'],
2982
            'add_signatures' => ['Drh', 'Teacher', 'Date'],
2983
            'pdf_teachers' => $teacherName,
2984
            'pdf_course_category' => $courseCategory ? $courseCategory['name'] : '',
2985
            'format' => 'A4-L',
2986
            'orientation' => 'L',
2987
        ];
2988
2989
        Export::export_html_to_pdf($content, $params);
2990
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2991
    }
2992
2993
    /**
2994
     * Gets attendance base in the table:
2995
     * TABLE_STATISTIC_TRACK_E_COURSE_ACCESS.
2996
     *
2997
     * @param bool $showForm
2998
     * @param bool $exportToPdf
2999
     */
3000
    public function getAttendanceBaseInLogin($showForm = false, $exportToPdf = true)
3001
    {
3002
        $table = null;
3003
        $formToDisplay = null;
3004
        $startDate = null;
3005
        $endDate = null;
3006
3007
        $sessionId = api_get_session_id();
3008
        if ($showForm) {
3009
            $form = new FormValidator(
3010
                'search',
3011
                'post',
3012
                api_get_self().'?'.api_get_cidreq().'&action=calendar_logins'
3013
            );
3014
            $form->addDateRangePicker('range', get_lang('Date range'));
3015
            $form->addButton('submit', get_lang('Submit'));
3016
3017
            if ($form->validate()) {
3018
                $values = $form->getSubmitValues();
3019
                $startDate = api_get_utc_datetime($values['range_start']);
3020
                $endDate = api_get_utc_datetime($values['range_end']);
3021
            }
3022
            $formToDisplay = $form->returnForm();
3023
        } else {
3024
            if (!empty($sessionId)) {
3025
                $sessionInfo = api_get_session_info($sessionId);
3026
                $startDate = $sessionInfo['access_start_date'];
3027
                $endDate = $sessionInfo['access_end_date'];
3028
            }
3029
        }
3030
3031
        if ($exportToPdf) {
3032
            $result = $this->exportAttendanceLogin($startDate, $endDate);
3033
            if (empty($result)) {
3034
                api_not_allowed(true, get_lang('No data available'));
3035
            }
3036
        }
3037
3038
        $table = $this->getAttendanceLoginTable($startDate, $endDate);
3039
3040
        return [
3041
            'form' => $formToDisplay,
3042
            'table' => $table,
3043
        ];
3044
    }
3045
}
3046