Total Complexity | 341 |
Total Lines | 3089 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like Attendance often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Attendance, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | class Attendance |
||
18 | { |
||
19 | public const DONE_ATTENDANCE_LOG_TYPE = 'done_attendance_sheet'; |
||
20 | public const UPDATED_ATTENDANCE_LOG_TYPE = 'updated_attendance_sheet'; |
||
21 | public const LOCKED_ATTENDANCE_LOG_TYPE = 'locked_attendance_sheet'; |
||
22 | public $category_id; |
||
23 | private $session_id; |
||
24 | private $course_id; |
||
25 | private $date_time; |
||
26 | private $title; |
||
27 | private $description; |
||
28 | private $attendance_qualify_title; |
||
29 | private $attendance_weight; |
||
30 | |||
31 | /** |
||
32 | * Get attendance list only the id, title and attendance_qualify_max fields. |
||
33 | * |
||
34 | * @return CAttendance[] |
||
35 | */ |
||
36 | public function getAttendanceList(Course $course, Session $session = null) |
||
37 | { |
||
38 | $repo = Container::getAttendanceRepository(); |
||
39 | $qb = $repo->getResourcesByCourse($course, $session, null); |
||
40 | //$qb->select('resource'); |
||
41 | $qb->andWhere('resource.active = 1'); |
||
42 | |||
43 | return $qb->getQuery()->getResult(); |
||
44 | |||
45 | /*$table = Database::get_course_table(TABLE_ATTENDANCE); |
||
46 | $course_id = (int) $course_id; |
||
47 | if (empty($course_id)) { |
||
48 | $course_id = api_get_course_int_id(); |
||
49 | } |
||
50 | |||
51 | $session_id = !empty($session_id) ? (int) $session_id : api_get_session_id(); |
||
52 | $condition_session = api_get_session_condition($session_id); |
||
53 | |||
54 | // Get attendance data |
||
55 | $sql = "SELECT iid, title, attendance_qualify_max |
||
56 | FROM $table |
||
57 | WHERE active = 1 $condition_session "; |
||
58 | $result = Database::query($sql); |
||
59 | $data = []; |
||
60 | if (Database::num_rows($result) > 0) { |
||
61 | while ($row = Database::fetch_assoc($result)) { |
||
62 | $data[$row['iid']] = $row; |
||
63 | } |
||
64 | } |
||
65 | |||
66 | return $data;*/ |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Get the total number of attendance inside current course and current session. |
||
71 | * |
||
72 | * @return int |
||
73 | * |
||
74 | * @see SortableTable#get_total_number_of_items() |
||
75 | */ |
||
76 | public static function getNumberOfAttendances() |
||
77 | { |
||
78 | $repo = Container::getAttendanceRepository(); |
||
79 | |||
80 | $course = api_get_course_entity(api_get_course_int_id()); |
||
81 | $session = api_get_session_entity(api_get_session_id()); |
||
82 | $group = api_get_group_entity(api_get_group_id()); |
||
83 | |||
84 | $qb = $repo->getResourcesByCourse($course, $session, $group); |
||
85 | $qb->select('count(resource)'); |
||
86 | $qb->andWhere('resource.active <> 2'); |
||
87 | |||
88 | if ((isset($_GET['isStudentView']) && 'true' == $_GET['isStudentView']) || |
||
89 | !api_is_allowed_to_edit(null, true) |
||
90 | ) { |
||
91 | $qb |
||
92 | ->andWhere('resource.active = :active') |
||
93 | ->setParameter('active', 1); |
||
94 | //$active_plus = ' AND att.active = 1'; |
||
95 | } |
||
96 | |||
97 | return $qb->getQuery()->getSingleScalarResult(); |
||
98 | |||
99 | $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE); |
||
|
|||
100 | $session_id = api_get_session_id(); |
||
101 | $condition_session = ''; |
||
102 | |||
103 | $active_plus = ''; |
||
104 | if ((isset($_GET['isStudentView']) && 'true' == $_GET['isStudentView']) || |
||
105 | !api_is_allowed_to_edit(null, true) |
||
106 | ) { |
||
107 | $active_plus = ' AND att.active = 1'; |
||
108 | } |
||
109 | |||
110 | $sql = "SELECT COUNT(att.iid) AS total_number_of_items |
||
111 | FROM $tbl_attendance att |
||
112 | WHERE |
||
113 | active <> 2 $active_plus $condition_session "; |
||
114 | /*$active = (int) $active; |
||
115 | if ($active === 1 || $active === 0) { |
||
116 | $sql .= "AND att.active = $active"; |
||
117 | }*/ |
||
118 | $res = Database::query($sql); |
||
119 | $obj = Database::fetch_object($res); |
||
120 | |||
121 | return (int) $obj->total_number_of_items; |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * Get the attendances to display on the current page (fill the sortable-table). |
||
126 | * |
||
127 | * @param int offset of first user to recover |
||
128 | * @param int Number of users to get |
||
129 | * @param int Column to sort on |
||
130 | * @param string Order (ASC,DESC) |
||
131 | * |
||
132 | * @see SortableTable#get_table_data($from) |
||
133 | * |
||
134 | * @return array |
||
135 | */ |
||
136 | public static function getAttendanceData( |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * Get the attendances by id to display on the current page. |
||
307 | * |
||
308 | * @param int $attendanceId |
||
309 | * |
||
310 | * @return array attendance data |
||
311 | */ |
||
312 | public function get_attendance_by_id($attendanceId) |
||
313 | { |
||
314 | $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE); |
||
315 | $attendanceId = (int) $attendanceId; |
||
316 | |||
317 | $attendance_data = []; |
||
318 | $sql = "SELECT * FROM $tbl_attendance |
||
319 | WHERE iid = $attendanceId"; |
||
320 | $res = Database::query($sql); |
||
321 | if (Database::num_rows($res) > 0) { |
||
322 | while ($row = Database::fetch_array($res)) { |
||
323 | $attendance_data = $row; |
||
324 | } |
||
325 | } |
||
326 | |||
327 | return $attendance_data; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * Add attendances sheet inside table. This is the *list of* dates, not |
||
332 | * a specific date in itself. |
||
333 | * |
||
334 | * @param bool true for adding link in gradebook or false otherwise (optional) |
||
335 | * |
||
336 | * @return int last attendance id |
||
337 | */ |
||
338 | public function attendance_add($link_to_gradebook = false) |
||
339 | { |
||
340 | $courseInfo = api_get_course_info(); |
||
341 | $tableLink = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK); |
||
342 | $sessionId = api_get_session_id(); |
||
343 | $courseCode = $courseInfo['code']; |
||
344 | $titleGradebook = (string) $this->attendance_qualify_title; |
||
345 | $valueCalification = 0; |
||
346 | $weightCalification = api_float_val($this->attendance_weight); |
||
347 | $course = api_get_course_entity(); |
||
348 | $attendance = new CAttendance(); |
||
349 | $attendance |
||
350 | ->setTitle($this->title) |
||
351 | ->setDescription($this->description) |
||
352 | ->setAttendanceQualifyTitle($titleGradebook) |
||
353 | ->setAttendanceWeight($weightCalification) |
||
354 | ->setParent($course) |
||
355 | ->addCourseLink($course, api_get_session_entity()) |
||
356 | ; |
||
357 | |||
358 | $repo = Container::getAttendanceRepository(); |
||
359 | $repo->create($attendance); |
||
360 | $lastId = $attendance->getIid(); |
||
361 | |||
362 | // add link to gradebook |
||
363 | if ($link_to_gradebook && !empty($this->category_id)) { |
||
364 | $description = ''; |
||
365 | $linkInfo = GradebookUtils::isResourceInCourseGradebook( |
||
366 | $course->getId(), |
||
367 | 7, |
||
368 | $lastId, |
||
369 | $sessionId |
||
370 | ); |
||
371 | $linkId = $linkInfo['id']; |
||
372 | if (!$linkInfo) { |
||
373 | GradebookUtils::add_resource_to_course_gradebook( |
||
374 | $this->category_id, |
||
375 | $courseInfo['real_id'], |
||
376 | 7, |
||
377 | $lastId, |
||
378 | $titleGradebook, |
||
379 | $weightCalification, |
||
380 | $valueCalification, |
||
381 | $description, |
||
382 | 1, |
||
383 | $sessionId |
||
384 | ); |
||
385 | } else { |
||
386 | Database::query("UPDATE $tableLink SET weight = $weightCalification WHERE iid = $linkId"); |
||
387 | } |
||
388 | } |
||
389 | |||
390 | return $lastId; |
||
391 | } |
||
392 | |||
393 | /** |
||
394 | * edit attendances inside table. |
||
395 | * |
||
396 | * @param CAttendance $attendance |
||
397 | * @param bool true for adding link in gradebook or false otherwise (optional) |
||
398 | * |
||
399 | * @return int last id |
||
400 | */ |
||
401 | public function attendance_edit($attendance, $link_to_gradebook = false) |
||
473 | } |
||
474 | |||
475 | /** |
||
476 | * Restore attendance. |
||
477 | * |
||
478 | * @param int|array one or many attendances id |
||
479 | * |
||
480 | * @return int affected rows |
||
481 | */ |
||
482 | public function attendance_restore($attendanceId) |
||
483 | { |
||
484 | $_course = api_get_course_info(); |
||
485 | $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE); |
||
486 | $user_id = api_get_user_id(); |
||
487 | $course_id = $_course['real_id']; |
||
488 | if (is_array($attendanceId)) { |
||
489 | foreach ($attendanceId as $id) { |
||
490 | $id = (int) $id; |
||
491 | $sql = "UPDATE $tbl_attendance SET active = 1 |
||
492 | WHERE iid = '$id'"; |
||
493 | $result = Database::query($sql); |
||
494 | $affected_rows = Database::affected_rows($result); |
||
495 | if (!empty($affected_rows)) { |
||
496 | // update row item property table |
||
497 | /*api_item_property_update( |
||
498 | $_course, |
||
499 | TOOL_ATTENDANCE, |
||
500 | $id, |
||
501 | 'restore', |
||
502 | $user_id |
||
503 | );*/ |
||
504 | } |
||
505 | } |
||
506 | } else { |
||
507 | $attendanceId = (int) $attendanceId; |
||
508 | $sql = "UPDATE $tbl_attendance SET active = 1 |
||
509 | WHERE iid = '$attendanceId'"; |
||
510 | $result = Database::query($sql); |
||
511 | $affected_rows = Database::affected_rows($result); |
||
512 | if (!empty($affected_rows)) { |
||
513 | // update row item property table |
||
514 | /*api_item_property_update( |
||
515 | $_course, |
||
516 | TOOL_ATTENDANCE, |
||
517 | $attendanceId, |
||
518 | 'restore', |
||
519 | $user_id |
||
520 | );*/ |
||
521 | } |
||
522 | } |
||
523 | |||
524 | return $affected_rows; |
||
525 | } |
||
526 | |||
527 | /** |
||
528 | * Delete attendances. |
||
529 | * |
||
530 | * @param CAttendance $attendance one or many attendances id |
||
531 | * |
||
532 | * @return bool |
||
533 | */ |
||
534 | public function attendance_delete(CAttendance $attendance) |
||
535 | { |
||
536 | $allowDeleteAttendance = api_get_setting('allow_delete_attendance'); |
||
537 | if ('true' !== $allowDeleteAttendance) { |
||
538 | return false; |
||
539 | } |
||
540 | |||
541 | $repo = Container::getAttendanceRepository(); |
||
542 | $attendance->setActive(2); |
||
543 | $repo->update($attendance); |
||
544 | |||
545 | SkillModel::deleteSkillsFromItem($attendance->getIid(), ITEM_TYPE_ATTENDANCE); |
||
546 | |||
547 | return true; |
||
548 | |||
549 | /*$_course = api_get_course_info(); |
||
550 | $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE); |
||
551 | $user_id = api_get_user_id(); |
||
552 | $course_id = $_course['real_id']; |
||
553 | |||
554 | $attendanceId = (int) $attendanceId; |
||
555 | $sql = "UPDATE $tbl_attendance SET active = 2 |
||
556 | WHERE c_id = $course_id AND id = '$attendanceId'"; |
||
557 | |||
558 | $result = Database::query($sql); |
||
559 | $affected_rows = Database::affected_rows($result); |
||
560 | if (!empty($affected_rows)) { |
||
561 | // update row item property table |
||
562 | api_item_property_update( |
||
563 | $_course, |
||
564 | TOOL_ATTENDANCE, |
||
565 | $attendanceId, |
||
566 | "delete", |
||
567 | $user_id |
||
568 | ); |
||
569 | }return $affected_rows; |
||
570 | */ |
||
571 | } |
||
572 | |||
573 | /** |
||
574 | * Changes visibility. |
||
575 | * |
||
576 | * @param CAttendance $attendance one or many attendances id |
||
577 | * @param int $status |
||
578 | * |
||
579 | * @return int affected rows |
||
580 | */ |
||
581 | public function changeVisibility(CAttendance $attendance, $status = 1) |
||
590 | /* |
||
591 | |||
592 | $attendanceId = (int) $attendanceId; |
||
593 | $sql = "UPDATE $tbl_attendance SET active = $status |
||
594 | WHERE c_id = $course_id AND id = '$attendanceId'"; |
||
595 | $result = Database::query($sql); |
||
596 | $affected_rows = Database::affected_rows($result); |
||
597 | if (!empty($affected_rows)) { |
||
598 | // update row item property table |
||
599 | api_item_property_update( |
||
600 | $_course, |
||
601 | TOOL_ATTENDANCE, |
||
602 | $attendanceId, |
||
603 | $action, |
||
604 | $user_id |
||
605 | ); |
||
606 | } |
||
607 | |||
608 | return $affected_rows; |
||
609 | */ |
||
610 | } |
||
611 | |||
612 | /** |
||
613 | * Lock or unlock an attendance. |
||
614 | * |
||
615 | * @param bool True to lock or false otherwise |
||
616 | * |
||
617 | * @return bool |
||
618 | */ |
||
619 | public function lock(CAttendance $attendance, $lock = true) |
||
620 | { |
||
621 | $repo = Container::getAttendanceRepository(); |
||
622 | $attendance->setLocked($lock); |
||
623 | $repo->update($attendance); |
||
624 | |||
625 | $this->saveAttendanceSheetLog( |
||
626 | $attendance, |
||
627 | api_get_utc_datetime(time(), false, true), |
||
628 | self::LOCKED_ATTENDANCE_LOG_TYPE, |
||
629 | api_get_user_entity() |
||
630 | ); |
||
631 | |||
632 | return true; |
||
633 | } |
||
634 | |||
635 | /** |
||
636 | * Get registered users inside current course. |
||
637 | * |
||
638 | * @param int $attendanceId attendance id for showing attendance result field (optional) |
||
639 | * @param int $groupId |
||
640 | * |
||
641 | * @return array users data |
||
642 | */ |
||
643 | public function get_users_rel_course($attendanceId = 0, $groupId = 0) |
||
644 | { |
||
645 | $current_session_id = api_get_session_id(); |
||
646 | $current_course_id = api_get_course_id(); |
||
647 | $currentCourseIntId = api_get_course_int_id(); |
||
648 | $studentInGroup = []; |
||
649 | |||
650 | if (!empty($current_session_id)) { |
||
651 | $a_course_users = CourseManager:: get_user_list_from_course_code( |
||
652 | $current_course_id, |
||
653 | $current_session_id, |
||
654 | '', |
||
655 | 'lastname' |
||
656 | ); |
||
657 | } else { |
||
658 | $a_course_users = CourseManager:: get_user_list_from_course_code( |
||
659 | $current_course_id, |
||
660 | 0, |
||
661 | '', |
||
662 | 'lastname' |
||
663 | ); |
||
664 | } |
||
665 | |||
666 | if (!empty($groupId)) { |
||
667 | $groupInfo = GroupManager::get_group_properties($groupId); |
||
668 | $students = GroupManager::getStudents($groupInfo['iid']); |
||
669 | if (!empty($students)) { |
||
670 | foreach ($students as $student) { |
||
671 | $studentInGroup[$student['user_id']] = true; |
||
672 | } |
||
673 | } |
||
674 | } |
||
675 | |||
676 | // get registered users inside current course |
||
677 | $a_users = []; |
||
678 | foreach ($a_course_users as $key => $user_data) { |
||
679 | $value = []; |
||
680 | $uid = $user_data['user_id']; |
||
681 | $userInfo = api_get_user_info($uid); |
||
682 | $status = $user_data['status']; |
||
683 | |||
684 | if (!empty($groupId)) { |
||
685 | if (!isset($studentInGroup[$uid])) { |
||
686 | continue; |
||
687 | } |
||
688 | } |
||
689 | |||
690 | $user_status_in_session = null; |
||
691 | $user_status_in_course = null; |
||
692 | |||
693 | if (api_get_session_id()) { |
||
694 | $user_status_in_session = SessionManager::get_user_status_in_course_session( |
||
695 | $uid, |
||
696 | $currentCourseIntId, |
||
697 | $current_session_id |
||
698 | ); |
||
699 | } else { |
||
700 | $user_status_in_course = CourseManager::getUserInCourseStatus( |
||
701 | $uid, |
||
702 | $currentCourseIntId |
||
703 | ); |
||
704 | } |
||
705 | |||
706 | // Not taking into account DRH or COURSEMANAGER |
||
707 | if ($uid <= 1 || |
||
708 | DRH == $status || |
||
709 | COURSEMANAGER == $user_status_in_course || |
||
710 | 2 == $user_status_in_session |
||
711 | ) { |
||
712 | continue; |
||
713 | } |
||
714 | |||
715 | if (!empty($attendanceId)) { |
||
716 | $user_faults = $this->get_faults_of_user( |
||
717 | $uid, |
||
718 | $attendanceId, |
||
719 | $groupId |
||
720 | ); |
||
721 | $value['attendance_result'] = $user_faults['faults'].'/'.$user_faults['total'].' ('.$user_faults['faults_porcent'].'%)'; |
||
722 | $value['result_color_bar'] = $user_faults['color_bar']; |
||
723 | } |
||
724 | |||
725 | $photo = Display::img( |
||
726 | $userInfo['avatar_small'], |
||
727 | $userInfo['complete_name'], |
||
728 | [], |
||
729 | false |
||
730 | ); |
||
731 | |||
732 | $value['photo'] = $photo; |
||
733 | $value['firstname'] = $user_data['firstname']; |
||
734 | $value['lastname'] = $user_data['lastname']; |
||
735 | $value['username'] = $user_data['username']; |
||
736 | $value['user_id'] = $uid; |
||
737 | |||
738 | // Sending only 5 items in the array instead of 60 |
||
739 | $a_users[$key] = $value; |
||
740 | } |
||
741 | |||
742 | return $a_users; |
||
743 | } |
||
744 | |||
745 | /** |
||
746 | * add attendances sheet inside table. |
||
747 | * |
||
748 | * @param int $calendar_id attendance calendar id |
||
749 | * @param array $users_present present users during current class |
||
750 | * |
||
751 | * @return int affected rows |
||
752 | */ |
||
753 | public function attendance_sheet_add($calendar_id, $users_present, CAttendance $attendance) |
||
754 | { |
||
755 | $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET); |
||
756 | $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
757 | |||
758 | $calendar_id = (int) $calendar_id; |
||
759 | $users = $this->get_users_rel_course(); |
||
760 | $user_ids = array_keys($users); |
||
761 | $users_absent = array_diff($user_ids, $users_present); |
||
762 | $affected_rows = 0; |
||
763 | |||
764 | // get last edit type |
||
765 | $calendar_data = $this->get_attendance_calendar_by_id($calendar_id); |
||
766 | $lastedit_type = self::DONE_ATTENDANCE_LOG_TYPE; |
||
767 | if ($calendar_data['done_attendance']) { |
||
768 | $lastedit_type = self::UPDATED_ATTENDANCE_LOG_TYPE; |
||
769 | } |
||
770 | |||
771 | // save users present in class |
||
772 | foreach ($users_present as $user_present) { |
||
773 | $uid = (int) $user_present; |
||
774 | // check if user already was registered with the $calendar_id |
||
775 | $sql = "SELECT user_id FROM $tbl_attendance_sheet |
||
776 | WHERE user_id = $uid AND attendance_calendar_id = $calendar_id"; |
||
777 | $rs = Database::query($sql); |
||
778 | if (0 == Database::num_rows($rs)) { |
||
779 | $sql = "INSERT INTO $tbl_attendance_sheet SET |
||
780 | user_id = '$uid', |
||
781 | attendance_calendar_id = '$calendar_id', |
||
782 | presence = 1, |
||
783 | signature = ''"; |
||
784 | $result = Database::query($sql); |
||
785 | |||
786 | $affected_rows += Database::affected_rows($result); |
||
787 | } else { |
||
788 | $sql = "UPDATE $tbl_attendance_sheet |
||
789 | SET presence = 1 |
||
790 | WHERE |
||
791 | user_id = $uid AND |
||
792 | attendance_calendar_id = $calendar_id |
||
793 | "; |
||
794 | $result = Database::query($sql); |
||
795 | $affected_rows += Database::affected_rows($result); |
||
796 | } |
||
797 | } |
||
798 | |||
799 | // save users absent in class |
||
800 | foreach ($users_absent as $user_absent) { |
||
801 | $uid = (int) $user_absent; |
||
802 | // check if user already was registered with the $calendar_id |
||
803 | $sql = "SELECT user_id FROM $tbl_attendance_sheet |
||
804 | WHERE user_id = $uid AND attendance_calendar_id = '$calendar_id'"; |
||
805 | $rs = Database::query($sql); |
||
806 | if (0 == Database::num_rows($rs)) { |
||
807 | $sql = "INSERT INTO $tbl_attendance_sheet SET |
||
808 | user_id ='$uid', |
||
809 | attendance_calendar_id = '$calendar_id', |
||
810 | presence = 0, |
||
811 | signature = ''"; |
||
812 | $result = Database::query($sql); |
||
813 | $affected_rows += Database::affected_rows($result); |
||
814 | } else { |
||
815 | $sql = "UPDATE $tbl_attendance_sheet SET presence = 0 |
||
816 | WHERE |
||
817 | user_id ='$uid' AND |
||
818 | attendance_calendar_id = '$calendar_id'"; |
||
819 | $result = Database::query($sql); |
||
820 | $affected_rows += Database::affected_rows($result); |
||
821 | } |
||
822 | } |
||
823 | |||
824 | // update done_attendance inside attendance calendar table |
||
825 | $sql = "UPDATE $tbl_attendance_calendar SET done_attendance = 1 |
||
826 | WHERE iid = '$calendar_id'"; |
||
827 | Database::query($sql); |
||
828 | |||
829 | // save users' results |
||
830 | $this->updateUsersResults($user_ids, $attendance); |
||
831 | |||
832 | if ($affected_rows) { |
||
833 | //save attendance sheet log |
||
834 | $this->saveAttendanceSheetLog( |
||
835 | $attendance, |
||
836 | api_get_utc_datetime(time(), false, true), |
||
837 | $lastedit_type, |
||
838 | api_get_user_entity(), |
||
839 | api_get_utc_datetime($calendar_data['date_time'], true, true) |
||
840 | ); |
||
841 | } |
||
842 | |||
843 | return $affected_rows; |
||
844 | } |
||
845 | |||
846 | /** |
||
847 | * update users' attendance results. |
||
848 | * |
||
849 | * @param array $user_ids registered users inside current course |
||
850 | */ |
||
851 | public function updateUsersResults($user_ids, CAttendance $attendance) |
||
852 | { |
||
853 | $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET); |
||
854 | $tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT); |
||
855 | $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE); |
||
856 | $attendanceId = $attendance->getIid(); |
||
857 | // fill results about presence of students |
||
858 | $attendance_calendar = $this->get_attendance_calendar( |
||
859 | $attendanceId, |
||
860 | 'all', |
||
861 | null, |
||
862 | null, |
||
863 | true |
||
864 | ); |
||
865 | $calendar_ids = []; |
||
866 | // get all dates from calendar by current attendance |
||
867 | foreach ($attendance_calendar as $cal) { |
||
868 | $calendar_ids[] = $cal['iid']; |
||
869 | } |
||
870 | |||
871 | // get count of presences by users inside current attendance and save like results |
||
872 | if (count($user_ids) > 0) { |
||
873 | foreach ($user_ids as $uid) { |
||
874 | $uid = (int) $uid; |
||
875 | $count_presences = 0; |
||
876 | if (count($calendar_ids) > 0) { |
||
877 | $sql = "SELECT count(presence) as count_presences |
||
878 | FROM $tbl_attendance_sheet |
||
879 | WHERE |
||
880 | user_id = $uid AND |
||
881 | attendance_calendar_id IN (".implode(',', $calendar_ids).') AND |
||
882 | presence = 1'; |
||
883 | $rs_count = Database::query($sql); |
||
884 | $row_count = Database::fetch_array($rs_count); |
||
885 | $count_presences = $row_count['count_presences']; |
||
886 | } |
||
887 | |||
888 | // save results |
||
889 | $sql = "SELECT iid FROM $tbl_attendance_result |
||
890 | WHERE |
||
891 | user_id = '$uid' AND |
||
892 | attendance_id = '$attendanceId' "; |
||
893 | $rs_check_result = Database::query($sql); |
||
894 | |||
895 | if (Database::num_rows($rs_check_result) > 0) { |
||
896 | // update result |
||
897 | $sql = "UPDATE $tbl_attendance_result SET |
||
898 | score = '$count_presences' |
||
899 | WHERE |
||
900 | user_id='$uid' AND |
||
901 | attendance_id='$attendanceId'"; |
||
902 | Database::query($sql); |
||
903 | } else { |
||
904 | // insert new result |
||
905 | $sql = "INSERT INTO $tbl_attendance_result SET |
||
906 | user_id = '$uid', |
||
907 | attendance_id = '$attendanceId', |
||
908 | score = '$count_presences'"; |
||
909 | Database::query($sql); |
||
910 | $insertId = Database::insert_id(); |
||
911 | } |
||
912 | } |
||
913 | } |
||
914 | |||
915 | // update attendance qualify max |
||
916 | $count_done_calendar = self::get_done_attendance_calendar($attendance); |
||
917 | $sql = "UPDATE $tbl_attendance SET |
||
918 | attendance_qualify_max = '$count_done_calendar' |
||
919 | WHERE iid = '$attendanceId'"; |
||
920 | Database::query($sql); |
||
921 | } |
||
922 | |||
923 | /** |
||
924 | * update attendance_sheet_log table, is used as history of an attendance sheet. |
||
925 | */ |
||
926 | public function saveAttendanceSheetLog( |
||
927 | CAttendance $attendance, |
||
928 | DateTime $lastEditDate, |
||
929 | string $lastEditType, |
||
930 | User $user, |
||
931 | ?DateTime $dateValue = null |
||
932 | ) { |
||
933 | $log = new CAttendanceSheetLog(); |
||
934 | $log |
||
935 | ->setAttendance($attendance) |
||
936 | ->setUser($user) |
||
937 | ->setCalendarDateValue($dateValue) |
||
938 | ->setLasteditDate($lastEditDate) |
||
939 | ->setLasteditType($lastEditType) |
||
940 | ; |
||
941 | $em = Database::getManager(); |
||
942 | $em->persist($log); |
||
943 | $em->flush(); |
||
944 | } |
||
945 | |||
946 | /** |
||
947 | * Get number of done attendances inside current sheet. |
||
948 | * |
||
949 | * @return int number of done attendances |
||
950 | */ |
||
951 | public static function get_done_attendance_calendar(CAttendance $attendance) |
||
952 | { |
||
953 | $criteria = Criteria::create()->where( |
||
954 | Criteria::expr()->eq('doneAttendance', 1) |
||
955 | ); |
||
956 | |||
957 | if (!$attendance->getCalendars()) { |
||
958 | return 0; |
||
959 | } |
||
960 | |||
961 | return $attendance->getCalendars()->matching($criteria)->count(); |
||
962 | |||
963 | /*$table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
964 | $attendanceId = (int) $attendanceId; |
||
965 | $course_id = api_get_course_int_id(); |
||
966 | $sql = "SELECT count(done_attendance) as count |
||
967 | FROM $table |
||
968 | WHERE |
||
969 | attendance_id = '$attendanceId' AND |
||
970 | done_attendance = 1 |
||
971 | "; |
||
972 | $rs = Database::query($sql); |
||
973 | $row = Database::fetch_array($rs); |
||
974 | $count = $row['count']; |
||
975 | |||
976 | return $count;*/ |
||
977 | } |
||
978 | |||
979 | /** |
||
980 | * Get results of faults (absents) by user. |
||
981 | * |
||
982 | * @param int $user_id |
||
983 | * @param int $attendanceId |
||
984 | * @param int $groupId |
||
985 | * |
||
986 | * @return array results containing number of faults, total done attendance, |
||
987 | * percent of faults and color depend on result (red, orange) |
||
988 | */ |
||
989 | public function get_faults_of_user($user_id, $attendanceId, $groupId = null) |
||
990 | { |
||
991 | $user_id = (int) $user_id; |
||
992 | $attendanceId = (int) $attendanceId; |
||
993 | $results = []; |
||
994 | $calendar_count = self::get_number_of_attendance_calendar( |
||
995 | $attendanceId, |
||
996 | $groupId, |
||
997 | null, |
||
998 | $user_id |
||
999 | ); |
||
1000 | // $total_done_attendance = $attendance_data['attendance_qualify_max']; |
||
1001 | $total_done_attendance = self::get_number_of_attendance_calendar( |
||
1002 | $attendanceId, |
||
1003 | $groupId, |
||
1004 | true, |
||
1005 | $user_id |
||
1006 | ); |
||
1007 | $attendance_user_score = $this->get_user_score($user_id, $attendanceId, $groupId); |
||
1008 | |||
1009 | //This is the main change of the BT#1381 |
||
1010 | //$total_done_attendance = $calendar_count; |
||
1011 | |||
1012 | // calculate results |
||
1013 | $faults = $total_done_attendance - $attendance_user_score; |
||
1014 | |||
1015 | if (empty($calendar_count)) { |
||
1016 | $faults = 0; |
||
1017 | } |
||
1018 | |||
1019 | $faults = $faults > 0 ? $faults : 0; |
||
1020 | $faults_porcent = $calendar_count > 0 ? round(($faults * 100) / $calendar_count, 0) : 0; |
||
1021 | $results['faults'] = $faults; |
||
1022 | $results['total'] = $calendar_count; |
||
1023 | $results['faults_porcent'] = $faults_porcent; |
||
1024 | $color_bar = ''; |
||
1025 | |||
1026 | if ($faults_porcent > 25) { |
||
1027 | $color_bar = '#f28989'; |
||
1028 | } elseif ($faults_porcent > 10) { |
||
1029 | $color_bar = '#F90'; |
||
1030 | } |
||
1031 | $results['color_bar'] = $color_bar; |
||
1032 | |||
1033 | return $results; |
||
1034 | } |
||
1035 | |||
1036 | /** |
||
1037 | * Get results of faults average for all courses by user. |
||
1038 | * |
||
1039 | * @param int $user_id |
||
1040 | * |
||
1041 | * @return array results containing number of faults, total done attendance, |
||
1042 | * percentage of faults and color depend on result (red, orange) |
||
1043 | */ |
||
1044 | public function get_faults_average_inside_courses($user_id) |
||
1045 | { |
||
1046 | // get all courses of current user |
||
1047 | $courses = CourseManager::get_courses_list_by_user_id($user_id, true); |
||
1048 | $user_id = (int) $user_id; |
||
1049 | $results = []; |
||
1050 | $total_faults = $total_weight = $porcent = 0; |
||
1051 | foreach ($courses as $course) { |
||
1052 | //$course_code = $course['code']; |
||
1053 | //$course_info = api_get_course_info($course_code); |
||
1054 | $course_id = $course['real_id']; |
||
1055 | $tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT); |
||
1056 | $attendances = $this->getAttendanceList(api_get_course_entity($course_id)); |
||
1057 | |||
1058 | foreach ($attendances as $attendance) { |
||
1059 | $attendanceId = $attendance->getIid(); |
||
1060 | // get total faults and total weight |
||
1061 | $total_done_attendance = $attendance->getAttendanceQualifyMax(); |
||
1062 | $sql = "SELECT score |
||
1063 | FROM $tbl_attendance_result |
||
1064 | WHERE |
||
1065 | user_id = $user_id AND |
||
1066 | attendance_id = ".$attendanceId; |
||
1067 | $rs = Database::query($sql); |
||
1068 | $score = 0; |
||
1069 | if (Database::num_rows($rs) > 0) { |
||
1070 | $row = Database::fetch_array($rs); |
||
1071 | $score = $row['score']; |
||
1072 | } |
||
1073 | $faults = $total_done_attendance - $score; |
||
1074 | $faults = $faults > 0 ? $faults : 0; |
||
1075 | $total_faults += $faults; |
||
1076 | $total_weight += $total_done_attendance; |
||
1077 | } |
||
1078 | } |
||
1079 | |||
1080 | $percent = $total_weight > 0 ? round(($total_faults * 100) / $total_weight, 0) : 0; |
||
1081 | $results['faults'] = $total_faults; |
||
1082 | $results['total'] = $total_weight; |
||
1083 | $results['percent'] = $percent; |
||
1084 | |||
1085 | return $results; |
||
1086 | } |
||
1087 | |||
1088 | /** |
||
1089 | * Get results of faults average by course. |
||
1090 | * |
||
1091 | * @return array results containing number of faults, |
||
1092 | * total done attendance, percent of faults and color depend on result (red, orange) |
||
1093 | */ |
||
1094 | public function get_faults_average_by_course($user_id, Course $course, Session $session = null) |
||
1095 | { |
||
1096 | // Database tables and variables |
||
1097 | $courseId = $course->getId(); |
||
1098 | $tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT); |
||
1099 | $user_id = (int) $user_id; |
||
1100 | $results = []; |
||
1101 | $total_faults = $total_weight = 0; |
||
1102 | $attendances = $this->getAttendanceList($course, $session); |
||
1103 | |||
1104 | foreach ($attendances as $attendance) { |
||
1105 | $attendanceId = $attendance->getIid(); |
||
1106 | // Get total faults and total weight |
||
1107 | $total_done_attendance = $attendance->getAttendanceQualifyMax(); |
||
1108 | $sql = "SELECT score FROM $tbl_attendance_result |
||
1109 | WHERE |
||
1110 | user_id = $user_id AND |
||
1111 | attendance_id=".$attendanceId; |
||
1112 | $rs = Database::query($sql); |
||
1113 | $score = 0; |
||
1114 | if (Database::num_rows($rs) > 0) { |
||
1115 | $row = Database::fetch_array($rs); |
||
1116 | $score = $row['score']; |
||
1117 | } |
||
1118 | $faults = $total_done_attendance - $score; |
||
1119 | $faults = $faults > 0 ? $faults : 0; |
||
1120 | $total_faults += $faults; |
||
1121 | $total_weight += $total_done_attendance; |
||
1122 | } |
||
1123 | |||
1124 | $percent = $total_weight > 0 ? round(($total_faults * 100) / $total_weight, 0) : 0; |
||
1125 | $results['faults'] = $total_faults; |
||
1126 | $results['total'] = $total_weight; |
||
1127 | $results['percent'] = $percent; |
||
1128 | |||
1129 | return $results; |
||
1130 | } |
||
1131 | |||
1132 | /** |
||
1133 | * Get registered users' attendance sheet inside current course. |
||
1134 | * |
||
1135 | * @param int $attendanceId |
||
1136 | * @param int $user_id for showing data for only one user (optional) |
||
1137 | * @param int $groupId |
||
1138 | * |
||
1139 | * @return array users attendance sheet data |
||
1140 | */ |
||
1141 | public function get_users_attendance_sheet( |
||
1142 | $attendanceId, |
||
1143 | $user_id = 0, |
||
1144 | $groupId = 0, |
||
1145 | $course_id = 0, |
||
1146 | DateTime $startDate = null, |
||
1147 | DateTime $endDate = null |
||
1148 | ) { |
||
1149 | //Get actual course or by course_id |
||
1150 | $course_id = (0 == $course_id) ? api_get_course_int_id() : (int) $course_id; |
||
1151 | $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET); |
||
1152 | $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1153 | $attendance_calendar = $this->get_attendance_calendar( |
||
1154 | $attendanceId, |
||
1155 | 'all', |
||
1156 | null, |
||
1157 | $groupId, |
||
1158 | true, |
||
1159 | $course_id, |
||
1160 | $startDate, |
||
1161 | $endDate |
||
1162 | ); |
||
1163 | $calendar_ids = []; |
||
1164 | // get all dates from calendar by current attendance |
||
1165 | foreach ($attendance_calendar as $cal) { |
||
1166 | $calendar_ids[] = $cal['iid']; |
||
1167 | } |
||
1168 | |||
1169 | $whereDate = ''; |
||
1170 | if (!empty($startDate)) { |
||
1171 | $whereDate .= " AND cal.date_time >= '".$startDate->format('Y-m-d H:i:s')."'"; |
||
1172 | } |
||
1173 | if (!empty($endDate)) { |
||
1174 | $whereDate .= " AND cal.date_time <= '".$endDate->format('Y-m-d H:i:s')."'"; |
||
1175 | } |
||
1176 | |||
1177 | // moved at start of this function |
||
1178 | // $course_id = api_get_course_int_id(); |
||
1179 | |||
1180 | $data = []; |
||
1181 | if (empty($user_id)) { |
||
1182 | // get all registered users inside current course |
||
1183 | $users = $this->get_users_rel_course(); |
||
1184 | $user_ids = array_keys($users); |
||
1185 | if (count($calendar_ids) > 0 && count($user_ids) > 0) { |
||
1186 | foreach ($user_ids as $uid) { |
||
1187 | $uid = (int) $uid; |
||
1188 | $sql = "SELECT * FROM $tbl_attendance_sheet |
||
1189 | WHERE |
||
1190 | user_id = '$uid' AND |
||
1191 | attendance_calendar_id IN(".implode(',', $calendar_ids).') |
||
1192 | '; |
||
1193 | $res = Database::query($sql); |
||
1194 | if (Database::num_rows($res) > 0) { |
||
1195 | while ($row = Database::fetch_array($res)) { |
||
1196 | $data[$uid][$row['attendance_calendar_id']]['presence'] = $row['presence']; |
||
1197 | } |
||
1198 | } |
||
1199 | } |
||
1200 | } |
||
1201 | } else { |
||
1202 | // Get attendance for current user |
||
1203 | $user_id = (int) $user_id; |
||
1204 | if (count($calendar_ids) > 0) { |
||
1205 | $sql = "SELECT cal.date_time, att.presence |
||
1206 | FROM $tbl_attendance_sheet att |
||
1207 | INNER JOIN $tbl_attendance_calendar cal |
||
1208 | ON cal.iid = att.attendance_calendar_id |
||
1209 | WHERE |
||
1210 | att.user_id = $user_id AND |
||
1211 | att.attendance_calendar_id IN (".implode(',', $calendar_ids).") |
||
1212 | $whereDate |
||
1213 | ORDER BY date_time"; |
||
1214 | $res = Database::query($sql); |
||
1215 | if (Database::num_rows($res) > 0) { |
||
1216 | while ($row = Database::fetch_array($res)) { |
||
1217 | $row['date_time'] = api_convert_and_format_date($row['date_time'], null, date_default_timezone_get()); |
||
1218 | $data[$user_id][] = $row; |
||
1219 | } |
||
1220 | } |
||
1221 | } |
||
1222 | } |
||
1223 | |||
1224 | return $data; |
||
1225 | } |
||
1226 | |||
1227 | /** |
||
1228 | * Get next attendance calendar without presences (done attendances). |
||
1229 | * |
||
1230 | * @param int attendance id |
||
1231 | * |
||
1232 | * @return int attendance calendar id |
||
1233 | */ |
||
1234 | public function get_next_attendance_calendar_id($attendanceId) |
||
1235 | { |
||
1236 | $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1237 | $attendanceId = (int) $attendanceId; |
||
1238 | $course_id = api_get_course_int_id(); |
||
1239 | |||
1240 | $sql = "SELECT iid FROM $table |
||
1241 | WHERE |
||
1242 | attendance_id = '$attendanceId' AND |
||
1243 | done_attendance = 0 |
||
1244 | ORDER BY date_time |
||
1245 | LIMIT 1"; |
||
1246 | $rs = Database::query($sql); |
||
1247 | $next_calendar_id = 0; |
||
1248 | if (Database::num_rows($rs) > 0) { |
||
1249 | $row = Database::fetch_array($rs); |
||
1250 | $next_calendar_id = $row['iid']; |
||
1251 | } |
||
1252 | |||
1253 | return $next_calendar_id; |
||
1254 | } |
||
1255 | |||
1256 | /** |
||
1257 | * Get next attendance calendar datetime without presences (done attendances). |
||
1258 | * |
||
1259 | * @param int attendance id |
||
1260 | * |
||
1261 | * @return int UNIX time format datetime |
||
1262 | */ |
||
1263 | public function getNextAttendanceCalendarDatetime($attendanceId) |
||
1264 | { |
||
1265 | $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1266 | $course_id = api_get_course_int_id(); |
||
1267 | $attendanceId = (int) $attendanceId; |
||
1268 | $sql = "SELECT iid, date_time FROM $table |
||
1269 | WHERE |
||
1270 | attendance_id = '$attendanceId' AND |
||
1271 | done_attendance = 0 |
||
1272 | ORDER BY date_time |
||
1273 | LIMIT 1"; |
||
1274 | $rs = Database::query($sql); |
||
1275 | $next_calendar_datetime = 0; |
||
1276 | if (Database::num_rows($rs) > 0) { |
||
1277 | $row = Database::fetch_array($rs); |
||
1278 | $next_calendar_datetime = api_get_local_time($row['date_time']); |
||
1279 | } |
||
1280 | |||
1281 | return $next_calendar_datetime; |
||
1282 | } |
||
1283 | |||
1284 | /** |
||
1285 | * Get user's score from current attendance. |
||
1286 | * |
||
1287 | * @param int $user_id |
||
1288 | * @param int $attendanceId |
||
1289 | * @param int $groupId |
||
1290 | * |
||
1291 | * @return int score |
||
1292 | */ |
||
1293 | public function get_user_score($user_id, $attendanceId, $groupId = 0) |
||
1294 | { |
||
1295 | $tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT); |
||
1296 | $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET); |
||
1297 | $tbl_attendance_cal_rel_group = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP); |
||
1298 | $tbl_attendance_cal = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1299 | $user_id = (int) $user_id; |
||
1300 | $attendanceId = (int) $attendanceId; |
||
1301 | $groupId = (int) $groupId; |
||
1302 | $course_id = api_get_course_int_id(); |
||
1303 | |||
1304 | if (empty($groupId)) { |
||
1305 | $sql = "SELECT score FROM $tbl_attendance_result |
||
1306 | WHERE |
||
1307 | user_id='$user_id' AND |
||
1308 | attendance_id='$attendanceId'"; |
||
1309 | } else { |
||
1310 | $sql = "SELECT count(presence) as score |
||
1311 | FROM $tbl_attendance_sheet |
||
1312 | WHERE |
||
1313 | user_id = '$user_id' AND |
||
1314 | presence = 1 AND |
||
1315 | attendance_calendar_id IN ( |
||
1316 | SELECT calendar_id FROM $tbl_attendance_cal_rel_group crg |
||
1317 | INNER JOIN $tbl_attendance_cal c |
||
1318 | ON (crg.calendar_id = c.iid) |
||
1319 | WHERE |
||
1320 | crg.group_id = $groupId AND |
||
1321 | c.attendance_id = $attendanceId |
||
1322 | ) |
||
1323 | "; |
||
1324 | } |
||
1325 | $rs = Database::query($sql); |
||
1326 | $score = 0; |
||
1327 | if (Database::num_rows($rs) > 0) { |
||
1328 | $row = Database::fetch_array($rs); |
||
1329 | $score = $row['score']; |
||
1330 | } |
||
1331 | |||
1332 | return $score; |
||
1333 | } |
||
1334 | |||
1335 | /** |
||
1336 | * Get attendance calendar data by id. |
||
1337 | * |
||
1338 | * @param int attendance calendar id |
||
1339 | * |
||
1340 | * @return array attendance calendar data |
||
1341 | */ |
||
1342 | public function get_attendance_calendar_by_id($calendar_id) |
||
1343 | { |
||
1344 | $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1345 | $calendar_id = (int) $calendar_id; |
||
1346 | $course_id = api_get_course_int_id(); |
||
1347 | $sql = "SELECT * FROM $table |
||
1348 | WHERE iid = '$calendar_id' "; |
||
1349 | $rs = Database::query($sql); |
||
1350 | $data = []; |
||
1351 | if (Database::num_rows($rs) > 0) { |
||
1352 | while ($row = Database::fetch_array($rs)) { |
||
1353 | $row['date_time'] = api_get_local_time($row['date_time']); |
||
1354 | $data = $row; |
||
1355 | } |
||
1356 | } |
||
1357 | |||
1358 | return $data; |
||
1359 | } |
||
1360 | |||
1361 | /** |
||
1362 | * Get all attendance calendar data inside current attendance. |
||
1363 | * |
||
1364 | * @param int $attendanceId |
||
1365 | * @param string $type |
||
1366 | * @param int $calendar_id |
||
1367 | * @param int $groupId |
||
1368 | * @param bool $showAll = false show group calendar items or not |
||
1369 | * @param int $course_id |
||
1370 | * @param DateTime $startDate Filter calendar with a start date |
||
1371 | * @param DateTime $endDate Filter calendar with a end date |
||
1372 | * |
||
1373 | * @return array attendance calendar data |
||
1374 | */ |
||
1375 | public function get_attendance_calendar( |
||
1376 | $attendanceId, |
||
1377 | $type = 'all', |
||
1378 | $calendar_id = null, |
||
1379 | $groupId = 0, |
||
1380 | $showAll = false, |
||
1381 | $course_id = 0, |
||
1382 | DateTime $startDate = null, |
||
1383 | DateTime $endDate = null |
||
1384 | ) { |
||
1385 | $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1386 | $tbl_acrg = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP); |
||
1387 | $attendanceId = (int) $attendanceId; |
||
1388 | $course_id = 0 == $course_id ? api_get_course_int_id() : (int) $course_id; |
||
1389 | $whereDate = ''; |
||
1390 | if (!empty($startDate)) { |
||
1391 | $whereDate .= " AND c.date_time >= '".$startDate->format('Y-m-d H:i:s')."'"; |
||
1392 | } |
||
1393 | if (!empty($endDate)) { |
||
1394 | $whereDate .= " AND c.date_time <= '".$endDate->format('Y-m-d H:i:s')."'"; |
||
1395 | } |
||
1396 | if ($showAll) { |
||
1397 | $sql = "SELECT * FROM $tbl_attendance_calendar c |
||
1398 | WHERE |
||
1399 | attendance_id = '$attendanceId' |
||
1400 | $whereDate"; |
||
1401 | } else { |
||
1402 | $sql = "SELECT * FROM $tbl_attendance_calendar c |
||
1403 | WHERE |
||
1404 | attendance_id = '$attendanceId' AND |
||
1405 | iid NOT IN ( |
||
1406 | SELECT calendar_id FROM $tbl_acrg |
||
1407 | WHERE attendance_id = '$attendanceId' AND group_id != 0 AND group_id IS NOT NULL |
||
1408 | ) |
||
1409 | $whereDate |
||
1410 | "; |
||
1411 | } |
||
1412 | |||
1413 | if (!empty($groupId)) { |
||
1414 | $groupId = (int) $groupId; |
||
1415 | $sql = "SELECT c.* FROM $tbl_attendance_calendar c |
||
1416 | INNER JOIN $tbl_acrg g |
||
1417 | ON c.iid = g.calendar_id |
||
1418 | WHERE |
||
1419 | g.group_id = '$groupId' AND |
||
1420 | c.attendance_id = '$attendanceId' |
||
1421 | "; |
||
1422 | } |
||
1423 | |||
1424 | if (!in_array($type, ['today', 'all', 'all_done', 'all_not_done', 'calendar_id'])) { |
||
1425 | $type = 'all'; |
||
1426 | } |
||
1427 | |||
1428 | switch ($type) { |
||
1429 | case 'calendar_id': |
||
1430 | $calendar_id = (int) $calendar_id; |
||
1431 | if (!empty($calendar_id)) { |
||
1432 | $sql .= " AND c.iid = $calendar_id"; |
||
1433 | } |
||
1434 | break; |
||
1435 | case 'today': |
||
1436 | //$sql .= ' AND DATE_FORMAT(date_time,"%d-%m-%Y") = DATE_FORMAT("'.api_get_utc_datetime().'", "%d-%m-%Y" )'; |
||
1437 | break; |
||
1438 | case 'all_done': |
||
1439 | $sql .= ' AND done_attendance = 1 '; |
||
1440 | break; |
||
1441 | case 'all_not_done': |
||
1442 | $sql .= ' AND done_attendance = 0 '; |
||
1443 | break; |
||
1444 | case 'all': |
||
1445 | default: |
||
1446 | break; |
||
1447 | } |
||
1448 | $sql .= ' ORDER BY date_time '; |
||
1449 | |||
1450 | $rs = Database::query($sql); |
||
1451 | $data = []; |
||
1452 | if (Database::num_rows($rs) > 0) { |
||
1453 | while ($row = Database::fetch_assoc($rs)) { |
||
1454 | $row['db_date_time'] = $row['date_time']; |
||
1455 | $row['date_time'] = api_get_local_time($row['date_time']); |
||
1456 | $row['date'] = api_format_date($row['date_time'], DATE_FORMAT_SHORT); |
||
1457 | $row['time'] = api_format_date($row['date_time'], TIME_NO_SEC_FORMAT); |
||
1458 | $row['groups'] = $this->getGroupListByAttendanceCalendar($row['iid'], $course_id); |
||
1459 | if ('today' === $type) { |
||
1460 | if (date('d-m-Y', api_strtotime($row['date_time'], 'UTC')) == date('d-m-Y', time())) { |
||
1461 | $data[] = $row; |
||
1462 | } |
||
1463 | } else { |
||
1464 | $data[] = $row; |
||
1465 | } |
||
1466 | } |
||
1467 | } |
||
1468 | |||
1469 | return $data; |
||
1470 | } |
||
1471 | |||
1472 | /** |
||
1473 | * Get number of attendance calendar inside current attendance. |
||
1474 | * |
||
1475 | * @param int $attendanceId |
||
1476 | * @param int $groupId |
||
1477 | * @param $done_attendance |
||
1478 | * @param int $userId |
||
1479 | * |
||
1480 | * @return int number of dates in attendance calendar |
||
1481 | */ |
||
1482 | public static function get_number_of_attendance_calendar( |
||
1483 | $attendanceId, |
||
1484 | $groupId = 0, |
||
1485 | $done_attendance = null, |
||
1486 | $userId = 0 |
||
1487 | ) { |
||
1488 | $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1489 | $calendarRelGroup = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP); |
||
1490 | $tbl_groupRelUser = Database::get_course_table(TABLE_GROUP_USER); |
||
1491 | $attendanceId = (int) $attendanceId; |
||
1492 | $groupId = (int) $groupId; |
||
1493 | $course_id = api_get_course_int_id(); |
||
1494 | |||
1495 | $where_attendance = ''; |
||
1496 | if ($done_attendance) { |
||
1497 | $where_attendance = ' done_attendance = 1 AND '; |
||
1498 | } |
||
1499 | if (empty($userId)) { |
||
1500 | if (empty($groupId)) { |
||
1501 | $sql = "SELECT count(a.iid) |
||
1502 | FROM $tbl_attendance_calendar a |
||
1503 | WHERE |
||
1504 | $where_attendance |
||
1505 | attendance_id = '$attendanceId' AND |
||
1506 | iid NOT IN ( |
||
1507 | SELECT calendar_id FROM $calendarRelGroup |
||
1508 | WHERE |
||
1509 | attendance_id = $attendanceId AND |
||
1510 | group_id != 0 AND |
||
1511 | group_id IS NOT NULL |
||
1512 | ) |
||
1513 | "; |
||
1514 | } else { |
||
1515 | $sql = "SELECT count(a.iid) |
||
1516 | FROM $tbl_attendance_calendar a |
||
1517 | INNER JOIN $calendarRelGroup g |
||
1518 | ON (a.iid = g.calendar_id) |
||
1519 | WHERE |
||
1520 | $where_attendance |
||
1521 | attendance_id = '$attendanceId' AND |
||
1522 | group_id = $groupId |
||
1523 | "; |
||
1524 | } |
||
1525 | } else { |
||
1526 | if (empty($groupId)) { |
||
1527 | $sql = "SELECT count(a.iid) |
||
1528 | FROM $tbl_attendance_calendar a |
||
1529 | WHERE |
||
1530 | $where_attendance |
||
1531 | attendance_id = '$attendanceId' AND |
||
1532 | iid NOT IN ( |
||
1533 | SELECT calendar_id FROM $calendarRelGroup |
||
1534 | WHERE |
||
1535 | group_id != 0 AND |
||
1536 | group_id IS NOT NULL AND |
||
1537 | group_id NOT IN ( |
||
1538 | SELECT group_id |
||
1539 | FROM $tbl_groupRelUser |
||
1540 | WHERE user_id = $userId |
||
1541 | ) |
||
1542 | ) |
||
1543 | "; |
||
1544 | } else { |
||
1545 | $sql = "SELECT count(a.iid) |
||
1546 | FROM $tbl_attendance_calendar a |
||
1547 | INNER JOIN $calendarRelGroup g |
||
1548 | ON (a.iid = g.calendar_id) |
||
1549 | WHERE |
||
1550 | $where_attendance |
||
1551 | attendance_id = '$attendanceId' AND |
||
1552 | group_id = $groupId |
||
1553 | "; |
||
1554 | } |
||
1555 | } |
||
1556 | |||
1557 | $rs = Database::query($sql); |
||
1558 | $row = Database::fetch_row($rs); |
||
1559 | |||
1560 | return $row[0]; |
||
1561 | } |
||
1562 | |||
1563 | /** |
||
1564 | * Get count dates inside attendance calendar by attendance id. |
||
1565 | * |
||
1566 | * @param int $attendanceId |
||
1567 | * |
||
1568 | * @return int count of dates |
||
1569 | */ |
||
1570 | public static function get_count_dates_inside_attendance_calendar($attendanceId) |
||
1571 | { |
||
1572 | $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1573 | $attendanceId = (int) $attendanceId; |
||
1574 | $course_id = api_get_course_int_id(); |
||
1575 | $sql = "SELECT count(iid) FROM $tbl_attendance_calendar |
||
1576 | WHERE |
||
1577 | attendance_id = '$attendanceId'"; |
||
1578 | $rs = Database::query($sql); |
||
1579 | $count = 0; |
||
1580 | if (Database::num_rows($rs) > 0) { |
||
1581 | $row = Database::fetch_row($rs); |
||
1582 | $count = $row[0]; |
||
1583 | } |
||
1584 | |||
1585 | return $count; |
||
1586 | } |
||
1587 | |||
1588 | /** |
||
1589 | * check if all calendar of an attendance is done. |
||
1590 | * |
||
1591 | * @return bool True if all calendar is done, otherwise false |
||
1592 | */ |
||
1593 | public static function is_all_attendance_calendar_done(CAttendance $attendance) |
||
1594 | { |
||
1595 | $done_calendar = self::get_done_attendance_calendar($attendance); |
||
1596 | //$count_dates_in_calendar = self::get_count_dates_inside_attendance_calendar($attendanceId); |
||
1597 | $count_dates_in_calendar = 0; |
||
1598 | if ($attendance->getCalendars()) { |
||
1599 | $count_dates_in_calendar = $attendance->getCalendars()->count(); |
||
1600 | } |
||
1601 | |||
1602 | //$number_of_dates = self::get_number_of_attendance_calendar($attendanceId); |
||
1603 | |||
1604 | $result = false; |
||
1605 | if ($count_dates_in_calendar == $done_calendar) { |
||
1606 | $result = true; |
||
1607 | } |
||
1608 | |||
1609 | return $result; |
||
1610 | } |
||
1611 | |||
1612 | /** |
||
1613 | * check if an attendance is locked. |
||
1614 | * |
||
1615 | * @param int $attendanceId |
||
1616 | * @param bool |
||
1617 | * |
||
1618 | * @return bool |
||
1619 | */ |
||
1620 | public static function is_locked_attendance($attendanceId) |
||
1621 | { |
||
1622 | // Use gradebook lock |
||
1623 | return api_resource_is_locked_by_gradebook($attendanceId, LINK_ATTENDANCE); |
||
1624 | } |
||
1625 | |||
1626 | /** |
||
1627 | * Add new datetime inside attendance calendar table. |
||
1628 | * |
||
1629 | * @param CAttendance $attendance |
||
1630 | * @param array $groupList |
||
1631 | * |
||
1632 | * @return int affected rows |
||
1633 | */ |
||
1634 | public function attendance_calendar_add($attendance, $groupList = []) |
||
1635 | { |
||
1636 | $course_id = api_get_course_int_id(); |
||
1637 | $calendar = new CAttendanceCalendar(); |
||
1638 | $calendar |
||
1639 | ->setAttendance($attendance) |
||
1640 | ->setDateTime(new Datetime($this->date_time)) |
||
1641 | ->setDoneAttendance(false) |
||
1642 | ->setBlocked(false); |
||
1643 | |||
1644 | $em = Database::getManager(); |
||
1645 | $em->persist($calendar); |
||
1646 | $em->flush(); |
||
1647 | |||
1648 | $this->addAttendanceCalendarToGroup($calendar->getIid(), $course_id, $groupList); |
||
1649 | |||
1650 | // update locked attendance |
||
1651 | $is_all_calendar_done = $this->is_all_attendance_calendar_done($attendance); |
||
1652 | if (!$is_all_calendar_done) { |
||
1653 | $this->lock($attendance, false); |
||
1654 | } else { |
||
1655 | $this->lock($attendance); |
||
1656 | } |
||
1657 | |||
1658 | return true; |
||
1659 | } |
||
1660 | |||
1661 | /** |
||
1662 | * @param int $calendarId |
||
1663 | * @param int $courseId |
||
1664 | * @param array $groupList |
||
1665 | * |
||
1666 | * @return bool |
||
1667 | */ |
||
1668 | public function addAttendanceCalendarToGroup($calendarId, $courseId, $groupList) |
||
1669 | { |
||
1670 | if (empty($groupList)) { |
||
1671 | return false; |
||
1672 | } |
||
1673 | |||
1674 | $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP); |
||
1675 | foreach ($groupList as $groupId) { |
||
1676 | if (empty($groupId)) { |
||
1677 | continue; |
||
1678 | } |
||
1679 | |||
1680 | $result = $this->getAttendanceCalendarGroup( |
||
1681 | $calendarId, |
||
1682 | $courseId, |
||
1683 | $groupId |
||
1684 | ); |
||
1685 | |||
1686 | if (empty($result)) { |
||
1687 | $params = [ |
||
1688 | 'calendar_id' => $calendarId, |
||
1689 | 'group_id' => $groupId, |
||
1690 | ]; |
||
1691 | Database::insert($table, $params); |
||
1692 | } |
||
1693 | } |
||
1694 | |||
1695 | return true; |
||
1696 | } |
||
1697 | |||
1698 | /** |
||
1699 | * @param int $calendarId |
||
1700 | * |
||
1701 | * @return array |
||
1702 | */ |
||
1703 | public function getGroupListByAttendanceCalendar($calendarId) |
||
1704 | { |
||
1705 | $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP); |
||
1706 | |||
1707 | return Database::select( |
||
1708 | '*', |
||
1709 | $table, |
||
1710 | [ |
||
1711 | 'where' => [ |
||
1712 | 'calendar_id = ? ' => [$calendarId], |
||
1713 | ], |
||
1714 | ] |
||
1715 | ); |
||
1716 | } |
||
1717 | |||
1718 | /** |
||
1719 | * @param int $calendarId |
||
1720 | * @param int $courseId |
||
1721 | * @param int $groupId |
||
1722 | * |
||
1723 | * @return array |
||
1724 | */ |
||
1725 | public function getAttendanceCalendarGroup($calendarId, $groupId) |
||
1726 | { |
||
1727 | $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP); |
||
1728 | |||
1729 | return Database::select( |
||
1730 | '*', |
||
1731 | $table, |
||
1732 | [ |
||
1733 | 'where' => [ |
||
1734 | 'calendar_id = ? AND group_id = ?' => [$calendarId, $groupId], |
||
1735 | ], |
||
1736 | ] |
||
1737 | ); |
||
1738 | } |
||
1739 | |||
1740 | /** |
||
1741 | * @param int $calendarId |
||
1742 | * @param int $courseId |
||
1743 | */ |
||
1744 | public function deleteAttendanceCalendarGroup($calendarId, $courseId) |
||
1745 | { |
||
1746 | $table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP); |
||
1747 | Database::delete( |
||
1748 | $table, |
||
1749 | [ |
||
1750 | 'calendar_id = ?' => [$calendarId, $courseId], |
||
1751 | ] |
||
1752 | ); |
||
1753 | } |
||
1754 | |||
1755 | /** |
||
1756 | * save repeated date inside attendance calendar table. |
||
1757 | * |
||
1758 | * @param CAttendance $attendance |
||
1759 | * @param int $start_date start date in tms |
||
1760 | * @param int $end_date end date in tms |
||
1761 | * @param string $repeat_type daily, weekly, monthlyByDate |
||
1762 | * @param array $groupList |
||
1763 | */ |
||
1764 | public function attendance_repeat_calendar_add( |
||
1765 | $attendance, |
||
1766 | $start_date, |
||
1767 | $end_date, |
||
1768 | $repeat_type, |
||
1769 | $groupList = [] |
||
1770 | ) { |
||
1771 | $attendanceId = $attendance->getIid(); |
||
1772 | // save start date |
||
1773 | $this->set_date_time(api_get_utc_datetime($start_date)); |
||
1774 | $this->attendance_calendar_add($attendance, $groupList); |
||
1775 | |||
1776 | // 86400 = 24 hours in seconds |
||
1777 | // 604800 = 1 week in seconds |
||
1778 | // Saves repeated dates |
||
1779 | switch ($repeat_type) { |
||
1780 | case 'daily': |
||
1781 | $j = 1; |
||
1782 | for ($i = $start_date + 86400; ($i <= $end_date); $i += 86400) { |
||
1783 | $this->set_date_time(api_get_utc_datetime($i)); |
||
1784 | $this->attendance_calendar_add($attendance, $groupList); |
||
1785 | $j++; |
||
1786 | } |
||
1787 | break; |
||
1788 | case 'weekly': |
||
1789 | $j = 1; |
||
1790 | for ($i = $start_date + 604800; ($i <= $end_date); $i += 604800) { |
||
1791 | $this->set_date_time(api_get_utc_datetime($i)); |
||
1792 | $this->attendance_calendar_add($attendance, $groupList); |
||
1793 | $j++; |
||
1794 | } |
||
1795 | break; |
||
1796 | case 'monthlyByDate': |
||
1797 | $j = 1; |
||
1798 | //@todo fix bug with february |
||
1799 | for ($i = $start_date + 2419200; ($i <= $end_date); $i += 2419200) { |
||
1800 | $this->set_date_time(api_get_utc_datetime($i)); |
||
1801 | $this->attendance_calendar_add($attendanceId, $groupList); |
||
1802 | $j++; |
||
1803 | } |
||
1804 | break; |
||
1805 | } |
||
1806 | } |
||
1807 | |||
1808 | /** |
||
1809 | * edit a datetime inside attendance calendar table. |
||
1810 | * |
||
1811 | * @param int $calendar_id |
||
1812 | * @param CAttendance $attendance |
||
1813 | * |
||
1814 | * @return int affected rows |
||
1815 | */ |
||
1816 | public function attendance_calendar_edit($calendar_id, $attendance) |
||
1817 | { |
||
1818 | $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1819 | $affected_rows = 0; |
||
1820 | $attendanceId = $attendance->getIid(); |
||
1821 | |||
1822 | $course_id = api_get_course_int_id(); |
||
1823 | // check if datetime already exists inside the table |
||
1824 | $sql = "SELECT iid FROM $tbl_attendance_calendar |
||
1825 | WHERE |
||
1826 | date_time = '".Database::escape_string($this->date_time)."' AND |
||
1827 | attendance_id = '$attendanceId'"; |
||
1828 | $rs = Database::query($sql); |
||
1829 | |||
1830 | if (0 == Database::num_rows($rs)) { |
||
1831 | $sql = "UPDATE $tbl_attendance_calendar |
||
1832 | SET date_time='".Database::escape_string($this->date_time)."' |
||
1833 | WHERE iid = '".$calendar_id."'"; |
||
1834 | Database::query($sql); |
||
1835 | } |
||
1836 | |||
1837 | // update locked attendance |
||
1838 | $is_all_calendar_done = self::is_all_attendance_calendar_done($attendance); |
||
1839 | if (!$is_all_calendar_done) { |
||
1840 | $this->lock($attendance, false); |
||
1841 | } else { |
||
1842 | $this->lock($attendance); |
||
1843 | } |
||
1844 | |||
1845 | return $affected_rows; |
||
1846 | } |
||
1847 | |||
1848 | /** |
||
1849 | * delete a datetime from attendance calendar table. |
||
1850 | * |
||
1851 | * @param int attendance calendar id |
||
1852 | * @param CAttendance attendance |
||
1853 | * @param bool true for removing all calendar inside current attendance, false for removing by calendar id |
||
1854 | * |
||
1855 | * @return int affected rows |
||
1856 | */ |
||
1857 | public function attendance_calendar_delete($calendar_id, CAttendance $attendance, $all_delete = false) |
||
1858 | { |
||
1859 | $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); |
||
1860 | $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET); |
||
1861 | |||
1862 | $attendanceId = $attendance->getIid(); |
||
1863 | $calendar_id = (int) $calendar_id; |
||
1864 | |||
1865 | // get all registered users inside current course |
||
1866 | $users = $this->get_users_rel_course(); |
||
1867 | $user_ids = array_keys($users); |
||
1868 | $course_id = api_get_course_int_id(); |
||
1869 | $affected_rows = 0; |
||
1870 | if ($all_delete) { |
||
1871 | $attendance_calendar = $this->get_attendance_calendar($attendanceId); |
||
1872 | // get all dates from calendar by current attendance |
||
1873 | if (!empty($attendance_calendar)) { |
||
1874 | foreach ($attendance_calendar as $cal) { |
||
1875 | // delete all data from attendance sheet |
||
1876 | $sql = "DELETE FROM $tbl_attendance_sheet |
||
1877 | WHERE attendance_calendar_id = '".intval($cal['iid'])."'"; |
||
1878 | Database::query($sql); |
||
1879 | // delete data from attendance calendar |
||
1880 | $sql = "DELETE FROM $tbl_attendance_calendar |
||
1881 | WHERE iid = '".intval($cal['iid'])."'"; |
||
1882 | Database::query($sql); |
||
1883 | |||
1884 | $this->deleteAttendanceCalendarGroup($cal['iid'], $course_id); |
||
1885 | $affected_rows++; |
||
1886 | } |
||
1887 | } |
||
1888 | } else { |
||
1889 | // delete just one row from attendance sheet by the calendar id |
||
1890 | $sql = "DELETE FROM $tbl_attendance_sheet |
||
1891 | WHERE attendance_calendar_id = '".$calendar_id."'"; |
||
1892 | Database::query($sql); |
||
1893 | // delete data from attendance calendar |
||
1894 | $sql = "DELETE FROM $tbl_attendance_calendar |
||
1895 | WHERE iid = '".$calendar_id."'"; |
||
1896 | Database::query($sql); |
||
1897 | |||
1898 | $this->deleteAttendanceCalendarGroup($calendar_id, $course_id); |
||
1899 | $affected_rows++; |
||
1900 | } |
||
1901 | |||
1902 | // update users' results |
||
1903 | $this->updateUsersResults($user_ids, $attendance); |
||
1904 | |||
1905 | return $affected_rows; |
||
1906 | } |
||
1907 | |||
1908 | public function set_session_id($sessionId) |
||
1909 | { |
||
1910 | $this->session_id = $sessionId; |
||
1911 | } |
||
1912 | |||
1913 | public function set_course_id($course_id) |
||
1914 | { |
||
1915 | $this->course_id = $course_id; |
||
1916 | } |
||
1917 | |||
1918 | public function set_date_time($datetime) |
||
1919 | { |
||
1920 | $this->date_time = $datetime; |
||
1921 | } |
||
1922 | |||
1923 | public function set_title($title) |
||
1924 | { |
||
1925 | $this->title = $title; |
||
1926 | } |
||
1927 | |||
1928 | public function set_description($description) |
||
1929 | { |
||
1930 | $this->description = $description; |
||
1931 | } |
||
1932 | |||
1933 | public function set_attendance_qualify_title($attendance_qualify_title) |
||
1934 | { |
||
1935 | $this->attendance_qualify_title = $attendance_qualify_title; |
||
1936 | } |
||
1937 | |||
1938 | public function set_attendance_weight($attendance_weight) |
||
1939 | { |
||
1940 | $this->attendance_weight = $attendance_weight; |
||
1941 | } |
||
1942 | |||
1943 | /** Getters for fields of attendances tables */ |
||
1944 | public function get_session_id() |
||
1945 | { |
||
1946 | return $this->session_id; |
||
1947 | } |
||
1948 | |||
1949 | public function get_course_id() |
||
1950 | { |
||
1951 | return $this->course_id; |
||
1952 | } |
||
1953 | |||
1954 | public function get_date_time() |
||
1955 | { |
||
1956 | return $this->date_time; |
||
1957 | } |
||
1958 | |||
1959 | public function get_title() |
||
1960 | { |
||
1961 | return $this->title; |
||
1962 | } |
||
1963 | |||
1964 | public function get_description() |
||
1965 | { |
||
1966 | return $this->description; |
||
1967 | } |
||
1968 | |||
1969 | public function get_attendance_qualify_title() |
||
1970 | { |
||
1971 | return $this->attendance_qualify_title; |
||
1972 | } |
||
1973 | |||
1974 | public function get_attendance_weight() |
||
1975 | { |
||
1976 | return $this->attendance_weight; |
||
1977 | } |
||
1978 | |||
1979 | /** |
||
1980 | * @param string $startDate in UTC time |
||
1981 | * @param string $endDate in UTC time |
||
1982 | * |
||
1983 | * @return array |
||
1984 | */ |
||
1985 | public function getAttendanceLogin($startDate, $endDate) |
||
1986 | { |
||
1987 | if (empty($startDate) || |
||
1988 | '0000-00-00' === $startDate || |
||
1989 | '0000-00-00 00:00:00' === $startDate || |
||
1990 | empty($endDate) || |
||
1991 | '0000-00-00' === $endDate || |
||
1992 | '0000-00-00 00:00:00' === $endDate |
||
1993 | ) { |
||
1994 | return false; |
||
1995 | } |
||
1996 | |||
1997 | $sessionId = api_get_session_id(); |
||
1998 | $courseCode = api_get_course_id(); |
||
1999 | $courseId = api_get_course_int_id(); |
||
2000 | |||
2001 | if (!empty($sessionId)) { |
||
2002 | $users = CourseManager::get_user_list_from_course_code( |
||
2003 | $courseCode, |
||
2004 | $sessionId, |
||
2005 | '', |
||
2006 | 'lastname', |
||
2007 | 0 |
||
2008 | ); |
||
2009 | } else { |
||
2010 | $users = CourseManager::get_user_list_from_course_code( |
||
2011 | $courseCode, |
||
2012 | 0, |
||
2013 | '', |
||
2014 | 'lastname', |
||
2015 | STUDENT |
||
2016 | ); |
||
2017 | } |
||
2018 | |||
2019 | $dateTimeStartOriginal = new DateTime($startDate); |
||
2020 | $dateTimeStart = new DateTime($startDate); |
||
2021 | $dateTimeEnd = new DateTime($endDate); |
||
2022 | $interval = $dateTimeStart->diff($dateTimeEnd); |
||
2023 | $days = (int) $interval->format('%a'); |
||
2024 | |||
2025 | $dateList = [$dateTimeStart->format('Y-m-d')]; |
||
2026 | $headers = [ |
||
2027 | get_lang('User'), |
||
2028 | $dateTimeStart->format('Y-m-d'), |
||
2029 | ]; |
||
2030 | |||
2031 | for ($i = 0; $i < $days; $i++) { |
||
2032 | $dateTimeStart = $dateTimeStart->add(new DateInterval('P1D')); |
||
2033 | $date = $dateTimeStart->format('Y-m-d'); |
||
2034 | $dateList[] = $date; |
||
2035 | $headers[] = $date; |
||
2036 | } |
||
2037 | |||
2038 | $accessData = CourseManager::getCourseAccessPerCourseAndSession( |
||
2039 | $courseId, |
||
2040 | $sessionId, |
||
2041 | $dateTimeStartOriginal->format('Y-m-d H:i:s'), |
||
2042 | $dateTimeEnd->format('Y-m-d H:i:s') |
||
2043 | ); |
||
2044 | |||
2045 | $results = []; |
||
2046 | if (!empty($accessData)) { |
||
2047 | foreach ($accessData as $data) { |
||
2048 | $onlyDate = substr($data['login_course_date'], 0, 10); |
||
2049 | $results[$data['user_id']][$onlyDate] = true; |
||
2050 | } |
||
2051 | } |
||
2052 | |||
2053 | return [ |
||
2054 | 'users' => $users, |
||
2055 | 'dateList' => $dateList, |
||
2056 | 'headers' => $headers, |
||
2057 | 'results' => $results, |
||
2058 | ]; |
||
2059 | } |
||
2060 | |||
2061 | /** |
||
2062 | * @param string $startDate in UTC time |
||
2063 | * @param string $endDate in UTC time |
||
2064 | * |
||
2065 | * @return string |
||
2066 | */ |
||
2067 | public function getAttendanceLoginTable($startDate, $endDate) |
||
2068 | { |
||
2069 | $data = $this->getAttendanceLogin($startDate, $endDate); |
||
2070 | if (!$data) { |
||
2071 | return null; |
||
2072 | } |
||
2073 | |||
2074 | $headers = $data['headers']; |
||
2075 | $dateList = $data['dateList']; |
||
2076 | $users = $data['users']; |
||
2077 | $results = $data['results']; |
||
2078 | |||
2079 | $table = new HTML_Table(['class' => 'table table-hover table-striped data_table']); |
||
2080 | $row = 0; |
||
2081 | $column = 0; |
||
2082 | foreach ($headers as $header) { |
||
2083 | $table->setHeaderContents($row, $column, $header); |
||
2084 | $column++; |
||
2085 | } |
||
2086 | $row = 1; |
||
2087 | foreach ($users as $user) { |
||
2088 | $table->setCellContents( |
||
2089 | $row, |
||
2090 | 0, |
||
2091 | $user['lastname'].' '.$user['firstname'].' ('.$user['username'].')' |
||
2092 | ); |
||
2093 | $row++; |
||
2094 | } |
||
2095 | |||
2096 | $column = 1; |
||
2097 | $row = 1; |
||
2098 | foreach ($users as $user) { |
||
2099 | foreach ($dateList as $date) { |
||
2100 | $status = null; |
||
2101 | if (isset($results[$user['user_id']]) && |
||
2102 | isset($results[$user['user_id']][$date]) |
||
2103 | ) { |
||
2104 | $status = 'X'; |
||
2105 | } |
||
2106 | $table->setCellContents($row, $column, $status); |
||
2107 | $column++; |
||
2108 | } |
||
2109 | $row++; |
||
2110 | $column = 1; |
||
2111 | } |
||
2112 | |||
2113 | return $table->toHtml(); |
||
2114 | } |
||
2115 | |||
2116 | /** |
||
2117 | * @param string $startDate in UTC time |
||
2118 | * @param string $endDate in UTC time |
||
2119 | * |
||
2120 | * @return string |
||
2121 | */ |
||
2122 | public function exportAttendanceLogin($startDate, $endDate) |
||
2123 | { |
||
2124 | $data = $this->getAttendanceLogin($startDate, $endDate); |
||
2125 | |||
2126 | if (!$data) { |
||
2127 | return null; |
||
2128 | } |
||
2129 | $users = $data['users']; |
||
2130 | $results = $data['results']; |
||
2131 | |||
2132 | $table = new HTML_Table(['class' => 'table table-hover table-striped data_table']); |
||
2133 | $table->setHeaderContents(0, 0, get_lang('User')); |
||
2134 | $table->setHeaderContents(0, 1, get_lang('Date')); |
||
2135 | |||
2136 | $row = 1; |
||
2137 | foreach ($users as $user) { |
||
2138 | $table->setCellContents( |
||
2139 | $row, |
||
2140 | 0, |
||
2141 | $user['lastname'].' '.$user['firstname'].' ('.$user['username'].')' |
||
2142 | ); |
||
2143 | $row++; |
||
2144 | } |
||
2145 | $table->setColAttributes(0, ['style' => 'width:28%']); |
||
2146 | |||
2147 | $row = 1; |
||
2148 | foreach ($users as $user) { |
||
2149 | if (isset($results[$user['user_id']]) && |
||
2150 | !empty($results[$user['user_id']]) |
||
2151 | ) { |
||
2152 | $dates = implode(', ', array_keys($results[$user['user_id']])); |
||
2153 | $table->setCellContents($row, 1, $dates); |
||
2154 | } |
||
2155 | $row++; |
||
2156 | } |
||
2157 | |||
2158 | $tableToString = $table->toHtml(); |
||
2159 | $params = [ |
||
2160 | 'filename' => get_lang('Attendance').'_'.api_get_utc_datetime(), |
||
2161 | 'pdf_title' => get_lang('Attendance'), |
||
2162 | 'course_code' => api_get_course_id(), |
||
2163 | 'show_real_course_teachers' => true, |
||
2164 | ]; |
||
2165 | $pdf = new PDF('A4', null, $params); |
||
2166 | $pdf->html_to_pdf_with_template($tableToString); |
||
2167 | } |
||
2168 | |||
2169 | /** |
||
2170 | * Return all course for a student between dates and order by key date (Y-m-d). |
||
2171 | * |
||
2172 | * @param \DateTime $startDate |
||
2173 | * @param \DateTime $endDate |
||
2174 | * @param bool $orderDesc |
||
2175 | * |
||
2176 | * @return array |
||
2177 | */ |
||
2178 | public function getCoursesWithAttendance( |
||
2179 | int $studentId, |
||
2180 | DateTime $startDate = null, |
||
2181 | DateTime $endDate = null, |
||
2182 | $orderDesc = false |
||
2183 | ) { |
||
2184 | $presentString = get_lang('Present'); |
||
2185 | $absentString = '-'; |
||
2186 | $attendanceLib = new Attendance(); |
||
2187 | $data = []; |
||
2188 | $courses = CourseManager::get_courses_list_by_user_id($studentId); |
||
2189 | /* Get course with (in_category) and without (not_category) category */ |
||
2190 | $i = 0; |
||
2191 | foreach ($courses as $courseItem) { |
||
2192 | $i++; |
||
2193 | $courseId = $courseItem['real_id']; |
||
2194 | |||
2195 | /* Get all attendance by courses*/ |
||
2196 | $attendanceList = $attendanceLib->getAttendanceList(api_get_course_entity($courseId)); |
||
2197 | $temp = []; |
||
2198 | $sheetsProcessed = []; |
||
2199 | $tempDate = []; |
||
2200 | foreach ($attendanceList as $attendanceData) { |
||
2201 | $attendanceId = $attendanceData->getIid(); |
||
2202 | $sheets = $attendanceLib->get_users_attendance_sheet( |
||
2203 | $attendanceId, |
||
2204 | $studentId, |
||
2205 | 0, |
||
2206 | $courseId, |
||
2207 | $startDate, |
||
2208 | $endDate |
||
2209 | ); |
||
2210 | |||
2211 | $sheetsProcessed[] = []; |
||
2212 | foreach ($sheets as $sheetData) { |
||
2213 | $totalb = count($sheetData); |
||
2214 | $tempDate = []; |
||
2215 | for ($ii = 0; $ii < $totalb; $ii++) { |
||
2216 | $attendancesProcess = $sheetData[$ii]; |
||
2217 | if (!empty($attendancesProcess)) { |
||
2218 | $dateTemp = $attendancesProcess['0']; |
||
2219 | $attendancesProcess[0] = $attendancesProcess[1]; |
||
2220 | $attendancesProcess[1] = $dateTemp; |
||
2221 | |||
2222 | $attendancesProcess[2] = $courseItem['title']; |
||
2223 | $attendancesProcess['courseTitle'] = $courseItem['title']; |
||
2224 | |||
2225 | $attendancesProcess[3] = $courseItem['real_id']; |
||
2226 | $attendancesProcess['courseId'] = $courseItem['real_id']; |
||
2227 | |||
2228 | $attendancesProcess[4] = $attendanceData->getTitle(); |
||
2229 | $attendancesProcess['attendanceName'] = $attendanceData->getTitle(); |
||
2230 | $attendancesProcess['courseCode'] = $courseItem['course_code']; |
||
2231 | |||
2232 | $attendancesProcess[5] = $attendanceId; |
||
2233 | $attendancesProcess['attendanceId'] = $attendanceId; |
||
2234 | if (1 == $attendancesProcess['presence']) { |
||
2235 | $attendancesProcess['presence'] = $presentString; |
||
2236 | $attendancesProcess[0] = 1; |
||
2237 | } else { |
||
2238 | $attendancesProcess['presence'] = $absentString; |
||
2239 | $attendancesProcess[0] = 0; |
||
2240 | } |
||
2241 | $attendancesProcess['session'] = 0; |
||
2242 | $attendancesProcess['sessionName'] = ''; |
||
2243 | $tempDate[] = $attendancesProcess; |
||
2244 | $dateKey = new DateTime($dateTemp); |
||
2245 | /* |
||
2246 | $attendancesProcess['teacher'] = ''; |
||
2247 | if(isset($courseItem['teachers']) and isset($courseItem['teachers'][0])){ |
||
2248 | $attendancesProcess['teacher'] = $courseItem['teachers'][0]['fullname']; |
||
2249 | } |
||
2250 | */ |
||
2251 | $data[$dateKey->format('Y-m-d')][] = $attendancesProcess; |
||
2252 | } |
||
2253 | } |
||
2254 | } |
||
2255 | $sheetsProcessed[] = $tempDate; |
||
2256 | $temp[] = $sheetsProcessed; |
||
2257 | } |
||
2258 | $courses['not_category'][$i]['attendanceSheet'] = $temp; |
||
2259 | } |
||
2260 | |||
2261 | $sql = "SELECT session_id, c_id FROM session_rel_course_rel_user |
||
2262 | WHERE user_id = $studentId"; |
||
2263 | |||
2264 | $rs = Database::query($sql); |
||
2265 | // get info from sessions |
||
2266 | while ($row = Database::fetch_assoc($rs)) { |
||
2267 | $courseId = $row['c_id']; |
||
2268 | $sessionId = $row['session_id']; |
||
2269 | $courseItem = api_get_course_info_by_id($courseId); |
||
2270 | $attendanceList = $attendanceLib->getAttendanceList( |
||
2271 | api_get_course_entity($courseId), |
||
2272 | api_get_session_entity($sessionId) |
||
2273 | ); |
||
2274 | $temp = []; |
||
2275 | $sheetsProcessed = []; |
||
2276 | $tempDate = []; |
||
2277 | foreach ($attendanceList as $attendanceData) { |
||
2278 | $attendanceId = $attendanceData->getIid(); |
||
2279 | $sheets = $attendanceLib->get_users_attendance_sheet( |
||
2280 | $attendanceId, |
||
2281 | $studentId, |
||
2282 | 0, |
||
2283 | $courseId, |
||
2284 | $startDate, |
||
2285 | $endDate |
||
2286 | ); |
||
2287 | |||
2288 | $sheetsProcessed[] = []; |
||
2289 | foreach ($sheets as $sheetData) { |
||
2290 | $totalb = count($sheetData); |
||
2291 | $tempDate = []; |
||
2292 | for ($ii = 0; $ii < $totalb; $ii++) { |
||
2293 | $work = $sheetData[$ii]; |
||
2294 | $attendancesProcess = $work; |
||
2295 | if (!empty($attendancesProcess)) { |
||
2296 | $dateTemp = $attendancesProcess['0']; |
||
2297 | $attendancesProcess[0] = $attendancesProcess[1]; |
||
2298 | $attendancesProcess[1] = $dateTemp; |
||
2299 | $attendancesProcess[2] = $courseItem['title']; |
||
2300 | $attendancesProcess['courseTitle'] = $courseItem['title']; |
||
2301 | $attendancesProcess[3] = $courseItem['real_id']; |
||
2302 | $attendancesProcess['courseId'] = $courseItem['real_id']; |
||
2303 | $attendancesProcess[4] = $attendanceData->getTitle(); |
||
2304 | $attendancesProcess['attendanceName'] = $attendanceData->getTitle(); |
||
2305 | $attendancesProcess[5] = $attendanceId; |
||
2306 | $attendancesProcess['attendanceId'] = $attendanceId; |
||
2307 | $attendancesProcess['courseCode'] = $courseItem['official_code']; |
||
2308 | if (1 == $attendancesProcess['presence']) { |
||
2309 | $attendancesProcess['presence'] = $presentString; |
||
2310 | $attendancesProcess[0] = 1; |
||
2311 | } else { |
||
2312 | $attendancesProcess['presence'] = $absentString; |
||
2313 | $attendancesProcess[0] = 0; |
||
2314 | } |
||
2315 | $attendancesProcess['session'] = $sessionId; |
||
2316 | $attendancesProcess['sessionName'] = api_get_session_name($sessionId); |
||
2317 | |||
2318 | $tempDate[] = $attendancesProcess; |
||
2319 | $dateKey = new DateTime($dateTemp); |
||
2320 | /* |
||
2321 | $attendancesProcess['teacher'] = ''; |
||
2322 | if(isset($courseItem['tutor_name']) ){ |
||
2323 | $attendancesProcess['teacher'] = $courseItem['tutor_name']; |
||
2324 | } |
||
2325 | */ |
||
2326 | $data[$dateKey->format('Y-m-d')][] = $attendancesProcess; |
||
2327 | } |
||
2328 | } |
||
2329 | } |
||
2330 | $sheetsProcessed[] = $tempDate; |
||
2331 | $temp[] = $sheetsProcessed; |
||
2332 | } |
||
2333 | $courses['session'][$i]['attendanceSheet'] = $temp; |
||
2334 | } |
||
2335 | |||
2336 | /* Order desc by date, by default */ |
||
2337 | if (true == $orderDesc) { |
||
2338 | ksort($data); |
||
2339 | } else { |
||
2340 | krsort($data); |
||
2341 | } |
||
2342 | |||
2343 | return $data; |
||
2344 | } |
||
2345 | |||
2346 | public function setAttendanceForm(FormValidator $form, CAttendance $attendance = null) |
||
2428 | } |
||
2429 | |||
2430 | public function getCalendarSheet($edit, CAttendance $attendance, $student_id) |
||
2431 | { |
||
2432 | $attendanceId = $attendance->getIid(); |
||
2433 | $content = ''; |
||
2434 | $groupId = isset($_REQUEST['group_id']) ? $_REQUEST['group_id'] : null; |
||
2435 | $filter_type = 'today'; |
||
2436 | if (!empty($_REQUEST['filter'])) { |
||
2437 | $filter_type = $_REQUEST['filter']; |
||
2438 | } |
||
2439 | |||
2440 | $users_in_course = $this->get_users_rel_course($attendanceId, $groupId); |
||
2441 | $is_locked_attendance = $this->is_locked_attendance($attendanceId); |
||
2442 | |||
2443 | $attendant_calendar_all = $this->get_attendance_calendar( |
||
2444 | $attendanceId, |
||
2445 | 'all', |
||
2446 | null, |
||
2447 | $groupId |
||
2448 | ); |
||
2449 | $attendant_calendar = $this->get_attendance_calendar( |
||
2450 | $attendanceId, |
||
2451 | $filter_type, |
||
2452 | null, |
||
2453 | $groupId |
||
2454 | ); |
||
2455 | |||
2456 | $allowToEdit = api_is_allowed_to_edit(null, true); |
||
2457 | |||
2458 | $isDrhOfCourse = api_is_drh() || CourseManager::isUserSubscribedInCourseAsDrh( |
||
2459 | api_get_user_id(), |
||
2460 | api_get_course_info() |
||
2461 | ); |
||
2462 | if ($edit) { |
||
2463 | if ($isDrhOfCourse || $allowToEdit) { |
||
2464 | $users_presence = $this->get_users_attendance_sheet( |
||
2465 | $attendanceId, |
||
2466 | 0, |
||
2467 | $groupId |
||
2468 | ); |
||
2469 | } |
||
2470 | } else { |
||
2471 | if (!empty($student_id)) { |
||
2472 | $user_id = (int) $student_id; |
||
2473 | } else { |
||
2474 | $user_id = api_get_user_id(); |
||
2475 | } |
||
2476 | |||
2477 | if ($isDrhOfCourse || |
||
2478 | $allowToEdit || |
||
2479 | api_is_coach(api_get_session_id(), api_get_course_int_id()) |
||
2480 | ) { |
||
2481 | $users_presence = $this->get_users_attendance_sheet($attendanceId, 0, $groupId); |
||
2482 | } else { |
||
2483 | $users_presence = $this->get_users_attendance_sheet($attendanceId, $user_id, $groupId); |
||
2484 | } |
||
2485 | $faults = $this->get_faults_of_user($user_id, $attendanceId, $groupId); |
||
2486 | } |
||
2487 | |||
2488 | $next_attendance_calendar_id = $this->get_next_attendance_calendar_id($attendanceId); |
||
2489 | $next_attendance_calendar_datetime = $this->getNextAttendanceCalendarDatetime($attendanceId); |
||
2490 | |||
2491 | if ($isDrhOfCourse || |
||
2492 | $allowToEdit || |
||
2493 | api_is_coach(api_get_session_id(), api_get_course_int_id()) |
||
2494 | ) { |
||
2495 | $form = new FormValidator( |
||
2496 | 'filter', |
||
2497 | 'post', |
||
2498 | 'index.php?action=attendance_sheet_list&'.api_get_cidreq().'&attendance_id='.$attendanceId, |
||
2499 | null, |
||
2500 | [], |
||
2501 | 'inline' |
||
2502 | ); |
||
2503 | |||
2504 | $values = [ |
||
2505 | 'all' => get_lang('All'), |
||
2506 | 'today' => get_lang('Today'), |
||
2507 | 'all_done' => get_lang('All done'), |
||
2508 | 'all_not_done' => get_lang('All not done'), |
||
2509 | ]; |
||
2510 | $today = api_convert_and_format_date(null, DATE_FORMAT_SHORT); |
||
2511 | $exists_attendance_today = false; |
||
2512 | |||
2513 | if (!empty($attendant_calendar_all)) { |
||
2514 | $values[''] = '---------------'; |
||
2515 | foreach ($attendant_calendar_all as $attendance_date) { |
||
2516 | $includeCalendar = true; |
||
2517 | if (isset($attendance_date['groups']) && !empty($groupId)) { |
||
2518 | foreach ($attendance_date['groups'] as $group) { |
||
2519 | if ($groupId == $group['group_id']) { |
||
2520 | $includeCalendar = true; |
||
2521 | |||
2522 | break; |
||
2523 | } else { |
||
2524 | $includeCalendar = false; |
||
2525 | } |
||
2526 | } |
||
2527 | } |
||
2528 | |||
2529 | if ($today == $attendance_date['date']) { |
||
2530 | $exists_attendance_today = true; |
||
2531 | } |
||
2532 | if ($includeCalendar) { |
||
2533 | $values[$attendance_date['iid']] = $attendance_date['date_time']; |
||
2534 | } |
||
2535 | } |
||
2536 | } |
||
2537 | |||
2538 | if (!$exists_attendance_today) { |
||
2539 | $content .= Display::return_message( |
||
2540 | get_lang( |
||
2541 | 'There is no class scheduled today, try picking another day or add your attendance entry yourself using the action icons.' |
||
2542 | ), |
||
2543 | 'warning' |
||
2544 | ); |
||
2545 | } |
||
2546 | |||
2547 | $form->addSelect( |
||
2548 | 'filter', |
||
2549 | get_lang('Filter'), |
||
2550 | $values, |
||
2551 | ['id' => 'filter_id', 'onchange' => 'submit();'] |
||
2552 | ); |
||
2553 | |||
2554 | $groupList = GroupManager::get_group_list(null, null, 1); |
||
2555 | $groupIdList = ['--']; |
||
2556 | foreach ($groupList as $group) { |
||
2557 | $groupIdList[$group['iid']] = $group['title']; |
||
2558 | } |
||
2559 | |||
2560 | if (!empty($groupList)) { |
||
2561 | $form->addSelect('group_id', get_lang('Group'), $groupIdList); |
||
2562 | } |
||
2563 | |||
2564 | $default_filter = 'today'; |
||
2565 | if (isset($_REQUEST['filter'])) { |
||
2566 | if (in_array($_REQUEST['filter'], array_keys($values))) { |
||
2567 | $default_filter = $_REQUEST['filter']; |
||
2568 | } |
||
2569 | } |
||
2570 | $renderer = $form->defaultRenderer(); |
||
2571 | $renderer->setCustomElementTemplate( |
||
2572 | '<div class="col-md-2">{label}</div><div class="col-md-10"> {element} </div>' |
||
2573 | ); |
||
2574 | |||
2575 | $form->setDefaults( |
||
2576 | [ |
||
2577 | 'filter' => $default_filter, |
||
2578 | 'group_id' => $groupId, |
||
2579 | ] |
||
2580 | ); |
||
2581 | |||
2582 | if (!$is_locked_attendance || api_is_platform_admin()) { |
||
2583 | $actionsLeft = '<a |
||
2584 | style="float:left;" |
||
2585 | href="index.php?'.api_get_cidreq().'&action=calendar_list&attendance_id='.$attendanceId.'">'. |
||
2586 | Display::getMdiIcon(ObjectIcon::AGENDA, 'ch-tool-icon', null, ICON_SIZE_MEDIUM, get_lang('Attendance calendar')). |
||
2587 | '</a>'; |
||
2588 | $actionsLeft .= '<a |
||
2589 | id="pdf_export" style="float:left;" |
||
2590 | href="index.php?'.api_get_cidreq().'&action=attendance_sheet_export_to_pdf&attendance_id='.$attendanceId.'&filter='.$default_filter.'&group_id='.$groupId.'">'. |
||
2591 | Display::getMdiIcon(ActionIcon::EXPORT_PDF, 'ch-tool-icon', null, ICON_SIZE_MEDIUM, get_lang('Export to PDF')).'</a>'; |
||
2592 | |||
2593 | $actionsRight = $form->returnForm(); |
||
2594 | $content .= Display::toolbarAction('toolbar-attendance', [$actionsLeft, $actionsRight]); |
||
2595 | } |
||
2596 | |||
2597 | $message_information = get_lang( |
||
2598 | 'The attendance sheets allow you to specify a list of dates in which you will report attendance to your courses' |
||
2599 | ); |
||
2600 | if (!empty($message_information)) { |
||
2601 | $message = '<strong>'.get_lang('Information').'</strong><br />'; |
||
2602 | $message .= $message_information; |
||
2603 | $content .= Display::return_message($message, 'normal', false); |
||
2604 | } |
||
2605 | |||
2606 | if ($is_locked_attendance) { |
||
2607 | $content .= Display::return_message(get_lang('The attendance sheet is locked.'), 'warning', false); |
||
2608 | } |
||
2609 | |||
2610 | $param_filter = '&filter='.Security::remove_XSS($default_filter).'&group_id='.$groupId; |
||
2611 | |||
2612 | if (count($users_in_course) > 0) { |
||
2613 | $form = ' |
||
2614 | <form method="post" action="index.php?action=attendance_sheet_add&'.api_get_cidreq().$param_filter.'&attendance_id='.$attendanceId.'"> |
||
2615 | <div |
||
2616 | class="attendance-sheet-content" |
||
2617 | style="width:100%;background-color:#E1E1E1;margin-top:20px;"> |
||
2618 | <div |
||
2619 | class="divTableWithFloatingHeader attendance-users-table" |
||
2620 | style="width:45%;float:left;margin:0px;padding:0px;"> |
||
2621 | <table class="tableWithFloatingHeader data_table" width="100%"> |
||
2622 | <thead> |
||
2623 | <tr class="tableFloatingHeader" |
||
2624 | style="position: absolute; top: 0px; left: 0px; visibility: hidden; margin:0px;padding:0px" > |
||
2625 | <th width="10px">#</th> |
||
2626 | <th width="10px">'.get_lang('Photo').'</th> |
||
2627 | <th width="100px">'.get_lang('Last name').'</th> |
||
2628 | <th width="100px">'.get_lang('First name').'</th> |
||
2629 | <th width="100px">'.get_lang('Not attended').'</th> |
||
2630 | </tr> |
||
2631 | <tr class="tableFloatingHeaderOriginal"> |
||
2632 | <th width="10px">#</th> |
||
2633 | <th width="10px">'.get_lang('Photo').'</th> |
||
2634 | <th width="150px">'.get_lang('Last name').'</th> |
||
2635 | <th width="140px">'.get_lang('First name').'</th> |
||
2636 | <th width="100px">'.get_lang('Not attended').'</th> |
||
2637 | </tr> |
||
2638 | </thead> |
||
2639 | <tbody>'; |
||
2640 | $i = 1; |
||
2641 | foreach ($users_in_course as $data) { |
||
2642 | $faults = 0; |
||
2643 | $class = 'row_even'; |
||
2644 | if (0 == $i % 2) { |
||
2645 | $class = 'row_odd'; |
||
2646 | } |
||
2647 | $username = api_htmlentities( |
||
2648 | sprintf(get_lang('Login: %s'), $data['username']), |
||
2649 | ENT_QUOTES |
||
2650 | ); |
||
2651 | |||
2652 | $form .= '<tr class="'.$class.'"> |
||
2653 | <td><center>'.$i.'</center></td> |
||
2654 | <td>'.$data['photo'].'</td> |
||
2655 | <td><span title="'.$username.'">'.$data['lastname'].'</span></td> |
||
2656 | <td>'.$data['firstname'].'</td> |
||
2657 | <td> |
||
2658 | <div class="attendance-faults-bar" |
||
2659 | style="background-color:'.(!empty($data['result_color_bar']) ? $data['result_color_bar'] : 'none').'"> |
||
2660 | '.$data['attendance_result'].' |
||
2661 | </div> |
||
2662 | </td> |
||
2663 | </tr>'; |
||
2664 | $i++; |
||
2665 | } |
||
2666 | $form .= '</tbody> |
||
2667 | </table> |
||
2668 | </div>'; |
||
2669 | |||
2670 | $form .= '<div |
||
2671 | class="divTableWithFloatingHeader attendance-calendar-table" |
||
2672 | style="margin:0px;padding:0px;float:left;width:55%;overflow:auto;overflow-y:hidden;">'; |
||
2673 | $form .= '<table class="tableWithFloatingHeader data_table" width="100%">'; |
||
2674 | $form .= '<thead>'; |
||
2675 | $result = null; |
||
2676 | if (count($attendant_calendar) > 0) { |
||
2677 | foreach ($attendant_calendar as $calendar) { |
||
2678 | $calendarId = $calendar['iid']; |
||
2679 | $date = $calendar['date']; |
||
2680 | $time = $calendar['time']; |
||
2681 | $datetime = '<div class="grey">'.$date.' - '.$time.'</div>'; |
||
2682 | |||
2683 | $img_lock = Display::getMdiIcon(ActionIcon::LOCK, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Unlock date')); |
||
2684 | |||
2685 | if (!empty($calendar['done_attendance'])) { |
||
2686 | $datetime = '<div class="blue">'.$date.' - '.$time.'</div>'; |
||
2687 | } |
||
2688 | $disabled_check = 'disabled = "true"'; |
||
2689 | $input_hidden = '<input |
||
2690 | type="hidden" id="hidden_input_'.$calendarId.'" name="hidden_input[]" value="" disabled />'; |
||
2691 | if ($next_attendance_calendar_id == $calendarId) { |
||
2692 | $input_hidden = '<input |
||
2693 | type="hidden" |
||
2694 | id="hidden_input_'.$calendarId.'" name="hidden_input[]" |
||
2695 | value="'.$calendarId.'" />'; |
||
2696 | $disabled_check = ''; |
||
2697 | $img_lock = Display::getMdiIcon(ActionIcon::LOCK, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Lock date')); |
||
2698 | } |
||
2699 | |||
2700 | $result .= '<th>'; |
||
2701 | $result .= '<div class="date-attendance">'.$datetime.' '; |
||
2702 | if ($allowToEdit) { |
||
2703 | $result .= '<span |
||
2704 | id="attendance_lock" |
||
2705 | style="cursor:pointer">'. |
||
2706 | (!$is_locked_attendance || api_is_platform_admin() ? $img_lock : ''). |
||
2707 | '</span>'; |
||
2708 | } |
||
2709 | |||
2710 | if (false == $is_locked_attendance) { |
||
2711 | if ($allowToEdit) { |
||
2712 | $result .= '<input |
||
2713 | type="checkbox" |
||
2714 | class="checkbox_head_'.$calendarId.'" |
||
2715 | id="checkbox_head_'.$calendarId.'" '.$disabled_check.' checked="checked" />'. |
||
2716 | $input_hidden.'</div></th>'; |
||
2717 | } |
||
2718 | } |
||
2719 | } |
||
2720 | } else { |
||
2721 | $result = '<th width="2000px"><span> |
||
2722 | <a href="index.php?'.api_get_cidreq().'&action=calendar_list&attendance_id='.$attendanceId.'">'; |
||
2723 | $result .= Display::getMdiIcon(ObjectIcon::AGENDA, 'ch-tool-icon', null, ICON_SIZE_MEDIUM, get_lang('Attendance calendar')).' '.get_lang('Go to the attendance calendar'); |
||
2724 | $result .= '</a></span></th>'; |
||
2725 | } |
||
2726 | |||
2727 | $form .= '<tr |
||
2728 | class="tableFloatingHeader row_odd" |
||
2729 | style="position: absolute; top: 0px; left: 0px; visibility: hidden; margin:0px;padding:0px">'; |
||
2730 | $form .= $result; |
||
2731 | $form .= '</tr>'; |
||
2732 | $form .= '<tr class="tableWithFloatingHeader row_odd tableFloatingHeaderOriginal">'; |
||
2733 | $form .= $result; |
||
2734 | $form .= '</tr>'; |
||
2735 | $form .= '</thead>'; |
||
2736 | $form .= '<tbody>'; |
||
2737 | $i = 0; |
||
2738 | foreach ($users_in_course as $user) { |
||
2739 | $class = 'row_odd'; |
||
2740 | if (0 == $i % 2) { |
||
2741 | $class = 'row_even'; |
||
2742 | } |
||
2743 | $form .= '<tr class="'.$class.'">'; |
||
2744 | if (count($attendant_calendar) > 0) { |
||
2745 | foreach ($attendant_calendar as $calendar) { |
||
2746 | $checked = 'checked'; |
||
2747 | $presence = -1; |
||
2748 | if (isset($users_presence[$user['user_id']][$calendar['iid']]['presence'])) { |
||
2749 | $presence = $users_presence[$user['user_id']][$calendar['iid']]['presence']; |
||
2750 | |||
2751 | $checked = ''; |
||
2752 | if (1 == (int) $presence) { |
||
2753 | $checked = 'checked'; |
||
2754 | } |
||
2755 | } else { |
||
2756 | //if the user wasn't registered at that time, consider unchecked |
||
2757 | if (0 == $next_attendance_calendar_datetime || |
||
2758 | $calendar['date_time'] < $next_attendance_calendar_datetime |
||
2759 | ) { |
||
2760 | $checked = ''; |
||
2761 | } |
||
2762 | } |
||
2763 | $disabled = 'disabled'; |
||
2764 | $style_td = ''; |
||
2765 | if ($next_attendance_calendar_id == $calendar['iid']) { |
||
2766 | if (0 == $i % 2) { |
||
2767 | $style_td = 'background-color:#eee;'; |
||
2768 | } else { |
||
2769 | $style_td = 'background-color:#dcdcdc;'; |
||
2770 | } |
||
2771 | $disabled = ''; |
||
2772 | } |
||
2773 | |||
2774 | $form .= '<td style="'.$style_td.'" class="checkboxes_col_'.$calendar['iid'].'">'; |
||
2775 | $form .= '<div class="check">'; |
||
2776 | if ($allowToEdit) { |
||
2777 | if (!$is_locked_attendance || api_is_platform_admin()) { |
||
2778 | $form .= '<input |
||
2779 | type="checkbox" |
||
2780 | name="check_presence['.$calendar['iid'].'][]" |
||
2781 | value="'.$user['user_id'].'" '.$disabled.' '.$checked.' />'; |
||
2782 | $form .= '<span class="anchor_'.$calendar['iid'].'"></span>'; |
||
2783 | } else { |
||
2784 | $form .= $presence ? Display::getMdiIcon(StateIcon::CHECKBOX_MARKED, 'ch-tool-icon', null, ICON_SIZE_TINY, get_lang('Assistance')) : Display::getMdiIcon(StateIcon::CHECKBOX_BLANK, 'ch-tool-icon', null, ICON_SIZE_TINY, get_lang('Assistance')); |
||
2785 | } |
||
2786 | } else { |
||
2787 | switch ($presence) { |
||
2788 | case 1: |
||
2789 | $form .= Display::getMdiIcon(StateIcon::CHECKBOX_BLANK, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Attended')); |
||
2790 | |||
2791 | break; |
||
2792 | case 0: |
||
2793 | $form .= Display::getMdiIcon(StateIcon::CHECKBOX_MARKED, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Not attended')); |
||
2794 | |||
2795 | break; |
||
2796 | case -1: |
||
2797 | break; |
||
2798 | } |
||
2799 | } |
||
2800 | |||
2801 | $form .= '</div>'; |
||
2802 | $form .= '</td>'; |
||
2803 | } |
||
2804 | } else { |
||
2805 | $calendarClass = null; |
||
2806 | if (isset($calendar)) { |
||
2807 | $calendarClass = 'checkboxes_col_'.$calendar['iid']; |
||
2808 | } |
||
2809 | $form .= '<td class="'.$calendarClass.'">'; |
||
2810 | $form .= '<div>'; |
||
2811 | $form .= '<center> </center> |
||
2812 | </div> |
||
2813 | </td>'; |
||
2814 | } |
||
2815 | echo '</tr>'; |
||
2816 | $i++; |
||
2817 | } |
||
2818 | $form .= '</tbody></table>'; |
||
2819 | $form .= '</div></div>'; |
||
2820 | |||
2821 | $form .= '<div class="row"> |
||
2822 | <div class="col-md-12">'; |
||
2823 | if (!$is_locked_attendance || api_is_platform_admin()) { |
||
2824 | if ($allowToEdit) { |
||
2825 | $form .= '<button type="submit" class="btn btn--primary">'.get_lang('Save').'</button>'; |
||
2826 | } |
||
2827 | } |
||
2828 | $form .= '</div> |
||
2829 | </div> |
||
2830 | </form>'; |
||
2831 | $content .= $form; |
||
2832 | } else { |
||
2833 | $content .= Display::return_message( |
||
2834 | '<a href="'.api_get_path(WEB_CODE_PATH).'user/user.php?'.api_get_cidreq().'">'. |
||
2835 | get_lang('There are no registered learners inside the course').'</a>', |
||
2836 | 'warning', |
||
2837 | false |
||
2838 | ); |
||
2839 | } |
||
2840 | } else { |
||
2841 | $content .= Display::page_header(get_lang('Report of attendance sheets')); |
||
2842 | if (!empty($users_presence)) { |
||
2843 | $content .= ' |
||
2844 | <div> |
||
2845 | <table width="250px;"> |
||
2846 | <tr> |
||
2847 | <td>'.get_lang('To attend').': </td> |
||
2848 | <td> |
||
2849 | <center> |
||
2850 | <div |
||
2851 | class="attendance-faults-bar" |
||
2852 | style="background-color:'.(!empty($faults['color_bar']) ? $faults['color_bar'] : 'none').'"> |
||
2853 | '.$faults['faults'].'/'.$faults['total'].' ('.$faults['faults_porcent'].'%) |
||
2854 | </div> |
||
2855 | </center> |
||
2856 | </td> |
||
2857 | </tr> |
||
2858 | </table> |
||
2859 | </div>'; |
||
2860 | } |
||
2861 | |||
2862 | $content .= '<table class="data_table"> |
||
2863 | <tr class="row_odd" > |
||
2864 | <th>'.get_lang('Attendance').'</th> |
||
2865 | </tr>'; |
||
2866 | |||
2867 | if (!empty($users_presence)) { |
||
2868 | $i = 0; |
||
2869 | foreach ($users_presence[$user_id] as $presence) { |
||
2870 | $class = ''; |
||
2871 | if (0 == $i % 2) { |
||
2872 | $class = 'row_even'; |
||
2873 | } else { |
||
2874 | $class = 'row_odd'; |
||
2875 | } |
||
2876 | |||
2877 | $check = $presence['presence'] ? Display::getMdiIcon(StateIcon::CHECKBOX_MARKED, 'ch-tool-icon', null, ICON_SIZE_TINY, get_lang('Assistance')) : Display::getMdiIcon(StateIcon::CHECKBOX_BLANK, 'ch-tool-icon', null, ICON_SIZE_TINY, get_lang('Assistance')); |
||
2878 | $content .= '<tr class="'.$class.'"> |
||
2879 | <td> |
||
2880 | '.$check.' '.$presence['date_time'].' |
||
2881 | </td> |
||
2882 | </tr>'; |
||
2883 | } |
||
2884 | } else { |
||
2885 | $content .= ' |
||
2886 | <tr> |
||
2887 | <td> |
||
2888 | <center>'.get_lang('You do not have attendances').'</center> |
||
2889 | </td> |
||
2890 | </tr>'; |
||
2891 | } |
||
2892 | $content .= ' </table>'; |
||
2893 | } |
||
2894 | |||
2895 | return $content; |
||
2896 | } |
||
2897 | |||
2898 | /** |
||
2899 | * It's used to print attendance sheet. |
||
2900 | * |
||
2901 | * @param int $attendance_id |
||
2902 | */ |
||
2903 | public function attendance_sheet_export_to_pdf( |
||
2904 | $attendance_id, |
||
2905 | $student_id = 0, |
||
2906 | $course_id = '' |
||
2907 | ) { |
||
2908 | $courseInfo = api_get_course_info($course_id); |
||
2909 | $this->set_course_id($courseInfo['code']); |
||
2910 | $groupId = isset($_REQUEST['group_id']) ? $_REQUEST['group_id'] : null; |
||
2911 | $data_array = []; |
||
2912 | $data_array['attendance_id'] = $attendance_id; |
||
2913 | $data_array['users_in_course'] = $this->get_users_rel_course($attendance_id, $groupId); |
||
2914 | |||
2915 | $filter_type = 'today'; |
||
2916 | |||
2917 | if (!empty($_REQUEST['filter'])) { |
||
2918 | $filter_type = $_REQUEST['filter']; |
||
2919 | } |
||
2920 | |||
2921 | $my_calendar_id = null; |
||
2922 | if (is_numeric($filter_type)) { |
||
2923 | $my_calendar_id = $filter_type; |
||
2924 | $filter_type = 'calendar_id'; |
||
2925 | } |
||
2926 | |||
2927 | $data_array['attendant_calendar'] = $this->get_attendance_calendar( |
||
2928 | $attendance_id, |
||
2929 | $filter_type, |
||
2930 | $my_calendar_id, |
||
2931 | $groupId |
||
2932 | ); |
||
2933 | |||
2934 | if (api_is_allowed_to_edit(null, true) || api_is_drh()) { |
||
2935 | $data_array['users_presence'] = $this->get_users_attendance_sheet($attendance_id, 0, $groupId); |
||
2936 | } else { |
||
2937 | if (!empty($student_id)) { |
||
2938 | $user_id = (int) $student_id; |
||
2939 | } else { |
||
2940 | $user_id = api_get_user_id(); |
||
2941 | } |
||
2942 | $data_array['users_presence'] = $this->get_users_attendance_sheet($attendance_id, $user_id, $groupId); |
||
2943 | $data_array['faults'] = $this->get_faults_of_user($user_id, $attendance_id, $groupId); |
||
2944 | $data_array['user_id'] = $user_id; |
||
2945 | } |
||
2946 | |||
2947 | $data_array['next_attendance_calendar_id'] = $this->get_next_attendance_calendar_id($attendance_id); |
||
2948 | |||
2949 | // Set headers pdf. |
||
2950 | $courseCategory = CourseManager::get_course_category($courseInfo['categoryCode']); |
||
2951 | $teacherInfo = CourseManager::get_teacher_list_from_course_code($courseInfo['code']); |
||
2952 | $teacherName = null; |
||
2953 | foreach ($teacherInfo as $teacherData) { |
||
2954 | if (null != $teacherName) { |
||
2955 | $teacherName .= ' / '; |
||
2956 | } |
||
2957 | $teacherName .= api_get_person_name($teacherData['firstname'], $teacherData['lastname']); |
||
2958 | } |
||
2959 | |||
2960 | // Get data table |
||
2961 | $data_table = []; |
||
2962 | $head_table = ['#', get_lang('Name')]; |
||
2963 | foreach ($data_array['attendant_calendar'] as $class_day) { |
||
2964 | $head_table[] = |
||
2965 | api_format_date($class_day['date_time'], DATE_FORMAT_NUMBER_NO_YEAR).' '. |
||
2966 | api_format_date($class_day['date_time'], TIME_NO_SEC_FORMAT); |
||
2967 | } |
||
2968 | $data_table[] = $head_table; |
||
2969 | $data_attendant_calendar = $data_array['attendant_calendar']; |
||
2970 | $data_users_presence = $data_array['users_presence']; |
||
2971 | $count = 1; |
||
2972 | |||
2973 | if (!empty($data_array['users_in_course'])) { |
||
2974 | foreach ($data_array['users_in_course'] as $user) { |
||
2975 | $cols = 1; |
||
2976 | $result = []; |
||
2977 | $result['count'] = $count; |
||
2978 | $result['full_name'] = api_get_person_name($user['firstname'], $user['lastname']); |
||
2979 | foreach ($data_array['attendant_calendar'] as $class_day) { |
||
2980 | if (1 == $class_day['done_attendance']) { |
||
2981 | if (1 == $data_users_presence[$user['user_id']][$class_day['iid']]['presence']) { |
||
2982 | $result[$class_day['iid']] = get_lang('P'); |
||
2983 | } else { |
||
2984 | $result[$class_day['iid']] = '<span style="color:red">'.get_lang('NP').'</span>'; |
||
2985 | } |
||
2986 | } else { |
||
2987 | $result[$class_day['iid']] = ' '; |
||
2988 | } |
||
2989 | $cols++; |
||
2990 | } |
||
2991 | $count++; |
||
2992 | $data_table[] = $result; |
||
2993 | } |
||
2994 | } |
||
2995 | $max_cols_per_page = 12; //10 dates + 2 name and number |
||
2996 | $max_dates_per_page = $max_dates_per_page_original = $max_cols_per_page - 2; //10 |
||
2997 | $rows = count($data_table); |
||
2998 | |||
2999 | if ($cols > $max_cols_per_page) { |
||
3000 | $number_tables = round(($cols - 2) / $max_dates_per_page); |
||
3001 | $headers = $data_table[0]; |
||
3002 | $all = []; |
||
3003 | $tables = []; |
||
3004 | $changed = 1; |
||
3005 | |||
3006 | for ($i = 0; $i <= $rows; $i++) { |
||
3007 | $row = isset($data_table[$i]) ? $data_table[$i] : null; |
||
3008 | $key = 1; |
||
3009 | $max_dates_per_page = 10; |
||
3010 | $item = isset($data_table[$i]) ? $data_table[$i] : null; |
||
3011 | $count_j = 0; |
||
3012 | |||
3013 | if (!empty($item)) { |
||
3014 | foreach ($item as $value) { |
||
3015 | if ($count_j >= $max_dates_per_page) { |
||
3016 | $key++; |
||
3017 | $max_dates_per_page = $max_dates_per_page_original * $key; |
||
3018 | //magic hack |
||
3019 | $tables[$key][$i][] = $tables[1][$i][0]; |
||
3020 | $tables[$key][$i][] = $tables[1][$i][1]; |
||
3021 | } |
||
3022 | $tables[$key][$i][] = $value; |
||
3023 | $count_j++; |
||
3024 | } |
||
3025 | } |
||
3026 | } |
||
3027 | |||
3028 | $content = null; |
||
3029 | if (!empty($tables)) { |
||
3030 | foreach ($tables as $sub_table) { |
||
3031 | $content .= Export::convert_array_to_html($sub_table).'<br /><br />'; |
||
3032 | } |
||
3033 | } |
||
3034 | } else { |
||
3035 | $content = Export::convert_array_to_html( |
||
3036 | $data_table, |
||
3037 | ['header_attributes' => ['align' => 'center']] |
||
3038 | ); |
||
3039 | } |
||
3040 | |||
3041 | $params = [ |
||
3042 | 'filename' => get_lang('Attendance').'-'.api_get_local_time(), |
||
3043 | 'pdf_title' => $courseInfo['title'], |
||
3044 | 'course_code' => $courseInfo['code'], |
||
3045 | 'add_signatures' => ['Drh', 'Teacher', 'Date'], |
||
3046 | 'pdf_teachers' => $teacherName, |
||
3047 | 'pdf_course_category' => $courseCategory ? $courseCategory['title'] : '', |
||
3048 | 'format' => 'A4-L', |
||
3049 | 'orientation' => 'L', |
||
3050 | ]; |
||
3051 | Export::export_html_to_pdf($content, $params); |
||
3052 | exit; |
||
3053 | } |
||
3054 | |||
3055 | /** |
||
3056 | * Gets attendance base in the table: |
||
3057 | * TABLE_STATISTIC_TRACK_E_COURSE_ACCESS. |
||
3058 | * |
||
3059 | * @param bool $showForm |
||
3060 | * @param bool $exportToPdf |
||
3061 | */ |
||
3062 | public function getAttendanceBaseInLogin($showForm = false, $exportToPdf = true) |
||
3106 | ]; |
||
3107 | } |
||
3108 | } |
||
3109 |
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
orexit
statements that have been added for debug purposes.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.