Attendance - Improve date management and adding comments - refs BT#20363

pull/4502/head
Christian 3 years ago
parent 1635f46ab6
commit 8a0f8fdd3b
  1. 49
      main/attendance/attendance_calendar.php
  2. 88
      main/attendance/attendance_comment.inc.php
  3. 52
      main/attendance/attendance_controller.php
  4. 19
      main/attendance/attendance_sheet.php
  5. 13
      main/attendance/index.php
  6. 26
      main/inc/ajax/user_manager.ajax.php
  7. 267
      main/inc/lib/attendance.lib.php
  8. 62
      main/inc/lib/export.lib.inc.php
  9. 4
      main/inc/lib/extra_field.lib.php
  10. 6
      main/install/configuration.dist.php
  11. 1
      src/Chamilo/CoreBundle/Entity/ExtraField.php
  12. 31
      src/Chamilo/CourseBundle/Entity/CAttendanceSheet.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', '<div id="repeat-date-xdaysnumber" style="display:none">');
$form->addText('xdays_number', get_lang('NumberOfDays'));
$form->addElement('html', '</div>');
$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', '</div>');
$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 '</div>';
} 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
).
'&nbsp;';
'&nbsp;&nbsp;'.$labelDuration;
if (isset($calendar['groups']) && !empty($calendar['groups'])) {
foreach ($calendar['groups'] as $group) {

@ -0,0 +1,88 @@
<div id="comment-popup" style="display: none">
<div id="comment-area" class="well">
<textarea id="txt-comment" style="width: 100%;height: 150px;" placeholder="<?php echo get_lang('WriteAComment'); ?>"></textarea>
</div>
<span id="save-comment-controls">
<span id="comment-results"></span>
<button id="comment-popup-save" class="btn btn-primary" type="submit">
<em class="fa fa-save"></em> <?php echo get_lang('Save'); ?>
</button>
<button id="comment-popup-close" class="btn btn-default" type="submit">
<em class="fa fa-eraser"></em> <?php echo get_lang('Close'); ?>
</button>
</span>
<span class="loading" style="display: none"><em class="fa fa-spinner"></em></span>
<input type="hidden" id="comment-selected" />
</div>
<script>
var urlAjax = "<?php echo api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?'.api_get_cidreq(); ?>";
var attendance_id = "<?php echo $attendance_id; ?>";
$(function() {
$("#comment-popup-save").on("click", function() {
var comment = $("#txt-comment").val();
if (comment == '') {
alert('<?php echo get_lang('ProvideACommentFirst'); ?>');
return false;
}
var selected = $("#comment-selected").val();
$.ajax({
beforeSend: function(result) {
$('#loading').show();
},
type: "POST",
url: urlAjax,
data: "a=comment_attendance&selected="+selected+"&comment="+comment+"&attendance_id="+attendance_id,
success: function(data) {
$('#loading').hide();
$('#save-comment-controls').hide();
$('#comment-area').hide();
if (1 == data) {
$('#comment-results').html('<?php echo get_lang('Saved'); ?>');
} else {
$('#comment-results').html('<?php echo get_lang('Error'); ?>');
}
$("#comment-popup-close").click();
},
});
});
$("#comment-popup-close").on("click", function() {
$("#comment-popup").dialog("close");
$('#loading').hide();
$('#save-comment-controls').show();
$('#comment-area').show();
$("#txt-comment").val('');
});
$(".attendance-comment").on("click", function() {
var selected = $(this).attr("id");
$("#comment-selected").val(selected);
$("#comment-popup").dialog({
autoOpen: true,
width: 500,
height: 'auto'
});
$("#comment-results").hide();
$("#save-comment-controls").show();
$('#comment-area').show();
var comment = getComment(selected);
$("#txt-comment").val(comment);
});
function getComment(selected) {
var response = $.ajax({
data: "a=get_attendance_comment&selected="+selected,
url: urlAjax,
async: false,
success: function (comment) {
response = comment;
},
type: 'post'
});
return response.responseText;
}
});
</script>

@ -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'];

@ -114,6 +114,8 @@ if (api_is_allowed_to_edit(null, true) ||
Display::return_icon('attendance_calendar.png', get_lang('AttendanceCalendar'), '', 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('ExportToPDF'), '', ICON_SIZE_MEDIUM).'</a>';
$actionsLeft .= '<a id="pdf_export" style="float:left;" href="index.php?'.api_get_cidreq().'&action=attendance_sheet_export_to_xls&attendance_id='.$attendance_id.'&filter='.$default_filter.'&group_id='.$groupId.'">'.
Display::return_icon('export_excel.png', get_lang('ExportToXLS'), '', ICON_SIZE_MEDIUM).'</a>';
$actionsLeft .= '<a style="float:left;" title="QR" href="index.php?'.api_get_cidreq().'&action=attendance_sheet_qrcode&attendance_id='.$attendance_id.'&filter='.$default_filter.'&group_id='.$groupId.'">'.
Display::return_icon('paint.png', get_lang('DownloadQr'), '', ICON_SIZE_MEDIUM).'</a>';
$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 = '<div class="grey">'.$date.' - '.$time.'</div>';
$duration = !empty($calendar['duration']) ? get_lang('Duration').' : '.$calendar['duration'] : '';
$datetime = '<div class="grey">'.$date.' - '.$time.' '.$duration.'</div>';
$img_lock = Display::return_icon(
'lock-closed.png',
@ -394,12 +397,20 @@ if (api_is_allowed_to_edit(null, true) ||
echo '<td style="'.$style_td.'" class="checkboxes_col_'.$calendar['id'].'">';
echo '<div class="check">';
$commentBtnIcon = '';
if ($allowComment) {
$commentBtnIcon = '&nbsp;&nbsp;<a id="comment-'.$user['user_id'].'-'.$calendar['id'].'" title="'.get_lang('Comment').'" class="attendance-comment" href="javascript:void(0)">
<em class="fa fa-commenting-o" style="font-size: 24px;"></em>
</a>';
}
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 '<input type="hidden" name="check_presence['.$calendar['id'].'][]" value="'.$user['user_id'].'" />';
echo $commentBtnIcon;
echo '<div class="list-data">
<span class="item"></span>
<a id="sign-'.$user['user_id'].'-'.$calendar['id'].'" class="btn btn-primary attendance-sign-view" href="javascript:void(0)">
@ -409,6 +420,7 @@ if (api_is_allowed_to_edit(null, true) ||
} else {
echo '<input type="checkbox" name="check_presence['.$calendar['id'].'][]" value="'.$user['user_id'].'" '.$disabled.' '.$checked.' />';
echo '<span class="anchor_'.$calendar['id'].'"></span>';
echo $commentBtnIcon;
echo '<div class="list-data">
<span class="item"></span>
<a id="sign-'.$user['user_id'].'-'.$calendar['id'].'" class="btn btn-primary attendance-sign" href="javascript:void(0)">
@ -419,6 +431,7 @@ if (api_is_allowed_to_edit(null, true) ||
} else {
echo '<input type="checkbox" name="check_presence['.$calendar['id'].'][]" value="'.$user['user_id'].'" '.$disabled.' '.$checked.' />';
echo '<span class="anchor_'.$calendar['id'].'"></span>';
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';
}

@ -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) {

@ -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();

@ -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':
$seconds = 2419200;
break;
case 'xdays':
$seconds = isset($extraValues['xdays_number']) ? (int) $extraValues['xdays_number'] * 86400 : 0;
break;
}
if ($seconds > 0) {
$j = 1;
//@todo fix bug with february
for ($i = $start_date + 2419200; ($i <= $end_date); $i += 2419200) {
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);
$this->attendance_calendar_add($attendanceId, $groupList, $extraValues);
$j++;
}
break;
}
}
/**
* 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 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.
*

@ -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).
*

@ -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')) {

@ -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

@ -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

@ -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;
}
}

Loading…
Cancel
Save