Refactor attendance code

pull/3124/head
Julio Montoya 5 years ago
parent 96b7ea0677
commit 43f231ebdf
  1. 75
      public/main/attendance/attendance_add.php
  2. 187
      public/main/attendance/attendance_calendar.php
  3. 730
      public/main/attendance/attendance_controller.php
  4. 110
      public/main/attendance/attendance_edit.php
  5. 55
      public/main/attendance/attendance_list.php
  6. 472
      public/main/attendance/attendance_sheet.php
  7. 11
      public/main/attendance/calendar_logins.php
  8. 685
      public/main/attendance/index.php
  9. 28
      public/main/attendance/layout.php
  10. 5
      public/main/course_progress/index.php
  11. 15
      public/main/gradebook/lib/GradebookUtils.php
  12. 1201
      public/main/inc/lib/attendance.lib.php
  13. 3
      src/CourseBundle/Entity/CAttendance.php
  14. 78
      src/ThemeBundle/Resources/views/Attendance/sheet.html.twig

@ -1,75 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* View (MVC patter) for adding a attendance.
*
* @author Christian Fasanando <christian1827@gmail.com>
*/
// protect a course script
api_protect_course_script(true);
// error messages
if (isset($error)) {
echo Display::return_message(get_lang('The form contains incorrect or incomplete data. Please check your input.'), 'error', false);
}
if (!isset($error)) {
$token = Security::get_token();
}
// display form
$form = new FormValidator(
'attendance_add',
'POST',
'index.php?action=attendance_add&'.api_get_cidreq()
);
$form->addElement('header', '', get_lang('Create a new attendance list'));
$form->addElement('hidden', 'sec_token', $token);
$form->addText('title', get_lang('Title'), true);
$form->applyFilter('title', 'html_filter');
$form->addHtmlEditor(
'description',
get_lang('Description'),
false,
false,
['ToolbarSet' => 'Basic', 'Width' => '100%', 'Height' => '150']
);
// Advanced Parameters
if ((0 != api_get_session_id() && Gradebook::is_active()) || 0 == api_get_session_id()) {
$form->addButtonAdvancedSettings('id_qualify');
$form->addElement('html', '<div id="id_qualify_options" style="display:none">');
// Qualify Attendance for gradebook option
$form->addElement(
'checkbox',
'attendance_qualify_gradebook',
'',
get_lang('Grade the attendance list in the assessment tool'),
'onclick="javascript: if(this.checked){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
);
$form->addElement('html', '<div id="options_field" style="display:none">');
GradebookUtils::load_gradebook_select_in_tool($form);
$form->addElement('text', 'attendance_qualify_title', get_lang('Column header in Competences Report'));
$form->applyFilter('attendance_qualify_title', 'html_filter');
$form->addElement(
'text',
'attendance_weight',
get_lang('Weight in Report'),
'value="0.00" Style="width:40px" onfocus="javascript: this.select();"'
);
$form->applyFilter('attendance_weight', 'html_filter');
$form->addElement('html', '</div>');
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_ATTENDANCE, 0);
$form->addElement('html', '</div>');
}
$form->addButtonCreate(get_lang('Save'));
$form->display();

@ -1,187 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* View (MVC patter) for attendance calendar (list, edit, add).
*
* @author Christian Fasanando <christian1827@gmail.com>
*/
// protect a course script
api_protect_course_script(true);
if (!$is_locked_attendance || api_is_platform_admin()) {
echo '<div class="actions">';
if ('calendar_add' == $action) {
echo '<a href="index.php?'.api_get_cidreq().'&action=calendar_list&attendance_id='.$attendance_id.'">'.
Display::return_icon('back.png', get_lang('Attendance calendar'), '', ICON_SIZE_MEDIUM).'</a>';
} else {
echo '<a href="index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendance_id.'">'.
Display::return_icon('back.png', get_lang('Attendance sheet'), '', ICON_SIZE_MEDIUM).'</a>';
if (api_is_allowed_to_edit()) {
echo '<a href="index.php?'.api_get_cidreq().'&action=calendar_add&attendance_id='.$attendance_id.'">'.
Display::return_icon('add.png', get_lang('Add a date and time'), '', ICON_SIZE_MEDIUM).'</a>';
echo '<a onclick="javascript:if(!confirm(\''.get_lang('Are you sure you want to delete all dates?').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=calendar_all_delete&attendance_id='.$attendance_id.'">'.
Display::return_icon('clean.png', get_lang('Clean the calendar of all lists'), '', ICON_SIZE_MEDIUM).'</a>';
}
}
echo '</div>';
}
$message_information = get_lang('Attendance calendarDescription');
if (!empty($message_information)) {
$message = '<strong>'.get_lang('Information').'</strong><br />';
$message .= $message_information;
echo Display::return_message($message, 'normal', false);
}
if (isset($error_repeat_date) && $error_repeat_date) {
$message = get_lang('End date must be more than the start date');
echo Display::return_message($message, 'error', false);
}
if (isset($error_checkdate) && $error_checkdate) {
$message = get_lang('Invalid date');
echo Display::return_message($message, 'error', false);
}
if (isset($action) && 'calendar_add' == $action) {
$groupList = GroupManager::get_group_list(null, null, 1);
$groupIdList = ['--'];
foreach ($groupList as $group) {
$groupIdList[$group['id']] = $group['name'];
}
// calendar add form
$form = new FormValidator(
'attendance_calendar_add',
'POST',
'index.php?action=calendar_add&attendance_id='.$attendance_id.'&'.api_get_cidreq(),
''
);
$form->addElement('header', get_lang('Add a date time'));
$form->addDateTimePicker(
'date_time',
[get_lang('Start Date')],
['id' => 'date_time']
);
$defaults['date_time'] = date('Y-m-d H:i', api_strtotime(api_get_local_time()));
$form->addElement(
'checkbox',
'repeat',
null,
get_lang('Repeat date'),
[
'onclick' => "javascript: if(this.checked){document.getElementById('repeat-date-attendance').style.display='block';}else{document.getElementById('repeat-date-attendance').style.display='none';}",
]
);
$defaults['repeat'] = isset($repeat) ? $repeat : null;
if ($defaults['repeat']) {
$form->addElement('html', '<div id="repeat-date-attendance" style="display:block">');
} else {
$form->addElement('html', '<div id="repeat-date-attendance" style="display:none">');
}
$a_repeat_type = [
'daily' => get_lang('Daily'),
'weekly' => get_lang('Weekly'),
'monthlyByDate' => get_lang('Monthly, by date'),
];
$form->addElement('select', 'repeat_type', get_lang('Repeat type'), $a_repeat_type);
$form->addElement(
'date_picker',
'end_date_time',
get_lang('Repeat end date'),
['form_name' => 'attendance_calendar_add']
);
$defaults['end_date_time'] = date('Y-m-d');
$form->addElement('html', '</div>');
$defaults['repeat_type'] = 'weekly';
$form->addSelect('groups', get_lang('Group'), $groupIdList);
$form->addButtonCreate(get_lang('Save'));
$form->setDefaults($defaults);
$form->display();
} else {
// Calendar list
$groupList = GroupManager::get_group_list();
$groupIdList = ['--'];
foreach ($groupList as $group) {
$groupIdList[$group['id']] = $group['name'];
}
echo Display::page_subheader(get_lang('Calendar list of attendances'));
echo '<ul class="list-group">';
if (!empty($attendance_calendar)) {
foreach ($attendance_calendar as $calendar) {
echo '<li class="list-group-item">';
if ((isset($action) && 'calendar_edit' === $action) &&
(isset($calendar_id) && $calendar_id == $calendar['id'])
) {
// calendar edit form
echo '<div class="attendance-calendar-edit">';
$form = new FormValidator(
'attendance_calendar_edit',
'POST',
'index.php?action=calendar_edit&attendance_id='.$attendance_id.'&calendar_id='.$calendar_id.'&'.api_get_cidreq(),
''
);
$form->addDateTimePicker(
'date_time',
[get_lang('Date')],
['form_name' => 'attendance_calendar_edit'],
5
);
$defaults['date_time'] = $calendar['date_time'];
$form->addButtonSave(get_lang('Save'));
$form->addButtonCancel(get_lang('Cancel'), 'cancel');
$form->setDefaults($defaults);
$form->display();
echo '</div>';
} else {
echo Display::return_icon(
'lp_calendar_event.png',
get_lang('Date DateTime time'),
null,
ICON_SIZE_MEDIUM
).' '.
substr(
$calendar['date_time'],
0,
strlen($calendar['date_time']) - 3
).
'&nbsp;';
if (isset($calendar['groups']) && !empty($calendar['groups'])) {
foreach ($calendar['groups'] as $group) {
echo '&nbsp;'.Display::label($groupIdList[$group['group_id']]);
}
}
if (!$is_locked_attendance || api_is_platform_admin()) {
if (api_is_allowed_to_edit()) {
echo '<div class="pull-right">';
echo '<a href="index.php?'.api_get_cidreq().'&action=calendar_edit&calendar_id='.(int) ($calendar['id']).'&attendance_id='.$attendance_id.'">'.
Display::return_icon('edit.png', get_lang('Edit'), ['style' => 'vertical-align:middle'], ICON_SIZE_SMALL).'</a>&nbsp;';
echo '<a onclick="javascript:if(!confirm(\''.get_lang('Are you sure you want to delete').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=calendar_delete&calendar_id='.(int) ($calendar['id']).'&attendance_id='.$attendance_id.'">'.
Display::return_icon('delete.png', get_lang('Delete'), ['style' => 'vertical-align:middle'], ICON_SIZE_SMALL).'</a>';
echo '</div>';
}
}
}
echo '</li>';
}
} else {
echo Display::return_message(get_lang('There is no date/time registered yet'), 'warning');
}
echo '</ul>';
}

