Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
chamilo-lms/main/mySpace/student_follow_export.php

575 lines
19 KiB

<?php
/* For licensing terms, see /license.txt */
use Chamilo\CourseBundle\Entity\CLpCategory;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
require_once __DIR__.'/../inc/global.inc.php';
require_once '../work/work.lib.php';
api_block_anonymous_users(false);
$allowedToTrackUser = api_is_platform_admin(true, true) ||
api_is_allowed_to_edit(null, true) ||
api_is_session_admin() ||
api_is_drh() ||
api_is_student_boss() ||
api_is_course_admin() ||
api_is_teacher();
if (!$allowedToTrackUser) {
api_not_allowed();
}
$httpRequest = HttpRequest::createFromGlobals();
$studentInfo = api_get_user_info($httpRequest->query->getInt('student'));
if (empty($studentInfo)) {
api_not_allowed();
}
function getCoursesInSession(int $studentId): array
{
$coursesInSessions = [];
$courseRelUser = Database::select(
'c_id',
Database::get_main_table(TABLE_MAIN_COURSE_USER),
[
'where' => [
'relation_type <> ? AND user_id = ?' => [COURSE_RELATION_TYPE_RRHH, $studentId],
],
]
);
$sessionRelCourseRelUser = Database::select(
['session_id', 'c_id'],
Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER),
[
'where' => [
'user_id = ?' => $studentId,
],
]
);
foreach ($courseRelUser as $row) {
$coursesInSessions[0][] = $row['c_id'];
}
foreach ($sessionRelCourseRelUser as $row) {
$coursesInSessions[$row['session_id']][] = $row['c_id'];
}
return $coursesInSessions;
}
function generateForm(int $studentId, array $coursesInSessions): FormValidator
{
$form = new FormValidator(
'frm_export',
'post',
api_get_self()."?student=$studentId",
'',
[],
FormValidator::LAYOUT_BOX
);
// Options to hide columns or blocks in export pdf
$hideOptionsExport['connection_time'] = get_lang('HideConnectionTime');
$hideOptionsExport['skills'] = get_lang('HideSkills');
$hideOptionsExport['assignment'] = get_lang('HideAssignment');
$form->addCheckBoxGroup("hide_options", get_lang('OptionsToHideInExport'), $hideOptionsExport);
foreach ($coursesInSessions as $sId => $courses) {
if (empty($courses)) {
continue;
}
if ($sId) {
$sessionInfo = api_get_session_info($sId);
$dateSession = empty($sessionInfo['duration'])
? '('.SessionManager::parseSessionDates($sessionInfo, true)['display'].')'
: '';
$fieldTitle = $sessionInfo['name'].PHP_EOL.Display::tag('small', $dateSession);
} else {
$fieldTitle = get_lang('Courses');
}
$options = [];
foreach ($courses as $courseId) {
$courseInfoItem = api_get_course_info_by_id($courseId);
if (empty($sessionInfo)) {
$isSubscribed = CourseManager::is_user_subscribed_in_course(
$studentId,
$courseInfoItem['code']
);
} else {
$isSubscribed = CourseManager::is_user_subscribed_in_course(
$studentId,
$courseInfoItem['code'],
true,
$sId
);
}
if (!$isSubscribed) {
continue;
}
$options[$sId.'_'.$courseId] = $courseInfoItem['title'];
}
$form->addCheckBoxGroup("sc", $fieldTitle, $options, ['checked' => 'checked']);
}
$form->addButtonExport(get_lang('ExportToPDF'));
return $form;
}
function generateHtmlForLearningPaths(int $studentId, array $courseInfo, int $sessionId, bool $hideConnectionTime = false): string
{
$student = api_get_user_entity($studentId);
$showTime = ($hideConnectionTime === false);
$html = '';
$columnHeaders = [];
$columnHeaders['lp'] = get_lang('LearningPath');
if ($showTime) {
$columnHeaders['time'] = get_lang('Time');
}
$columnHeaders['best_score'] = get_lang('BestScore');
$columnHeaders['latest_attempt_avg_score'] = get_lang('LatestAttemptAverageScore');
$columnHeaders['progress'] = get_lang('Progress');
$columnHeaders['last_connection'] = get_lang('LastConnexion');
$trackingColumns = api_get_configuration_value('tracking_columns');
if (isset($trackingColumns['my_students_lp'])) {
foreach ($columnHeaders as $key => $value) {
if (!isset($trackingColumns['my_progress_lp'][$key]) || $trackingColumns['my_students_lp'][$key] == false) {
unset($columnHeaders[$key]);
}
}
}
if (true === api_get_configuration_value('student_follow_page_add_LP_subscription_info')) {
$columnHeaders['student_follow_page_add_LP_subscription_info'] = get_lang('Unlock');
}
if (true === api_get_configuration_value('student_follow_page_add_LP_acquisition_info')) {
$columnHeaders['student_follow_page_add_LP_acquisition_info'] = get_lang('Acquisition');
}
$columnHeadersKeys = array_keys($columnHeaders);
$hideInvisibleViews = api_get_configuration_value('student_follow_page_add_LP_invisible_checkbox');
$includeNotsubscribedLp = api_get_configuration_value('student_follow_page_include_not_subscribed_lp_students');
$timeCourse = Tracking::minimumTimeAvailable($sessionId, $courseInfo['real_id'])
? Tracking::getCalculateTime($student->getId(), $courseInfo['real_id'], $sessionId)
: null;
$lpCategories = learnpath::getCategories($courseInfo['real_id'], true);
/** @var CLpCategory $item */
foreach ($lpCategories as $item) {
$categoryId = $item->getId();
if (!learnpath::categoryIsVisibleForStudent($item, $student, $courseInfo['real_id'], $sessionId)) {
continue;
}
$lpList = new LearnpathList(
$student->getId(),
$courseInfo,
$sessionId,
null,
false,
$categoryId,
false,
false,
$includeNotsubscribedLp === true
);
$flatList = $lpList->get_flat_list();
$lpTable = [];
foreach ($flatList as $learnpath) {
$lpId = $learnpath['lp_old_id'];
if ($hideInvisibleViews
&& !StudentFollowPage::isViewVisible($lpId, $student->getId(), $courseInfo['real_id'], $sessionId)
) {
continue;
}
$contentToExport = [];
if (in_array('lp', $columnHeadersKeys)) {
$contentToExport[] = api_html_entity_decode(stripslashes($learnpath['lp_name']), ENT_QUOTES);
}
if (in_array('time', $columnHeadersKeys) && $showTime) {
// Get time in lp
if (!empty($timeCourse)) {
$lpTime = $timeCourse[TOOL_LEARNPATH] ?? 0;
$totalTime = isset($lpTime[$lpId]) ? (int) $lpTime[$lpId] : 0;
} else {
$totalTime = Tracking::get_time_spent_in_lp(
$student->getId(),
$courseInfo['code'],
[$lpId],
$sessionId
);
}
$contentToExport[] = api_time_to_hms($totalTime);
}
if (in_array('best_score', $columnHeadersKeys)) {
$bestScore = Tracking::get_avg_student_score(
$student->getId(),
$courseInfo['code'],
[$lpId],
$sessionId,
false,
false,
true
);
$contentToExport[] = empty($bestScore) ? '' : "$bestScore %";
}
if (in_array('latest_attempt_avg_score', $columnHeadersKeys)) {
$scoreLatest = Tracking::get_avg_student_score(
$student->getId(),
$courseInfo['code'],
[$lpId],
$sessionId,
false,
true
);
if (isset($scoreLatest) && is_numeric($scoreLatest)) {
$scoreLatest = "$scoreLatest %";
}
$contentToExport[] = $scoreLatest;
}
if (in_array('progress', $columnHeadersKeys)) {
$progress = Tracking::get_avg_student_progress(
$student->getId(),
$courseInfo['code'],
[$lpId],
$sessionId
);
$contentToExport[] = is_numeric($progress) ? "$progress %" : '0 %';
}
if (in_array('last_connection', $columnHeadersKeys)) {
// Get last connection time in lp
$startTime = Tracking::get_last_connection_time_in_lp(
$student->getId(),
$courseInfo['code'],
$lpId,
$sessionId
);
$contentToExport[] = empty($startTime)
? '-'
: api_convert_and_format_date($startTime, DATE_TIME_FORMAT_LONG);
}
if (in_array('student_follow_page_add_LP_subscription_info', $columnHeadersKeys)) {
$lpSubscription = StudentFollowPage::getLpSubscription(
$learnpath,
$student->getId(),
$courseInfo['real_id'],
$sessionId
);
$contentToExport[] = strip_tags(str_replace('<br>', "\n", $lpSubscription));
}
if (in_array('student_follow_page_add_LP_acquisition_info', $columnHeadersKeys)) {
$lpAcquisition = StudentFollowPage::getLpAcquisition(
$learnpath,
$student->getId(),
$courseInfo['real_id'],
$sessionId
);
$contentToExport[] = strip_tags(str_replace('<br>', "\n", $lpAcquisition));
}
$lpTable[] = $contentToExport;
}
if (empty($lpTable)) {
continue;
}
if (count($lpCategories) > 1) {
$html .= Display::page_subheader3($item->getName());
}
array_unshift($lpTable, [$columnHeaders]);
$html .= Export::convert_array_to_html($lpTable);
}
if (!empty($html)) {
$html = Display::page_subheader2(get_lang('ToolLearnpath')).PHP_EOL.$html;
}
return $html;
}
function generateHtmlForQuizzes(int $studentId, array $courseInfo, int $sessionId): string
{
$html = Display::page_subheader2(get_lang('ToolQuiz'));
$columnHeaders = [];
$columnHeaders[] = get_lang('Exercises');
$columnHeaders[] = get_lang('LearningPath');
$columnHeaders[] = get_lang('AvgCourseScore');
$columnHeaders[] = get_lang('Attempts');
$taskTable = [$columnHeaders];
$tblQuiz = Database::get_course_table(TABLE_QUIZ_TEST);
$sessionCondition = api_get_session_condition($sessionId, true, true, 'quiz.session_id');
$sql = "SELECT quiz.title, iid
FROM $tblQuiz AS quiz
WHERE
quiz.c_id = ".$courseInfo['real_id']."
AND active IN (0, 1)
$sessionCondition
ORDER BY quiz.title ASC";
$resultExercices = Database::query($sql);
if (Database::num_rows($resultExercices) > 0) {
while ($exercices = Database::fetch_array($resultExercices)) {
$exerciseId = (int) $exercices['iid'];
$countAttempts = Tracking::count_student_exercise_attempts(
$studentId,
$courseInfo['real_id'],
$exerciseId,
0,
0,
$sessionId,
2
);
$scorePercentage = Tracking::get_avg_student_exercise_score(
$studentId,
$courseInfo['code'],
$exerciseId,
$sessionId
);
$lpName = '-';
if (!isset($scorePercentage) && $countAttempts > 0) {
$lpScores = Tracking::get_avg_student_exercise_score(
$studentId,
$courseInfo['code'],
$exerciseId,
$sessionId,
2,
1
);
$scorePercentage = $lpScores[0];
$lpName = $lpScores[1];
}
$lpName = !empty($lpName) ? $lpName : get_lang('NoLearnpath');
$contentToExport = [];
$contentToExport[] = Exercise::get_formated_title_variable($exercices['title']);
$contentToExport[] = empty($lpName) ? '-' : $lpName;
$contentToExport[] = $countAttempts > 0 ? sprintf(get_lang('XPercent'), $scorePercentage) : '-';
$contentToExport[] = $countAttempts;
$taskTable[] = $contentToExport;
}
$html .= Export::convert_array_to_html($taskTable);
}
return $html;
}
function generateHtmlForTasks(int $studentId, array $courseInfo, int $sessionId): string
{
$columnHeaders = [];
$columnHeaders[] = get_lang('Tasks');
$columnHeaders[] = get_lang('DocumentNumber');
$columnHeaders[] = get_lang('Note');
$columnHeaders[] = get_lang('HandedOut');
$columnHeaders[] = get_lang('HandOutDateLimit');
$columnHeaders[] = get_lang('ConsideredWorkingTime');
$workingTime = api_get_configuration_value('considered_working_time');
$userWorks = getWorkPerUser($studentId, $courseInfo['real_id'], $sessionId);
$taskTable = [$columnHeaders];
foreach ($userWorks as $work) {
$work = $work['work'];
foreach ($work->user_results as $key => $results) {
$documentNumber = $key + 1;
$contentToExport = [];
$contentToExport[] = $work->title;
$contentToExport[] = $documentNumber;
$contentToExport[] = !empty($results['qualification']) ? $results['qualification'] : '-';
$contentToExport[] = api_convert_and_format_date($results['sent_date_from_db']).PHP_EOL
.$results['expiry_note'];
$assignment = get_work_assignment_by_id($work->id, $courseInfo['real_id']);
if (!empty($assignment['expires_on'])) {
$contentToExport[] = api_convert_and_format_date($assignment['expires_on']);
}
$fieldValue = new ExtraFieldValue('work');
$resultExtra = $fieldValue->getAllValuesForAnItem($work->iid, true);
foreach ($resultExtra as $field) {
$field = $field['value'];
if ($workingTime == $field->getField()->getVariable()) {
$time = $field->getValue();
$contentToExport[] = $time;
}
}
$taskTable[] = $contentToExport;
}
}
return Display::page_subheader2(get_lang('ToolStudentPublication')).PHP_EOL
.Export::convert_array_to_html($taskTable);
}
function generateHtmlForCourse(int $studentId, array $coursesInSessions, int $courseId, int $sessionId, bool $hideConnectionTime = false, bool $hideAssignment = false): ?string
{
if (empty($coursesInSessions[$sessionId]) || !in_array($courseId, $coursesInSessions[$sessionId])) {
return null;
}
$courseInfo = api_get_course_info_by_id($courseId);
$courseHtml = [];
if ($sessionId) {
$sessionInfo = api_get_session_info($sessionId);
$dateSession = empty($sessionInfo['duration'])
? '('.SessionManager::parseSessionDates($sessionInfo, true)['display'].')'
: '';
$courseHtml[] = Display::page_header($sessionInfo['name'].PHP_EOL.Display::tag('small', $dateSession))
.Display::page_subheader($courseInfo['title']);
} else {
$courseHtml[] = Display::page_header($courseInfo['title']);
}
$courseHtml[] = generateHtmlForLearningPaths($studentId, $courseInfo, $sessionId, $hideConnectionTime);
$courseHtml[] = generateHtmlForQuizzes($studentId, $courseInfo, $sessionId);
if (!$hideAssignment) {
$courseHtml[] = generateHtmlForTasks($studentId, $courseInfo, $sessionId);
}
return implode(PHP_EOL, $courseHtml);
}
$coursesInSessions = getCoursesInSession($studentInfo['id']);
$form = generateForm($studentInfo['id'], $coursesInSessions);
if ($form->validate()) {
$values = $form->exportValues();
$studentInfo['status'] = api_get_status_langvars()[$studentInfo['status']];
$studentInfo['official_code'] = empty($studentInfo['official_code']) ? get_lang('NoOfficialCode')
: $studentInfo['code'];
$studentInfo['phone'] = empty($studentInfo['phone']) ? get_lang('NoTel') : $studentInfo['phone'];
$studentInfo['first_login'] = Tracking::get_first_connection_date($studentInfo['id']) ?? get_lang('NoConnexion');
$studentInfo['last_login'] = Tracking::get_last_connection_date($studentInfo['id'], true)
?? get_lang('NoConnexion');
$studentInfo['last_course_connection'] = api_format_date(
Tracking::getLastConnectionInAnyCourse($studentInfo['id']),
DATE_FORMAT_SHORT
);
$coursesInfo = [];
$hideConnectionTime = isset($values['hide_options']['connection_time']);
$hideSkills = isset($values['hide_options']['skills']);
$hideAssignment = isset($values['hide_options']['assignment']);
if (!empty($values['sc'])) {
foreach ($values['sc'] as $courseKey) {
[$sessionId, $courseId] = explode('_', $courseKey);
$coursesInfo[] = generateHtmlForCourse($studentInfo['id'], $coursesInSessions, $courseId, $sessionId, $hideConnectionTime, $hideAssignment);
}
}
$skills = Tracking::displayUserSkills($studentInfo['id']);
if ($hideSkills) {
$skills = '';
}
$view = new Template('', false, false, false, true, false, false);
$view->assign('user_info', $studentInfo);
$view->assign('careers', MyStudents::userCareersTable($studentInfo['id']));
$view->assign('skills', $skills);
$view->assign('classes', MyStudents::getBlockForClasses($studentInfo['id']));
$view->assign('courses_info', $coursesInfo);
$template = $view->get_template('my_space/student_follow_pdf.tpl');
$filename = $studentInfo['firstname'].' '.$studentInfo['lastname'];
$params = [
'filename' => $filename,
'format' => 'A4',
'orientation' => 'P',
];
$css = '
.user-info { clear: both; }
.user-info__col { float: left; width: 33.33%; }
';
$pdf = new PDF($params['format'], $params['orientation'], $params);
try {
$pdf->content_to_pdf(
$view->fetch($template),
$css,
$filename,
null,
'D',
false,
null,
false,
true
);
} catch (MpdfException $e) {
echo Display::return_message(get_lang('ErrorWhileBuildingReport'), 'error');
}
exit;
}
echo Display::page_subheader($studentInfo['complete_name_with_username']);
$form->display();