From 8a0f8fdd3b5b587102b472088c44ce8c2a9ca489 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 20 Dec 2022 14:57:52 -0500 Subject: [PATCH] Attendance - Improve date management and adding comments - refs BT#20363 --- main/attendance/attendance_calendar.php | 49 ++- main/attendance/attendance_comment.inc.php | 88 ++++++ main/attendance/attendance_controller.php | 52 +++- main/attendance/attendance_sheet.php | 19 +- main/attendance/index.php | 13 + main/inc/ajax/user_manager.ajax.php | 26 ++ main/inc/lib/attendance.lib.php | 279 ++++++++++++++++-- main/inc/lib/export.lib.inc.php | 62 ++++ main/inc/lib/extra_field.lib.php | 4 + main/install/configuration.dist.php | 6 + src/Chamilo/CoreBundle/Entity/ExtraField.php | 1 + .../CourseBundle/Entity/CAttendanceSheet.php | 31 ++ 12 files changed, 593 insertions(+), 37 deletions(-) create mode 100644 main/attendance/attendance_comment.inc.php diff --git a/main/attendance/attendance_calendar.php b/main/attendance/attendance_calendar.php index 776b0b4ab1..a9f2ad81e6 100755 --- a/main/attendance/attendance_calendar.php +++ b/main/attendance/attendance_calendar.php @@ -91,9 +91,24 @@ if (isset($action) && $action == 'calendar_add') { $a_repeat_type = [ 'daily' => get_lang('RepeatDaily'), 'weekly' => get_lang('RepeatWeekly'), + 'biweekly' => get_lang('RepeatBiweekly'), + 'xdays' => get_lang('RepeatXDays'), 'monthlyByDate' => get_lang('RepeatMonthlyByDate'), ]; - $form->addElement('select', 'repeat_type', get_lang('RepeatType'), $a_repeat_type); + + $form->addElement( + 'select', + 'repeat_type', + get_lang('RepeatType'), + $a_repeat_type, + [ + 'onchange' => "javascript: if(this.value == 'xdays'){document.getElementById('repeat-date-xdaysnumber').style.display='block';}else{document.getElementById('repeat-date-xdaysnumber').style.display='none';}", + ] + ); + + $form->addElement('html', ''); $form->addElement( 'date_picker', @@ -104,8 +119,20 @@ if (isset($action) && $action == 'calendar_add') { $defaults['end_date_time'] = date('Y-m-d'); $form->addElement('html', ''); - $defaults['repeat_type'] = 'weekly'; + $extraField = new ExtraField('attendance_calendar'); + $extraField->addElements( + $form, + 0, + [], //exclude + false, // filter + false, // tag as select + [], //show only fields + [], // order fields + [] // extra data + ); + $defaults['repeat_type'] = 'weekly'; + $defaults['xdays_number'] = '0'; $form->addSelect('groups', get_lang('Group'), $groupIdList); $form->addButtonCreate(get_lang('Save')); @@ -142,6 +169,19 @@ if (isset($action) && $action == 'calendar_add') { ['form_name' => 'attendance_calendar_edit'], 5 ); + + $extraField = new ExtraField('attendance_calendar'); + $extraField->addElements( + $form, + $calendar_id, + [], //exclude + false, // filter + false, // tag as select + [], //show only fields + [], // order fields + [] // extra data + ); + $defaults['date_time'] = $calendar['date_time']; $form->addButtonSave(get_lang('Save')); $form->addButtonCancel(get_lang('Cancel'), 'cancel'); @@ -149,6 +189,9 @@ if (isset($action) && $action == 'calendar_add') { $form->display(); echo ''; } else { + $extraValueDuration = Attendance::getAttendanceCalendarExtraFieldValue('duration', $calendar['id']); + $labelDuration = !empty($extraValueDuration) ? ' - '.get_lang('Duration').': '.$extraValueDuration : ''; + echo Display::return_icon( 'lp_calendar_event.png', get_lang('DateTime'), @@ -160,7 +203,7 @@ if (isset($action) && $action == 'calendar_add') { 0, strlen($calendar['date_time']) - 3 ). - ' '; + '  '.$labelDuration; if (isset($calendar['groups']) && !empty($calendar['groups'])) { foreach ($calendar['groups'] as $group) { diff --git a/main/attendance/attendance_comment.inc.php b/main/attendance/attendance_comment.inc.php new file mode 100644 index 0000000000..6941104926 --- /dev/null +++ b/main/attendance/attendance_comment.inc.php @@ -0,0 +1,88 @@ + + diff --git a/main/attendance/attendance_controller.php b/main/attendance/attendance_controller.php index bb54903833..67468869be 100755 --- a/main/attendance/attendance_controller.php +++ b/main/attendance/attendance_controller.php @@ -406,6 +406,7 @@ class AttendanceController $attendanceInfo = $attendance->get_attendance_by_id($attendance_id); $allowSignature = api_get_configuration_value('enable_sign_attendance_sheet'); + $allowComment = api_get_configuration_value('attendance_allow_comments'); $func = isset($_REQUEST['func']) ? $_REQUEST['func'] : null; $calendarId = isset($_REQUEST['calendar_id']) ? (int) $_REQUEST['calendar_id'] : null; $fullScreen = ($func == 'fullscreen' && $calendarId > 0 && $allowSignature); @@ -413,6 +414,7 @@ class AttendanceController $data['edit_table'] = intval($edit); $data['is_locked_attendance'] = $attendance->is_locked_attendance($attendance_id); $data['allowSignature'] = $allowSignature; + $data['allowComment'] = $allowComment; $data['fullScreen'] = $fullScreen; $data['attendanceName'] = $attendanceInfo['name']; @@ -478,7 +480,8 @@ class AttendanceController $start_datetime, $end_datetime, $repeat_type, - $groupList + $groupList, + $_POST ); $action = 'calendar_list'; } else { @@ -513,7 +516,7 @@ class AttendanceController $datetime = $_POST['date_time']; $datetimezone = api_get_utc_datetime($datetime); $attendance->set_date_time($datetimezone); - $attendance->attendance_calendar_edit($calendar_id, $attendance_id); + $attendance->attendance_calendar_edit($calendar_id, $attendance_id, $_POST); $data['calendar_id'] = 0; $action = 'calendar_list'; } else { @@ -544,6 +547,47 @@ class AttendanceController $this->view->render(); } + /** + * It checks the attendance sheet to export XLS + * + * @param $attendanceId + * @param int $studentId + * @param string $courseId + * @param null $groupId + * @param null $filter + */ + public function attendanceSheetExportToXls( + $attendanceId, + $studentId = 0, + $courseId = '', + $groupId = null, + $filter = null + ) { + $attendance = new Attendance(); + $courseInfo = api_get_course_info($courseId); + $attendance->set_course_id($courseInfo['code']); + + $filterType = 'today'; + if (!empty($filter)) { + $filterType = $filter; + } + + $myCalendarId = null; + if (is_numeric($filterType)) { + $myCalendarId = $filterType; + $filterType = 'calendar_id'; + } + + $attendance->exportAttendanceSheetToXls( + $attendanceId, + $studentId, + $courseId, + $groupId, + $filterType, + $myCalendarId + ); + } + /** * It's used to print attendance sheet. * @@ -613,9 +657,11 @@ class AttendanceController $data_table = []; $head_table = ['#', get_lang('Name')]; foreach ($data_array['attendant_calendar'] as $class_day) { + $labelDuration = !empty($class_day['duration']) ? get_lang('Duration').' : '.$class_day['duration'] : ''; $head_table[] = api_format_date($class_day['date_time'], DATE_FORMAT_NUMBER_NO_YEAR).' '. - api_format_date($class_day['date_time'], TIME_NO_SEC_FORMAT); + api_format_date($class_day['date_time'], TIME_NO_SEC_FORMAT).' '. + $labelDuration; } $data_table[] = $head_table; $data_attendant_calendar = $data_array['attendant_calendar']; diff --git a/main/attendance/attendance_sheet.php b/main/attendance/attendance_sheet.php index 130739a54a..16b86dea69 100755 --- a/main/attendance/attendance_sheet.php +++ b/main/attendance/attendance_sheet.php @@ -114,6 +114,8 @@ if (api_is_allowed_to_edit(null, true) || Display::return_icon('attendance_calendar.png', get_lang('AttendanceCalendar'), '', ICON_SIZE_MEDIUM).''; $actionsLeft .= ''. Display::return_icon('pdf.png', get_lang('ExportToPDF'), '', ICON_SIZE_MEDIUM).''; + $actionsLeft .= ''. + Display::return_icon('export_excel.png', get_lang('ExportToXLS'), '', ICON_SIZE_MEDIUM).''; $actionsLeft .= ''. Display::return_icon('paint.png', get_lang('DownloadQr'), '', ICON_SIZE_MEDIUM).''; $actionsRight = $form->returnForm(); @@ -270,7 +272,8 @@ if (api_is_allowed_to_edit(null, true) || foreach ($attendant_calendar as $calendar) { $date = $calendar['date']; $time = $calendar['time']; - $datetime = '
'.$date.' - '.$time.'
'; + $duration = !empty($calendar['duration']) ? get_lang('Duration').' : '.$calendar['duration'] : ''; + $datetime = '
'.$date.' - '.$time.' '.$duration.'
'; $img_lock = Display::return_icon( 'lock-closed.png', @@ -394,12 +397,20 @@ if (api_is_allowed_to_edit(null, true) || echo ''; echo '
'; + $commentBtnIcon = ''; + if ($allowComment) { + $commentBtnIcon = '   + + '; + } + if (api_is_allowed_to_edit(null, true)) { if (!$is_locked_attendance || api_is_platform_admin()) { if ($allowSignature) { if ($signed) { echo Display::return_icon('checkbox_on.png', get_lang('Presence'), null, ICON_SIZE_TINY); echo ''; + echo $commentBtnIcon; echo '
@@ -409,6 +420,7 @@ if (api_is_allowed_to_edit(null, true) || } else { echo ''; echo ''; + echo $commentBtnIcon; echo '
@@ -419,6 +431,7 @@ if (api_is_allowed_to_edit(null, true) || } else { echo ''; echo ''; + echo $commentBtnIcon; } } else { echo $presence ? Display::return_icon('checkbox_on.png', get_lang('Presence'), null, ICON_SIZE_TINY) : Display::return_icon('checkbox_off.png', get_lang('Presence'), null, ICON_SIZE_TINY); @@ -564,4 +577,6 @@ if (api_is_allowed_to_edit(null, true) || if ($allowSignature) { include_once 'attendance_signature.inc.php'; } -?> +if ($allowComment) { + include_once 'attendance_comment.inc.php'; +} diff --git a/main/attendance/index.php b/main/attendance/index.php index 9018d978fb..a0be765a34 100755 --- a/main/attendance/index.php +++ b/main/attendance/index.php @@ -37,6 +37,7 @@ $actions = [ 'attendance_set_visible_select', 'attendance_restore', 'attendance_sheet_export_to_pdf', + 'attendance_sheet_export_to_xls', 'attendance_sheet_list_no_edit', 'calendar_logins', 'lock_attendance', @@ -349,6 +350,18 @@ switch ($action) { $student_id, $course_id ); + break; + case 'attendance_sheet_export_to_xls': + $groupId = isset($_REQUEST['group_id']) ? $_REQUEST['group_id'] : null; + $filter = isset($_REQUEST['filter']) ? $_REQUEST['filter'] : null; + $attendanceController->attendanceSheetExportToXls( + $attendance_id, + $student_id, + $course_id, + $groupId, + $filter + ); + break; case 'attendance_sheet_add': if ($allowToEdit) { diff --git a/main/inc/ajax/user_manager.ajax.php b/main/inc/ajax/user_manager.ajax.php index b14d362f60..a9613d25b5 100755 --- a/main/inc/ajax/user_manager.ajax.php +++ b/main/inc/ajax/user_manager.ajax.php @@ -17,6 +17,32 @@ $isRequestByAjax = $request->isXmlHttpRequest(); $action = $_REQUEST['a']; switch ($action) { + case 'comment_attendance': + $selected = $_REQUEST['selected']; + $comment = $_REQUEST['comment']; + $attendanceId = $_REQUEST['attendance_id']; + if (!empty($selected)) { + list($prefix, $userId, $attendanceCalendarId) = explode('-', $selected); + $attendance = new Attendance(); + $attendance->saveComment($userId, + $attendanceCalendarId, + $comment, + $attendanceId + ); + echo 1; + exit; + } + echo 0; + break; + case 'get_attendance_comment': + $selected = $_REQUEST['selected']; + if (!empty($selected)) { + list($prefix, $userId, $attendanceCalendarId) = explode('-', $selected); + $attendance = new Attendance(); + $comment = $attendance->getComment($userId, $attendanceCalendarId); + echo $comment; + } + break; case 'block_attendance_calendar': $calendarId = (int) $_REQUEST['calendar_id']; $attendance = new Attendance(); diff --git a/main/inc/lib/attendance.lib.php b/main/inc/lib/attendance.lib.php index f3248030cf..b516eac20c 100755 --- a/main/inc/lib/attendance.lib.php +++ b/main/inc/lib/attendance.lib.php @@ -1567,6 +1567,7 @@ class Attendance $row['date'] = api_format_date($row['date_time'], DATE_FORMAT_SHORT); $row['time'] = api_format_date($row['date_time'], TIME_NO_SEC_FORMAT); $row['groups'] = $this->getGroupListByAttendanceCalendar($row['id'], $course_id); + $row['duration'] = Attendance::getAttendanceCalendarExtraFieldValue('duration', $row['id']); if ($type == 'today') { if (date('d-m-Y', api_strtotime($row['date_time'], 'UTC')) == date('d-m-Y', time())) { $data[] = $row; @@ -1746,10 +1747,11 @@ class Attendance * * @param int $attendanceId * @param array $groupList + * @param array $extraValues * * @return int affected rows */ - public function attendance_calendar_add($attendanceId, $groupList = []) + public function attendance_calendar_add($attendanceId, $groupList = [], $extraValues = []) { $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); $affected_rows = 0; @@ -1775,6 +1777,13 @@ class Attendance $sql = "UPDATE $tbl_attendance_calendar SET id = iid WHERE iid = $id"; Database::query($sql); $affected_rows++; + + if (!empty($extraValues)) { + // It saves extra fields values + $extraFieldValue = new ExtraFieldValue('attendance_calendar'); + $extraValues['item_id'] = $id; + $extraFieldValue->saveFieldValues($extraValues); + } } $this->addAttendanceCalendarToGroup($id, $course_id, $groupList); //} @@ -1892,7 +1901,7 @@ class Attendance * @param int $attendanceId * @param int $start_date start date in tms * @param int $end_date end date in tms - * @param string $repeat_type daily, weekly, monthlyByDate + * @param string $repeat_type daily, weekly, biweekly, xdays, monthlyByDate * @param array $groupList */ public function attendance_repeat_calendar_add( @@ -1900,58 +1909,80 @@ class Attendance $start_date, $end_date, $repeat_type, - $groupList = [] + $groupList = [], + $extraValues = [] ) { $attendanceId = intval($attendanceId); // save start date $datetimezone = api_get_utc_datetime($start_date); $this->set_date_time($datetimezone); - $this->attendance_calendar_add($attendanceId, $groupList); + $this->attendance_calendar_add($attendanceId, $groupList, $extraValues); // 86400 = 24 hours in seconds // 604800 = 1 week in seconds + // 1296000 = 1 biweek in seconds + // 2419200 = 1 month in seconds + // 86400 x xdays = interval by x days (in seconds) // Saves repeated dates + $seconds = 0; switch ($repeat_type) { case 'daily': - $j = 1; - for ($i = $start_date + 86400; ($i <= $end_date); $i += 86400) { - $datetimezone = api_get_utc_datetime($i); - $this->set_date_time($datetimezone); - $this->attendance_calendar_add($attendanceId, $groupList); - $j++; - } + $seconds = 86400; break; case 'weekly': - $j = 1; - for ($i = $start_date + 604800; ($i <= $end_date); $i += 604800) { - $datetimezone = api_get_utc_datetime($i); - $this->set_date_time($datetimezone); - $this->attendance_calendar_add($attendanceId, $groupList); - $j++; - } + $seconds = 604800; + break; + case 'biweekly': + $seconds = 1296000; break; case 'monthlyByDate': - $j = 1; - //@todo fix bug with february - for ($i = $start_date + 2419200; ($i <= $end_date); $i += 2419200) { - $datetimezone = api_get_utc_datetime($i); - $this->set_date_time($datetimezone); - $this->attendance_calendar_add($attendanceId, $groupList); - $j++; - } + $seconds = 2419200; break; + case 'xdays': + $seconds = isset($extraValues['xdays_number']) ? (int) $extraValues['xdays_number'] * 86400 : 0; + break; + } + + if ($seconds > 0) { + $j = 1; + for ($i = $start_date + $seconds; ($i <= $end_date); $i += $seconds) { + $datetimezone = api_get_utc_datetime($i); + $this->set_date_time($datetimezone); + $this->attendance_calendar_add($attendanceId, $groupList, $extraValues); + $j++; + } + } + } + + /** + * Gets the value of a attendance calendar extra field. Returns null if it was not found. + * + * @param string $variable Name of the extra field + * @param string $calendarId Calendar id + * + * @return string Value + */ + public static function getAttendanceCalendarExtraFieldValue($variable, $calendarId) + { + $extraFieldValues = new ExtraFieldValue('attendance_calendar'); + $result = $extraFieldValues->get_values_by_handler_and_field_variable($calendarId, $variable); + if (!empty($result['value'])) { + return $result['value']; } + + return null; } /** * edit a datetime inside attendance calendar table. * - * @param int attendance calendar id - * @param int attendance id + * @param int attendance calendar id + * @param int attendance id + * @param array extra values * * @return int affected rows */ - public function attendance_calendar_edit($calendar_id, $attendanceId) + public function attendance_calendar_edit($calendar_id, $attendanceId, $extraValues = []) { $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); $affected_rows = 0; @@ -1972,6 +2003,11 @@ class Attendance Database::query($sql); } + // It saves extra fields values + $extraFieldValue = new ExtraFieldValue('attendance_calendar'); + $extraValues['item_id'] = $calendar_id; + $extraFieldValue->saveFieldValues($extraValues); + // update locked attendance $is_all_calendar_done = self::is_all_attendance_calendar_done($attendanceId); if (!$is_all_calendar_done) { @@ -2635,6 +2671,191 @@ class Attendance return $signature; } + /** + * It exports the attendance sheet to Xls format. + * + * @param $attendanceId + * @param $studentId + * @param $courseId + * @param $groupId + * @param $filterType + * @param $myCalendarId + */ + public function exportAttendanceSheetToXls( + $attendanceId, + $studentId, + $courseId, + $groupId, + $filterType, + $myCalendarId + ) { + $users = $this->get_users_rel_course($attendanceId, $groupId); + $calendar = $this->get_attendance_calendar( + $attendanceId, + $filterType, + $myCalendarId, + $groupId + ); + + if (!empty($studentId)) { + $userId = (int) $studentId; + } else { + $userId = api_get_user_id(); + } + $courseInfo = api_get_course_info($courseId); + + $userPresence = []; + $faults = []; + if (api_is_allowed_to_edit(null, true) || api_is_drh()) { + $userPresence = $this->get_users_attendance_sheet($attendanceId, 0, $groupId); + } else { + $userPresence = $this->get_users_attendance_sheet($attendanceId, $userId, $groupId); + $faults = $this->get_faults_of_user($userId, $attendanceId, $groupId); + } + + // Set headers pdf. + $teacherInfo = CourseManager::get_teacher_list_from_course_code($courseInfo['code']); + $teacherName = null; + foreach ($teacherInfo as $teacherData) { + if ($teacherName != null) { + $teacherName = $teacherName." / "; + } + $teacherName .= api_get_person_name($teacherData['firstname'], $teacherData['lastname']); + } + + // Get data table + $dataTable = []; + $headTable = ['#', get_lang('Name')]; + foreach ($calendar as $classDay) { + $labelDuration = !empty($classDay['duration']) ? get_lang('Duration').' : '.$classDay['duration'] : ''; + $headTable[] = + api_format_date($classDay['date_time'], DATE_FORMAT_NUMBER_NO_YEAR).' '. + api_format_date($classDay['date_time'], TIME_NO_SEC_FORMAT).' '. + $labelDuration; + } + $dataTable[] = $headTable; + $dataUsersPresence = $userPresence; + $count = 1; + + if (!empty($users)) { + foreach ($users as $user) { + $cols = 1; + $result = []; + $result['count'] = $count; + $result['full_name'] = api_get_person_name($user['firstname'], $user['lastname']); + foreach ($calendar as $classDay) { + $comment = $this->getComment($user['user_id'], $classDay['id']); + $txtComment = !empty($comment) ? '[comment]'.$comment : ''; + if (1 == (int) $classDay['done_attendance']) { + if (1 == (int) $dataUsersPresence[$user['user_id']][$classDay['id']]['presence']) { + $result[$classDay['id']] = get_lang('UserAttendedSymbol').$txtComment; + } else { + $result[$classDay['id']] = get_lang('UserNotAttendedSymbol').$txtComment; + } + } else { + $result[$classDay['id']] = ' '; + } + $cols++; + } + $count++; + $dataTable[] = $result; + } + } + + $filename = get_lang('Attendance').'-'.api_get_local_time(); + Export::arrayToXlsAndComments($dataTable, $filename); + + exit; + } + + /** + * Get the user comment in attendance sheet. + * + * @param $userId + * @param $attendanceCalendarId + * + * @return false|string + */ + public function getComment( + $userId, + $attendanceCalendarId + ) { + $allowComment = api_get_configuration_value('attendance_allow_comments'); + if (!$allowComment) { + return false; + } + + $courseId = api_get_course_int_id(); + $em = Database::getManager(); + $repo = $em->getRepository('ChamiloCourseBundle:CAttendanceSheet'); + + $criteria = [ + 'userId' => $userId, + 'attendanceCalendarId' => $attendanceCalendarId, + 'cId' => $courseId, + ]; + $attendanceSheet = $repo->findOneBy($criteria); + + $comment = ""; + if ($attendanceSheet) { + /** @var CAttendanceSheet $attendanceSheet */ + $comment = $attendanceSheet->getComment(); + } + + return $comment; + } + + /** + * It saves the user comment from attendance sheet. + * + * @param $userId + * @param $attendanceCalendarId + * @param $comment string + * + * @return false or void when it is saved. + */ + public function saveComment( + $userId, + $attendanceCalendarId, + $comment, + $attendanceId + ) { + $allowComment = api_get_configuration_value('attendance_allow_comments'); + if (!$allowComment) { + return false; + } + + $courseId = api_get_course_int_id(); + $em = Database::getManager(); + $criteria = [ + 'userId' => $userId, + 'attendanceCalendarId' => $attendanceCalendarId, + 'cId' => $courseId, + ]; + + $repo = $em->getRepository('ChamiloCourseBundle:CAttendanceSheet'); + $attendanceSheet = $repo->findOneBy($criteria); + + /** @var CAttendanceSheet $attendanceSheet */ + if ($attendanceSheet) { + $attendanceSheet->setComment($comment); + $em->persist($attendanceSheet); + $em->flush(); + } else { + $attendanceSheet = new CAttendanceSheet(); + $attendanceSheet + ->setCId($courseId) + ->setPresence(0) + ->setUserId($userId) + ->setAttendanceCalendarId($attendanceCalendarId) + ->setComment($comment); + + $em->persist($attendanceSheet); + $em->flush(); + } + $this->updateUsersResults([$userId], $attendanceId); + } + /** * It saves the user sign from attendance sheet. * diff --git a/main/inc/lib/export.lib.inc.php b/main/inc/lib/export.lib.inc.php index a775cfb796..8ebdb48640 100755 --- a/main/inc/lib/export.lib.inc.php +++ b/main/inc/lib/export.lib.inc.php @@ -90,6 +90,68 @@ class Export exit; } + /** + * Export tabular data to XLS-file included comments. + * + * @param array $data The comment by cell should be added with the prefix [comment] to be added ($txtCellValue.'[comment]'.$txtComment) + * @param string $filename + */ + public static function arrayToXlsAndComments($data, $filename = 'export', $encoding = 'utf-8') + { + $filePath = api_get_path(SYS_ARCHIVE_PATH).uniqid('').'.xlsx'; + $file = new \SplFileObject($filePath, 'w'); + + $excel = @new PHPExcel(); + + $type = 'Excel2007'; + $sheet = null; + $row = 1; + $prependHeaderRow = false; + if (null !== $sheet && !$excel->sheetNameExists($sheet)) { + $excel->removeSheetByIndex(0); + } + + if (null !== $sheet) { + if (!$excel->sheetNameExists($sheet)) { + $excel->createSheet()->setTitle($sheet); + } + $excel->setActiveSheetIndexByName($sheet); + } + + foreach ($data as $item) { + $count = count($item); + if ($prependHeaderRow && 1 == $row) { + $headers = array_keys($item); + + for ($i = 0; $i < $count; $i++) { + @$excel->getActiveSheet()->setCellValueByColumnAndRow($i, $row, $headers[$i]); + } + $row++; + } + $values = array_values($item); + for ($i = 0; $i < $count; $i++) { + $txtComment = ''; + $txtValue = $values[$i]; + if (false !== strpos($values[$i], '[comment]')) { + list($txtValue, $txtComment) = explode('[comment]', $values[$i]); + } + @$excel->getActiveSheet()->setCellValueByColumnAndRow($i, $row, $txtValue); + if (!empty($txtComment)) { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($i); + $coordinate = $columnLetter.$row; + @$excel->getActiveSheet()->getComment($coordinate)->getText()->createTextRun($txtComment); + } + } + $row++; + } + + $writer = \PHPExcel_IOFactory::createWriter($excel, $type); + $writer->save($file->getPathname()); + DocumentManager::file_send_for_download($filePath, true, $filename.'.xlsx'); + + exit; + } + /** * Export tabular data to XLS-file (as html table). * diff --git a/main/inc/lib/extra_field.lib.php b/main/inc/lib/extra_field.lib.php index 46facd3b8d..39d59d571a 100755 --- a/main/inc/lib/extra_field.lib.php +++ b/main/inc/lib/extra_field.lib.php @@ -174,6 +174,9 @@ class ExtraField extends Model case 'document': $this->extraFieldType = EntityExtraField::DOCUMENT_TYPE; break; + case 'attendance_calendar': + $this->extraFieldType = EntityExtraField::ATTENDANCE_CALENDAR_TYPE; + break; } $this->pageUrl = 'extra_fields.php?type='.$this->type; @@ -208,6 +211,7 @@ class ExtraField extends Model 'course_announcement', 'message', 'document', + 'attendance_calendar', ]; if (api_get_configuration_value('allow_scheduled_announcements')) { diff --git a/main/install/configuration.dist.php b/main/install/configuration.dist.php index 0a7977c3e8..9249530545 100755 --- a/main/install/configuration.dist.php +++ b/main/install/configuration.dist.php @@ -2321,6 +2321,12 @@ INSERT INTO `extra_field` (`extra_field_type`, `field_type`, `variable`, `displa // Create a document extra field with field label "can_be_downloaded" of type "Checkbox options". // $_configuration['documents_hide_download_icon'] = false; +// Enable comments in attendance sheet for users +// Require DB changes: +// ALTER TABLE c_attendance_sheet ADD comment longtext NULL; +// Requires edit Entity CAttendanceSheet : src/Chamilo/CourseBundle/Entity/CAttendanceSheet.php uncomment "comment" variable. +//$_configuration['attendance_allow_comments'] = false; + // KEEP THIS AT THE END // -------- Custom DB changes // Add user activation by confirmation email diff --git a/src/Chamilo/CoreBundle/Entity/ExtraField.php b/src/Chamilo/CoreBundle/Entity/ExtraField.php index 4063440f7a..2305fcc6ac 100644 --- a/src/Chamilo/CoreBundle/Entity/ExtraField.php +++ b/src/Chamilo/CoreBundle/Entity/ExtraField.php @@ -42,6 +42,7 @@ class ExtraField extends BaseAttribute public const COURSE_ANNOUNCEMENT = 21; public const MESSAGE_TYPE = 22; public const DOCUMENT_TYPE = 23; + public const ATTENDANCE_CALENDAR_TYPE = 24; /** * @var int diff --git a/src/Chamilo/CourseBundle/Entity/CAttendanceSheet.php b/src/Chamilo/CourseBundle/Entity/CAttendanceSheet.php index 1035ac2305..1306d6bb94 100644 --- a/src/Chamilo/CourseBundle/Entity/CAttendanceSheet.php +++ b/src/Chamilo/CourseBundle/Entity/CAttendanceSheet.php @@ -64,6 +64,13 @@ class CAttendanceSheet */ //protected $signature; + /** + * @var string + * + * @ORM\Column(name="comment", type="text", nullable=true) + */ + //protected $comment; + /** * Set presence. * @@ -189,4 +196,28 @@ class CAttendanceSheet { return $this->signature; } + + /** + * Set comment. + * + * @param string $comment + * + * @return CAttendanceSheet + */ + public function setComment($comment) + { + $this->comment = $comment; + + return $this; + } + + /** + * Get comment. + * + * @return string + */ + public function getComment() + { + return $this->comment; + } }