@ -1,730 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This file contains class used like controller,
* it should be included inside a dispatcher file (e.g: index.php).
*
* !!! WARNING !!! : ALL DATES IN THIS MODULE ARE STORED IN UTC !
* DO NOT CONVERT DURING THE TRANSITION FROM CHAMILO 1.8.x TO 2.0
*
* @author Christian Fasanando <christian1827@gmail.com>
* @author Julio Montoya <gugli100@gmail.com> lot of bugfixes + improvements
*/
class AttendanceController
{
/**
* Constructor.
*/
public function __construct()
{
$this->toolname = 'attendance';
$this->view = new View($this->toolname);
}
/**
* It's used for listing attendance,
* render to attendance_list view.
*/
public function attendance_list()
{
// render to the view
$this->view->set_data([]);
$this->view->set_layout('layout');
$this->view->set_template('attendance_list');
$this->view->render();
}
/**
* It's used for adding attendace,
* render to attendance_add or attendance_list view.
*/
public function attendance_add()
{
$attendance = new Attendance();
$data = [];
if ('POST' == strtoupper($_SERVER['REQUEST_METHOD'])) {
if (!empty($_POST['title'])) {
$check = Security::check_token();
$attendanceId = 0;
if ($check) {
$attendance->set_name($_POST['title']);
$attendance->set_description($_POST['description']);
$attendance->set_attendance_qualify_title($_POST['attendance_qualify_title']);
$attendance->set_attendance_weight($_POST['attendance_weight']);
$link_to_gradebook = false;
if (isset($_POST['attendance_qualify_gradebook']) &&
1 == $_POST['attendance_qualify_gradebook']
) {
$link_to_gradebook = true;
}
$attendance->category_id = isset($_POST['category_id']) ? $_POST['category_id'] : 0;
$attendanceId = $attendance->attendance_add($link_to_gradebook);
if ($attendanceId) {
$form = new FormValidator('attendance_add');
Skill::saveSkills($form, ITEM_TYPE_ATTENDANCE, $attendanceId);
}
Security::clear_token();
}
header('Location: index.php?action=calendar_add&attendance_id='.$attendanceId.'&'.api_get_cidreq());
exit;
} else {
$data['error'] = true;
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('attendance_add');
$this->view->render();
}
} else {
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('attendance_add');
$this->view->render();
}
}
/**
* It's used for editing attendance,
* render to attendance_edit or attendance_list view.
*
* @param int $attendance_id
*/
public function attendance_edit($attendance_id)
{
$attendance = new Attendance();
$data = [];
$attendance_id = (int) $attendance_id;
if ('POST' == strtoupper($_SERVER['REQUEST_METHOD'])) {
if (!empty($_POST['title'])) {
$check = Security::check_token();
if ($check) {
$attendance->set_name($_POST['title']);
$attendance->set_description($_POST['description']);
if (isset($_POST['attendance_qualify_title'])) {
$attendance->set_attendance_qualify_title(
$_POST['attendance_qualify_title']
);
}
if (isset($_POST['attendance_weight'])) {
$attendance->set_attendance_weight(
$_POST['attendance_weight']
);
}
$attendance->category_id = isset($_POST['category_id']) ? $_POST['category_id'] : '';
$link_to_gradebook = false;
if (isset($_POST['attendance_qualify_gradebook']) &&
1 == $_POST['attendance_qualify_gradebook']
) {
$link_to_gradebook = true;
}
$attendance->attendance_edit($attendance_id, $link_to_gradebook);
$form = new FormValidator('attendance_edit');
Skill::saveSkills($form, ITEM_TYPE_ATTENDANCE, $attendance_id);
Display::addFlash(Display::return_message(get_lang('Update successful')));
Security::clear_token();
header('Location:index.php?action=attendance_list&'.api_get_cidreq());
exit;
}
} else {
$data['attendance_id'] = $_POST['attendance_id'];
$data['error'] = true;
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('attendance_edit');
$this->view->render();
}
} else {
// default values
$attendance_data = $attendance->get_attendance_by_id(
$attendance_id
);
$data['attendance_id'] = $attendance_data['id'];
$data['title'] = $attendance_data['name'];
$data['description'] = $attendance_data['description'];
$data['attendance_qualify_title'] = $attendance_data['attendance_qualify_title'];
$data['attendance_weight'] = $attendance_data['attendance_weight'];
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('attendance_edit');
$this->view->render();
}
}
/**
* It's used for delete attendaces
* render to attendance_list view.
*
* @param int $attendance_id
*
* @return bool
*/
public function attendance_delete($attendance_id)
{
$allowDeleteAttendance = api_get_setting('allow_delete_attendance');
if ('true' !== $allowDeleteAttendance) {
$this->attendance_list();
return false;
}
$attendance = new Attendance();
if (!empty($attendance_id)) {
$affected_rows = $attendance->attendance_delete($attendance_id);
Skill::deleteSkillsFromItem($attendance_id, ITEM_TYPE_ATTENDANCE);
}
if ($affected_rows) {
$message['message_attendance_delete'] = true;
}
$this->attendance_list();
return true;
}
/**
* It's used for make attendance visible
* render to attendance_list view.
*
* @param int $attendanceId
*/
public function attendanceSetVisible($attendanceId)
{
$attendance = new Attendance();
$affectedRows = null;
if (!empty($attendanceId)) {
$affectedRows = $attendance->changeVisibility($attendanceId, 1);
}
if ($affectedRows) {
$message['message_attendance_delete'] = true;
}
$this->attendance_list();
}
/**
* It's used for make attendance invisible
* render to attendance_list view.
*
* @param int $attendanceId
*/
public function attendanceSetInvisible($attendanceId)
{
$attendance = new Attendance();
if (!empty($attendanceId)) {
$affectedRows = $attendance->changeVisibility($attendanceId, 0);
}
if ($affectedRows) {
$message['message_attendance_delete'] = true;
}
$this->attendance_list();
}
/**
* Restores an attendance entry and fallback to attendances rendering.
*
* @param int $attendance_id
*/
public function attendance_restore($attendance_id)
{
$attendance = new Attendance();
$affected_rows = false;
if (!empty($attendance_id)) {
$affected_rows = $attendance->attendance_restore($attendance_id);
}
if ($affected_rows) {
$message['message_attendance_restore'] = true;
}
$this->attendance_list();
}
/**
* Lock or unlock an attendance
* render to attendance_list view.
*
* @param string $action (lock_attendance or unlock_attendance)
* @param int $attendance_id
* render to attendance_list view
*/
public function lock_attendance($action, $attendance_id)
{
$attendance = new Attendance();
$attendance_id = (int) $attendance_id;
if ('lock_attendance' == $action) {
$result = $attendance->lock_attendance($attendance_id);
} else {
$result = $attendance->lock_attendance($attendance_id, false);
}
if ($result) {
$message['message_locked_attendance'] = true;
}
$this->attendance_list();
}
public function export($id, $type = 'pdf')
{
$attendance = new Attendance();
}
/**
* It's used for controlling attendance sheet (list, add),
* render to attendance_sheet view.
*
* @param string $action
* @param int $attendance_id
* @param int $student_id
* @param bool $edit
*/
public function attendance_sheet(
$action,
$attendance_id,
$student_id = 0,
$edit = true
) {
$attendance = new Attendance();
$data = [];
$data['attendance_id'] = $attendance_id;
$groupId = isset($_REQUEST['group_id']) ? $_REQUEST['group_id'] : null;
$data['users_in_course'] = $attendance->get_users_rel_course($attendance_id, $groupId);
$filter_type = 'today';
if (!empty($_REQUEST['filter'])) {
$filter_type = $_REQUEST['filter'];
}
$isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
api_get_user_id(),
api_get_course_info()
) || api_is_drh();
if (true == $edit) {
if (api_is_allowed_to_edit(null, true) || $isDrhOfCourse) {
$data['users_presence'] = $attendance->get_users_attendance_sheet(
$attendance_id,
0,
$groupId
);
}
} else {
if (!empty($student_id)) {
$user_id = (int) $student_id;
} else {
$user_id = api_get_user_id();
}
if (api_is_allowed_to_edit(null, true) ||
api_is_coach(api_get_session_id(), api_get_course_int_id()) ||
$isDrhOfCourse
) {
$data['users_presence'] = $attendance->get_users_attendance_sheet(
$attendance_id,
0,
$groupId
);
} else {
$data['users_presence'] = $attendance->get_users_attendance_sheet(
$attendance_id,
$user_id,
$groupId
);
}
$data['faults'] = $attendance->get_faults_of_user($user_id, $attendance_id, $groupId);
$data['user_id'] = $user_id;
}
$data['next_attendance_calendar_id'] = $attendance->get_next_attendance_calendar_id(
$attendance_id
);
$data['next_attendance_calendar_datetime'] = $attendance->getNextAttendanceCalendarDatetime(
$attendance_id
);
if ('POST' == strtoupper($_SERVER['REQUEST_METHOD'])) {
if (isset($_POST['hidden_input'])) {
foreach ($_POST['hidden_input'] as $cal_id) {
$users_present = [];
if (isset($_POST['check_presence'][$cal_id])) {
$users_present = $_POST['check_presence'][$cal_id];
}
$attendance->attendance_sheet_add(
$cal_id,
$users_present,
$attendance_id
);
}
}
$data['users_in_course'] = $attendance->get_users_rel_course($attendance_id, $groupId);
$my_calendar_id = null;
if (is_numeric($filter_type)) {
$my_calendar_id = $filter_type;
$filter_type = 'calendar_id';
}
$data['attendant_calendar'] = $attendance->get_attendance_calendar(
$attendance_id,
$filter_type,
$my_calendar_id,
$groupId
);
$data['attendant_calendar_all'] = $attendance->get_attendance_calendar(
$attendance_id,
'all',
null,
$groupId
);
$data['users_presence'] = $attendance->get_users_attendance_sheet($attendance_id, 0, $groupId);
$data['next_attendance_calendar_id'] = $attendance->get_next_attendance_calendar_id($attendance_id);
$data['next_attendance_calendar_datetime'] = $attendance->getNextAttendanceCalendarDatetime($attendance_id);
} else {
$data['attendant_calendar_all'] = $attendance->get_attendance_calendar(
$attendance_id,
'all',
null,
$groupId
);
$data['attendant_calendar'] = $attendance->get_attendance_calendar(
$attendance_id,
$filter_type,
null,
$groupId
);
}
$data['edit_table'] = (int) $edit;
$data['is_locked_attendance'] = $attendance->is_locked_attendance($attendance_id);
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('attendance_sheet');
$this->view->render();
}
/**
* It's used for controlling attendance calendar (list, add, edit, delete),
* render to attendance_calendar view.
*
* @param string $action (optional, by default 'calendar_list')
* @param int $attendance_id (optional)
* @param int $calendar_id (optional)
*/
public function attendance_calendar($action = 'calendar_list', $attendance_id = 0, $calendar_id = 0)
{
$attendance = new Attendance();
$calendar_id = (int) $calendar_id;
$data = [];
$data['attendance_id'] = $attendance_id;
$attendance_id = (int) $attendance_id;
$groupList = isset($_POST['groups']) ? [$_POST['groups']] : [];
if ('calendar_add' == $action) {
if ('POST' == strtoupper($_SERVER['REQUEST_METHOD'])) {
if (!isset($_POST['cancel'])) {
if (isset($_POST['repeat'])) {
//@todo check this error_logs
$start_datetime = api_strtotime(
api_get_utc_datetime($_POST['date_time']),
'UTC'
);
$end_datetime = api_strtotime(api_get_utc_datetime($_POST['end_date_time'].' 23:59:59'), 'UTC');
$checkdate = api_is_valid_date(api_get_utc_datetime($_POST['end_date_time'].' 23:59:59'));
$repeat_type = $_POST['repeat_type'];
if (($end_datetime > $start_datetime) && $checkdate) {
$attendance->attendance_repeat_calendar_add(
$attendance_id,
$start_datetime,
$end_datetime,
$repeat_type,
$groupList
);
$action = 'calendar_list';
} else {
if (!$checkdate) {
$data['error_checkdate'] = true;
} else {
$data['error_repeat_date'] = true;
}
$data['repeat'] = true;
$action = 'calendar_add';
}
} else {
$datetime = $_POST['date_time'];
$datetimezone = api_get_utc_datetime($datetime);
if (!empty($datetime)) {
$attendance->set_date_time($datetimezone);
$attendance->attendance_calendar_add($attendance_id, $groupList);
$action = 'calendar_list';
} else {
$data['error_date'] = true;
$action = 'calendar_add';
}
}
} else {
$action = 'calendar_list';
}
}
} elseif ('calendar_edit' === $action) {
$data['calendar_id'] = $calendar_id;
if ('POST' == strtoupper($_SERVER['REQUEST_METHOD'])) {
if (!isset($_POST['cancel'])) {
$datetime = $_POST['date_time'];
$datetimezone = api_get_utc_datetime($datetime);
$attendance->set_date_time($datetimezone);
$attendance->attendance_calendar_edit($calendar_id, $attendance_id);
$data['calendar_id'] = 0;
$action = 'calendar_list';
} else {
$action = 'calendar_list';
}
}
} elseif ('calendar_delete' == $action) {
$attendance->attendance_calendar_delete($calendar_id, $attendance_id);
$action = 'calendar_list';
} elseif ('calendar_all_delete' == $action) {
$attendance->attendance_calendar_delete(0, $attendance_id, true);
$action = 'calendar_list';
}
$data['action'] = $action;
$data['attendance_calendar'] = $attendance->get_attendance_calendar(
$attendance_id,
'all',
null,
null,
true
);
$data['is_locked_attendance'] = $attendance->is_locked_attendance($attendance_id);
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('attendance_calendar');
$this->view->render();
}
/**
* It's used to print attendance sheet.
*
* @param string $action
* @param int $attendance_id
*/
public function attendance_sheet_export_to_pdf(
$action,
$attendance_id,
$student_id = 0,
$course_id = ''
) {
$attendance = new Attendance();
$courseInfo = api_get_course_info($course_id);
$attendance->set_course_id($courseInfo['code']);
$groupId = isset($_REQUEST['group_id']) ? $_REQUEST['group_id'] : null;
$data_array = [];
$data_array['attendance_id'] = $attendance_id;
$data_array['users_in_course'] = $attendance->get_users_rel_course($attendance_id, $groupId);
$filter_type = 'today';
if (!empty($_REQUEST['filter'])) {
$filter_type = $_REQUEST['filter'];
}
$my_calendar_id = null;
if (is_numeric($filter_type)) {
$my_calendar_id = $filter_type;
$filter_type = 'calendar_id';
}
$data_array['attendant_calendar'] = $attendance->get_attendance_calendar(
$attendance_id,
$filter_type,
$my_calendar_id,
$groupId
);
if (api_is_allowed_to_edit(null, true) || api_is_drh()) {
$data_array['users_presence'] = $attendance->get_users_attendance_sheet($attendance_id, 0, $groupId);
} else {
if (!empty($student_id)) {
$user_id = (int) $student_id;
} else {
$user_id = api_get_user_id();
}
$data_array['users_presence'] = $attendance->get_users_attendance_sheet($attendance_id, $user_id, $groupId);
$data_array['faults'] = $attendance->get_faults_of_user($user_id, $attendance_id, $groupId);
$data_array['user_id'] = $user_id;
}
$data_array['next_attendance_calendar_id'] = $attendance->get_next_attendance_calendar_id($attendance_id);
// Set headers pdf.
$courseCategory = CourseManager::get_course_category($courseInfo['categoryCode']);
$teacherInfo = CourseManager::get_teacher_list_from_course_code($courseInfo['code']);
$teacherName = null;
foreach ($teacherInfo as $teacherData) {
if (null != $teacherName) {
$teacherName .= ' / ';
}
$teacherName .= api_get_person_name($teacherData['firstname'], $teacherData['lastname']);
}
// Get data table
$data_table = [];
$head_table = ['#', get_lang('Name')];
foreach ($data_array['attendant_calendar'] as $class_day) {
$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);
}
$data_table[] = $head_table;
$data_attendant_calendar = $data_array['attendant_calendar'];
$data_users_presence = $data_array['users_presence'];
$count = 1;
if (!empty($data_array['users_in_course'])) {
foreach ($data_array['users_in_course'] as $user) {
$cols = 1;
$result = [];
$result['count'] = $count;
$result['full_name'] = api_get_person_name($user['firstname'], $user['lastname']);
foreach ($data_array['attendant_calendar'] as $class_day) {
if (1 == $class_day['done_attendance']) {
if (1 == $data_users_presence[$user['user_id']][$class_day['id']]['presence']) {
$result[$class_day['id']] = get_lang('P');
} else {
$result[$class_day['id']] = '<span style="color:red">'.get_lang('NP').'</span>';
}
} else {
$result[$class_day['id']] = ' ';
}
$cols++;
}
$count++;
$data_table[] = $result;
}
}
$max_cols_per_page = 12; //10 dates + 2 name and number
$max_dates_per_page = $max_dates_per_page_original = $max_cols_per_page - 2; //10
$rows = count($data_table);
if ($cols > $max_cols_per_page) {
$number_tables = round(($cols - 2) / $max_dates_per_page);
$headers = $data_table[0];
$all = [];
$tables = [];
$changed = 1;
for ($i = 0; $i <= $rows; $i++) {
$row = isset($data_table[$i]) ? $data_table[$i] : null;
$key = 1;
$max_dates_per_page = 10;
$item = isset($data_table[$i]) ? $data_table[$i] : null;
$count_j = 0;
if (!empty($item)) {
foreach ($item as $value) {
if ($count_j >= $max_dates_per_page) {
$key++;
$max_dates_per_page = $max_dates_per_page_original * $key;
//magic hack
$tables[$key][$i][] = $tables[1][$i][0];
$tables[$key][$i][] = $tables[1][$i][1];
}
$tables[$key][$i][] = $value;
$count_j++;
}
}
}
$content = null;
if (!empty($tables)) {
foreach ($tables as $sub_table) {
$content .= Export::convert_array_to_html($sub_table).'<br /><br />';
}
}
} else {
$content = Export::convert_array_to_html(
$data_table,
['header_attributes' => ['align' => 'center']]
);
}
$params = [
'filename' => get_lang('Attendance').'-'.api_get_local_time(),
'pdf_title' => $courseInfo['title'],
'course_code' => $courseInfo['code'],
'add_signatures' => ['Drh', 'Teacher', 'Date'],
'orientation' => 'landscape',
'pdf_teachers' => $teacherName,
'pdf_course_category' => $courseCategory['name'],
'format' => 'A4-L',
'orientation' => 'L',
];
Export::export_html_to_pdf($content, $params);
exit;
}
/**
* Gets attendance base in the table:
* TABLE_STATISTIC_TRACK_E_COURSE_ACCESS.
*
* @param bool $showForm
* @param bool $exportToPdf
*/
public function getAttendanceBaseInLogin($showForm = false, $exportToPdf = true)
{
$table = null;
$formToDisplay = null;
$startDate = null;
$endDate = null;
$sessionId = api_get_session_id();
if ($showForm) {
$form = new FormValidator(
'search',
'post',
api_get_self().'?'.api_get_cidreq().'&action=calendar_logins'
);
$form->addDateRangePicker('range', get_lang('Date range'));
$form->addButton('submit', get_lang('Submit'));
if ($form->validate()) {
$values = $form->getSubmitValues();
$startDate = api_get_utc_datetime($values['range_start']);
$endDate = api_get_utc_datetime($values['range_end']);
}
$formToDisplay = $form->returnForm();
} else {
if (!empty($sessionId)) {
$sessionInfo = api_get_session_info($sessionId);
$startDate = $sessionInfo['access_start_date'];
$endDate = $sessionInfo['access_end_date'];
}
}
$attendance = new Attendance();
if ($exportToPdf) {
$result = $attendance->exportAttendanceLogin($startDate, $endDate);
if (empty($result)) {
api_not_allowed(true, get_lang('No data available'));
}
}
$table = $attendance->getAttendanceLoginTable($startDate, $endDate);
$data = [
'form' => $formToDisplay,
'table' => $table,
];
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('calendar_logins');
$this->view->render();
}
}

@ -1,110 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* View (MVC patter) for editing an attendance.
*
* @author Christian Fasanando <christian1827@gmail.com>
*/
// protect a course script
api_protect_course_script(true);
// error messages
if (isset($error)) {
echo Display::return_message(get_lang('The form contains incorrect or incomplete data. Please check your input.'), 'error', false);
}
if (!isset($error)) {
$token = Security::get_token();
}
$attendance_weight = api_float_val($attendance_weight);
// display form
$form = new FormValidator(
'attendance_edit',
'POST',
'index.php?action=attendance_edit&'.api_get_cidreq().'&attendance_id='.$attendance_id
);
$form->addElement('header', '', get_lang('Edit'));
$form->addElement('hidden', 'sec_token', $token);
$form->addElement('hidden', 'attendance_id', $attendance_id);
$form->addText('title', get_lang('Title'), true);
$form->applyFilter('title', 'html_filter');
$form->addHtmlEditor(
'description',
get_lang('Description'),
false,
false,
[
'ToolbarSet' => 'Basic',
'Width' => '100%',
'Height' => '200',
]
);
// Advanced Parameters
$skillList = [];
if (Gradebook::is_active()) {
if (!empty($attendance_qualify_title) || !empty($attendance_weight)) {
$form->addButtonAdvancedSettings('id_qualify');
$form->addElement('html', '<div id="id_qualify_options" style="display:block">');
$form->addElement(
'checkbox',
'attendance_qualify_gradebook',
'',
get_lang('Grade the attendance list in the assessment tool'),
[
'checked' => 'true',
'onclick' => 'javascript: if(this.checked){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}',
]
);
$form->addElement('html', '<div id="options_field" style="display:block">');
} else {
$form->addButtonAdvancedSettings('id_qualify');
$form->addElement('html', '<div id="id_qualify_options" style="display:none">');
$form->addElement(
'checkbox',
'attendance_qualify_gradebook',
'',
get_lang('Grade the attendance list in the assessment tool'),
'onclick="javascript: if(this.checked){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}"'
);
$form->addElement('html', '<div id="options_field" style="display:none">');
}
GradebookUtils::load_gradebook_select_in_tool($form);
$form->addElement('text', 'attendance_qualify_title', get_lang('Column header in Competences Report'));
$form->applyFilter('attendance_qualify_title', 'html_filter');
$form->addElement(
'text',
'attendance_weight',
get_lang('Weight in Report'),
'value="0.00" Style="width:40px" onfocus="javascript: this.select();"'
);
$form->applyFilter('attendance_weight', 'html_filter');
$form->addElement('html', '</div>');
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_ATTENDANCE, $attendance_id);
$form->addElement('html', '</div>');
}
$form->addButtonUpdate(get_lang('Save'));
// set default values
$default['title'] = Security::remove_XSS($title);
$default['description'] = Security::remove_XSS($description, STUDENT);
$default['attendance_qualify_title'] = $attendance_qualify_title;
$default['attendance_weight'] = $attendance_weight;
$default['skills'] = array_keys($skillList);
$link_info = GradebookUtils::isResourceInCourseGradebook(
api_get_course_id(),
7,
$attendance_id,
api_get_session_id()
);
$default['category_id'] = $link_info['category_id'];
$form->setDefaults($default);
$form->display();

@ -1,55 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* View (MVC patter) for listing attendances.
*
* @author Christian Fasanando <christian1827@gmail.com>
*/
// protect a course script
api_protect_course_script(true);
if (api_is_allowed_to_edit(null, true)) {
echo '<div class="actions">';
echo '<a href="index.php?'.api_get_cidreq().'&action=attendance_add">'.
Display::return_icon('new_attendance_list.png', get_lang('Create a new attendance list'), '', ICON_SIZE_MEDIUM).'</a>';
echo '</div>';
}
$attendance = new Attendance();
if (0 == $attendance->getNumberOfAttendances()) {
$attendance->set_name(get_lang('Attendances'));
$attendance->set_description(get_lang('Attendances'));
$attendance->attendance_add();
}
$default_column = isset($default_column) ? $default_column : null;
$parameters = isset($parameters) ? $parameters : null;
$table = new SortableTable(
'attendance_list',
['Attendance', 'getNumberOfAttendances'],
['Attendance', 'get_attendance_data'],
$default_column
);
$table->set_additional_parameters($parameters);
$table->set_header(0, '', false, ['style' => 'width:20px;']);
$table->set_header(1, get_lang('Name'), true);
$table->set_header(2, get_lang('Description'), true);
$table->set_header(3, get_lang('CountDoneAttendance'), true, ['style' => 'width:90px;']);
if (api_is_allowed_to_edit(null, true)) {
$table->set_header(4, get_lang('Detail'), false, ['style' => 'text-align:center']);
$actions = [
'attendance_set_invisible_select' => get_lang('Set invisible'),
'attendance_set_visible_select' => get_lang('Set visible'),
];
$allow = api_get_setting('allow_delete_attendance');
if ('true' === $allow) {
$actions['attendance_delete_select'] = get_lang('Delete all selected attendances');
}
$table->set_form_actions($actions);
}
if ($table->get_total_number_of_items() > 0) {
$table->display();
}

@ -1,472 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* View (MVC patter) for attendance sheet (list, edit, add).
*
* @author Christian Fasanando <christian1827@gmail.com>
* @author Julio Montoya reworked 2010
*/
// Protect a course script
api_protect_course_script(true);
$isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
api_get_user_id(),
api_get_course_info()
) || api_is_drh();
if (api_is_allowed_to_edit(null, true) ||
api_is_coach(api_get_session_id(), api_get_course_int_id()) ||
$isDrhOfCourse
) {
$groupId = isset($_REQUEST['group_id']) ? (int) ($_REQUEST['group_id']) : null;
$form = new FormValidator(
'filter',
'post',
'index.php?action=attendance_sheet_list&'.api_get_cidreq().'&attendance_id='.$attendance_id,
null,
[],
'inline'
);
$values = [
'all' => get_lang('All'),
'today' => get_lang('Today'),
'all_done' => get_lang('All done'),
'all_not_done' => get_lang('All not done'),
];
$today = api_convert_and_format_date(null, DATE_FORMAT_SHORT);
$exists_attendance_today = false;
if (!empty($attendant_calendar_all)) {
$values[''] = '---------------';
foreach ($attendant_calendar_all as $attendance_date) {
$includeCalendar = true;
if (isset($attendance_date['groups']) && !empty($groupId)) {
foreach ($attendance_date['groups'] as $group) {
if ($groupId == $group['group_id']) {
$includeCalendar = true;
break;
} else {
$includeCalendar = false;
}
}
}
if ($today == $attendance_date['date']) {
$exists_attendance_today = true;
}
if ($includeCalendar) {
$values[$attendance_date['id']] = $attendance_date['date_time'];
}
}
}
if (!$exists_attendance_today) {
echo Display::return_message(
get_lang('There is no class scheduled today, try picking another day or add your attendance entry yourself using the action icons.'),
'warning'
);
}
$form->addSelect(
'filter',
get_lang('Filter'),
$values,
['id' => 'filter_id', 'onchange' => 'submit();']
);
$groupList = GroupManager::get_group_list(null, null, 1);
$groupIdList = ['--'];
foreach ($groupList as $group) {
$groupIdList[$group['id']] = $group['name'];
}
if (!empty($groupList)) {
$form->addSelect('group_id', get_lang('Group'), $groupIdList);
}
if (isset($_REQUEST['filter'])) {
if (in_array($_REQUEST['filter'], array_keys($values))) {
$default_filter = $_REQUEST['filter'];
}
} else {
$default_filter = 'today';
}
$renderer = $form->defaultRenderer();
$renderer->setCustomElementTemplate('<div class="col-md-2">{label}</div><div class="col-md-10"> {element} </div>');
$form->setDefaults(
[
'filter' => $default_filter,
'group_id' => $groupId,
]
);
if (!$is_locked_attendance || api_is_platform_admin()) {
$actionsLeft = '<a style="float:left;" href="index.php?'.api_get_cidreq().'&action=calendar_list&attendance_id='.$attendance_id.'">'.
Display::return_icon('attendance_calendar.png', get_lang('Attendance calendar'), '', ICON_SIZE_MEDIUM).'</a>';
$actionsLeft .= '<a id="pdf_export" style="float:left;" href="index.php?'.api_get_cidreq().'&action=attendance_sheet_export_to_pdf&attendance_id='.$attendance_id.'&filter='.$default_filter.'&group_id='.$groupId.'">'.
Display::return_icon('pdf.png', get_lang('Export to PDF'), '', ICON_SIZE_MEDIUM).'</a>';
$actionsRight = $form->returnForm();
$toolbar = Display::toolbarAction('toolbar-attendance', [$actionsLeft, $actionsRight]);
echo $toolbar;
}
$message_information = get_lang('The attendance sheets allow you to specify a list of dates in which you will report attendance to your courses');
if (!empty($message_information)) {
$message = '<strong>'.get_lang('Information').'</strong><br />';
$message .= $message_information;
echo Display::return_message($message, 'normal', false);
}
if ($is_locked_attendance) {
echo Display::return_message(get_lang('The attendance sheet is locked.'), 'warning', false);
}
$param_filter = '&filter='.Security::remove_XSS($default_filter).'&group_id='.$groupId;
if (count($users_in_course) > 0) {
?>
<script>
var original_url = '';
$("#filter_id").on('change', function() {
filter = $(this).val();
if (original_url == '') {
original_url = $("#pdf_export").attr('href');
}
new_url = original_url + "&filter=" +filter
$("#pdf_export").attr('href', new_url);
});
function UpdateTableHeaders() {
$("div.divTableWithFloatingHeader").each(function() {
var originalHeaderRow = $(".tableFloatingHeaderOriginal", this);
var floatingHeaderRow = $(".tableFloatingHeader", this);
var offset = $(this).offset();
var scrollTop = $(window).scrollTop();
if ((scrollTop > offset.top) && (scrollTop < offset.top + $(this).height())) {
floatingHeaderRow.css("visibility", "hidden");
var topbar = 0;
if ($("#topbar").length != 0) {
topbar = $("#topbar").height();
} else {
if ($(".subnav").length != 0) {
topbar = $(".subnav").height();
}
}
var top_value = Math.min(scrollTop - offset.top, $(this).height() - floatingHeaderRow.height()) + topbar;
floatingHeaderRow.css("top", top_value + "px");
// Copy cell widths from original header
$("th", floatingHeaderRow).each(function(index) {
var cellWidth = $("th", originalHeaderRow).eq(index).css('width');
$(this).css('width', cellWidth);
});
// Copy row width from whole table
floatingHeaderRow.css("width", $(this).css("width"));
floatingHeaderRow.css("visibility", "visible");
floatingHeaderRow.css("z-index", "1000");
originalHeaderRow.css("height", "64px");
} else {
floatingHeaderRow.css("visibility", "hidden");
floatingHeaderRow.css("top", "0px");
}
});
}
$(function() {
$("table.tableWithFloatingHeader").each(function() {
$(this).wrap("<div class=\"divTableWithFloatingHeader\" style=\"position:relative\"></div>");
var originalHeaderRow = $("tr:first", this)
originalHeaderRow.before(originalHeaderRow.clone());
var clonedHeaderRow = $("tr:first", this)
clonedHeaderRow.addClass("tableFloatingHeader");
clonedHeaderRow.css("position", "absolute");
clonedHeaderRow.css("top", "0px");
clonedHeaderRow.css("left", $(this).css("margin-left"));
clonedHeaderRow.css("visibility", "hidden");
originalHeaderRow.addClass("tableFloatingHeaderOriginal");
});
UpdateTableHeaders();
$(window).scroll(UpdateTableHeaders);
$(window).resize(UpdateTableHeaders);
});
</script>
<form method="post" action="index.php?action=attendance_sheet_add&<?php echo api_get_cidreq().$param_filter; ?>&attendance_id=<?php echo $attendance_id; ?>" >
<div class="attendance-sheet-content" style="width:100%;background-color:#E1E1E1;margin-top:20px;">
<div class="divTableWithFloatingHeader attendance-users-table" style="width:45%;float:left;margin:0px;padding:0px;">
<table class="tableWithFloatingHeader data_table" width="100%">
<thead>
<tr class="tableFloatingHeader" style="position: absolute; top: 0px; left: 0px; visibility: hidden; margin:0px;padding:0px" >
<th width="10px"><?php echo '#'; ?></th>
<th width="10px"><?php echo get_lang('Photo'); ?></th>
<th width="100px"><?php echo get_lang('Last name'); ?></th>
<th width="100px"><?php echo get_lang('First name'); ?></th>
<th width="100px"><?php echo get_lang('Not attended'); ?></th>
</tr>
<tr class="tableFloatingHeaderOriginal" >
<th width="10px"><?php echo '#'; ?></th>
<th width="10px"><?php echo get_lang('Photo'); ?></th>
<th width="150px"><?php echo get_lang('Last name'); ?></th>
<th width="140px"><?php echo get_lang('First name'); ?></th>
<th width="100px"><?php echo get_lang('Not attended'); ?></th>
</tr>
</thead>
<tbody>
<?php
$i = 1;
$class = '';
foreach ($users_in_course as $data) {
$faults = 0;
if (0 == $i % 2) {
$class = 'row_odd';
} else {
$class = 'row_even';
}
$username = api_htmlentities(
sprintf(get_lang('Login: %s'), $data['username']),
ENT_QUOTES
); ?>
<tr class="<?php echo $class; ?>">
<td><center><?php echo $i; ?></center></td>
<td><?php echo $data['photo']; ?></td>
<td><span title="<?php echo $username; ?>"><?php echo $data['lastname']; ?></span></td>
<td><?php echo $data['firstname']; ?></td>
<td>
<div class="attendance-faults-bar" style="background-color:<?php echo !empty($data['result_color_bar']) ? $data['result_color_bar'] : 'none'; ?>">
<?php echo $data['attendance_result']; ?>
</div>
</td>
</tr>
<?php
$i++;
} ?>
</tbody>
</table>
</div>
<?php
echo '<div class="divTableWithFloatingHeader attendance-calendar-table" style="margin:0px;padding:0px;float:left;width:55%;overflow:auto;overflow-y:hidden;">';
echo '<table class="tableWithFloatingHeader data_table" width="100%">';
echo '<thead>';
$result = null;
if (count($attendant_calendar) > 0) {
foreach ($attendant_calendar as $calendar) {
$date = $calendar['date'];
$time = $calendar['time'];
$datetime = '<div class="grey">'.$date.' - '.$time.'</div>';
$img_lock = Display::return_icon(
'lock-closed.png',
get_lang('Unlock date'),
['class' => 'img_lock', 'id' => 'datetime_column_'.$calendar['id']]
);
if (!empty($calendar['done_attendance'])) {
$datetime = '<div class="blue">'.$date.' - '.$time.'</div>';
}
$disabled_check = 'disabled = "true"';
$input_hidden = '<input type="hidden" id="hidden_input_'.$calendar['id'].'" name="hidden_input[]" value="" disabled />';
if ($next_attendance_calendar_id == $calendar['id']) {
$input_hidden = '<input type="hidden" id="hidden_input_'.$calendar['id'].'" name="hidden_input[]" value="'.$calendar['id'].'" />';
$disabled_check = '';
$img_lock = Display::return_icon('lock-closed.png', get_lang('Lock date'), ['class' => 'img_unlock', 'id' => 'datetime_column_'.$calendar['id']]);
}
$result .= '<th>';
$result .= '<div class="date-attendance">'.$datetime.'&nbsp;';
if (api_is_allowed_to_edit(null, true)) {
$result .= '<span id="attendance_lock" style="cursor:pointer">'.(!$is_locked_attendance || api_is_platform_admin() ? $img_lock : '').'</span>';
}
if (false == $is_locked_attendance) {
if (api_is_allowed_to_edit(null, true)) {
$result .= '<input type="checkbox" class="checkbox_head_'.$calendar['id'].'" id="checkbox_head_'.$calendar['id'].'" '.$disabled_check.' checked="checked" />'.$input_hidden.'</div></th>';
}
}
}
} else {
$result = '<th width="2000px"><span><a href="index.php?'.api_get_cidreq().'&action=calendar_list&attendance_id='.$attendance_id.'">';
$result .= Display::return_icon('attendance_calendar.png', get_lang('Attendance calendar'), '', ICON_SIZE_MEDIUM).' '.get_lang('GoTo attendance calendar').'</a></span></th>';
}
echo '<tr class="tableFloatingHeader row_odd" style="position: absolute; top: 0px; left: 0px; visibility: hidden; margin:0px;padding:0px">';
echo $result;
echo '</tr>';
echo '<tr class="tableWithFloatingHeader row_odd tableFloatingHeaderOriginal">';
echo $result;
echo '</tr>';
echo '</thead>';
echo '<tbody>';
$i = 0;
foreach ($users_in_course as $user) {
$class = '';
if (0 == $i % 2) {
$class = 'row_even';
} else {
$class = 'row_odd';
}
echo '<tr class="'.$class.'">';
if (count($attendant_calendar) > 0) {
foreach ($attendant_calendar as $calendar) {
$checked = 'checked';
$presence = -1;
if (isset($users_presence[$user['user_id']][$calendar['id']]['presence'])) {
$presence = $users_presence[$user['user_id']][$calendar['id']]['presence'];
if (1 == (int) $presence) {
$checked = 'checked';
} else {
$checked = '';
}
} else {
//if the user wasn't registered at that time, consider unchecked
if (0 == $next_attendance_calendar_datetime ||
$calendar['date_time'] < $next_attendance_calendar_datetime
) {
$checked = '';
}
}
$disabled = 'disabled';
$style_td = '';
if ($next_attendance_calendar_id == $calendar['id']) {
if (0 == $i % 2) {
$style_td = 'background-color:#eee;';
} else {
$style_td = 'background-color:#dcdcdc;';
}
$disabled = '';
}
echo '<td style="'.$style_td.'" class="checkboxes_col_'.$calendar['id'].'">';
echo '<div class="check">';
if (api_is_allowed_to_edit(null, true)) {
if (!$is_locked_attendance || api_is_platform_admin()) {
echo '<input type="checkbox" name="check_presence['.$calendar['id'].'][]" value="'.$user['user_id'].'" '.$disabled.' '.$checked.' />';
echo '<span class="anchor_'.$calendar['id'].'"></span>';
} else {
echo $presence ? Display::return_icon('checkbox_on.png', get_lang('Assistance'), null, ICON_SIZE_TINY) : Display::return_icon('checkbox_off.png', get_lang('Assistance'), null, ICON_SIZE_TINY);
}
} else {
switch ($presence) {
case 1:
echo Display::return_icon('accept.png', get_lang('Attended'));
break;
case 0:
echo Display::return_icon('exclamation.png', get_lang('Not attended'));
break;
case -1:
//echo Display::return_icon('warning.png',get_lang('Not attended'));
break;
}
}
echo '</div>';
echo '</td>';
}
} else {
$calendarClass = null;
if (isset($calendar)) {
$calendarClass = 'checkboxes_col_'.$calendar['id'];
}
echo '<td class="'.$calendarClass.'">';
echo '<div>';
echo '<center>&nbsp;</center>
</div>
</td>';
}
echo '</tr>';
$i++;
}
echo '</tbody></table>';
echo '</div></div>'; ?>
<div class="row">
<div class="col-md-12">
<?php if (!$is_locked_attendance || api_is_platform_admin()) {
if (api_is_allowed_to_edit(null, true)) {
?>
<button type="submit" class="btn btn-primary"><?php echo get_lang('Save'); ?></button>
<?php
}
} ?>
</div>
</div>
</form>
<?php
} else {
echo Display::return_message(
'<a href="'.api_get_path(WEB_CODE_PATH).'user/user.php?'.api_get_cidreq().'">'.
get_lang('There are no registered learners inside the course').'</a>',
'warning',
false
);
}
} else {
echo Display::page_header(get_lang('Report of attendance sheets'));
// View for students?>
<?php if (!empty($users_presence)) {
?>
<div>
<table width="250px;">
<tr>
<td><?php echo get_lang('To attend').': '; ?></td>
<td>
<center><div class="attendance-faults-bar" style="background-color:<?php echo !empty($faults['color_bar']) ? $faults['color_bar'] : 'none'; ?>">
<?php echo $faults['faults'].'/'.$faults['total'].' ('.$faults['faults_porcent'].'%)'; ?></div></center>
</td>
</tr>
</table>
</div>
<?php
} ?>
<table class="data_table">
<tr class="row_odd" >
<th><?php echo get_lang('Attendance'); ?></th>
</tr>
<?php
if (!empty($users_presence)) {
$i = 0;
foreach ($users_presence[$user_id] as $presence) {
$class = '';
if (0 == $i % 2) {
$class = 'row_even';
} else {
$class = 'row_odd';
} ?>
<tr class="<?php echo $class; ?>">
<td>
<?php echo $presence['presence'] ? Display::return_icon('checkbox_on.png', get_lang('Assistance'), null, ICON_SIZE_TINY) : Display::return_icon('checkbox_off.png', get_lang('Assistance'), null, ICON_SIZE_TINY); ?>
<?php echo '&nbsp; '.$presence['date_time']; ?>
</td>
</tr>
<?php
}
} else {
?>
<tr><td>
<center><?php echo get_lang('You do not have attendances'); ?></center></td>
</tr>
<?php
} ?>
</table>
<?php
} ?>

@ -1,11 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
// See AttendanceController::calendarLogins function
echo '<div class="actions">';
echo '<a href="index.php?'.api_get_cidreq().'&action=calendar_list">'.
Display::return_icon('back.png', get_lang('Attendance calendar'), '', ICON_SIZE_MEDIUM).'</a>';
echo '</div>';
echo $form;
echo $table;

@ -2,15 +2,14 @@
/* For licensing terms, see /license.txt */
/**
* Template (front controller in MVC pattern) used for dispatching
* to the controllers depend on the current action.
*
* @author Christian Fasanando <christian1827@gmail.com>
* @author Julio Montoya <gugli100@gmail.com> Bug fixing, sql improvements
*/
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\CourseBundle\Entity\CAttendance;
use Chamilo\CourseBundle\Entity\CAttendanceCalendar;
require_once __DIR__.'/../inc/global.inc.php';
require_once 'attendance_controller.php';
api_protect_course_script(true);
require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/fe/exportgradebook.php';
$current_course_tool = TOOL_ATTENDANCE;
@ -18,9 +17,6 @@ $current_course_tool = TOOL_ATTENDANCE;
// current section
$this_section = SECTION_COURSES;
// protect a course script
api_protect_course_script(true);
// Get actions
$actions = [
'attendance_list',
@ -38,9 +34,6 @@ $actions = [
'attendance_sheet_export_to_pdf',
'attendance_sheet_list_no_edit',
'calendar_logins',
];
$actions_calendar = [
'calendar_list',
'calendar_add',
'calendar_edit',
@ -48,46 +41,41 @@ $actions_calendar = [
'calendar_all_delete',
];
$action = 'attendance_list';
$course_id = '';
if (isset($_GET['cidReq'])) {
$course_id = $_GET['cidReq'];
$action = 'attendance_list';
if (isset($_REQUEST['action']) && (in_array($_REQUEST['action'], $actions))) {
$action = $_REQUEST['action'];
}
if (isset($_GET['action']) &&
(in_array($_GET['action'], $actions) || in_array($_GET['action'], $actions_calendar))
) {
$action = $_GET['action'];
}
if (isset($_GET['isStudentView']) && 'true' == $_GET['isStudentView']) {
if (isset($_GET['isStudentView']) && 'true' === $_GET['isStudentView']) {
$action = 'attendance_list';
}
$repo = Container::getAttendanceRepository();
$attendanceEntity = null;
// get attendance id
$attendance_id = 0;
$attendanceId = 0;
if (isset($_GET['attendance_id'])) {
$attendance_id = (int) ($_GET['attendance_id']);
$attendanceId = (int) ($_GET['attendance_id']);
/** @var CAttendance $attendanceEntity */
$attendanceEntity = $repo->find($attendanceId);
}
// get calendar id
$calendar_id = '';
$calendarId = '';
$calendarEntity = null;
if (isset($_GET['calendar_id'])) {
$calendar_id = (int) ($_GET['calendar_id']);
$calendarId = (int) ($_GET['calendar_id']);
/** @var CAttendanceCalendar $calendarEntity */
$calendarEntity = Database::getManager()->getRepository('ChamiloCourseBundle:CAttendanceCalendar')->find($calendarId);
}
$token = Security::get_token();
// instance attendance object for using like library here
$attendance = new Attendance();
// attendance controller object
$attendanceController = new AttendanceController();
$attendance_data = [];
// get attendance data
if (!empty($attendance_id)) {
// attendance data by id
$attendance_data = $attendance->get_attendance_by_id($attendance_id);
}
$htmlHeadXtra[] = '<script>
$(function() {
$("table th img").click(function() {
@ -102,7 +90,7 @@ $(function() {
$(".row_odd td.checkboxes_col_"+calendar_id).css({
"opacity":"1",
"background-color":"#F9F9F9",
"background-color":"#F9F9F9",
"border-left":"none",
"border-right":"none"
});
@ -124,16 +112,16 @@ $(function() {
$(".row_odd td.checkboxes_col_"+calendar_id).css({
"opacity":"1",
"background-color":"#dcdcdc",
"border-left":"1px #bbb solid",
"border-right":"1px #bbb solid",
"background-color":"#dcdcdc",
"border-left":"1px #bbb solid",
"border-right":"1px #bbb solid",
"z-index":"1"
});
$(".row_even td.checkboxes_col_"+calendar_id).css({
"opacity":"1",
"background-color":"#eee",
"border-left":"1px #bbb solid",
"border-right":"1px #bbb solid",
"background-color":"#eee",
"border-left":"1px #bbb solid",
"border-right":"1px #bbb solid",
"z-index":"1"
});
@ -184,6 +172,8 @@ $(function() {
});
</script>';
$tpl = new Template(get_lang('Attendance'));
$student_param = '';
$student_id = null;
@ -206,166 +196,595 @@ $interbreadcrumb[] = [
'url' => 'index.php?'.api_get_cidreq().'&action=attendance_list&'.$student_param,
'name' => get_lang('Attendances'),
];
if ('attendance_add' == $action) {
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Create a new attendance list')];
}
if ('attendance_edit' == $action) {
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Edit')];
}
if ('attendance_sheet_list' == $action || 'attendance_sheet_add' == $action) {
$interbreadcrumb[] = ['url' => '#', 'name' => $attendance_data['name']];
if ($attendanceEntity) {
$interbreadcrumb[] = ['url' => '#', 'name' => $attendanceEntity->getName()];
}
if ('calendar_list' == $action || 'calendar_edit' == $action || 'calendar_delete' == $action ||
'calendar_all_delete' == $action
) {
if ('calendar_list' == $action || 'calendar_edit' == $action) {
$interbreadcrumb[] = [
'url' => 'index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendance_id,
'name' => $attendance_data['name'],
'url' => 'index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendanceId,
'name' => $attendanceEntity->getName(),
];
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Attendance calendar')];
}
if ('calendar_add' == $action) {
$interbreadcrumb[] = [
'url' => 'index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendance_id,
'name' => $attendance_data['name'],
];
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Add a date and time')];
}
$allowToEdit = api_is_allowed_to_edit(null, true);
// Delete selected attendance
if (isset($_POST['action']) && 'attendance_delete_select' == $_POST['action'] && $allowToEdit) {
$attendanceController->attendance_delete($_POST['id']);
}
if (isset($_POST['action']) && 'attendance_set_invisible_select' == $_POST['action'] && $allowToEdit) {
$attendanceController->attendanceSetInvisible($_POST['id']);
}
if (isset($_POST['action']) && 'attendance_set_visible_select' == $_POST['action'] && $allowToEdit) {
$attendanceController->attendanceSetVisible($_POST['id']);
}
$currentUrl = api_get_path(WEB_CODE_PATH).'attendance/index.php?'.api_get_cidreq();
$content = '';
switch ($action) {
case 'attendance_list':
$attendanceController->attendance_list();
if ($allowToEdit) {
$content .= '<div class="actions">';
$content .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_add">';
$content .= Display::return_icon(
'new_attendance_list.png',
get_lang('Create a new attendance list'),
'',
ICON_SIZE_MEDIUM
);
$content .= '</a>';
$content .= '</div>';
}
if (0 === $attendance->getNumberOfAttendances()) {
$attendance->set_name(get_lang('Attendances'));
$attendance->set_description(get_lang('Attendances'));
$attendance->attendance_add();
}
$default_column = isset($default_column) ? $default_column : null;
$parameters = isset($parameters) ? $parameters : null;
$table = new SortableTable(
'attendance_list',
['Attendance', 'getNumberOfAttendances'],
['Attendance', 'get_attendance_data'],
$default_column
);
$table->set_additional_parameters($parameters);
$table->set_header(0, '', false, ['style' => 'width:20px;']);
$table->set_header(1, get_lang('Name'), true);
$table->set_header(2, get_lang('Description'), true);
$table->set_header(3, get_lang('# attended'), true, ['style' => 'width:90px;']);
if (api_is_allowed_to_edit(null, true)) {
$table->set_header(4, get_lang('Detail'), false, ['style' => 'text-align:center']);
$actions = [
'attendance_set_invisible_select' => get_lang('Set invisible'),
'attendance_set_visible_select' => get_lang('Set visible'),
];
$allow = api_get_setting('allow_delete_attendance');
if ('true' === $allow) {
$actions['attendance_delete_select'] = get_lang('Delete all selected attendances');
}
$table->set_form_actions($actions);
}
if ($table->get_total_number_of_items() > 0) {
$content .= $table->return_table();
}
break;
case 'attendance_add':
if ($allowToEdit) {
$attendanceController->attendance_add();
} else {
if (!$allowToEdit) {
api_not_allowed(true);
}
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Create a new attendance list')];
$form = new FormValidator(
'attendance_add',
'POST',
$currentUrl.'&action=attendance_add&'
);
$attendance->setAttendanceForm($form);
if ($form->validate()) {
$attendance->set_name($_POST['title']);
$attendance->set_description($_POST['description']);
$attendance->set_attendance_qualify_title($_POST['attendance_qualify_title']);
$attendance->set_attendance_weight($_POST['attendance_weight']);
$link_to_gradebook = false;
if (isset($_POST['attendance_qualify_gradebook']) &&
1 == $_POST['attendance_qualify_gradebook']
) {
$link_to_gradebook = true;
}
$attendance->category_id = isset($_POST['category_id']) ? $_POST['category_id'] : 0;
$attendanceId = $attendance->attendance_add($link_to_gradebook);
if ($attendanceId) {
Skill::saveSkills($form, ITEM_TYPE_ATTENDANCE, $attendanceId);
header('Location: '.$currentUrl.'&action=calendar_add&attendance_id='.$attendanceId);
exit;
}
header('Location: '.$currentUrl);
exit;
} else {
$content = $form->returnForm();
}
break;
case 'attendance_edit':
if ($allowToEdit) {
$attendanceController->attendance_edit($attendance_id);
} else {
if (!$allowToEdit) {
api_not_allowed(true);
}
break;
case 'attendance_delete':
if ($allowToEdit) {
$attendanceController->attendance_delete($attendance_id);
Display::addFlash(Display::return_message(get_lang('Deleted')));
$form = new FormValidator(
'attendance_edit',
'POST',
'index.php?action=attendance_edit&'.api_get_cidreq().'&attendance_id='.$attendanceId
);
$attendance->setAttendanceForm($form, $attendanceEntity);
if (!empty($_POST['title'])) {
$attendance->set_name($_POST['title']);
$attendance->set_description($_POST['description']);
if (isset($_POST['attendance_qualify_title'])) {
$attendance->set_attendance_qualify_title($_POST['attendance_qualify_title']);
}
if (isset($_POST['attendance_weight'])) {
$attendance->set_attendance_weight($_POST['attendance_weight']);
}
$attendance->category_id = isset($_POST['category_id']) ? $_POST['category_id'] : '';
$link_to_gradebook = false;
if (isset($_POST['attendance_qualify_gradebook']) &&
1 == $_POST['attendance_qualify_gradebook']
) {
$link_to_gradebook = true;
}
$attendance->attendance_edit($attendanceEntity, $link_to_gradebook);
Skill::saveSkills($form, ITEM_TYPE_ATTENDANCE, $attendanceId);
Display::addFlash(Display::return_message(get_lang('Update successful')));
Security::clear_token();
header('Location:index.php?action=attendance_list&'.api_get_cidreq());
exit;
} else {
$content = $form->returnForm();
}
break;
case 'attendance_set_visible':
case 'attendance_set_visible_select':
if (!$allowToEdit) {
api_not_allowed(true);
}
if (isset($_POST['id']) && is_array($_POST['id'])) {
foreach ($_POST['id'] as $id) {
$attendanceEntity = $repo->find($id);
$attendance->changeVisibility($attendanceEntity, 1);
}
} else {
$attendance->changeVisibility($attendanceEntity, 1);
}
Display::addFlash(Display::return_message(get_lang('Updated')));
header('Location: '.$currentUrl);
exit;
break;
case 'attendance_set_invisible':
if ($allowToEdit) {
$attendanceController->attendanceSetInvisible($attendance_id);
case 'attendance_set_invisible_select':
if (isset($_POST['id']) && is_array($_POST['id'])) {
foreach ($_POST['id'] as $id) {
$attendanceEntity = $repo->find($id);
$attendance->changeVisibility($attendanceEntity, 0);
}
} else {
api_not_allowed(true);
$attendance->changeVisibility($attendanceEntity, 0);
}
Display::addFlash(Display::return_message(get_lang('Updated')));
header('Location: '.$currentUrl);
exit;
break;
case 'attendance_set_visible':
if ($allowToEdit) {
$attendanceController->attendanceSetVisible($attendance_id);
} else {
case 'attendance_delete_select':
case 'attendance_delete':
if (!$allowToEdit) {
api_not_allowed(true);
}
break;
/*case 'attendance_restore':
if ($allowToEdit) {
$attendanceController->attendance_restore($attendance_id);
if (isset($_POST['id']) && is_array($_POST['id'])) {
foreach ($_POST['id'] as $id) {
$attendanceEntity = $repo->find($id);
$attendance->attendance_delete($attendanceEntity);
}
} else {
api_not_allowed(true);
$attendance->attendance_delete($attendanceEntity);
}
break;*/
case 'attendance_sheet_list':
$attendanceController->attendance_sheet(
$action,
$attendance_id,
$student_id,
true
);
Display::addFlash(Display::return_message(get_lang('Deleted')));
header('Location: '.$currentUrl);
exit;
break;
case 'attendance_sheet_list_no_edit':
$attendanceController->attendance_sheet(
$action,
$attendance_id,
$student_id,
false
);
case 'attendance_sheet_list':
$edit = true;
if ('attendance_sheet_list_no_edit' === $action) {
$edit = false;
}
$groupId = isset($_REQUEST['group_id']) ? $_REQUEST['group_id'] : null;
$users_in_course = $attendance->get_users_rel_course($attendanceId, $groupId);
$filter_type = 'today';
if (!empty($_REQUEST['filter'])) {
$filter_type = $_REQUEST['filter'];
}
if ('POST' === strtoupper($_SERVER['REQUEST_METHOD'])) {
$my_calendar_id = null;
if (is_numeric($filter_type)) {
$my_calendar_id = $filter_type;
$filter_type = 'calendar_id';
}
$attendant_calendar = $attendance->get_attendance_calendar(
$attendanceId,
$filter_type,
$my_calendar_id,
$groupId
);
$attendant_calendar_all = $attendance->get_attendance_calendar(
$attendanceId,
'all',
null,
$groupId
);
$users_presence = $attendance->get_users_attendance_sheet($attendanceId, 0, $groupId);
$next_attendance_calendar_id = $attendance->get_next_attendance_calendar_id($attendanceId);
$next_attendance_calendar_datetime = $attendance->getNextAttendanceCalendarDatetime($attendanceId);
}
$content = $attendance->getCalendarSheet($edit, $attendanceId, $student_id);
$tpl->assign('table', $content);
$content = $tpl->fetch('@ChamiloTheme/Attendance/sheet.html.twig');
break;
case 'attendance_sheet_export_to_pdf':
$attendanceController->attendance_sheet_export_to_pdf(
$action,
$attendance_id,
$attendance->attendance_sheet_export_to_pdf(
$attendanceId,
$student_id,
$course_id
api_get_course_id()
);
break;
case 'attendance_sheet_add':
if ($allowToEdit) {
$attendanceController->attendance_sheet($action, $attendance_id);
} else {
if (!$allowToEdit) {
api_not_allowed(true);
}
if (isset($_POST['hidden_input'])) {
foreach ($_POST['hidden_input'] as $cal_id) {
$users_present = [];
if (isset($_POST['check_presence'][$cal_id])) {
$users_present = $_POST['check_presence'][$cal_id];
}
$attendance->attendance_sheet_add(
$cal_id,
$users_present,
$attendanceId
);
}
}
Display::addFlash(Display::return_message(get_lang('Updated')));
header('Location: '.$currentUrl.'&action=attendance_sheet_list&attendance_id='.$attendanceId);
exit;
break;
case 'lock_attendance':
case 'unlock_attendance':
if ($allowToEdit) {
$attendanceController->lock_attendance($action, $attendance_id);
} else {
if (!$allowToEdit) {
api_not_allowed(true);
}
if ('lock_attendance' === $action) {
$attendance->lock($attendanceEntity);
} else {
$attendance->lock($attendanceEntity, false);
}
Display::addFlash(Display::return_message(get_lang('Updated')));
header('Location: '.$currentUrl);
exit;
break;
case 'calendar_add':
$groupList = isset($_POST['groups']) ? [$_POST['groups']] : [];
$interbreadcrumb[] = [
'url' => 'index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendanceId,
'name' => $attendanceEntity->getName(),
];
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Add a date and time')];
if (!$allowToEdit) {
api_not_allowed(true);
}
if ('POST' === strtoupper($_SERVER['REQUEST_METHOD'])) {
if (!isset($_POST['cancel'])) {
if (isset($_POST['repeat'])) {
//@todo check this error_logs
$start_datetime = api_strtotime(
api_get_utc_datetime($_POST['date_time']),
'UTC'
);
$end_datetime = api_strtotime(api_get_utc_datetime($_POST['end_date_time'].' 23:59:59'), 'UTC');
$checkdate = api_is_valid_date(api_get_utc_datetime($_POST['end_date_time'].' 23:59:59'));
$repeat_type = $_POST['repeat_type'];
if (($end_datetime > $start_datetime) && $checkdate) {
$attendance->attendance_repeat_calendar_add(
$attendanceEntity,
$start_datetime,
$end_datetime,
$repeat_type,
$groupList
);
$action = 'calendar_list';
} else {
if (!$checkdate) {
$data['error_checkdate'] = true;
} else {
$data['error_repeat_date'] = true;
}
$data['repeat'] = true;
$action = 'calendar_add';
}
} else {
$datetime = $_POST['date_time'];
$datetimezone = api_get_utc_datetime($datetime);
if (!empty($datetime)) {
$attendance->set_date_time($datetimezone);
$attendance->attendance_calendar_add($attendanceEntity, $groupList);
}
}
}
header('Location: '.$currentUrl.'&action=attendance_sheet_list&attendance_id='.$attendanceId);
exit;
} else {
$groupList = GroupManager::get_group_list(null, null, 1);
$groupIdList = ['--'];
foreach ($groupList as $group) {
$groupIdList[$group['id']] = $group['name'];
}
// calendar add form
$form = new FormValidator(
'attendance_calendar_add',
'POST',
'index.php?action=calendar_add&attendance_id='.$attendanceId.'&'.api_get_cidreq(),
''
);
$form->addElement('header', get_lang('Add a date time'));
$form->addDateTimePicker(
'date_time',
[get_lang('Start Date')],
['id' => 'date_time']
);
$defaults['date_time'] = date('Y-m-d H:i', api_strtotime(api_get_local_time()));
$form->addElement(
'checkbox',
'repeat',
null,
get_lang('Repeat date'),
[
'onclick' => "javascript: if(this.checked){document.getElementById('repeat-date-attendance').style.display='block';}else{document.getElementById('repeat-date-attendance').style.display='none';}",
]
);
$defaults['repeat'] = isset($repeat) ? $repeat : null;
if ($defaults['repeat']) {
$form->addElement('html', '<div id="repeat-date-attendance" style="display:block">');
} else {
$form->addElement('html', '<div id="repeat-date-attendance" style="display:none">');
}
$a_repeat_type = [
'daily' => get_lang('Daily'),
'weekly' => get_lang('Weekly'),
'monthlyByDate' => get_lang('Monthly, by date'),
];
$form->addElement('select', 'repeat_type', get_lang('Repeat type'), $a_repeat_type);
$form->addElement(
'date_picker',
'end_date_time',
get_lang('Repeat end date'),
['form_name' => 'attendance_calendar_add']
);
$defaults['end_date_time'] = date('Y-m-d');
$form->addElement('html', '</div>');
$defaults['repeat_type'] = 'weekly';
$form->addSelect('groups', get_lang('Group'), $groupIdList);
$form->addButtonCreate(get_lang('Save'));
$form->setDefaults($defaults);
$content = $form->returnForm();
}
break;
case 'calendar_edit':
if (!$allowToEdit) {
api_not_allowed(true);
}
if ('POST' === strtoupper($_SERVER['REQUEST_METHOD'])) {
if (!isset($_POST['cancel'])) {
$attendance->set_date_time(api_get_utc_datetime($_POST['date_time']));
$attendance->attendance_calendar_edit($calendarId, $attendanceEntity);
Display::addFlash(Display::return_message(get_lang('Updated')));
}
header('Location: '.$currentUrl.'&action=calendar_list&attendance_id='.$attendanceId);
exit;
} else {
// calendar edit form
$content .= '<div class="attendance-calendar-edit">';
$form = new FormValidator(
'attendance_calendar_edit',
'POST',
'index.php?action=calendar_edit&attendance_id='.$attendanceId.'&calendar_id='.$calendarId.'&'.api_get_cidreq(),
''
);
$form->addDateTimePicker(
'date_time',
[get_lang('Date')],
['form_name' => 'attendance_calendar_edit'],
5
);
$defaults['date_time'] = $calendarEntity->getDateTime()->format('Y-m-d H:i:s');
$form->addButtonSave(get_lang('Save'));
$form->addButtonCancel(get_lang('Cancel'), 'cancel');
$form->setDefaults($defaults);
$content .= $form->returnForm();
$content .= '</div>';
}
break;
case 'calendar_all_delete':
if (!$allowToEdit) {
api_not_allowed(true);
}
$attendance->attendance_calendar_delete(0, $attendanceId, true);
Display::addFlash(Display::return_message(get_lang('Deleted')));
header('Location: '.$currentUrl.'&action=calendar_list&attendance_id='.$attendanceId);
exit;
break;
case 'calendar_delete':
if (!$allowToEdit) {
api_not_allowed(true);
}
$attendance->attendance_calendar_delete($calendarId, $attendanceId);
Display::addFlash(Display::return_message(get_lang('Deleted')));
header('Location: '.$currentUrl.'&action=calendar_list&attendance_id='.$attendanceId);
exit;
break;
//no break
case 'calendar_list':
$attendanceController->attendance_calendar(
$action,
$attendance_id,
$calendar_id
$groupList = isset($_POST['groups']) ? [$_POST['groups']] : [];
$attendance_calendar = $attendance->get_attendance_calendar(
$attendanceId,
'all',
null,
null,
true
);
$is_locked_attendance = $attendance->is_locked_attendance($attendanceId);
if (!$is_locked_attendance || api_is_platform_admin()) {
$content .= '<div class="actions">';
if ('calendar_add' == $action) {
$content .= '<a href="index.php?'.api_get_cidreq().'&action=calendar_list&attendance_id='.$attendanceId.'">'.
Display::return_icon('back.png', get_lang('Attendance calendar'), '', ICON_SIZE_MEDIUM).'</a>';
} else {
$content .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendanceId.'">'.
Display::return_icon('back.png', get_lang('Attendance sheet'), '', ICON_SIZE_MEDIUM).'</a>';
if (api_is_allowed_to_edit()) {
$content .= '<a href="index.php?'.api_get_cidreq().'&action=calendar_add&attendance_id='.$attendanceId.'">'.
Display::return_icon('add.png', get_lang('Add a date and time'), '', ICON_SIZE_MEDIUM).'</a>';
$content .= '<a onclick="javascript:if(!confirm(\''.get_lang('Are you sure you want to delete all dates?').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=calendar_all_delete&attendance_id='.$attendanceId.'">'.
Display::return_icon('clean.png', get_lang('Clean the calendar of all lists'), '', ICON_SIZE_MEDIUM).'</a>';
}
}
$content .= '</div>';
}
$message_information = get_lang('The attendance calendar allows you to register attendance lists (one per real session the students need to attend). Add new attendance lists here.');
if (!empty($message_information)) {
$message = '<strong>'.get_lang('Information').'</strong><br />';
$message .= $message_information;
$content .= Display::return_message($message, 'normal', false);
}
if (isset($error_repeat_date) && $error_repeat_date) {
$message = get_lang('End date must be more than the start date');
$content .= Display::return_message($message, 'error', false);
}
if (isset($error_checkdate) && $error_checkdate) {
$message = get_lang('Invalid date');
$content .= Display::return_message($message, 'error', false);
}
// Calendar list
$groupList = GroupManager::get_group_list();
$groupIdList = ['--'];
foreach ($groupList as $group) {
$groupIdList[$group['id']] = $group['name'];
}
$content .= Display::page_subheader(get_lang('Calendar list of attendances'));
$content .= '<ul class="list-group">';
if (!empty($attendance_calendar)) {
foreach ($attendance_calendar as $calendar) {
$content .= '<li class="list-group-item">';
$content .= Display::return_icon(
'lp_calendar_event.png',
get_lang('Date DateTime time'),
null,
ICON_SIZE_MEDIUM
).' '.
substr(
$calendar['date_time'],
0,
strlen($calendar['date_time']) - 3
).
'&nbsp;';
if (isset($calendar['groups']) && !empty($calendar['groups'])) {
foreach ($calendar['groups'] as $group) {
$content .= '&nbsp;'.Display::label($groupIdList[$group['group_id']]);
}
}
if (!$is_locked_attendance || api_is_platform_admin()) {
if (api_is_allowed_to_edit()) {
$content .= '<div class="pull-right">';
$content .= '<a href="index.php?'.api_get_cidreq().'&action=calendar_edit&calendar_id='.(int) ($calendar['id']).'&attendance_id='.$attendanceId.'">'.
Display::return_icon('edit.png', get_lang('Edit'), ['style' => 'vertical-align:middle'], ICON_SIZE_SMALL).'</a>&nbsp;';
$content .= '<a onclick="javascript:if(!confirm(\''.get_lang('Are you sure you want to delete').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=calendar_delete&calendar_id='.(int) ($calendar['id']).'&attendance_id='.$attendanceId.'">'.
Display::return_icon('delete.png', get_lang('Delete'), ['style' => 'vertical-align:middle'], ICON_SIZE_SMALL).'</a>';
$content .= '</div>';
}
}
$content .= '</li>';
}
/* } else {
echo Display::return_message(get_lang('There is no date/time registered yet'), 'warning');
}*/
$content .= '</ul>';
}
break;
case 'calendar_logins':
if (api_is_course_admin() || api_is_drh()) {
$attendanceController->getAttendanceBaseInLogin(false, true);
$result = $attendance->getAttendanceBaseInLogin(false, true);
$content .= '<div class="actions">';
$content .= '<a href="index.php?'.api_get_cidreq().'&action=calendar_list">'.
Display::return_icon('back.png', get_lang('AttendanceCalendar'), '', ICON_SIZE_MEDIUM).'</a>';
$content .= '</div>';
$content .= $result['form'];
$content .= $result['table'];
}
break;
default:
$attendanceController->attendance_list();
}
$tpl->assign('content', $content);
//$tpl->assign('actions', $toolbar);
$tpl->display_one_col_template();

@ -1,28 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Layout (principal view) used for structuring other views.
*
* @author Christian Fasanando <christian1827@gmail.com>
*/
// protect a course script
api_protect_course_script(true);
// Header
$tool = TOOL_ATTENDANCE;
Display::display_header('');
// Introduction section
Display::display_introduction_section($tool);
// Tracking
Event::event_access_tool($tool);
// Display
echo $content;
// Footer
Display::display_footer();

@ -56,7 +56,6 @@ $displayHeader = !empty($_REQUEST['display']) && 'no_header' === $_REQUEST['disp
$thematicId = isset($_REQUEST['thematic_id']) ? (int) $_REQUEST['thematic_id'] : null;
$thematicAdvanceId = isset($_REQUEST['thematic_advance_id']) ? (int) $_REQUEST['thematic_advance_id'] : null;
$htmlHeadXtra[] = '<script>
$(function() {
$(".thematic_advance_actions, .thematic_tools ").hide();
@ -253,8 +252,8 @@ switch ($action) {
if (isset($_POST['replace']) && $_POST['replace']) {
// Remove current thematic.
$list = $thematicManager->get_thematic_list();
foreach ($list as $i) {
$thematicManager->delete($i);
foreach ($list as $id) {
$thematicManager->delete($id);
}
}

@ -561,9 +561,8 @@ class GradebookUtils
if (Database::num_rows($res) < 1) {
return false;
}
$row = Database::fetch_array($res, 'ASSOC');
return $row;
return Database::fetch_array($res, 'ASSOC');
}
/**
@ -911,7 +910,7 @@ class GradebookUtils
$courseInfo = api_get_course_info($course_code);
$t = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql = "SELECT * FROM $t
$sql = "SELECT * FROM $t
WHERE c_id = '".$courseInfo['real_id']."' ";
if (!empty($session_id)) {
$sql .= " AND session_id = ".$session_id;
@ -1190,10 +1189,10 @@ class GradebookUtils
if (!empty($current_session)) {
$sql = "SELECT user.user_id, user.username, lastname, firstname, official_code
FROM $tbl_session_course_user as scru
FROM $tbl_session_course_user as scru
INNER JOIN $tbl_user as user
ON (scru.user_id = user.user_id)
WHERE
WHERE
scru.status = 0 AND
scru.c_id='$courseId' AND
session_id ='$current_session'
@ -1362,7 +1361,7 @@ class GradebookUtils
$tbl_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
$tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
$sql = 'UPDATE '.$table_link.'
$sql = 'UPDATE '.$table_link.'
SET weight = '."'".Database::escape_string($weight)."'".'
WHERE id = '.$linkId;
@ -1375,13 +1374,13 @@ class GradebookUtils
$rs_attendance = Database::query($sql);
if (Database::num_rows($rs_attendance) > 0) {
$row_attendance = Database::fetch_array($rs_attendance);
$sql = 'UPDATE '.$tbl_attendance.' SET
$sql = 'UPDATE '.$tbl_attendance.' SET
attendance_weight ='.api_float_val($weight).'
WHERE c_id = '.$course_id.' AND id = '.intval($row_attendance['ref_id']);
Database::query($sql);
}
// Update weight into forum thread
$sql = 'UPDATE '.$tbl_forum_thread.' SET
$sql = 'UPDATE '.$tbl_forum_thread.' SET
thread_weight = '.api_float_val($weight).'
WHERE
c_id = '.$course_id.' AND

File diff suppressed because it is too large Load Diff

@ -104,6 +104,9 @@ class CAttendance extends AbstractResource implements ResourceInterface
public function __construct()
{
$this->active = 1;
$this->attendanceQualifyMax = 0;
$this->locked = 0;
}
/**

@ -0,0 +1,78 @@
{% autoescape false %}
<script>
var original_url = '';
$("#filter_id").on('change', function() {
filter = $(this).val();
if (original_url == '') {
original_url = $("#pdf_export").attr('href');
}
new_url = original_url + "&filter=" +filter
$("#pdf_export").attr('href', new_url);
});
function UpdateTableHeaders() {
$("div.divTableWithFloatingHeader").each(function() {
var originalHeaderRow = $(".tableFloatingHeaderOriginal", this);
var floatingHeaderRow = $(".tableFloatingHeader", this);
var offset = $(this).offset();
var scrollTop = $(window).scrollTop();
if ((scrollTop > offset.top) && (scrollTop < offset.top + $(this).height())) {
floatingHeaderRow.css("visibility", "hidden");
var topbar = 0;
if ($("#topbar").length != 0) {
topbar = $("#topbar").height();
} else {
if ($(".subnav").length != 0) {
topbar = $(".subnav").height();
}
}
var top_value = Math.min(scrollTop - offset.top, $(this).height() - floatingHeaderRow.height()) + topbar;
floatingHeaderRow.css("top", top_value + "px");
// Copy cell widths from original header
$("th", floatingHeaderRow).each(function(index) {
var cellWidth = $("th", originalHeaderRow).eq(index).css('width');
$(this).css('width', cellWidth);
});
// Copy row width from whole table
floatingHeaderRow.css("width", $(this).css("width"));
floatingHeaderRow.css("visibility", "visible");
floatingHeaderRow.css("z-index", "1000");
originalHeaderRow.css("height", "64px");
} else {
floatingHeaderRow.css("visibility", "hidden");
floatingHeaderRow.css("top", "0px");
}
});
}
$(function() {
$("table.tableWithFloatingHeader").each(function() {
$(this).wrap("<div class=\"divTableWithFloatingHeader\" style=\"position:relative\"></div>");
var originalHeaderRow = $("tr:first", this)
originalHeaderRow.before(originalHeaderRow.clone());
var clonedHeaderRow = $("tr:first", this)
clonedHeaderRow.addClass("tableFloatingHeader");
clonedHeaderRow.css("position", "absolute");
clonedHeaderRow.css("top", "0px");
clonedHeaderRow.css("left", $(this).css("margin-left"));
clonedHeaderRow.css("visibility", "hidden");
originalHeaderRow.addClass("tableFloatingHeaderOriginal");
});
UpdateTableHeaders();
$(window).scroll(UpdateTableHeaders);
$(window).resize(UpdateTableHeaders);
});
</script>
{{ table }}
{% endautoescape %}
Loading…
Cancel
Save