upgrade
This commit is contained in:
128
main/gradebook/all_my_gradebooks.php
Normal file
128
main/gradebook/all_my_gradebooks.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
$cidReset = true;
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
if (api_get_configuration_value('show_all_my_gradebooks_page') !== true) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
// Setting the tabs
|
||||
$this_section = SECTION_COURSES;
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
var show_icon = "'.Display::returnIconPath('view_more_stats.gif').'";
|
||||
var hide_icon = "'.Display::returnIconPath('view_less_stats.gif').'";
|
||||
|
||||
$(function() {
|
||||
$("body").on("click", ".view_children", function() {
|
||||
var id = $(this).attr("data-cat-id");
|
||||
$(".hidden_"+id).removeClass("hidden");
|
||||
$(this).removeClass("view_children");
|
||||
$(this).find("img").attr("src", hide_icon);
|
||||
$(this).attr("class", "hide_children");
|
||||
});
|
||||
|
||||
$("body").on("click", ".hide_children", function(event) {
|
||||
var id = $(this).attr("data-cat-id");
|
||||
$(".hidden_"+id).addClass("hidden");
|
||||
$(this).removeClass("hide_children");
|
||||
$(this).addClass("view_children");
|
||||
$(this).find("img").attr("src", show_icon);
|
||||
});
|
||||
|
||||
for (i=0;i<$(".actions").length;i++) {
|
||||
if ($(".actions:eq("+i+")").html()=="<table border=\"0\"></table>" || $(".actions:eq("+i+")").html()=="" || $(".actions:eq("+i+")").html()==null || $(".actions:eq("+i+")").html().split("<TBODY></TBODY>").length==2) {
|
||||
$(".actions:eq("+i+")").hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>';
|
||||
|
||||
Display::display_header(get_lang('GlobalGradebook'));
|
||||
|
||||
api_block_anonymous_users();
|
||||
|
||||
$user_id = api_get_user_id();
|
||||
$userCoursesList = CourseManager::get_courses_list_by_user_id($user_id, true, false, false, [], true, true);
|
||||
|
||||
foreach ($userCoursesList as $course) {
|
||||
$course_code = $course['code'];
|
||||
$stud_id = $user_id;
|
||||
if (isset($course['session_id']) && $course['session_id'] > 0) {
|
||||
$session_id = $course['session_id'];
|
||||
} else {
|
||||
$session_id = 0;
|
||||
}
|
||||
$course_id = $course['real_id'];
|
||||
$courseInfo = api_get_course_info($course_code);
|
||||
|
||||
if (!empty($course['session_name'])) {
|
||||
$title = "<h2>".$courseInfo['title']." (".$course['session_name'].")</h2>";
|
||||
} else {
|
||||
$title = "<h2>".$courseInfo['title']."</h2>";
|
||||
}
|
||||
|
||||
$cats = Category::load(
|
||||
null,
|
||||
null,
|
||||
$course_code,
|
||||
null,
|
||||
null,
|
||||
$session_id,
|
||||
false
|
||||
);
|
||||
|
||||
$showTitle = true;
|
||||
foreach ($cats as $cat) {
|
||||
$allcat = $cat->get_subcategories($stud_id, $course_code, $session_id);
|
||||
$alleval = $cat->get_evaluations($stud_id, false, $course_code, $session_id);
|
||||
$alllink = $cat->get_links($stud_id, true, $course_code, $session_id);
|
||||
|
||||
if ($cat->get_parent_id() != 0) {
|
||||
$i++;
|
||||
} else {
|
||||
if (empty($allcat) && empty($alleval) && empty($alllink)) {
|
||||
continue;
|
||||
}
|
||||
if ($showTitle) {
|
||||
echo $title;
|
||||
$showTitle = false;
|
||||
}
|
||||
// This is the father
|
||||
// Create gradebook/add gradebook links.
|
||||
DisplayGradebook::header(
|
||||
$cat,
|
||||
0,
|
||||
$cat->get_id(),
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
[]
|
||||
);
|
||||
|
||||
$gradebookTable = new GradebookTable(
|
||||
$cat,
|
||||
$allcat,
|
||||
$alleval,
|
||||
$alllink,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
api_get_user_id(),
|
||||
[],
|
||||
[]
|
||||
);
|
||||
|
||||
$table = '';
|
||||
$table = $gradebookTable->return_table();
|
||||
echo $table;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Display::display_footer();
|
||||
330
main/gradebook/certificate_report.php
Normal file
330
main/gradebook/certificate_report.php
Normal file
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* List all certificates filtered by session/course and month/year.
|
||||
*
|
||||
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
|
||||
*/
|
||||
$cidReset = true;
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
|
||||
$is_allowedToTrack = api_is_platform_admin(true) || api_is_student_boss();
|
||||
|
||||
if (!$is_allowedToTrack) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$this_section = SECTION_TRACKING;
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
"url" => api_is_student_boss() ? "#" : api_get_path(WEB_CODE_PATH)."mySpace/index.php?".api_get_cidreq(),
|
||||
"name" => get_lang("MySpace"),
|
||||
];
|
||||
|
||||
$selectedSession = isset($_POST['session']) && !empty($_POST['session']) ? intval($_POST['session']) : 0;
|
||||
$selectedCourse = isset($_POST['course']) && !empty($_POST['course']) ? intval($_POST['course']) : 0;
|
||||
$selectedMonth = isset($_POST['month']) && !empty($_POST['month']) ? intval($_POST['month']) : 0;
|
||||
$selectedYear = isset($_POST['year']) && !empty($_POST['year']) ? trim($_POST['year']) : null;
|
||||
$selectedStudent = isset($_POST['student']) && !empty($_POST['student']) ? intval($_POST['student']) : 0;
|
||||
|
||||
$userId = api_get_user_id();
|
||||
$sessions = $courses = $months = $students = [0 => get_lang('Select')];
|
||||
$userList = [];
|
||||
if (api_is_student_boss()) {
|
||||
$userGroup = new UserGroup();
|
||||
$userList = $userGroup->getGroupUsersByUser($userId);
|
||||
$sessionsList = SessionManager::getSessionsFollowedForGroupAdmin($userId);
|
||||
} else {
|
||||
$sessionsList = SessionManager::getSessionsCoachedByUser(
|
||||
$userId,
|
||||
false,
|
||||
api_is_platform_admin()
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($sessionsList as $session) {
|
||||
$sessions[$session['id']] = $session['name'];
|
||||
}
|
||||
|
||||
if ($selectedSession > 0) {
|
||||
if (!SessionManager::isValidId($selectedSession)) {
|
||||
Display::addFlash(Display::return_message(get_lang('NoSession')));
|
||||
|
||||
header("Location: $selfUrl");
|
||||
exit;
|
||||
}
|
||||
|
||||
$coursesList = SessionManager::get_course_list_by_session_id($selectedSession);
|
||||
|
||||
if (is_array($coursesList)) {
|
||||
foreach ($coursesList as &$course) {
|
||||
$course['real_id'] = $course['id'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (api_is_student_boss()) {
|
||||
$coursesList = CourseManager::getCoursesFollowedByGroupAdmin($userId);
|
||||
} else {
|
||||
$coursesList = CourseManager::get_courses_list_by_user_id(
|
||||
$userId,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
if (is_array($coursesList)) {
|
||||
foreach ($coursesList as &$course) {
|
||||
$courseInfo = api_get_course_info_by_id($course['real_id']);
|
||||
|
||||
$course = array_merge($course, $courseInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($coursesList as $course) {
|
||||
if (isset($course['real_id'])) {
|
||||
$courses[$course['real_id']] = $course['title'];
|
||||
} else {
|
||||
$courses[$course['id']] = $course['title'];
|
||||
}
|
||||
}
|
||||
|
||||
for ($key = 1; $key <= 12; $key++) {
|
||||
$months[$key] = sprintf("%02d", $key);
|
||||
}
|
||||
|
||||
$exportAllLink = null;
|
||||
$certificateStudents = [];
|
||||
$searchSessionAndCourse = $selectedSession > 0 && $selectedCourse > 0;
|
||||
$searchCourseOnly = $selectedSession <= 0 && $selectedCourse > 0;
|
||||
$searchStudentOnly = $selectedStudent > 0;
|
||||
|
||||
if ($searchSessionAndCourse || $searchCourseOnly) {
|
||||
$selectedCourseInfo = api_get_course_info_by_id($selectedCourse);
|
||||
|
||||
if (empty($selectedCourseInfo)) {
|
||||
Display::addFlash(Display::return_message(get_lang('NoCourse')));
|
||||
|
||||
header("Location: $selfUrl");
|
||||
exit;
|
||||
}
|
||||
|
||||
$gradebookCategories = Category::load(
|
||||
null,
|
||||
null,
|
||||
$selectedCourseInfo['code'],
|
||||
null,
|
||||
false,
|
||||
$selectedSession
|
||||
);
|
||||
|
||||
$gradebook = null;
|
||||
|
||||
if (!empty($gradebookCategories)) {
|
||||
$gradebook = current($gradebookCategories);
|
||||
}
|
||||
|
||||
if (!is_null($gradebook)) {
|
||||
$exportAllLink = GradebookUtils::returnJsExportAllCertificates(
|
||||
'#btn-export-all',
|
||||
$gradebook->get_id(),
|
||||
$selectedCourseInfo['code']
|
||||
);
|
||||
|
||||
$sessionName = api_get_session_name($selectedSession);
|
||||
$courseName = api_get_course_info($selectedCourseInfo['code'])['title'];
|
||||
|
||||
$studentList = GradebookUtils::get_list_users_certificates($gradebook->get_id());
|
||||
|
||||
$certificateStudents = [];
|
||||
|
||||
if (is_array($studentList) && !empty($studentList)) {
|
||||
foreach ($studentList as $student) {
|
||||
if (api_is_student_boss() && !in_array($student['user_id'], $userList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$certificateStudent = [
|
||||
'fullName' => api_get_person_name($student['firstname'], $student['lastname']),
|
||||
'sessionName' => $sessionName,
|
||||
'courseName' => $courseName,
|
||||
'certificates' => [],
|
||||
];
|
||||
|
||||
$studentCertificates = GradebookUtils::get_list_gradebook_certificates_by_user_id(
|
||||
$student['user_id'],
|
||||
$gradebook->get_id()
|
||||
);
|
||||
|
||||
if (!is_array($studentCertificates) || empty($studentCertificates)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($studentCertificates as $certificate) {
|
||||
$creationDate = new DateTime($certificate['created_at']);
|
||||
$creationMonth = $creationDate->format('m');
|
||||
$creationYear = $creationDate->format('Y');
|
||||
$creationMonthYear = $creationDate->format('m Y');
|
||||
|
||||
if ($selectedMonth > 0 && empty($selectedYear)) {
|
||||
if ($creationMonth != $selectedMonth) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($selectedMonth <= 0 && !empty($selectedYear)) {
|
||||
if ($creationYear != $selectedYear) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($selectedMonth > 0 && !empty($selectedYear)) {
|
||||
if ($creationMonthYear != sprintf("%02d %s", $selectedMonth, $selectedYear)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$certificateStudent['certificates'][] = [
|
||||
'createdAt' => api_convert_and_format_date($certificate['created_at']),
|
||||
'id' => $certificate['id'],
|
||||
];
|
||||
}
|
||||
|
||||
if (count($certificateStudent['certificates']) > 0) {
|
||||
$certificateStudents[] = $certificateStudent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($searchStudentOnly) {
|
||||
$selectedStudentInfo = api_get_user_info($selectedStudent);
|
||||
|
||||
if (empty($selectedStudentInfo)) {
|
||||
Display::addFlash(Display::return_message(get_lang('NoUser')));
|
||||
|
||||
header('Location: '.$selfUrl);
|
||||
exit;
|
||||
}
|
||||
|
||||
$sessionList = SessionManager::getSessionsFollowedByUser($selectedStudent);
|
||||
|
||||
foreach ($sessionList as $session) {
|
||||
$sessionCourseList = SessionManager::get_course_list_by_session_id($session['id']);
|
||||
|
||||
foreach ($sessionCourseList as $sessionCourse) {
|
||||
$gradebookCategories = Category::load(
|
||||
null,
|
||||
null,
|
||||
$sessionCourse['code'],
|
||||
null,
|
||||
false,
|
||||
$session['id']
|
||||
);
|
||||
|
||||
$gradebook = null;
|
||||
|
||||
if (!empty($gradebookCategories)) {
|
||||
$gradebook = current($gradebookCategories);
|
||||
}
|
||||
|
||||
if (!is_null($gradebook)) {
|
||||
$sessionName = $session['name'];
|
||||
$courseName = $sessionCourse['title'];
|
||||
|
||||
$certificateStudent = [
|
||||
'fullName' => $selectedStudentInfo['complete_name'],
|
||||
'sessionName' => $sessionName,
|
||||
'courseName' => $courseName,
|
||||
'certificates' => [],
|
||||
];
|
||||
|
||||
$studentCertificates = GradebookUtils::get_list_gradebook_certificates_by_user_id(
|
||||
$selectedStudent,
|
||||
$gradebook->get_id()
|
||||
);
|
||||
|
||||
if (!is_array($studentCertificates) || empty($studentCertificates)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($studentCertificates as $certificate) {
|
||||
$certificateStudent['certificates'][] = [
|
||||
'createdAt' => api_convert_and_format_date($certificate['created_at']),
|
||||
'id' => $certificate['id'],
|
||||
];
|
||||
}
|
||||
|
||||
if (count($certificateStudent['certificates']) > 0) {
|
||||
$certificateStudents[] = $certificateStudent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* View */
|
||||
$template = new Template(get_lang('GradebookListOfStudentsCertificates'));
|
||||
|
||||
$form = new FormValidator(
|
||||
'certificate_report_form',
|
||||
'post',
|
||||
api_get_path(WEB_CODE_PATH).'gradebook/certificate_report.php'
|
||||
);
|
||||
$form->addSelect('session', get_lang('Sessions'), $sessions, ['id' => 'session']);
|
||||
$form->addSelect('course', get_lang('Courses'), $courses, ['id' => 'course']);
|
||||
$form->addGroup(
|
||||
[
|
||||
$form->createElement(
|
||||
'select',
|
||||
'month',
|
||||
null,
|
||||
$months,
|
||||
['id' => 'month']
|
||||
),
|
||||
$form->createElement(
|
||||
'text',
|
||||
'year',
|
||||
null,
|
||||
['id' => 'year', 'placeholder' => get_lang('Year')]
|
||||
),
|
||||
],
|
||||
null,
|
||||
get_lang('Date')
|
||||
);
|
||||
$form->addButtonSearch();
|
||||
$form->setDefaults([
|
||||
'session' => $selectedSession,
|
||||
'course' => $selectedCourse,
|
||||
'month' => $selectedMonth,
|
||||
'year' => $selectedYear,
|
||||
]);
|
||||
|
||||
if (api_is_student_boss()) {
|
||||
foreach ($userList as $studentId) {
|
||||
$students[$studentId] = api_get_user_info($studentId)['complete_name_with_username'];
|
||||
}
|
||||
|
||||
$searchForm = new FormValidator(
|
||||
'certificate_report_form',
|
||||
'post',
|
||||
api_get_path(WEB_CODE_PATH).'gradebook/certificate_report.php'
|
||||
);
|
||||
$searchForm->addSelect('student', get_lang('Students'), $students, ['id' => 'student']);
|
||||
$searchForm->addButtonSearch();
|
||||
$searchForm->setDefaults([
|
||||
'student' => $selectedStudent,
|
||||
]);
|
||||
|
||||
$template->assign('search_form', $searchForm->returnForm());
|
||||
}
|
||||
|
||||
$template->assign('search_by_session_form', $form->returnForm());
|
||||
$template->assign('sessions', $sessions);
|
||||
$template->assign('courses', $courses);
|
||||
$template->assign('months', $months);
|
||||
$template->assign('export_all_link', $exportAllLink);
|
||||
$template->assign('certificate_students', $certificateStudents);
|
||||
$templateName = $template->get_template('gradebook/certificate_report.tpl');
|
||||
$content = $template->fetch($templateName);
|
||||
$template->assign('content', $content);
|
||||
$template->display_one_col_template();
|
||||
BIN
main/gradebook/certificate_template/certificate_template.png
Normal file
BIN
main/gradebook/certificate_template/certificate_template.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
113
main/gradebook/certificate_template/template.html
Normal file
113
main/gradebook/certificate_template/template.html
Normal file
@@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html prefix="og:http://ogp.me/ns/article#">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>((course_title)) - ((user_firstname)) ((user_lastname)) - ((date_certificate_no_time))</title>
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:title" content="((course_title)) - Certificate for ((user_firstname)) ((user_lastname))" />
|
||||
<meta property="og:url" content="((certificate_link))" />
|
||||
<style>((external_style))</style>
|
||||
</head>
|
||||
<body style="background-color: #fff;">
|
||||
<div style="width: 1072px;margin-left: auto;margin-right: auto;">
|
||||
<div style="background: url('{REL_CODE_PATH}img/paper.png') repeat;padding: 10px;">
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/side-bar.png" alt="Side bar">
|
||||
</td>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/side-top-a.png" alt="Side top element a">
|
||||
</td>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/certificate-logo.png" alt="Certificate logo">
|
||||
</td>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/side-top-b.png" alt="Side top element b">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td><img src="{REL_CODE_PATH}img/side-bar-button.png" alt="Side bar button"></td>
|
||||
<td>
|
||||
<table cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td style="font-size: 18px;text-align: center;font-weight: normal;padding-bottom: .2em;">
|
||||
<h2>((gradebook_institution))</h2>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;font-weight: bold;font-size: 42px;padding-top: .5em;padding-bottom: .5em;">
|
||||
CERTIFICATE
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;font-size: 18px;padding-bottom: .5em;padding-top: .5em;">
|
||||
This certificate is granted to
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: .5em;padding-top: .5em;font-size: 35px;text-align: center;">
|
||||
((user_firstname)) ((user_lastname))
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;font-size: 18px;padding-bottom: .5em;padding-top: .5em;">
|
||||
for successfully completing the course
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-bottom: .5em;padding-top: .5em;font-size: 30px;text-align: center;">
|
||||
((course_title))
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;font-size: 18px;padding-bottom: .5em;padding-top: .5em;">
|
||||
with the expected level of mastery
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table cellpadding="0" cellspacing="0" align="center">
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/signature1.png" alt="Signature 1">
|
||||
</td>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/blank.png" alt="blank">
|
||||
</td>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/signature2.png" alt="firm02">
|
||||
</td>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/certified.png" alt="certified">
|
||||
</td>
|
||||
<td>
|
||||
<img src="{REL_CODE_PATH}img/blank.png" alt="blank">
|
||||
</td>
|
||||
<td>
|
||||
((certificate_barcode))
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
31
main/gradebook/cli/export_all_certificates.php
Normal file
31
main/gradebook/cli/export_all_certificates.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Command to export certificates for a gradebook categori in course (or course session).
|
||||
*
|
||||
* <code>php main/gradebook/cli/export_all_certificated.php COURSE_CODE SESSION_ID CATEGORY_ID [USER_IDS]</code>
|
||||
*/
|
||||
require_once __DIR__.'/../../inc/global.inc.php';
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(get_lang('NotAllowed'));
|
||||
}
|
||||
|
||||
$courseCode = $argv[1];
|
||||
$sessionId = $argv[2];
|
||||
$categoryId = $argv[3];
|
||||
$userList = isset($argv[4]) ? explode(',', $argv[4]) : [];
|
||||
|
||||
$date = api_get_utc_datetime(null, false, true);
|
||||
|
||||
$pdfName = 'certs_'.$courseCode.'_'.$sessionId.'_'.$categoryId.'_'.$date->format('Y-m-d');
|
||||
|
||||
$finalFile = api_get_path(SYS_ARCHIVE_PATH)."$pdfName.pdf";
|
||||
|
||||
if (file_exists($finalFile)) {
|
||||
unlink(api_get_path(SYS_ARCHIVE_PATH)."$pdfName.pdf");
|
||||
}
|
||||
|
||||
Category::exportAllCertificates($categoryId, $userList, $courseCode, true, $pdfName);
|
||||
38
main/gradebook/docs/example_csv.html
Normal file
38
main/gradebook/docs/example_csv.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>CSV file example</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<h1>CSV example for certificate importation</h1>
|
||||
This is an example file and this data can't be imported on your platform. The user id must correspond to users existing on your platform.<br />
|
||||
|
||||
The mandatory fields are emphasized. The other fields can be omitted. The separator is always the ";". If you want to overwrite the scores, you must choose the "Overwrite score" option.<br />
|
||||
|
||||
<h2>Complete CSV score importation file</h2>
|
||||
<b>username</b>;official_code;<b>lastname</b>;<b>firstname</b>;<b>score</b>;date<br />
|
||||
<b>bgate</b>;bgate;Gate;Bill;<b>2</b>;02/25/09 12:24 PM<br />
|
||||
<b>ltorvald</b>;ltorvald;Torvald;Linus;<b>10</b>;02/25/09 12:24 PM<br />
|
||||
<b>jsmith</b>;;<b>Smith</b>;<b>John</b>;<b>3</b>;<br />
|
||||
<br /><br />
|
||||
|
||||
|
||||
<h2>Minimal CSV score importation file</h2>
|
||||
This is possible to use a minimal file if you choose the "Ingnore error option" :
|
||||
<br /><br />
|
||||
username;score<br />
|
||||
bgate;2<br />
|
||||
ltorvald;10<br />
|
||||
jsmith;3<br />
|
||||
|
||||
<h2>Presence score importation file</h2>
|
||||
For the presence this is the same file except the score fied which is "0" for absent and "1" for present :
|
||||
<br /><br />
|
||||
<b>username</b>;official_code;<b>lastname</b>;<b>firstname</b>;<b>score</b>;date<br />
|
||||
<b>bgate</b>;bgate;Gate;Bill;<b>0</b>;02/25/09 12:24 PM<br />
|
||||
<b>ltorvald</b>;ltorvald;Torvald;Linus;<b>1</b>;02/25/09 12:24 PM<br />
|
||||
<b>jsmith</b>;;<b>Smith</b>;<b>John</b>;<b>0</b>;<br />
|
||||
|
||||
|
||||
|
||||
</BODY>
|
||||
|
||||
107
main/gradebook/docs/example_xml.html
Normal file
107
main/gradebook/docs/example_xml.html
Normal file
@@ -0,0 +1,107 @@
|
||||
<HTML>
|
||||
<head profile="http://dublincore.org/documents/dcq-html/">
|
||||
<title></title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
||||
<meta content="" name="description" />
|
||||
<meta content="" name="keywords" />
|
||||
<link href="http://purl.org/dc/elements/1.1/" rel="schema.DC" />
|
||||
<meta content="" name="DC.title" />
|
||||
<meta content="" name="DC.subject" />
|
||||
<meta content="" name="DC.description" />
|
||||
<meta content="" name="DC.creator" />
|
||||
<meta content="" name="DC.date" />
|
||||
<meta content="" name="DC.language" />
|
||||
<style media="all" type="text/css">
|
||||
body {font-family:'Times New Roman',serif;font-size:16.0px}
|
||||
p.PreformattedText {margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;border:none;padding:0;font-family:'Times New Roman';font-size:13.333334px}
|
||||
</style>
|
||||
</head>
|
||||
<BODY>
|
||||
<h1>XML example for certificate importation</h1>
|
||||
This is an example file and this data can't be imported on your platform. The user id must correspond to users existing on your platform.<br />
|
||||
|
||||
The date and offical_code fiels aren't mandatory and can be omitted without any error. If you want to overwrite the scores, you must choose the "Overwrite score" option.<br />
|
||||
|
||||
<h2>Complete XML score importation file</h2>
|
||||
<p class="PreformattedText"><?xml version="1.0" encoding="ISO-8859-1"?></p>
|
||||
<p class="PreformattedText"> <XMLResults></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>bgate</username></p>
|
||||
<p class="PreformattedText"> <official_code>bgate</official_code></p>
|
||||
<p class="PreformattedText"> <lastname>Gate</lastname></p>
|
||||
<p class="PreformattedText"> <firstname>Bill</firstname></p>
|
||||
<p class="PreformattedText"> <score>2</score></p>
|
||||
<p class="PreformattedText"> <date>2009-2-25 12:28</date></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>ltorvald</username></p>
|
||||
<p class="PreformattedText"> <official_code>ltorvald</official_code></p>
|
||||
<p class="PreformattedText"> <lastname>Torvald</lastname></p>
|
||||
<p class="PreformattedText"> <firstname>Linus</firstname></p>
|
||||
<p class="PreformattedText"> <score>10</score></p>
|
||||
<p class="PreformattedText"> <date>2009-2-25 12:28</date></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>jsmith</username></p>
|
||||
<p class="PreformattedText"> <official_code></official_code></p>
|
||||
<p class="PreformattedText"> <lastname>Smith</lastname></p>
|
||||
<p class="PreformattedText"> <firstname>John</firstname></p>
|
||||
<p class="PreformattedText"> <score>3</score></p>
|
||||
<p class="PreformattedText"> <date></date></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"></XMLResults></p>
|
||||
|
||||
<h2>Minimal XML score importation file</h2>
|
||||
This is possible to use a minimal file if you choose the "Ingnore error option" :
|
||||
<br /><br />
|
||||
<p class="PreformattedText"><?xml version="1.0" encoding="ISO-8859-1"?></p>
|
||||
<p class="PreformattedText"> <XMLResults></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>bgate</username></p>
|
||||
<p class="PreformattedText"> <score>2</score></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>ltorvald</username></p>
|
||||
<p class="PreformattedText"> <score>10</score></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>jsmith</username></p>
|
||||
<p class="PreformattedText"> <score>3</score></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"></XMLResults></p>
|
||||
|
||||
<h2>Complete XML presence importation file</h2>
|
||||
For the presence this is the same file except the score fied which is "0" for absent and "1" for present :
|
||||
<br /><br />
|
||||
<p class="PreformattedText"><?xml version="1.0" encoding="ISO-8859-1"?></p>
|
||||
<p class="PreformattedText"> <XMLResults></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>bgate</username></p>
|
||||
<p class="PreformattedText"> <official_code>bgate</official_code></p>
|
||||
<p class="PreformattedText"> <lastname>Gate</lastname></p>
|
||||
<p class="PreformattedText"> <firstname>Bill</firstname></p>
|
||||
<p class="PreformattedText"> <score>0</score></p>
|
||||
<p class="PreformattedText"> <date>2009-2-25 12:28</date></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>ltorvald</username></p>
|
||||
<p class="PreformattedText"> <official_code>ltorvald</official_code></p>
|
||||
<p class="PreformattedText"> <lastname>Torvald</lastname></p>
|
||||
<p class="PreformattedText"> <firstname>Linus</firstname></p>
|
||||
<p class="PreformattedText"> <score>1</score></p>
|
||||
<p class="PreformattedText"> <date>2009-2-25 12:28</date></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"><Result></p>
|
||||
<p class="PreformattedText"> <username>jsmith</username></p>
|
||||
<p class="PreformattedText"> <official_code></official_code></p>
|
||||
<p class="PreformattedText"> <lastname>Smith</lastname></p>
|
||||
<p class="PreformattedText"> <firstname>John</firstname></p>
|
||||
<p class="PreformattedText"> <score>0</score></p>
|
||||
<p class="PreformattedText"> <date></date></p>
|
||||
<p class="PreformattedText"> </Result></p>
|
||||
<p class="PreformattedText"></XMLResults></p>
|
||||
|
||||
<br /><br />
|
||||
You could also use a minimal XML file for the presence.
|
||||
</BODY>
|
||||
|
||||
7
main/gradebook/docs/index.html
Normal file
7
main/gradebook/docs/index.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; url=../gradebook.php">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
87
main/gradebook/exercise_jump.php
Normal file
87
main/gradebook/exercise_jump.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Sets needed course variables and then jumps to the exercises result page.
|
||||
* This intermediate page is needed because the user is not inside a course
|
||||
* when visiting the gradebook, and several course scripts rely on these
|
||||
* variables.
|
||||
* Most code here is ripped from /main/course_home/course_home.php.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
api_block_anonymous_users();
|
||||
$this_section = SECTION_COURSES;
|
||||
|
||||
$gradebook = Security::remove_XSS($_GET['gradebook']);
|
||||
$session_id = api_get_session_id();
|
||||
$cidReq = Security::remove_XSS($_GET['cidReq']);
|
||||
$type = Security::remove_XSS($_GET['type']);
|
||||
$doExerciseUrl = '';
|
||||
|
||||
// no support for hot potatoes
|
||||
if ($type == LINK_HOTPOTATOES) {
|
||||
$exerciseId = $_GET['exerciseId'];
|
||||
$path = Security::remove_XSS($_GET['path']);
|
||||
$doExerciseUrl = api_get_path(WEB_CODE_PATH).'exercise/showinframes.php?'.http_build_query(
|
||||
[
|
||||
'session_id' => $session_id,
|
||||
'cidReq' => Security::remove_XSS($cidReq),
|
||||
'file' => $path,
|
||||
'cid' => api_get_course_id(),
|
||||
'uid' => api_get_user_id(),
|
||||
]
|
||||
);
|
||||
header('Location: '.$doExerciseUrl);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!empty($doExerciseUrl)) {
|
||||
header('Location: '.$doExerciseUrl);
|
||||
exit;
|
||||
} else {
|
||||
$url = api_get_path(WEB_CODE_PATH).'exercise/overview.php?'
|
||||
.http_build_query(['session_id' => $session_id, 'cidReq' => $cidReq]);
|
||||
if (isset($_GET['gradebook'])) {
|
||||
$url .= '&gradebook=view&exerciseId='.((int) $_GET['exerciseId']);
|
||||
|
||||
// Check if exercise is inserted inside a LP, if that's the case
|
||||
$exerciseId = $_GET['exerciseId'];
|
||||
$exercise = new Exercise();
|
||||
$exercise->read($exerciseId);
|
||||
if (!empty($exercise->id)) {
|
||||
if ($exercise->exercise_was_added_in_lp) {
|
||||
if (!empty($exercise->lpList)) {
|
||||
// If the exercise was added once redirect to the LP
|
||||
$firstLp = $exercise->getLpBySession($session_id);
|
||||
if (isset($firstLp['lp_id'])) {
|
||||
$url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.api_get_cidreq().'&'
|
||||
.http_build_query(
|
||||
[
|
||||
'lp_id' => $firstLp['lp_id'],
|
||||
'action' => 'view',
|
||||
'isStudentView' => 'true',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$url = api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.http_build_query(
|
||||
[
|
||||
'session_id' => $session_id,
|
||||
'cidReq' => $cidReq,
|
||||
'gradebook' => $gradebook,
|
||||
'origin' => '',
|
||||
'learnpath_id' => '',
|
||||
'learnpath_item_id' => '',
|
||||
'exerciseId' => (int) $_GET['exerciseId'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: '.$url);
|
||||
exit;
|
||||
}
|
||||
66
main/gradebook/get_badges.php
Normal file
66
main/gradebook/get_badges.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Show the achieved badges by an user.
|
||||
*
|
||||
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
$userId = isset($_GET['user']) ? (int) $_GET['user'] : 0;
|
||||
|
||||
if (empty($userId)) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
Skill::isAllowed($userId);
|
||||
|
||||
$courseId = api_get_course_int_id();
|
||||
$sessionId = api_get_session_id();
|
||||
|
||||
$objSkillRelUser = new SkillRelUser();
|
||||
$userSkills = $objSkillRelUser->getUserSkills($userId, $courseId, $sessionId);
|
||||
|
||||
if (empty($userSkills)) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$assertions = [];
|
||||
foreach ($userSkills as $skill) {
|
||||
$skillId = current($skill);
|
||||
$assertionUrl = api_get_path(WEB_CODE_PATH).'badge/assertion.php?';
|
||||
$assertionUrl .= http_build_query([
|
||||
'user' => $userId,
|
||||
'skill' => $skillId,
|
||||
'course' => $courseId,
|
||||
'session' => $sessionId,
|
||||
]);
|
||||
|
||||
$assertions[] = $assertionUrl;
|
||||
}
|
||||
|
||||
$backpack = 'https://backpack.openbadges.org/';
|
||||
|
||||
$configBackpack = api_get_setting('openbadges_backpack');
|
||||
if (0 !== strcmp($backpack, $configBackpack)) {
|
||||
$backpack = $configBackpack;
|
||||
if (substr($backpack, -1) !== '/') {
|
||||
$backpack .= '/';
|
||||
}
|
||||
}
|
||||
|
||||
$htmlHeadXtra[] = '<script src="'.$backpack.'issuer.js"></script>';
|
||||
|
||||
$tpl = new Template(get_lang('Badges'), false, false);
|
||||
|
||||
$tpl->assign(
|
||||
'content',
|
||||
"<script>
|
||||
$(function() {
|
||||
OpenBadges.issue_no_modal(".json_encode($assertions).");
|
||||
});
|
||||
</script>"
|
||||
);
|
||||
|
||||
$tpl->display_one_col_template();
|
||||
641
main/gradebook/gradebook.php
Normal file
641
main/gradebook/gradebook.php
Normal file
@@ -0,0 +1,641 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
// $cidReset : This is the main difference with gradebook.php, here we say,
|
||||
// basically, that we are inside a course, and many things depend from that
|
||||
$cidReset = true;
|
||||
$_in_course = false;
|
||||
//make sure the destination for scripts is index.php instead of gradebook.php
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
if (!empty($_GET['course'])) {
|
||||
Category::setUrl('index.php');
|
||||
$this_section = SECTION_COURSES;
|
||||
} else {
|
||||
Category::setUrl('gradebook.php');
|
||||
$this_section = SECTION_MYGRADEBOOK;
|
||||
unset($_GET['course']);
|
||||
}
|
||||
|
||||
$selectcat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
$(function() {
|
||||
for (i=0;i<$(".actions").length;i++) {
|
||||
if ($(".actions:eq("+i+")").html()=="<table border=\"0\"></table>" || $(".actions:eq("+i+")").html()=="" || $(".actions:eq("+i+")").html()==null) {
|
||||
$(".actions:eq("+i+")").hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>';
|
||||
api_block_anonymous_users();
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
function confirmation () {
|
||||
if (confirm("'.get_lang('DeleteAll').'?")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
</script>';
|
||||
$filter_confirm_msg = true;
|
||||
$filter_warning_msg = true;
|
||||
// ACTIONS
|
||||
|
||||
//this is called when there is no data for the course admin
|
||||
if (isset($_GET['createallcategories'])) {
|
||||
GradebookUtils::block_students();
|
||||
$coursecat = Category::get_not_created_course_categories(api_get_user_id());
|
||||
if (!count($coursecat) == 0) {
|
||||
foreach ($coursecat as $row) {
|
||||
$cat = new Category();
|
||||
$cat->set_name($row[1]);
|
||||
$cat->set_course_code($row[0]);
|
||||
$cat->set_description(null);
|
||||
$cat->set_user_id(api_get_user_id());
|
||||
$cat->set_parent_id(0);
|
||||
$cat->set_weight(0);
|
||||
$cat->set_visible(0);
|
||||
$cat->add();
|
||||
unset($cat);
|
||||
}
|
||||
}
|
||||
header('Location: '.Category::getUrl().'addallcat=&selectcat=0');
|
||||
exit;
|
||||
}
|
||||
|
||||
//move a category
|
||||
if (isset($_GET['movecat'])) {
|
||||
$move_cat = (int) $_GET['movecat'];
|
||||
GradebookUtils::block_students();
|
||||
$cats = Category::load($move_cat);
|
||||
if (!isset($_GET['targetcat'])) {
|
||||
$move_form = new CatForm(
|
||||
CatForm::TYPE_MOVE,
|
||||
$cats[0],
|
||||
'move_cat_form',
|
||||
null,
|
||||
api_get_self().'?movecat='.$move_cat.'&selectcat='.$selectcat
|
||||
);
|
||||
if ($move_form->validate()) {
|
||||
header('Location: '.api_get_self().'?selectcat='.$selectcat
|
||||
.'&movecat='.$move_cat
|
||||
.'&targetcat='.$move_form->exportValue('move_cat'));
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
$get_target_cat = Security::remove_XSS($_GET['targetcat']);
|
||||
$targetcat = Category::load($get_target_cat);
|
||||
$course_to_crsind = ($cats[0]->get_course_code() != null && $targetcat[0]->get_course_code() == null);
|
||||
|
||||
if (!($course_to_crsind && !isset($_GET['confirm']))) {
|
||||
$cats[0]->move_to_cat($targetcat[0]);
|
||||
header('Location: '.api_get_self().'?categorymoved=&selectcat='.$selectcat);
|
||||
exit;
|
||||
}
|
||||
unset($targetcat);
|
||||
}
|
||||
unset($cats);
|
||||
}
|
||||
|
||||
//move an evaluation
|
||||
if (isset($_GET['moveeval'])) {
|
||||
GradebookUtils::block_students();
|
||||
$get_move_eval = Security::remove_XSS($_GET['moveeval']);
|
||||
$evals = Evaluation::load($get_move_eval);
|
||||
if (!isset($_GET['targetcat'])) {
|
||||
$move_form = new EvalForm(
|
||||
EvalForm::TYPE_MOVE,
|
||||
$evals[0],
|
||||
null,
|
||||
'move_eval_form',
|
||||
null,
|
||||
api_get_self().'?moveeval='.$get_move_eval.'&selectcat='.$selectcat
|
||||
);
|
||||
|
||||
if ($move_form->validate()) {
|
||||
header('Location: '.api_get_self().'?selectcat='.$selectcat
|
||||
.'&moveeval='.$get_move_eval
|
||||
.'&targetcat='.$move_form->exportValue('move_cat'));
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
$get_target_cat = Security::remove_XSS($_GET['targetcat']);
|
||||
$targetcat = Category::load($get_target_cat);
|
||||
$course_to_crsind = ($evals[0]->get_course_code() != null && $targetcat[0]->get_course_code() == null);
|
||||
|
||||
if (!($course_to_crsind && !isset($_GET['confirm']))) {
|
||||
$evals[0]->move_to_cat($targetcat[0]);
|
||||
header('Location: '.api_get_self().'?evaluationmoved=&selectcat='.$selectcat);
|
||||
exit;
|
||||
}
|
||||
unset($targetcat);
|
||||
}
|
||||
unset($evals);
|
||||
}
|
||||
|
||||
// Move a link
|
||||
if (isset($_GET['movelink'])) {
|
||||
GradebookUtils::block_students();
|
||||
$get_move_link = Security::remove_XSS($_GET['movelink']);
|
||||
$link = LinkFactory::load($get_move_link);
|
||||
$move_form = new LinkForm(
|
||||
LinkForm::TYPE_MOVE,
|
||||
null,
|
||||
$link[0],
|
||||
'move_link_form',
|
||||
null,
|
||||
api_get_self().'?movelink='.$get_move_link.'&selectcat='.$selectcat
|
||||
);
|
||||
if ($move_form->validate()) {
|
||||
$targetcat = Category::load($move_form->exportValue('move_cat'));
|
||||
$link[0]->move_to_cat($targetcat[0]);
|
||||
unset($link);
|
||||
header('Location: '.api_get_self().'?linkmoved=&selectcat='.$selectcat);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
//parameters for categories
|
||||
if (isset($_GET['visiblecat'])) {
|
||||
GradebookUtils::block_students();
|
||||
if (isset($_GET['set_visible'])) {
|
||||
$visibility_command = 1;
|
||||
} else {
|
||||
$visibility_command = 0;
|
||||
}
|
||||
$cats = Category::load($_GET['visiblecat']);
|
||||
$cats[0]->set_visible($visibility_command);
|
||||
$cats[0]->save();
|
||||
$cats[0]->apply_visibility_to_children();
|
||||
unset($cats);
|
||||
if ($visibility_command) {
|
||||
$confirmation_message = get_lang('ViMod');
|
||||
$filter_confirm_msg = false;
|
||||
} else {
|
||||
$confirmation_message = get_lang('InViMod');
|
||||
$filter_confirm_msg = false;
|
||||
}
|
||||
}
|
||||
if (isset($_GET['deletecat'])) {
|
||||
GradebookUtils::block_students();
|
||||
$cats = Category::load($_GET['deletecat']);
|
||||
//delete all categories,subcategories and results
|
||||
if ($cats[0] != null) {
|
||||
if ($cats[0]->get_id() != 0) {
|
||||
// better don't try to delete the root...
|
||||
$cats[0]->delete_all();
|
||||
}
|
||||
}
|
||||
$confirmation_message = get_lang('CategoryDeleted');
|
||||
$filter_confirm_msg = false;
|
||||
}
|
||||
|
||||
//parameters for evaluations
|
||||
if (isset($_GET['visibleeval'])) {
|
||||
GradebookUtils::block_students();
|
||||
if (isset($_GET['set_visible'])) {
|
||||
$visibility_command = 1;
|
||||
} else {
|
||||
$visibility_command = 0;
|
||||
}
|
||||
|
||||
$eval = Evaluation::load($_GET['visibleeval']);
|
||||
$eval[0]->set_visible($visibility_command);
|
||||
$eval[0]->save();
|
||||
unset($eval);
|
||||
if ($visibility_command) {
|
||||
$confirmation_message = get_lang('ViMod');
|
||||
$filter_confirm_msg = false;
|
||||
} else {
|
||||
$confirmation_message = get_lang('InViMod');
|
||||
$filter_confirm_msg = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['deleteeval'])) {
|
||||
GradebookUtils::block_students();
|
||||
$eval = Evaluation::load($_GET['deleteeval']);
|
||||
if ($eval[0] != null) {
|
||||
$eval[0]->delete_with_results();
|
||||
}
|
||||
$confirmation_message = get_lang('GradebookEvaluationDeleted');
|
||||
$filter_confirm_msg = false;
|
||||
}
|
||||
//parameters for links
|
||||
if (isset($_GET['visiblelink'])) {
|
||||
GradebookUtils::block_students();
|
||||
if (isset($_GET['set_visible'])) {
|
||||
$visibility_command = 1;
|
||||
} else {
|
||||
$visibility_command = 0;
|
||||
}
|
||||
$link = LinkFactory::load($_GET['visiblelink']);
|
||||
$link[0]->set_visible($visibility_command);
|
||||
$link[0]->save();
|
||||
unset($link);
|
||||
if ($visibility_command) {
|
||||
$confirmation_message = get_lang('ViMod');
|
||||
$filter_confirm_msg = false;
|
||||
} else {
|
||||
$confirmation_message = get_lang('InViMod');
|
||||
$filter_confirm_msg = false;
|
||||
}
|
||||
}
|
||||
if (isset($_GET['deletelink'])) {
|
||||
GradebookUtils::block_students();
|
||||
//fixing #5229
|
||||
if (!empty($_GET['deletelink'])) {
|
||||
$link = LinkFactory::load($_GET['deletelink']);
|
||||
if ($link[0] != null) {
|
||||
$link[0]->delete();
|
||||
}
|
||||
unset($link);
|
||||
$confirmation_message = get_lang('LinkDeleted');
|
||||
$filter_confirm_msg = false;
|
||||
}
|
||||
}
|
||||
$course_to_crsind = isset($course_to_crsind) ? $course_to_crsind : '';
|
||||
if ($course_to_crsind && !isset($_GET['confirm'])) {
|
||||
GradebookUtils::block_students();
|
||||
if (!isset($_GET['movecat']) && !isset($_GET['moveeval'])) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
$button = '<form name="confirm"
|
||||
method="post"
|
||||
action="'.api_get_self().'?confirm='
|
||||
.(isset($_GET['movecat']) ? '&movecat='.Security::remove_XSS($_GET['movecat'])
|
||||
: '&moveeval='.intval($_GET['moveeval'])).'&selectcat='.$selectcat.'&targetcat='.Security::remove_XSS($_GET['targetcat']).'">
|
||||
<input type="submit" value="'.' '.get_lang('Ok').' '.'">
|
||||
</form>';
|
||||
|
||||
$warning_message = get_lang('MoveWarning').'<br><br>'.$button;
|
||||
$filter_warning_msg = false;
|
||||
}
|
||||
|
||||
//actions on the sortabletable
|
||||
if (isset($_POST['action'])) {
|
||||
GradebookUtils::block_students();
|
||||
$number_of_selected_items = count($_POST['id']);
|
||||
if ($number_of_selected_items == '0') {
|
||||
$warning_message = get_lang('NoItemsSelected');
|
||||
$filter_warning_msg = false;
|
||||
} else {
|
||||
switch ($_POST['action']) {
|
||||
case 'deleted':
|
||||
$number_of_deleted_categories = 0;
|
||||
$number_of_deleted_evaluations = 0;
|
||||
$number_of_deleted_links = 0;
|
||||
foreach ($_POST['id'] as $indexstr) {
|
||||
if (api_substr($indexstr, 0, 4) == 'CATE') {
|
||||
$cats = Category::load(api_substr($indexstr, 4));
|
||||
if ($cats[0] != null) {
|
||||
$cats[0]->delete_all();
|
||||
}
|
||||
$number_of_deleted_categories++;
|
||||
}
|
||||
if (api_substr($indexstr, 0, 4) == 'EVAL') {
|
||||
$eval = Evaluation::load(api_substr($indexstr, 4));
|
||||
if ($eval[0] != null) {
|
||||
$eval[0]->delete_with_results();
|
||||
}
|
||||
$number_of_deleted_evaluations++;
|
||||
}
|
||||
if (api_substr($indexstr, 0, 4) == 'LINK') {
|
||||
$id = api_substr($indexstr, 4);
|
||||
if (!empty($id)) {
|
||||
$link = LinkFactory::load();
|
||||
if ($link[0] != null) {
|
||||
$link[0]->delete();
|
||||
}
|
||||
$number_of_deleted_links++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$confirmation_message = get_lang('DeletedCategories').' : <b>'.$number_of_deleted_categories.'</b><br />'.get_lang('DeletedEvaluations').' : <b>'.$number_of_deleted_evaluations.'</b><br />'.get_lang('DeletedLinks').' : <b>'.$number_of_deleted_links.'</b><br /><br />'.get_lang('TotalItems').' : <b>'.$number_of_selected_items.'</b>';
|
||||
$filter_confirm_msg = false;
|
||||
break;
|
||||
case 'setvisible':
|
||||
foreach ($_POST['id'] as $indexstr) {
|
||||
if (api_substr($indexstr, 0, 4) == 'CATE') {
|
||||
$cats = Category::load(api_substr($indexstr, 4));
|
||||
$cats[0]->set_visible(1);
|
||||
$cats[0]->save();
|
||||
$cats[0]->apply_visibility_to_children();
|
||||
}
|
||||
if (api_substr($indexstr, 0, 4) == 'EVAL') {
|
||||
$eval = Evaluation::load(api_substr($indexstr, 4));
|
||||
$eval[0]->set_visible(1);
|
||||
$eval[0]->save();
|
||||
}
|
||||
if (api_substr($indexstr, 0, 4) == 'LINK') {
|
||||
$link = LinkFactory::load(api_substr($indexstr, 4));
|
||||
$link[0]->set_visible(1);
|
||||
$link[0]->save();
|
||||
}
|
||||
}
|
||||
$confirmation_message = get_lang('ItemsVisible');
|
||||
$filter_confirm_msg = false;
|
||||
break;
|
||||
case 'setinvisible':
|
||||
foreach ($_POST['id'] as $indexstr) {
|
||||
if (api_substr($indexstr, 0, 4) == 'CATE') {
|
||||
$cats = Category::load(api_substr($indexstr, 4));
|
||||
$cats[0]->set_visible(0);
|
||||
$cats[0]->save();
|
||||
$cats[0]->apply_visibility_to_children();
|
||||
}
|
||||
if (api_substr($indexstr, 0, 4) == 'EVAL') {
|
||||
$eval = Evaluation::load(api_substr($indexstr, 4));
|
||||
$eval[0]->set_visible(0);
|
||||
$eval[0]->save();
|
||||
}
|
||||
if (api_substr($indexstr, 0, 4) == 'LINK') {
|
||||
$link = LinkFactory::load(api_substr($indexstr, 4));
|
||||
$link[0]->set_visible(0);
|
||||
$link[0]->save();
|
||||
}
|
||||
}
|
||||
$confirmation_message = get_lang('ItemsInVisible');
|
||||
$filter_confirm_msg = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['submit']) && isset($_POST['keyword'])) {
|
||||
header('Location: '.api_get_self().'?selectcat='.$selectcat
|
||||
.'&search='.Security::remove_XSS($_POST['keyword']));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_GET['categorymoved'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('CategoryMoved'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['evaluationmoved'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('EvaluationMoved'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['linkmoved'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('LinkMoved'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['addcat'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('CategoryAdded'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['linkadded'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('LinkAdded'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['addresult'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('ResultAdded'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['editcat'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('CategoryEdited'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['editeval'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('EvaluationEdited'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['linkedited'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('LinkEdited'), 'confirmation', false));
|
||||
}
|
||||
if (isset($_GET['nolinkitems'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('NoLinkItems'), 'warning', false));
|
||||
}
|
||||
if (isset($_GET['addallcat'])) {
|
||||
Display::addFlash(Display::return_message(get_lang('AddAllCat'), 'normal', false));
|
||||
}
|
||||
if (isset($confirmation_message)) {
|
||||
Display::addFlash(Display::return_message($confirmation_message, 'confirmation', $filter_confirm_msg));
|
||||
}
|
||||
if (isset($warning_message)) {
|
||||
Display::addFlash(Display::return_message($warning_message, 'warning', $filter_warning_msg));
|
||||
}
|
||||
if (isset($move_form)) {
|
||||
Display::addFlash(Display::return_message($move_form->toHtml(), 'normal', false));
|
||||
}
|
||||
|
||||
// DISPLAY HEADERS AND MESSAGES -
|
||||
if (!isset($_GET['exportpdf']) && !isset($_GET['export_certificate'])) {
|
||||
if (isset($_GET['studentoverview'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$selectcat,
|
||||
'name' => get_lang('ToolGradebook'),
|
||||
];
|
||||
Display::display_header(get_lang('FlatView'));
|
||||
} elseif (isset($_GET['search'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
|
||||
if ((isset($_GET['selectcat']) && $_GET['selectcat'] > 0)) {
|
||||
if (!empty($_GET['course'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$selectcat,
|
||||
'name' => get_lang('Details'),
|
||||
];
|
||||
} else {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat=0',
|
||||
'name' => get_lang('Details'),
|
||||
];
|
||||
}
|
||||
}
|
||||
Display::display_header('');
|
||||
} else {
|
||||
Display::display_header('');
|
||||
}
|
||||
}
|
||||
|
||||
// LOAD DATA & DISPLAY TABLE -
|
||||
$is_platform_admin = api_is_platform_admin();
|
||||
$is_course_admin = api_is_allowed_to_edit();
|
||||
|
||||
//load data for category, evaluation and links
|
||||
if (empty($selectcat)) {
|
||||
$category = 0;
|
||||
} else {
|
||||
$category = $selectcat;
|
||||
}
|
||||
// search form
|
||||
|
||||
$simple_search_form = new UserForm(
|
||||
UserForm::TYPE_SIMPLE_SEARCH,
|
||||
null,
|
||||
'simple_search_form',
|
||||
null,
|
||||
api_get_self().'?selectcat='.$selectcat
|
||||
);
|
||||
$values = $simple_search_form->exportValues();
|
||||
$keyword = '';
|
||||
if (isset($_GET['search']) && !empty($_GET['search'])) {
|
||||
$keyword = Security::remove_XSS($_GET['search']);
|
||||
}
|
||||
if ($simple_search_form->validate() && (empty($keyword))) {
|
||||
$keyword = $values['keyword'];
|
||||
}
|
||||
|
||||
if (!empty($keyword)) {
|
||||
$cats = Category::load($category);
|
||||
$allcat = [];
|
||||
if ((isset($_GET['selectcat']) && $_GET['selectcat'] == 0) && isset($_GET['search'])) {
|
||||
$allcat = $cats[0]->get_subcategories(null);
|
||||
$allcat_info = Category::find_category($keyword, $allcat);
|
||||
$alleval = [];
|
||||
$alllink = [];
|
||||
} else {
|
||||
$alleval = Evaluation::findEvaluations($keyword, $cats[0]->get_id());
|
||||
$alllink = LinkFactory::find_links($keyword, $cats[0]->get_id());
|
||||
}
|
||||
} elseif (isset($_GET['studentoverview'])) {
|
||||
//@todo this code seems to be deprecated because the gradebook tab is off
|
||||
$cats = Category::load($category);
|
||||
$stud_id = (api_is_allowed_to_edit() ? null : api_get_user_id());
|
||||
$allcat = [];
|
||||
$alleval = $cats[0]->get_evaluations($stud_id, true);
|
||||
$alllink = $cats[0]->get_links($stud_id, true);
|
||||
if (isset($_GET['exportpdf'])) {
|
||||
$datagen = new GradebookDataGenerator($allcat, $alleval, $alllink);
|
||||
$header_names = [
|
||||
get_lang('Name'),
|
||||
get_lang('Description'),
|
||||
get_lang('Weight'),
|
||||
get_lang('Date'),
|
||||
get_lang('Results'),
|
||||
];
|
||||
$data_array = $datagen->get_data(GradebookDataGenerator::GDG_SORT_NAME, 0, null, true);
|
||||
$newarray = [];
|
||||
foreach ($data_array as $data) {
|
||||
$newarray[] = array_slice($data, 1);
|
||||
}
|
||||
$pdf = new Cezpdf();
|
||||
$pdf->selectFont(api_get_path(LIBRARY_PATH).'ezpdf/fonts/Courier.afm');
|
||||
$pdf->ezSetMargins(30, 30, 50, 30);
|
||||
$pdf->ezSetY(810);
|
||||
$pdf->ezText(get_lang('FlatView').' ('.api_convert_and_format_date(null, DATE_FORMAT_SHORT).' '.api_convert_and_format_date(null, TIME_NO_SEC_FORMAT).')', 12, ['justification' => 'center']);
|
||||
$pdf->line(50, 790, 550, 790);
|
||||
$pdf->line(50, 40, 550, 40);
|
||||
$pdf->ezSetY(750);
|
||||
$pdf->ezTable(
|
||||
$newarray,
|
||||
$header_names,
|
||||
'',
|
||||
[
|
||||
'showHeadings' => 1,
|
||||
'shaded' => 1,
|
||||
'showLines' => 1,
|
||||
'rowGap' => 3,
|
||||
'width' => 500,
|
||||
]
|
||||
);
|
||||
$pdf->ezStream();
|
||||
exit;
|
||||
}
|
||||
} elseif (!empty($_GET['export_certificate'])) {
|
||||
//@todo this code seems not to be used
|
||||
$user_id = strval(intval($_GET['user']));
|
||||
if (!api_is_allowed_to_edit(true, true)) {
|
||||
$user_id = api_get_user_id();
|
||||
}
|
||||
$category = Category::load($_GET['cat_id']);
|
||||
if ($category[0]->is_certificate_available($user_id)) {
|
||||
$user = api_get_user_info($user_id);
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$scorecourse = $category[0]->calc_score($user_id);
|
||||
$scorecourse_display = (isset($scorecourse) ? $scoredisplay->display_score($scorecourse, SCORE_AVERAGE) : get_lang('NoResultsAvailable'));
|
||||
|
||||
$cattotal = Category::load(0);
|
||||
$scoretotal = $cattotal[0]->calc_score($user_id);
|
||||
$scoretotal_display = (isset($scoretotal) ? $scoredisplay->display_score($scoretotal, SCORE_PERCENT) : get_lang('NoResultsAvailable'));
|
||||
|
||||
//prepare all necessary variables:
|
||||
$organization_name = api_get_setting('Institution');
|
||||
$portal_name = api_get_setting('siteName');
|
||||
$stud_fn = $user['firstname'];
|
||||
$stud_ln = $user['lastname'];
|
||||
$certif_text = sprintf(get_lang('CertificateWCertifiesStudentXFinishedCourseYWithGradeZ'), $organization_name, $stud_fn.' '.$stud_ln, $category[0]->get_name(), $scorecourse_display);
|
||||
$certif_text = str_replace("\\n", "\n", $certif_text);
|
||||
$date = api_convert_and_format_date(null, DATE_FORMAT_SHORT);
|
||||
|
||||
$pdf = new Cezpdf('a4', 'landscape');
|
||||
$pdf->selectFont(api_get_path(LIBRARY_PATH).'ezpdf/fonts/Courier.afm');
|
||||
$pdf->ezSetMargins(30, 30, 50, 50);
|
||||
//line Y coordinates in landscape mode are upside down (500 is on top, 10 is on the bottom)
|
||||
$pdf->line(50, 50, 790, 50);
|
||||
$pdf->line(50, 550, 790, 550);
|
||||
$pdf->ezSetY(450);
|
||||
$pdf->ezSetY(480);
|
||||
$pdf->ezText($certif_text, 28, ['justification' => 'center']);
|
||||
//$pdf->ezSetY(750);
|
||||
$pdf->ezSetY(50);
|
||||
$pdf->ezText($date, 18, ['justification' => 'center']);
|
||||
$pdf->ezSetY(580);
|
||||
$pdf->ezText($organization_name, 22, ['justification' => 'left']);
|
||||
$pdf->ezSetY(580);
|
||||
$pdf->ezText($portal_name, 22, ['justification' => 'right']);
|
||||
$pdf->ezStream();
|
||||
}
|
||||
exit;
|
||||
} else {
|
||||
$cats = Category::load($category);
|
||||
$stud_id = (api_is_allowed_to_edit() ? null : api_get_user_id());
|
||||
$allcat = $cats[0]->get_subcategories($stud_id);
|
||||
$alleval = $cats[0]->get_evaluations($stud_id);
|
||||
$alllink = $cats[0]->get_links($stud_id);
|
||||
}
|
||||
$addparams = ['selectcat' => $cats[0]->get_id()];
|
||||
if (isset($_GET['search'])) {
|
||||
$addparams['search'] = $keyword;
|
||||
}
|
||||
if (isset($_GET['studentoverview'])) {
|
||||
$addparams['studentoverview'] = '';
|
||||
}
|
||||
if (isset($allcat_info) && count($allcat_info) >= 0 &&
|
||||
(isset($_GET['selectcat']) && $_GET['selectcat'] == 0) &&
|
||||
isset($_GET['search']) && strlen(trim($_GET['search'])) > 0
|
||||
) {
|
||||
$allcat = $allcat_info;
|
||||
} else {
|
||||
$allcat = $allcat;
|
||||
}
|
||||
$gradebooktable = new GradebookTable(
|
||||
$cats[0],
|
||||
$allcat,
|
||||
$alleval,
|
||||
$alllink,
|
||||
$addparams
|
||||
);
|
||||
|
||||
if (empty($allcat) && empty($alleval) && empty($alllink) &&
|
||||
!$is_platform_admin && $is_course_admin && !isset($_GET['selectcat']) && api_is_course_tutor()
|
||||
) {
|
||||
echo Display::return_message(
|
||||
get_lang('GradebookWelcomeMessage').
|
||||
'<br /><br />
|
||||
<form name="createcat" method="post" action="'.api_get_self().'?createallcategories=1">
|
||||
<input type="submit" value="'.get_lang('CreateAllCat').'"></form>',
|
||||
'normal',
|
||||
false
|
||||
);
|
||||
}
|
||||
// Here we are in a sub category
|
||||
if ($category != '0') {
|
||||
DisplayGradebook::header(
|
||||
$cats[0],
|
||||
1,
|
||||
$_GET['selectcat'],
|
||||
$is_course_admin,
|
||||
$is_platform_admin,
|
||||
$simple_search_form
|
||||
);
|
||||
} else {
|
||||
// This is the root category
|
||||
DisplayGradebook::header(
|
||||
$cats[0],
|
||||
count($allcat) == '0' && !isset($_GET['search']) ? 0 : 1,
|
||||
0,
|
||||
$is_course_admin,
|
||||
$is_platform_admin,
|
||||
$simple_search_form
|
||||
);
|
||||
}
|
||||
$gradebooktable->display();
|
||||
Display::display_footer();
|
||||
124
main/gradebook/gradebook_add_cat.php
Normal file
124
main/gradebook/gradebook_add_cat.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
$_in_course = true;
|
||||
$course_code = api_get_course_id();
|
||||
if (empty($course_code)) {
|
||||
$_in_course = false;
|
||||
}
|
||||
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$edit_cat = isset($_REQUEST['editcat']) ? intval($_REQUEST['editcat']) : '';
|
||||
$get_select_cat = intval($_GET['selectcat']);
|
||||
|
||||
$catadd = new Category();
|
||||
$my_user_id = api_get_user_id();
|
||||
$catadd->set_user_id($my_user_id);
|
||||
$catadd->set_parent_id($get_select_cat);
|
||||
$catcourse = Category::load($get_select_cat);
|
||||
|
||||
if ($_in_course) {
|
||||
$catadd->set_course_code($course_code);
|
||||
} else {
|
||||
$catadd->set_course_code($catcourse[0]->get_course_code());
|
||||
}
|
||||
|
||||
$catadd->set_course_code(api_get_course_id());
|
||||
$form = new CatForm(
|
||||
CatForm::TYPE_ADD,
|
||||
$catadd,
|
||||
'add_cat_form',
|
||||
null,
|
||||
api_get_self().'?selectcat='.$get_select_cat.'&'.api_get_cidreq()
|
||||
);
|
||||
|
||||
if ($form->validate()) {
|
||||
$values = $form->exportValues();
|
||||
$select_course = isset($values['select_course']) ? $values['select_course'] : [];
|
||||
$cat = new Category();
|
||||
if ($values['hid_parent_id'] == '0') {
|
||||
if ($select_course == 'COURSEINDEPENDENT') {
|
||||
$cat->set_name($values['name']);
|
||||
$cat->set_course_code(null);
|
||||
} else {
|
||||
$cat->set_course_code($select_course);
|
||||
$cat->set_name($values['name']);
|
||||
}
|
||||
} else {
|
||||
$cat->set_name($values['name']);
|
||||
$cat->set_course_code($values['course_code']);
|
||||
}
|
||||
|
||||
$cat->set_session_id(api_get_session_id());
|
||||
|
||||
// Always add the gradebook to the course
|
||||
$cat->set_course_code(api_get_course_id());
|
||||
if (isset($values['skills'])) {
|
||||
$cat->set_skills($values['skills']);
|
||||
}
|
||||
|
||||
$cat->set_description($values['description']);
|
||||
$cat->set_user_id($values['hid_user_id']);
|
||||
$cat->set_parent_id($values['hid_parent_id']);
|
||||
$cat->set_weight($values['weight']);
|
||||
|
||||
if (isset($values['generate_certificates'])) {
|
||||
$cat->setGenerateCertificates(true);
|
||||
} else {
|
||||
$cat->setGenerateCertificates(false);
|
||||
}
|
||||
|
||||
if (isset($values['is_requirement'])) {
|
||||
$cat->setIsRequirement(true);
|
||||
} else {
|
||||
$cat->setIsRequirement(false);
|
||||
}
|
||||
|
||||
if (empty($values['visible'])) {
|
||||
$visible = 0;
|
||||
} else {
|
||||
$visible = 1;
|
||||
}
|
||||
$cat->set_visible($visible);
|
||||
$result = $cat->add();
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'tool_id' => 0,
|
||||
'tool_id_detail' => 0,
|
||||
'action' => 'new-cat',
|
||||
'action_details' => 'parent_id='.$cat->get_parent_id(),
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
header('Location: '.Category::getUrl().'addcat=&selectcat='.$cat->get_parent_id());
|
||||
exit;
|
||||
}
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'tool_id' => 0,
|
||||
'tool_id_detail' => 0,
|
||||
'action' => 'add-cat',
|
||||
'action_details' => Category::getUrl().'selectcat='.$get_select_cat,
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
if (!$_in_course) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$get_select_cat,
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
}
|
||||
$interbreadcrumb[] = ['url' => 'index.php?'.api_get_cidreq(), 'name' => get_lang('ToolGradebook')];
|
||||
Display::display_header(get_lang('NewCategory'));
|
||||
|
||||
$display_form = true;
|
||||
if ($display_form) {
|
||||
$form->display();
|
||||
}
|
||||
|
||||
Display::display_footer();
|
||||
135
main/gradebook/gradebook_add_eval.php
Normal file
135
main/gradebook/gradebook_add_eval.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
$current_course_tool = TOOL_GRADEBOOK;
|
||||
|
||||
api_protect_course_script(true);
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$select_cat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
$is_allowedToEdit = api_is_course_admin();
|
||||
|
||||
$userId = api_get_user_id();
|
||||
|
||||
$evaladd = new Evaluation();
|
||||
$evaladd->set_user_id($userId);
|
||||
if (!empty($select_cat)) {
|
||||
$evaladd->set_category_id($_GET['selectcat']);
|
||||
$cat = Category::load($_GET['selectcat']);
|
||||
$evaladd->set_course_code($cat[0]->get_course_code());
|
||||
} else {
|
||||
$evaladd->set_category_id(0);
|
||||
}
|
||||
|
||||
$form = new EvalForm(
|
||||
EvalForm::TYPE_ADD,
|
||||
$evaladd,
|
||||
null,
|
||||
'add_eval_form',
|
||||
null,
|
||||
api_get_self().'?selectcat='.$select_cat.'&'.api_get_cidreq()
|
||||
);
|
||||
|
||||
if ($form->validate()) {
|
||||
$values = $form->exportValues();
|
||||
$eval = new Evaluation();
|
||||
$eval->set_name($values['name']);
|
||||
$eval->set_description($values['description']);
|
||||
$eval->set_user_id($values['hid_user_id']);
|
||||
|
||||
if (!empty($values['hid_course_code'])) {
|
||||
$eval->set_course_code($values['hid_course_code']);
|
||||
}
|
||||
|
||||
// Always add the gradebook to the course
|
||||
$eval->set_course_code(api_get_course_id());
|
||||
$eval->set_category_id($values['hid_category_id']);
|
||||
|
||||
$parent_cat = Category::load($values['hid_category_id']);
|
||||
$global_weight = $cat[0]->get_weight();
|
||||
$values['weight'] = $values['weight_mask'];
|
||||
|
||||
$eval->set_weight($values['weight']);
|
||||
$eval->set_max($values['max']);
|
||||
$visible = 1;
|
||||
if (empty($values['visible'])) {
|
||||
$visible = 0;
|
||||
}
|
||||
$eval->set_visible($visible);
|
||||
$eval->add();
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'action' => 'new-eval',
|
||||
'action_details' => 'selectcat='.$eval->get_category_id(),
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
Skill::saveSkills($form, ITEM_TYPE_GRADEBOOK_EVALUATION, $eval->get_id());
|
||||
|
||||
if (null == $eval->get_course_code()) {
|
||||
if (1 == $values['adduser']) {
|
||||
//Disabling code when course code is null see issue #2705
|
||||
//header('Location: gradebook_add_user.php?selecteval=' . $eval->get_id());
|
||||
exit;
|
||||
} else {
|
||||
header('Location: '.Category::getUrl().'selectcat='.$eval->get_category_id());
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
$val_addresult = isset($values['addresult']) ? $values['addresult'] : null;
|
||||
if (1 == $val_addresult) {
|
||||
header('Location: gradebook_add_result.php?selecteval='.$eval->get_id().'&'.api_get_cidreq());
|
||||
exit;
|
||||
} else {
|
||||
header('Location: '.Category::getUrl().'selectcat='.$eval->get_category_id());
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'tool_id' => 0,
|
||||
'tool_id_detail' => 0,
|
||||
'action' => 'add-eval',
|
||||
'action_details' => 'selectcat='.$select_cat,
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$select_cat,
|
||||
'name' => get_lang('Gradebook'), ]
|
||||
;
|
||||
$this_section = SECTION_COURSES;
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
$(function() {
|
||||
$("#hid_category_id").change(function() {
|
||||
$("#hid_category_id option:selected").each(function () {
|
||||
var cat_id = $(this).val();
|
||||
$.ajax({
|
||||
url: "'.api_get_path(WEB_AJAX_PATH).'gradebook.ajax.php?a=get_gradebook_weight",
|
||||
data: "cat_id="+cat_id,
|
||||
success: function(return_value) {
|
||||
if (return_value != 0 ) {
|
||||
$("#max_weight").html(return_value);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>';
|
||||
|
||||
if ($evaladd->get_course_code() == null) {
|
||||
Display::addFlash(Display::return_message(get_lang('CourseIndependentEvaluation'), 'normal', false));
|
||||
}
|
||||
|
||||
Display::display_header(get_lang('NewEvaluation'));
|
||||
|
||||
$form->display();
|
||||
Display::display_footer();
|
||||
194
main/gradebook/gradebook_add_link.php
Normal file
194
main/gradebook/gradebook_add_link.php
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
require_once '../forum/forumfunction.inc.php';
|
||||
$current_course_tool = TOOL_GRADEBOOK;
|
||||
|
||||
api_protect_course_script(true);
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$courseCode = isset($_GET['course_code']) ? Security::remove_XSS($_GET['course_code']) : null;
|
||||
$selectCat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
|
||||
$course_info = api_get_course_info($courseCode);
|
||||
$tbl_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
|
||||
$tbl_link = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
|
||||
$session_id = api_get_session_id();
|
||||
$typeSelected = isset($_GET['typeselected']) ? (int) $_GET['typeselected'] : null;
|
||||
|
||||
if (0 == $session_id) {
|
||||
$all_categories = Category::load(
|
||||
null,
|
||||
null,
|
||||
api_get_course_id(),
|
||||
null,
|
||||
null,
|
||||
$session_id
|
||||
);
|
||||
} else {
|
||||
$all_categories = Category::loadSessionCategories(null, $session_id);
|
||||
}
|
||||
$category = Category::load($selectCat);
|
||||
$url = api_get_self().'?selectcat='.$selectCat.'&newtypeselected='.$typeSelected.'&course_code='.api_get_course_id().'&'.api_get_cidreq();
|
||||
$typeform = new LinkForm(
|
||||
LinkForm::TYPE_CREATE,
|
||||
$category[0],
|
||||
null,
|
||||
'create_link',
|
||||
null,
|
||||
$url,
|
||||
$typeSelected
|
||||
);
|
||||
|
||||
// if user selected a link type
|
||||
if ($typeform->validate() && isset($_GET['newtypeselected'])) {
|
||||
// reload page, this time with a parameter indicating the selected type
|
||||
header(
|
||||
'Location: '.api_get_self().'?selectcat='.$selectCat
|
||||
.'&typeselected='.$typeform->exportValue('select_link')
|
||||
.'&course_code='.Security::remove_XSS($_GET['course_code']).'&'.api_get_cidreq()
|
||||
);
|
||||
exit;
|
||||
}
|
||||
|
||||
// link type selected, show 2nd form to retrieve the link data
|
||||
if (isset($typeSelected) && '0' != $typeSelected) {
|
||||
$url = api_get_self().'?selectcat='.$selectCat.'&typeselected='.$typeSelected.'&course_code='.$courseCode.'&'.api_get_cidreq();
|
||||
|
||||
$addform = new LinkAddEditForm(
|
||||
LinkAddEditForm::TYPE_ADD,
|
||||
$all_categories,
|
||||
$typeSelected,
|
||||
null,
|
||||
'add_link',
|
||||
$url
|
||||
);
|
||||
|
||||
if ($addform->validate()) {
|
||||
$addvalues = $addform->exportValues();
|
||||
$link = LinkFactory::create($typeSelected);
|
||||
$link->set_user_id(api_get_user_id());
|
||||
$link->set_course_code(api_get_course_id());
|
||||
$link->set_category_id($addvalues['select_gradebook']);
|
||||
|
||||
if ($link->needs_name_and_description()) {
|
||||
$link->set_name($addvalues['name']);
|
||||
} else {
|
||||
$link->set_ref_id($addvalues['select_link']);
|
||||
}
|
||||
|
||||
$parent_cat = Category::load($addvalues['select_gradebook']);
|
||||
$global_weight = $category[0]->get_weight();
|
||||
$link->set_weight($addvalues['weight_mask']);
|
||||
|
||||
if ($link->needs_max()) {
|
||||
$link->set_max($addvalues['max']);
|
||||
}
|
||||
|
||||
if ($link->needs_name_and_description()) {
|
||||
$link->set_description($addvalues['description']);
|
||||
}
|
||||
$link->set_visible(empty($addvalues['visible']) ? 0 : 1);
|
||||
|
||||
// Update view_properties
|
||||
if (isset($typeSelected) &&
|
||||
5 == $typeSelected &&
|
||||
(isset($addvalues['select_link']) && "" != $addvalues['select_link'])
|
||||
) {
|
||||
$sql1 = 'SELECT thread_title from '.$tbl_forum_thread.'
|
||||
WHERE
|
||||
c_id = '.$course_info['real_id'].' AND
|
||||
thread_id = '.$addvalues['select_link'];
|
||||
$res1 = Database::query($sql1);
|
||||
$rowtit = Database::fetch_row($res1);
|
||||
$course_id = api_get_course_id();
|
||||
$sql_l = 'SELECT count(*) FROM '.$tbl_link.'
|
||||
WHERE
|
||||
ref_id='.$addvalues['select_link'].' AND
|
||||
course_code="'.$course_id.'" AND
|
||||
type = 5;';
|
||||
$res_l = Database::query($sql_l);
|
||||
$row = Database::fetch_row($res_l);
|
||||
if (0 == $row[0]) {
|
||||
$link->add();
|
||||
$sql = 'UPDATE '.$tbl_forum_thread.' SET
|
||||
thread_qualify_max= "'.api_float_val($addvalues['weight']).'",
|
||||
thread_weight= "'.api_float_val($addvalues['weight']).'",
|
||||
thread_title_qualify = "'.$rowtit[0].'"
|
||||
WHERE
|
||||
thread_id='.$addvalues['select_link'].' AND
|
||||
c_id = '.$course_info['real_id'].' ';
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
$link->add();
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'action' => 'new-link',
|
||||
'action_details' => 'selectcat='.$selectCat,
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
$addvalue_result = !empty($addvalues['addresult']) ? $addvalues['addresult'] : [];
|
||||
if (1 == $addvalue_result) {
|
||||
header('Location: gradebook_add_result.php?selecteval='.$link->get_ref_id().'&'.api_get_cidreq());
|
||||
exit;
|
||||
} else {
|
||||
header('Location: '.Category::getUrl().'linkadded=&selectcat='.$selectCat);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$action_details = '';
|
||||
$current_id = 0;
|
||||
if (isset($_GET['selectcat'])) {
|
||||
$action_details = 'selectcat';
|
||||
$current_id = (int) $_GET['selectcat'];
|
||||
}
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'action' => 'add-link',
|
||||
'action_details' => 'selectcat='.$selectCat,
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$selectCat,
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$this_section = SECTION_COURSES;
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
$(function() {
|
||||
$("#hide_category_id").change(function() {
|
||||
$("#hide_category_id option:selected").each(function () {
|
||||
var cat_id = $(this).val();
|
||||
$.ajax({
|
||||
url: "'.api_get_path(WEB_AJAX_PATH).'gradebook.ajax.php?a=get_gradebook_weight",
|
||||
data: "cat_id="+cat_id,
|
||||
success: function(return_value) {
|
||||
if (return_value != 0 ) {
|
||||
$("#max_weight").html(return_value);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>';
|
||||
|
||||
Display::display_header(get_lang('MakeLink'));
|
||||
if (isset($typeform)) {
|
||||
echo Display::return_message(get_lang('LearningPathGradebookWarning'), 'warning');
|
||||
$typeform->display();
|
||||
}
|
||||
if (isset($addform)) {
|
||||
$addform->display();
|
||||
}
|
||||
Display::display_footer();
|
||||
40
main/gradebook/gradebook_add_link_select_course.php
Normal file
40
main/gradebook/gradebook_add_link_select_course.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
$current_course_tool = TOOL_GRADEBOOK;
|
||||
|
||||
api_protect_course_script(true);
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$selectCat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
|
||||
$catadd = new Category();
|
||||
$catadd->set_user_id(api_get_user_id());
|
||||
$catadd->set_parent_id($selectCat);
|
||||
$catcourse = Category::load($selectCat);
|
||||
$form = new CatForm(
|
||||
CatForm::TYPE_SELECT_COURSE,
|
||||
$catadd,
|
||||
'add_cat_form',
|
||||
null,
|
||||
api_get_self().'?selectcat='.$selectCat.'&'.api_get_cidreq()
|
||||
);
|
||||
|
||||
if ($form->validate()) {
|
||||
$values = $form->exportValues();
|
||||
$cat = new Category();
|
||||
$cat->set_course_code($values['select_course']);
|
||||
$cat->set_name($values['name']);
|
||||
header('Location: gradebook_add_link.php?selectcat='.$selectCat.'&course_code='.Security::remove_XSS($values['select_course']).'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$selectCat,
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
Display::display_header(get_lang('NewCategory'));
|
||||
$form->display();
|
||||
Display::display_footer();
|
||||
74
main/gradebook/gradebook_add_result.php
Normal file
74
main/gradebook/gradebook_add_result.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
//$cidReset = true;
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
$current_course_tool = TOOL_GRADEBOOK;
|
||||
|
||||
api_protect_course_script(true);
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$selectEval = isset($_GET['selecteval']) ? (int) $_GET['selecteval'] : 0;
|
||||
|
||||
$resultadd = new Result();
|
||||
$resultadd->set_evaluation_id($selectEval);
|
||||
$evaluation = Evaluation::load($selectEval);
|
||||
$category = !empty($_GET['selectcat']) ? (int) $_GET['selectcat'] : '';
|
||||
$add_result_form = new EvalForm(
|
||||
EvalForm::TYPE_RESULT_ADD,
|
||||
$evaluation[0],
|
||||
$resultadd,
|
||||
'add_result_form',
|
||||
null,
|
||||
api_get_self().'?selectcat='.$category.'&selecteval='.$selectEval.'&'.api_get_cidreq()
|
||||
);
|
||||
$table = $add_result_form->toHtml();
|
||||
if ($add_result_form->validate()) {
|
||||
$values = $add_result_form->exportValues();
|
||||
$nr_users = $values['nr_users'];
|
||||
if ($nr_users == '0') {
|
||||
Display::addFlash(Display::return_message(get_lang('AddResultNoStudents'), 'warning', false));
|
||||
header('Location: gradebook_view_result.php?addresultnostudents=&selecteval='.$selectEval.'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
|
||||
$scores = $values['score'];
|
||||
$sumResult = 0;
|
||||
$bestResult = 0;
|
||||
$studentScoreList = [];
|
||||
foreach ($scores as $userId => $row) {
|
||||
$res = new Result();
|
||||
$res->set_evaluation_id($values['evaluation_id']);
|
||||
$res->set_user_id(key($scores));
|
||||
//if no scores are given, don't set the score
|
||||
if (!empty($row) || $row == '0') {
|
||||
$res->set_score($row);
|
||||
}
|
||||
|
||||
// To prevent error editing when going back in the browser,
|
||||
// check if a record exists for this user and evaluation_id
|
||||
if ($res->exists()) {
|
||||
$res->addResultLog($userId, $values['evaluation_id']);
|
||||
$res->save();
|
||||
} else {
|
||||
$res->add();
|
||||
}
|
||||
|
||||
next($scores);
|
||||
}
|
||||
|
||||
Evaluation::generateStats($values['evaluation_id']);
|
||||
|
||||
Display::addFlash(Display::return_message(get_lang('ResultAdded'), 'confirmation', false));
|
||||
header('Location: gradebook_view_result.php?addresult=&selecteval='.$selectEval.'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
Display::display_header(get_lang('AddResult'));
|
||||
DisplayGradebook::display_header_result($evaluation[0], null, 0, 0);
|
||||
echo $table;
|
||||
Display::display_footer();
|
||||
82
main/gradebook/gradebook_add_user.php
Normal file
82
main/gradebook/gradebook_add_user.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
/**
|
||||
* Script.
|
||||
*
|
||||
* @package chamilo.gradebook
|
||||
*/
|
||||
|
||||
//Disabling code when course code is null (gradebook as a tab) see issue #2705
|
||||
exit;
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
$this_section = SECTION_MYGRADEBOOK;
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$evaluation = Evaluation::load($_GET['selecteval']);
|
||||
$newstudents = $evaluation[0]->get_not_subscribed_students();
|
||||
|
||||
if (count($newstudents) == '0') {
|
||||
header('Location: gradebook_view_result.php?nouser=&selecteval='.intval($_GET['selecteval']).'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
$add_user_form = new EvalForm(
|
||||
EvalForm::TYPE_ADD_USERS_TO_EVAL,
|
||||
$evaluation[0],
|
||||
null,
|
||||
'add_users_to_evaluation',
|
||||
null,
|
||||
api_get_self().'?selecteval='.Security::remove_XSS($_GET['selecteval']),
|
||||
Security::remove_XSS($_GET['firstletter']),
|
||||
$newstudents
|
||||
);
|
||||
|
||||
if (isset($_POST['submit_button'])) {
|
||||
$users = is_array($_POST['add_users']) ? $_POST['add_users'] : [];
|
||||
foreach ($users as $key => $value) {
|
||||
$users[$key] = intval($value);
|
||||
}
|
||||
|
||||
if (count($users) == 0) {
|
||||
header('Location: '.api_get_self().'?erroroneuser=&selecteval='.Security::remove_XSS($_GET['selecteval']));
|
||||
exit;
|
||||
} else {
|
||||
foreach ($users as $user_id) {
|
||||
$result = new Result();
|
||||
$result->set_user_id($user_id);
|
||||
$result->set_evaluation_id($_GET['selecteval']);
|
||||
$result->add();
|
||||
}
|
||||
}
|
||||
header(
|
||||
'Location: gradebook_view_result.php?adduser=&selecteval='.Security::remove_XSS($_GET['selecteval']).'&'.api_get_cidreq()
|
||||
);
|
||||
exit;
|
||||
} elseif ($_POST['firstLetterUser']) {
|
||||
$firstletter = $_POST['firstLetterUser'];
|
||||
if (!empty($firstletter)) {
|
||||
header(
|
||||
'Location: '.api_get_self().'?firstletter='.Security::remove_XSS(
|
||||
$firstletter
|
||||
).'&selecteval='.Security::remove_XSS($_GET['selecteval'])
|
||||
);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = ['url' => Category::getUrl(), 'name' => get_lang('Gradebook')];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => 'gradebook_view_result.php?selecteval='.Security::remove_XSS($_GET['selecteval']).'&'.api_get_cidreq(),
|
||||
'name' => get_lang('ViewResult'),
|
||||
];
|
||||
Display::display_header(get_lang('AddUserToEval'));
|
||||
if (isset($_GET['erroroneuser'])) {
|
||||
echo Display::return_message(get_lang('AtLeastOneUser'), 'warning', false);
|
||||
}
|
||||
DisplayGradebook::display_header_result($evaluation[0], null, 0, 0);
|
||||
echo '<div class="main">';
|
||||
echo $add_user_form->toHtml();
|
||||
echo '</div>';
|
||||
Display::display_footer();
|
||||
438
main/gradebook/gradebook_display_certificate.php
Normal file
438
main/gradebook/gradebook_display_certificate.php
Normal file
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
$current_course_tool = TOOL_GRADEBOOK;
|
||||
|
||||
if (!api_is_student_boss()) {
|
||||
api_protect_course_script(true);
|
||||
}
|
||||
|
||||
api_block_anonymous_users();
|
||||
|
||||
if (!api_is_allowed_to_edit() && !api_is_student_boss()) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
api_set_more_memory_and_time_limits();
|
||||
|
||||
//extra javascript functions for in html head:
|
||||
$htmlHeadXtra[] = "<script>
|
||||
function confirmation() {
|
||||
if (confirm(\" ".trim(get_lang('AreYouSureToDelete'))." ?\")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
</script>";
|
||||
|
||||
$categoryId = isset($_GET['cat_id']) ? (int) $_GET['cat_id'] : 0;
|
||||
$action = isset($_GET['action']) && $_GET['action'] ? $_GET['action'] : null;
|
||||
$filterOfficialCode = isset($_POST['filter']) ? Security::remove_XSS($_POST['filter']) : null;
|
||||
$filterOfficialCodeGet = isset($_GET['filter']) ? Security::remove_XSS($_GET['filter']) : null;
|
||||
|
||||
$url = api_get_self().'?'.api_get_cidreq().'&cat_id='.$categoryId.'&filter='.$filterOfficialCode;
|
||||
$courseInfo = api_get_course_info();
|
||||
|
||||
$filter = api_get_setting('certificate_filter_by_official_code');
|
||||
$userList = [];
|
||||
$filterForm = null;
|
||||
$certificate_list = [];
|
||||
if ($filter === 'true') {
|
||||
$options = UserManager::getOfficialCodeGrouped();
|
||||
$options = array_merge(['all' => get_lang('All')], $options);
|
||||
$form = new FormValidator(
|
||||
'official_code_filter',
|
||||
'POST',
|
||||
api_get_self().'?'.api_get_cidreq().'&cat_id='.$categoryId
|
||||
);
|
||||
$form->addElement('select', 'filter', get_lang('OfficialCode'), $options);
|
||||
$form->addButton('submit', get_lang('Submit'));
|
||||
$filterForm = '<br />'.$form->returnForm();
|
||||
|
||||
if ($form->validate()) {
|
||||
$officialCode = $form->getSubmitValue('filter');
|
||||
if ($officialCode === 'all') {
|
||||
$certificate_list = GradebookUtils::get_list_users_certificates($categoryId);
|
||||
} else {
|
||||
$userList = UserManager::getUsersByOfficialCode($officialCode);
|
||||
if (!empty($userList)) {
|
||||
$certificate_list = GradebookUtils::get_list_users_certificates(
|
||||
$categoryId,
|
||||
$userList
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$certificate_list = GradebookUtils::get_list_users_certificates($categoryId);
|
||||
}
|
||||
} else {
|
||||
$certificate_list = GradebookUtils::get_list_users_certificates($categoryId);
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$courseCode = api_get_course_id();
|
||||
$allowCustomCertificate = api_get_plugin_setting('customcertificate', 'enable_plugin_customcertificate') === 'true' &&
|
||||
api_get_course_setting('customcertificate_course_enable', $courseInfo) == 1;
|
||||
|
||||
$tags = Certificate::notificationTags();
|
||||
|
||||
switch ($action) {
|
||||
case 'send_notifications':
|
||||
$currentUserInfo = api_get_user_info();
|
||||
$message = isset($_POST['message']) ? $_POST['message'] : '';
|
||||
$subject = get_lang('NotificationCertificateSubject');
|
||||
if (!empty($message)) {
|
||||
foreach ($certificate_list as $index => $value) {
|
||||
$userInfo = api_get_user_info($value['user_id']);
|
||||
if (empty($userInfo)) {
|
||||
continue;
|
||||
}
|
||||
$list = GradebookUtils::get_list_gradebook_certificates_by_user_id(
|
||||
$value['user_id'],
|
||||
$categoryId
|
||||
);
|
||||
|
||||
foreach ($list as $valueCertificate) {
|
||||
Certificate::sendNotification(
|
||||
$subject,
|
||||
$message,
|
||||
$userInfo,
|
||||
$courseInfo,
|
||||
$valueCertificate
|
||||
);
|
||||
}
|
||||
}
|
||||
Display::addFlash(Display::return_message(get_lang('Sent')));
|
||||
}
|
||||
|
||||
header('Location: '.$url);
|
||||
exit;
|
||||
break;
|
||||
case 'show_notification_form':
|
||||
$form = new FormValidator('notification', 'post', $url.'&action=send_notifications');
|
||||
$form->addHeader(get_lang('SendNotification'));
|
||||
$form->addHtmlEditor('message', get_lang('Message'));
|
||||
$form->addLabel(
|
||||
get_lang('Tags'),
|
||||
Display::return_message(implode('<br />', $tags), 'normal', false)
|
||||
);
|
||||
$form->addButtonSend(get_lang('Send'));
|
||||
$form->setDefaults(
|
||||
['message' => nl2br(get_lang('NotificationCertificateTemplate'))]
|
||||
);
|
||||
$content = $form->returnForm();
|
||||
break;
|
||||
case 'export_all_certificates_zip':
|
||||
if ($allowCustomCertificate) {
|
||||
$params = 'course_code='.api_get_course_id().
|
||||
'&session_id='.api_get_session_id().
|
||||
'&'.api_get_cidreq().
|
||||
'&cat_id='.$categoryId;
|
||||
$url = api_get_path(WEB_PLUGIN_PATH).'customcertificate/src/print_certificate.php?export_all=1&'.$params;
|
||||
|
||||
header('Location: '.$url);
|
||||
}
|
||||
exit;
|
||||
case 'generate_all_certificates':
|
||||
$userList = CourseManager::get_user_list_from_course_code(
|
||||
api_get_course_id(),
|
||||
api_get_session_id()
|
||||
);
|
||||
|
||||
if (!empty($userList)) {
|
||||
foreach ($userList as $userInfo) {
|
||||
if ($userInfo['status'] == INVITEE) {
|
||||
continue;
|
||||
}
|
||||
Category::generateUserCertificate($categoryId, $userInfo['user_id']);
|
||||
}
|
||||
}
|
||||
header('Location: '.$url);
|
||||
exit;
|
||||
break;
|
||||
case 'delete_all_certificates':
|
||||
Category::deleteAllCertificates($categoryId);
|
||||
Display::addFlash(Display::return_message(get_lang('Deleted')));
|
||||
header('Location: '.$url);
|
||||
exit;
|
||||
break;
|
||||
case 'download_all_certificates':
|
||||
$courseCode = api_get_course_id();
|
||||
$sessionId = api_get_session_id();
|
||||
$categoryId = (int) $_GET['catId'];
|
||||
$date = api_get_utc_datetime(null, false, true);
|
||||
$pdfName = 'certs_'.$courseCode.'_'.$sessionId.'_'.$categoryId.'_'.$date->format('Y-m-d');
|
||||
$finalFile = api_get_path(SYS_ARCHIVE_PATH)."$pdfName.pdf";
|
||||
|
||||
$result = DocumentManager::file_send_for_download($finalFile, true);
|
||||
if (false === $result) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
break;
|
||||
case 'download_certificates_report':
|
||||
$exportData = array_map(function ($learner) {
|
||||
return [
|
||||
$learner['user_id'],
|
||||
$learner['username'],
|
||||
$learner['firstname'],
|
||||
$learner['lastname'],
|
||||
];
|
||||
}, $certificate_list);
|
||||
|
||||
$csvContent = [];
|
||||
$csvHeaders = [];
|
||||
$csvHeaders[] = get_lang('Id');
|
||||
$csvHeaders[] = get_lang('UserName');
|
||||
$csvHeaders[] = get_lang('FirstName');
|
||||
$csvHeaders[] = get_lang('LastName');
|
||||
$csvHeaders[] = get_lang('Score');
|
||||
$csvHeaders[] = get_lang('Date');
|
||||
|
||||
$extraFields = [];
|
||||
$extraFieldsFromSettings = [];
|
||||
$extraFieldsFromSettings = api_get_configuration_value('certificate_export_report_user_extra_fields');
|
||||
|
||||
if (!empty($extraFieldsFromSettings) && isset($extraFieldsFromSettings['extra_fields'])) {
|
||||
$extraFields = $extraFieldsFromSettings['extra_fields'];
|
||||
$usersProfileInfo = [];
|
||||
|
||||
$userIds = array_column($certificate_list, 'user_id', 'user_id');
|
||||
|
||||
foreach ($extraFields as $fieldName) {
|
||||
$extraFieldInfo = UserManager::get_extra_field_information_by_name($fieldName);
|
||||
|
||||
if (!empty($extraFieldInfo)) {
|
||||
$csvHeaders[] = $fieldName;
|
||||
|
||||
$usersProfileInfo[$extraFieldInfo['id']] = TrackingCourseLog::getAdditionalProfileInformationOfFieldByUser(
|
||||
$extraFieldInfo['id'],
|
||||
$userIds
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($exportData as $key => $row) {
|
||||
$list = GradebookUtils::get_list_gradebook_certificates_by_user_id(
|
||||
$row[0],
|
||||
$categoryId
|
||||
);
|
||||
|
||||
foreach ($list as $valueCertificate) {
|
||||
$row[] = $valueCertificate['score_certificate'];
|
||||
$row[] = api_convert_and_format_date($valueCertificate['created_at']);
|
||||
}
|
||||
|
||||
foreach ($usersProfileInfo as $extraInfo) {
|
||||
$row[] = $extraInfo[$row[0]][0];
|
||||
}
|
||||
|
||||
$csvContent[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
array_unshift($csvContent, $csvHeaders);
|
||||
|
||||
$fileName = 'learner_certificate_report_'.api_get_local_time();
|
||||
Export::arrayToCsv($csvContent, $fileName);
|
||||
break;
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('GradebookListOfStudentsCertificates')];
|
||||
|
||||
$this_section = SECTION_COURSES;
|
||||
Display::display_header('');
|
||||
|
||||
if ($action === 'delete') {
|
||||
$check = Security::check_token('get');
|
||||
if ($check) {
|
||||
$certificate = new Certificate($_GET['certificate_id']);
|
||||
$result = $certificate->delete(true);
|
||||
Security::clear_token();
|
||||
if ($result == true) {
|
||||
echo Display::return_message(get_lang('CertificateRemoved'), 'confirmation');
|
||||
} else {
|
||||
echo Display::return_message(get_lang('CertificateNotRemoved'), 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$token = Security::get_token();
|
||||
echo Display::page_header(get_lang('GradebookListOfStudentsCertificates'));
|
||||
|
||||
if (!empty($content)) {
|
||||
echo $content;
|
||||
}
|
||||
|
||||
//@todo replace all this code with something like get_total_weight()
|
||||
$cats = Category::load($categoryId, null, null, null, null, null, false);
|
||||
|
||||
if (!empty($cats)) {
|
||||
//with this fix the teacher only can view 1 gradebook
|
||||
if (api_is_platform_admin()) {
|
||||
$stud_id = (api_is_allowed_to_edit() ? null : api_get_user_id());
|
||||
} else {
|
||||
$stud_id = api_get_user_id();
|
||||
}
|
||||
|
||||
$total_weight = $cats[0]->get_weight();
|
||||
$allcat = $cats[0]->get_subcategories(
|
||||
$stud_id,
|
||||
api_get_course_id(),
|
||||
api_get_session_id()
|
||||
);
|
||||
$alleval = $cats[0]->get_evaluations($stud_id);
|
||||
$alllink = $cats[0]->get_links($stud_id);
|
||||
|
||||
$datagen = new GradebookDataGenerator($allcat, $alleval, $alllink);
|
||||
|
||||
$total_resource_weight = 0;
|
||||
if (!empty($datagen)) {
|
||||
$data_array = $datagen->get_data(
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if (!empty($data_array)) {
|
||||
$newarray = [];
|
||||
foreach ($data_array as $data) {
|
||||
$newarray[] = array_slice($data, 1);
|
||||
}
|
||||
|
||||
foreach ($newarray as $item) {
|
||||
$total_resource_weight = $total_resource_weight + $item['2'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($total_resource_weight != $total_weight) {
|
||||
echo Display::return_message(
|
||||
get_lang('SumOfActivitiesWeightMustBeEqualToTotalWeight'),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$actions = '';
|
||||
$actions .= Display::url(
|
||||
Display::return_icon('tuning.png', get_lang('GenerateCertificates'), [], ICON_SIZE_MEDIUM),
|
||||
$url.'&action=generate_all_certificates'
|
||||
);
|
||||
$actions .= Display::url(
|
||||
Display::return_icon('delete.png', get_lang('DeleteAllCertificates'), [], ICON_SIZE_MEDIUM),
|
||||
$url.'&action=delete_all_certificates'
|
||||
);
|
||||
|
||||
$hideCertificateExport = api_get_setting('hide_certificate_export_link');
|
||||
|
||||
if (count($certificate_list) > 0 && $hideCertificateExport !== 'true') {
|
||||
if ($allowCustomCertificate) {
|
||||
$actions .= Display::url(
|
||||
Display::return_icon('pdf.png', get_lang('ExportAllCertificatesToPDF'), [], ICON_SIZE_MEDIUM),
|
||||
api_get_path(WEB_PLUGIN_PATH)
|
||||
.'customcertificate/src/print_certificate.php?'.api_get_cidreq().'&'
|
||||
.http_build_query(
|
||||
[
|
||||
'export_all_in_one' => 1,
|
||||
'course_code' => api_get_course_id(),
|
||||
'session_id' => api_get_session_id(),
|
||||
'cat_id' => $categoryId,
|
||||
]
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$actions .= Display::url(
|
||||
Display::return_icon('pdf.png', get_lang('ExportAllCertificatesToPDF'), [], ICON_SIZE_MEDIUM),
|
||||
'#',
|
||||
['id' => 'btn-export-all']
|
||||
);
|
||||
}
|
||||
|
||||
$actions .= Display::url(
|
||||
Display::return_icon('export_csv.png', get_lang('ExportCertificateReport'), [], ICON_SIZE_MEDIUM),
|
||||
$url.'&action=download_certificates_report'
|
||||
);
|
||||
|
||||
if ($allowCustomCertificate) {
|
||||
$actions .= Display::url(
|
||||
Display::return_icon('file_zip.png', get_lang('ExportAllCertificatesToZIP'), [], ICON_SIZE_MEDIUM),
|
||||
$url.'&action=export_all_certificates_zip'
|
||||
);
|
||||
}
|
||||
|
||||
$actions .= Display::url(
|
||||
Display::return_icon('notification_mail.png', get_lang('SendCertificateNotifications'), [], ICON_SIZE_MEDIUM),
|
||||
$url.'&action=show_notification_form'
|
||||
);
|
||||
}
|
||||
|
||||
echo Display::toolbarAction('actions', [$actions]);
|
||||
echo $filterForm;
|
||||
|
||||
if (count($certificate_list) == 0) {
|
||||
echo Display::return_message(get_lang('NoResultsAvailable'), 'warning');
|
||||
} else {
|
||||
echo '<table class="table data_table">';
|
||||
echo '<tbody>';
|
||||
foreach ($certificate_list as $index => $value) {
|
||||
echo '<tr>
|
||||
<td width="100%" class="actions">'.get_lang('Student').' : '.api_get_person_name($value['firstname'], $value['lastname']).' ('.$value['username'].')</td>';
|
||||
echo '</tr>';
|
||||
echo '<tr><td>
|
||||
<table class="table data_table">
|
||||
<tbody>';
|
||||
|
||||
$list = GradebookUtils::get_list_gradebook_certificates_by_user_id(
|
||||
$value['user_id'],
|
||||
$categoryId
|
||||
);
|
||||
foreach ($list as $valueCertificate) {
|
||||
echo '<tr>';
|
||||
echo '<td width="50%">'.get_lang('Score').' : '.$valueCertificate['score_certificate'].'</td>';
|
||||
echo '<td width="30%">'.get_lang('Date').' : '.api_convert_and_format_date($valueCertificate['created_at']).'</td>';
|
||||
echo '<td width="20%">';
|
||||
$url = api_get_path(WEB_PATH).'certificates/index.php?id='.$valueCertificate['id'].'&user_id='.$value['user_id'];
|
||||
$certificateUrl = Display::url(
|
||||
get_lang('Certificate'),
|
||||
$url,
|
||||
['target' => '_blank', 'class' => 'btn btn-default']
|
||||
);
|
||||
echo $certificateUrl.PHP_EOL;
|
||||
if ($hideCertificateExport !== 'true') {
|
||||
$url .= '&action=export';
|
||||
$pdf = Display::url(
|
||||
Display::return_icon('pdf.png', get_lang('Download')),
|
||||
$url,
|
||||
['target' => '_blank']
|
||||
);
|
||||
echo $pdf.PHP_EOL;
|
||||
}
|
||||
echo '<a onclick="return confirmation();" href="gradebook_display_certificate.php?sec_token='.$token.'&'.api_get_cidreq().'&action=delete&cat_id='.$categoryId.'&certificate_id='.$valueCertificate['id'].'">
|
||||
'.Display::return_icon('delete.png', get_lang('Delete')).'
|
||||
</a>'.PHP_EOL;
|
||||
echo '</td></tr>';
|
||||
}
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
echo '</td></tr>';
|
||||
}
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
|
||||
echo GradebookUtils::returnJsExportAllCertificates(
|
||||
'#btn-export-all',
|
||||
$categoryId,
|
||||
api_get_course_id(),
|
||||
api_get_session_id(),
|
||||
$filterOfficialCodeGet
|
||||
);
|
||||
}
|
||||
Display::display_footer();
|
||||
262
main/gradebook/gradebook_display_summary.php
Normal file
262
main/gradebook/gradebook_display_summary.php
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
$current_course_tool = TOOL_GRADEBOOK;
|
||||
|
||||
api_protect_course_script(true);
|
||||
api_set_more_memory_and_time_limits();
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$cat_id = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : null;
|
||||
$action = isset($_GET['action']) && $_GET['action'] ? $_GET['action'] : null;
|
||||
|
||||
$sessionId = api_get_session_id();
|
||||
$courseInfo = api_get_course_info();
|
||||
$statusToFilter = empty($sessionId) ? STUDENT : 0;
|
||||
|
||||
$userList = CourseManager::get_user_list_from_course_code(
|
||||
api_get_course_id(),
|
||||
$sessionId,
|
||||
null,
|
||||
null,
|
||||
$statusToFilter
|
||||
);
|
||||
|
||||
/*Session::write('use_gradebook_cache', false);
|
||||
$useCache = api_get_configuration_value('gradebook_use_apcu_cache');
|
||||
$cacheAvailable = api_get_configuration_value('apc') && $useCache;
|
||||
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver = new \Doctrine\Common\Cache\ApcuCache();
|
||||
$cacheDriver->deleteAll();
|
||||
$cacheDriver->flushAll();
|
||||
}*/
|
||||
|
||||
switch ($action) {
|
||||
case 'export_all':
|
||||
//Session::write('use_gradebook_cache', true);
|
||||
$cats = Category::load($cat_id, null, null, null, null, null, false);
|
||||
/** @var Category $cat */
|
||||
$cat = $cats[0];
|
||||
$allcat = $cat->get_subcategories(
|
||||
null,
|
||||
api_get_course_id(),
|
||||
api_get_session_id()
|
||||
);
|
||||
$alleval = $cat->get_evaluations(
|
||||
null,
|
||||
true,
|
||||
api_get_course_id(),
|
||||
api_get_session_id()
|
||||
);
|
||||
$alllink = $cat->get_links(
|
||||
null,
|
||||
true,
|
||||
api_get_course_id(),
|
||||
api_get_session_id()
|
||||
);
|
||||
|
||||
$loadStats = GradebookTable::getExtraStatsColumnsToDisplay();
|
||||
|
||||
$gradebooktable = new GradebookTable(
|
||||
$cat,
|
||||
$allcat,
|
||||
$alleval,
|
||||
$alllink,
|
||||
null, // params
|
||||
true, // $exportToPdf
|
||||
false, // showteacher
|
||||
null,
|
||||
$userList,
|
||||
$loadStats
|
||||
);
|
||||
|
||||
$key = $gradebooktable->getPreloadDataKey();
|
||||
// preloads data
|
||||
Session::erase($key);
|
||||
$defaultData = $gradebooktable->preloadData();
|
||||
|
||||
$tpl = new Template('', false, false, false);
|
||||
$params = [
|
||||
'pdf_title' => sprintf(get_lang('GradeFromX'), $courseInfo['name']),
|
||||
'session_info' => '',
|
||||
'course_info' => '',
|
||||
'pdf_date' => '',
|
||||
'course_code' => api_get_course_id(),
|
||||
'student_info' => null,
|
||||
'show_grade_generated_date' => true,
|
||||
'show_real_course_teachers' => false,
|
||||
'show_teacher_as_myself' => false,
|
||||
'orientation' => 'P',
|
||||
];
|
||||
$pdf = new PDF('A4', $params['orientation'], $params, $tpl);
|
||||
$counter = 0;
|
||||
$htmlList = [];
|
||||
foreach ($userList as $index => $value) {
|
||||
$htmlList[] = GradebookUtils::generateTable(
|
||||
$courseInfo,
|
||||
$value['user_id'],
|
||||
$cats,
|
||||
false,
|
||||
true,
|
||||
$userList,
|
||||
$pdf
|
||||
);
|
||||
$counter++;
|
||||
}
|
||||
|
||||
if (!empty($htmlList)) {
|
||||
$counter = 0;
|
||||
$content = '';
|
||||
foreach ($htmlList as $value) {
|
||||
$content .= $value.'<pagebreak>';
|
||||
$counter++;
|
||||
}
|
||||
|
||||
$tempFile = api_get_path(SYS_ARCHIVE_PATH).uniqid('gradebook_export_all').'.html';
|
||||
file_put_contents($tempFile, $content);
|
||||
$pdf->html_to_pdf(
|
||||
$tempFile,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Delete calc_score session data
|
||||
Session::erase('calc_score');
|
||||
break;
|
||||
case 'download':
|
||||
$userId = isset($_GET['user_id']) && $_GET['user_id'] ? $_GET['user_id'] : null;
|
||||
$cats = Category::load($cat_id, null, null, null, null, null, false);
|
||||
GradebookUtils::generateTable($courseInfo, $userId, $cats, false, false, $userList);
|
||||
break;
|
||||
case 'add_comment':
|
||||
if (!api_is_allowed_to_edit()) {
|
||||
exit;
|
||||
}
|
||||
$userId = isset($_GET['user_id']) ? (int) $_GET['user_id'] : 0;
|
||||
$gradeBookId = isset($_GET['gradebook_id']) ? (int) $_GET['gradebook_id'] : 0;
|
||||
$comment = '';
|
||||
$commentInfo = GradebookUtils::getComment($gradeBookId, $userId);
|
||||
if ($commentInfo) {
|
||||
$comment = $commentInfo['comment'];
|
||||
}
|
||||
$ajaxPath = api_get_path(WEB_AJAX_PATH).'gradebook.ajax.php?a=add_gradebook_comment';
|
||||
$save = Display::return_message(get_lang('Saved'));
|
||||
echo '<script>
|
||||
$(function() {
|
||||
$("form").on("submit", function(e) {
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
url: "'.$ajaxPath.'",
|
||||
data: {
|
||||
gradebook_id: "'.$gradeBookId.'",
|
||||
user_id: "'.$userId.'",
|
||||
comment: $("#comment").val()
|
||||
},
|
||||
success: function(data) {
|
||||
$(".result").html("'.addslashes($save).'");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>';
|
||||
$student = api_get_user_info($userId);
|
||||
$form = new FormValidator('add_comment');
|
||||
$form->addLabel(get_lang('User'), $student['complete_name']);
|
||||
$form->addTextarea('comment', get_lang('Comment'), ['id' => 'comment']);
|
||||
$form->addHtml('<div class="result"></div>');
|
||||
$form->addButtonSave(get_lang('Save'));
|
||||
$form->setDefaults(['comment' => $comment]);
|
||||
$form->display();
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
|
||||
$course_code = api_get_course_id();
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => '#',
|
||||
'name' => get_lang('GradebookListOfStudentsReports'),
|
||||
];
|
||||
$allowSkillRelItem = api_get_configuration_value('allow_skill_rel_items');
|
||||
if ($allowSkillRelItem) {
|
||||
$htmlContentExtraClass[] = 'feature-item-user-skill-on';
|
||||
}
|
||||
|
||||
$this_section = SECTION_COURSES;
|
||||
Display::display_header('');
|
||||
$token = Security::get_token();
|
||||
echo Display::page_header(get_lang('GradebookListOfStudentsReports'));
|
||||
|
||||
echo '<div class="btn-group">';
|
||||
if (count($userList) > 0) {
|
||||
$url = api_get_self().'?action=export_all&'.api_get_cidreq().'&selectcat='.$cat_id;
|
||||
echo Display::url(get_lang('ExportAllToPDF'), $url, ['class' => 'btn btn-default']);
|
||||
}
|
||||
echo '</div>';
|
||||
|
||||
if (count($userList) == 0) {
|
||||
echo Display::return_message(get_lang('NoResultsAvailable'), 'warning');
|
||||
} else {
|
||||
echo '<br /><br /><div class="table-responsive">
|
||||
<table class="table table-hover table-striped table-bordered data_table">';
|
||||
echo '<tr><th>';
|
||||
echo get_lang('Student');
|
||||
echo '</th>';
|
||||
echo '<th>';
|
||||
echo get_lang('Action');
|
||||
echo '</th></tr>';
|
||||
$allowComments = api_get_configuration_value('allow_gradebook_comments');
|
||||
foreach ($userList as $index => $value) {
|
||||
$userData = api_get_person_name($value['firstname'], $value['lastname']).' ('.$value['username'].')';
|
||||
echo '<tr>
|
||||
<td width="70%">'.$userData.'</td>';
|
||||
echo '<td>';
|
||||
$link = '';
|
||||
if ($allowSkillRelItem) {
|
||||
$url = api_get_path(WEB_CODE_PATH).
|
||||
'gradebook/skill_rel_user.php?'.api_get_cidreq().'&user_id='.$value['user_id'].'&selectcat='.$cat_id;
|
||||
$link = Display::url(
|
||||
get_lang('Skills'),
|
||||
$url,
|
||||
['class' => 'btn btn-default']
|
||||
).' ';
|
||||
}
|
||||
|
||||
$url = api_get_self().'?'.api_get_cidreq().'&action=download&user_id='.$value['user_id'].'&selectcat='.$cat_id;
|
||||
$link .= Display::url(
|
||||
get_lang('ExportToPDF'),
|
||||
$url,
|
||||
['target' => '_blank', 'class' => 'btn btn-default']
|
||||
);
|
||||
|
||||
if ($allowComments) {
|
||||
$url = api_get_self().'?'.api_get_cidreq().'&action=add_comment&user_id='.$value['user_id'].'&gradebook_id='.$cat_id;
|
||||
$link .= ' '.Display::url(
|
||||
get_lang('AddGradebookComment'),
|
||||
$url,
|
||||
['target' => '_blank', 'class' => 'ajax btn btn-default']
|
||||
);
|
||||
}
|
||||
|
||||
echo $link;
|
||||
|
||||
echo '</td></tr>';
|
||||
}
|
||||
echo '</table></div>';
|
||||
}
|
||||
|
||||
Display::display_footer();
|
||||
312
main/gradebook/gradebook_edit_all.php
Normal file
312
main/gradebook/gradebook_edit_all.php
Normal file
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Script.
|
||||
*
|
||||
* @package chamilo.gradebook
|
||||
*
|
||||
* @author Julio Montoya - fixes in order to use gradebook models + some code cleaning
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
$this_section = SECTION_COURSES;
|
||||
$current_course_tool = TOOL_GRADEBOOK;
|
||||
|
||||
api_protect_course_script(true);
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
$my_selectcat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
|
||||
if (empty($my_selectcat)) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$action_details = '';
|
||||
if (isset($_GET['selectcat'])) {
|
||||
$action_details = 'selectcat';
|
||||
}
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'action' => 'edit-weight',
|
||||
'action_details' => $action_details,
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
$course_id = GradebookUtils::get_course_id_by_link_id($my_selectcat);
|
||||
$table_link = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$table_evaluation = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
|
||||
$tbl_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
|
||||
$tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
|
||||
|
||||
$table_evaluated[LINK_EXERCISE] = [
|
||||
TABLE_QUIZ_TEST,
|
||||
'title',
|
||||
'iid',
|
||||
get_lang('Exercise'),
|
||||
];
|
||||
$table_evaluated[LINK_DROPBOX] = [
|
||||
TABLE_DROPBOX_FILE,
|
||||
'name',
|
||||
'id',
|
||||
get_lang('Dropbox'),
|
||||
];
|
||||
$table_evaluated[LINK_STUDENTPUBLICATION] = [
|
||||
TABLE_STUDENT_PUBLICATION,
|
||||
'url',
|
||||
'id',
|
||||
get_lang('Student_publication'),
|
||||
];
|
||||
$table_evaluated[LINK_LEARNPATH] = [
|
||||
TABLE_LP_MAIN,
|
||||
'name',
|
||||
'id',
|
||||
get_lang('Learnpath'),
|
||||
];
|
||||
$table_evaluated[LINK_FORUM_THREAD] = [
|
||||
TABLE_FORUM_THREAD,
|
||||
'thread_title_qualify',
|
||||
'thread_id',
|
||||
get_lang('Forum'),
|
||||
];
|
||||
$table_evaluated[LINK_ATTENDANCE] = [
|
||||
TABLE_ATTENDANCE,
|
||||
'attendance_title_qualify',
|
||||
'id',
|
||||
get_lang('Attendance'),
|
||||
];
|
||||
$table_evaluated[LINK_SURVEY] = [
|
||||
TABLE_SURVEY,
|
||||
'code',
|
||||
'survey_id',
|
||||
get_lang('Survey'),
|
||||
];
|
||||
|
||||
$submitted = isset($_POST['submitted']) ? $_POST['submitted'] : '';
|
||||
if ($submitted == 1) {
|
||||
Display::addFlash(Display::return_message(get_lang('GradebookWeightUpdated')));
|
||||
if (isset($_POST['evaluation'])) {
|
||||
$eval_log = new Evaluation();
|
||||
}
|
||||
}
|
||||
|
||||
$output = '';
|
||||
$my_cat = Category::load($my_selectcat);
|
||||
$my_cat = $my_cat[0];
|
||||
|
||||
$parent_id = $my_cat->get_parent_id();
|
||||
$parent_cat = Category::load($parent_id);
|
||||
|
||||
$my_category = [];
|
||||
$cat = new Category();
|
||||
$my_category = $cat->showAllCategoryInfo($my_selectcat);
|
||||
|
||||
$original_total = $my_category['weight'];
|
||||
$masked_total = $parent_cat[0]->get_weight();
|
||||
|
||||
$sql = 'SELECT * FROM '.$table_link.'
|
||||
WHERE category_id = '.$my_selectcat;
|
||||
$result = Database::query($sql);
|
||||
$links = Database::store_result($result, 'ASSOC');
|
||||
|
||||
foreach ($links as &$row) {
|
||||
$item_weight = $row['weight'];
|
||||
$sql = 'SELECT * FROM '.GradebookUtils::get_table_type_course($row['type']).'
|
||||
WHERE c_id = '.$course_id.' AND '.$table_evaluated[$row['type']][2].' = '.$row['ref_id'];
|
||||
|
||||
$result = Database::query($sql);
|
||||
$resource_name = Database::fetch_array($result);
|
||||
|
||||
if (isset($resource_name['lp_type'])) {
|
||||
$resource_name = $resource_name[4];
|
||||
} else {
|
||||
switch ($row['type']) {
|
||||
case LINK_EXERCISE:
|
||||
$resource_name = $resource_name['title'];
|
||||
break;
|
||||
default:
|
||||
$resource_name = $resource_name[3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$row['resource_name'] = $resource_name;
|
||||
|
||||
// Update only if value changed
|
||||
if (isset($_POST['link'][$row['id']])) {
|
||||
$new_weight = trim($_POST['link'][$row['id']]);
|
||||
GradebookUtils::updateLinkWeight(
|
||||
$row['id'],
|
||||
$resource_name,
|
||||
$new_weight
|
||||
);
|
||||
$item_weight = $new_weight;
|
||||
}
|
||||
|
||||
$output .= '<tr><td>'.GradebookUtils::build_type_icon_tag($row['type']).'</td>
|
||||
<td> '.$resource_name.' '.
|
||||
Display::label(
|
||||
$table_evaluated[$row['type']][3],
|
||||
'info'
|
||||
).' </td>';
|
||||
$output .= '<td>
|
||||
<input type="hidden" name="link_'.$row['id'].'" value="1" />
|
||||
<input size="10" type="text" name="link['.$row['id'].']" value="'.$item_weight.'"/>
|
||||
</td></tr>';
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM $table_evaluation
|
||||
WHERE category_id = $my_selectcat
|
||||
ORDER BY name";
|
||||
$result = Database::query($sql);
|
||||
$evaluations = Database::store_result($result);
|
||||
foreach ($evaluations as $evaluationRow) {
|
||||
$item_weight = $evaluationRow['weight'];
|
||||
// update only if value changed
|
||||
if (isset($_POST['evaluation'][$evaluationRow['id']])) {
|
||||
$new_weight = trim($_POST['evaluation'][$evaluationRow['id']]);
|
||||
GradebookUtils::updateEvaluationWeight(
|
||||
$evaluationRow['id'],
|
||||
$new_weight
|
||||
);
|
||||
|
||||
$item_weight = $new_weight;
|
||||
}
|
||||
|
||||
$output .= '<tr>
|
||||
<td>'.GradebookUtils::build_type_icon_tag('evalnotempty').'</td>
|
||||
<td>'.$evaluationRow['name'].' '.Display::label(get_lang('Evaluation')).'</td>';
|
||||
$output .= '<td>
|
||||
<input type="hidden" name="eval_'.$evaluationRow['id'].'" value="1" />
|
||||
<input type="text" size="10" name="evaluation['.$evaluationRow['id'].']" value="'.$item_weight.'"/>
|
||||
</td></tr>';
|
||||
}
|
||||
|
||||
$currentUrl = api_get_self().'?'.api_get_cidreq().'&selectcat='.$my_selectcat;
|
||||
|
||||
$form = new FormValidator('auto_weight', 'post', $currentUrl);
|
||||
$form->addHeader(get_lang('AutoWeight'));
|
||||
$form->addLabel(null, get_lang('AutoWeightExplanation'));
|
||||
$form->addButtonUpdate(get_lang('AutoWeight'));
|
||||
|
||||
if ($form->validate()) {
|
||||
$itemCount = count($links) + count($evaluations);
|
||||
$weight = round($original_total / $itemCount, 2);
|
||||
$total = $weight * $itemCount;
|
||||
|
||||
$diff = null;
|
||||
if ($original_total !== $total) {
|
||||
if ($total > $original_total) {
|
||||
$diff = $total - $original_total;
|
||||
}
|
||||
}
|
||||
|
||||
$total = 0;
|
||||
$diffApplied = false;
|
||||
|
||||
foreach ($links as $link) {
|
||||
$weightToApply = $weight;
|
||||
if ($diffApplied == false) {
|
||||
if (!empty($diff)) {
|
||||
$weightToApply = $weight - $diff;
|
||||
$diffApplied = true;
|
||||
}
|
||||
}
|
||||
GradebookUtils::updateLinkWeight(
|
||||
$link['id'],
|
||||
$link['resource_name'],
|
||||
$weightToApply
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($evaluations as $evaluation) {
|
||||
$weightToApply = $weight;
|
||||
if ($diffApplied == false) {
|
||||
if (!empty($diff)) {
|
||||
$weightToApply = $weight - $diff;
|
||||
$diffApplied = true;
|
||||
}
|
||||
}
|
||||
GradebookUtils::updateEvaluationWeight(
|
||||
$evaluation['id'],
|
||||
$weightToApply
|
||||
);
|
||||
}
|
||||
Display::addFlash(Display::return_message(get_lang('GradebookWeightUpdated')));
|
||||
|
||||
header('Location: '.$currentUrl);
|
||||
exit;
|
||||
}
|
||||
|
||||
// DISPLAY HEADERS AND MESSAGES
|
||||
if (!isset($_GET['exportpdf']) && !isset($_GET['export_certificate'])) {
|
||||
if (isset($_GET['studentoverview'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$my_selectcat,
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
Display::display_header(get_lang('FlatView'));
|
||||
} elseif (isset($_GET['search'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$my_selectcat,
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
Display::display_header(get_lang('SearchResults'));
|
||||
} else {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat=1',
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => '#',
|
||||
'name' => get_lang('EditAllWeights'),
|
||||
];
|
||||
Display::display_header('');
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="actions">
|
||||
<a href="<?php echo Category::getUrl(); ?>selectcat=<?php echo $my_selectcat; ?>">
|
||||
<?php echo Display::return_icon(
|
||||
'back.png',
|
||||
get_lang('FolderView'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
$form->display();
|
||||
|
||||
$formNormal = new FormValidator('normal_weight', 'post', $currentUrl);
|
||||
$formNormal->addHeader(get_lang('EditWeight'));
|
||||
$formNormal->display();
|
||||
|
||||
echo Display::return_message(sprintf(get_lang('TotalWeightMustBeX'), $original_total), 'warning', false);
|
||||
|
||||
?>
|
||||
<form method="post" action="<?php echo $currentUrl; ?>">
|
||||
<table class="table table-hover table-striped data_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo get_lang('Type'); ?></th>
|
||||
<th><?php echo get_lang('Resource'); ?></th>
|
||||
<th><?php echo get_lang('Weight'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php echo $output; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="hidden" name="submitted" value="1"/>
|
||||
<br/>
|
||||
<button class="btn btn-primary" type="submit" name="name"
|
||||
value="<?php echo get_lang('Save'); ?>">
|
||||
<?php echo get_lang('SaveScoringRules'); ?>
|
||||
</button>
|
||||
</form>
|
||||
<?php
|
||||
Display::display_footer();
|
||||
120
main/gradebook/gradebook_edit_cat.php
Normal file
120
main/gradebook/gradebook_edit_cat.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* @package chamilo.gradebook
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
$edit_cat = isset($_REQUEST['editcat']) ? (int) $_REQUEST['editcat'] : 0;
|
||||
$enableGradeSubCategorySkills = (true === api_get_configuration_value('gradebook_enable_subcategory_skills_independant_assignement'));
|
||||
$catedit = Category::load($edit_cat);
|
||||
$form = new CatForm(
|
||||
CatForm::TYPE_EDIT,
|
||||
$catedit[0],
|
||||
'edit_cat_form',
|
||||
'post',
|
||||
api_get_self().'?'.api_get_cidreq().'&editcat='.$edit_cat
|
||||
);
|
||||
|
||||
if ($form->validate()) {
|
||||
$values = $form->getSubmitValues();
|
||||
|
||||
$cat = new Category();
|
||||
|
||||
if (!empty($values['hid_id'])) {
|
||||
$cat = $cat->load($values['hid_id']);
|
||||
if (isset($cat[0])) {
|
||||
$cat = $cat[0];
|
||||
}
|
||||
}
|
||||
|
||||
$cat->set_id($values['hid_id']);
|
||||
$cat->set_name($values['name']);
|
||||
|
||||
if (empty($values['course_code'])) {
|
||||
$cat->set_course_code(null);
|
||||
} else {
|
||||
$cat->set_course_code($values['course_code']);
|
||||
}
|
||||
|
||||
if (isset($values['grade_model_id'])) {
|
||||
$cat->set_grade_model_id($values['grade_model_id']);
|
||||
}
|
||||
|
||||
$cat->set_description($values['description']);
|
||||
|
||||
if (isset($values['skills'])) {
|
||||
$cat->set_skills($values['skills']);
|
||||
}
|
||||
|
||||
$cat->set_user_id($values['hid_user_id']);
|
||||
$cat->set_parent_id($values['hid_parent_id']);
|
||||
$cat->set_weight($values['weight']);
|
||||
|
||||
if (isset($values['generate_certificates'])) {
|
||||
$cat->setGenerateCertificates($values['generate_certificates']);
|
||||
} else {
|
||||
$cat->setGenerateCertificates(false);
|
||||
}
|
||||
|
||||
if ($values['hid_parent_id'] == 0) {
|
||||
$cat->set_certificate_min_score($values['certif_min_score']);
|
||||
} else {
|
||||
if ($enableGradeSubCategorySkills) {
|
||||
$allowSkillsBySubCategory = $cat->getAllowSkillBySubCategory($cat->get_parent_id());
|
||||
if ($allowSkillsBySubCategory) {
|
||||
$cat->set_certificate_min_score($values['certif_min_score']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$visible = 1;
|
||||
if (empty($values['visible'])) {
|
||||
$visible = 0;
|
||||
}
|
||||
$cat->set_visible($visible);
|
||||
|
||||
if (isset($values['is_requirement'])) {
|
||||
$cat->setIsRequirement(true);
|
||||
} else {
|
||||
$cat->setIsRequirement(false);
|
||||
}
|
||||
|
||||
if ($enableGradeSubCategorySkills) {
|
||||
$allowSkillsBySubCategory = isset($values['allow_skills_by_subcategory']);
|
||||
$cat->updateAllowSkillBySubCategory($allowSkillsBySubCategory);
|
||||
}
|
||||
|
||||
$cat->save();
|
||||
header('Location: '.Category::getUrl().'editcat=&selectcat='.$cat->get_parent_id());
|
||||
exit;
|
||||
}
|
||||
$selectcat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
|
||||
$action_details = '';
|
||||
$current_id = 0;
|
||||
if (isset($_GET['editcat'])) {
|
||||
$action_details = 'editcat';
|
||||
$current_id = (int) $_GET['editcat'];
|
||||
}
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'tool_id' => 0,
|
||||
'tool_id_detail' => 0,
|
||||
'action' => 'edit-cat',
|
||||
'action_details' => $action_details,
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$selectcat,
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$this_section = SECTION_COURSES;
|
||||
Display::display_header(get_lang('EditCategory'));
|
||||
$form->display();
|
||||
Display::display_footer();
|
||||
86
main/gradebook/gradebook_edit_eval.php
Normal file
86
main/gradebook/gradebook_edit_eval.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Script.
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$evaledit = Evaluation::load($_GET['editeval']);
|
||||
if ($evaledit[0]->is_locked() && !api_is_platform_admin()) {
|
||||
api_not_allowed();
|
||||
}
|
||||
$form = new EvalForm(
|
||||
EvalForm::TYPE_EDIT,
|
||||
$evaledit[0],
|
||||
null,
|
||||
'edit_eval_form',
|
||||
null,
|
||||
api_get_self().'?editeval='.intval($_GET['editeval']).'&'.api_get_cidreq()
|
||||
);
|
||||
if ($form->validate()) {
|
||||
$values = $form->exportValues();
|
||||
$eval = new Evaluation();
|
||||
$eval->set_id($values['hid_id']);
|
||||
$eval->set_name($values['name']);
|
||||
$eval->set_description($values['description']);
|
||||
$eval->set_user_id($values['hid_user_id']);
|
||||
$eval->set_course_code($values['hid_course_code']);
|
||||
$eval->set_category_id($values['hid_category_id']);
|
||||
|
||||
$parent_cat = Category::load($values['hid_category_id']);
|
||||
$final_weight = $values['weight_mask'];
|
||||
|
||||
$eval->set_weight($final_weight);
|
||||
$eval->set_max($values['max']);
|
||||
|
||||
$visible = 1;
|
||||
if (empty($values['visible'])) {
|
||||
$visible = 0;
|
||||
}
|
||||
$eval->set_visible($visible);
|
||||
$eval->save();
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'action' => 'edit-eval',
|
||||
'action_details' => '',
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
Skill::saveSkills($form, ITEM_TYPE_GRADEBOOK_EVALUATION, $values['hid_id']);
|
||||
|
||||
header('Location: '.Category::getUrl().'editeval=&selectcat='.$eval->get_category_id());
|
||||
exit;
|
||||
}
|
||||
$selectcat_inter = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$selectcat_inter,
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
$(function() {
|
||||
$("#hid_category_id").change(function() {
|
||||
$("#hid_category_id option:selected").each(function () {
|
||||
var cat_id = $(this).val();
|
||||
$.ajax({
|
||||
url: "'.api_get_path(WEB_AJAX_PATH).'gradebook.ajax.php?a=get_gradebook_weight",
|
||||
data: "cat_id="+cat_id,
|
||||
success: function(return_value) {
|
||||
if (return_value != 0 ) {
|
||||
$("#max_weight").html(return_value);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>';
|
||||
|
||||
Display::display_header(get_lang('EditEvaluation'));
|
||||
$form->display();
|
||||
Display::display_footer();
|
||||
147
main/gradebook/gradebook_edit_link.php
Normal file
147
main/gradebook/gradebook_edit_link.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Script.
|
||||
*
|
||||
* @package chamilo.gradebook
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
$tbl_grade_links = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
//selected name of database
|
||||
$course_id = GradebookUtils::get_course_id_by_link_id($_GET['editlink']);
|
||||
$tbl_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
|
||||
$tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
|
||||
$em = Database::getManager();
|
||||
|
||||
$linkarray = LinkFactory::load($_GET['editlink']);
|
||||
/** @var AbstractLink $link */
|
||||
$link = $linkarray[0];
|
||||
if ($link->is_locked() && !api_is_platform_admin()) {
|
||||
api_not_allowed();
|
||||
}
|
||||
|
||||
$linkcat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
$linkedit = isset($_GET['editlink']) ? Security::remove_XSS($_GET['editlink']) : '';
|
||||
$course_code = api_get_course_id();
|
||||
$session_id = api_get_session_id();
|
||||
|
||||
if ($session_id == 0) {
|
||||
$cats = Category::load(
|
||||
null,
|
||||
null,
|
||||
$course_code,
|
||||
null,
|
||||
null,
|
||||
$session_id,
|
||||
false
|
||||
); //already init
|
||||
} else {
|
||||
$cats = Category::loadSessionCategories(null, $session_id);
|
||||
}
|
||||
|
||||
$form = new LinkAddEditForm(
|
||||
LinkAddEditForm::TYPE_EDIT,
|
||||
$cats,
|
||||
null,
|
||||
$link,
|
||||
'edit_link_form',
|
||||
api_get_self().'?selectcat='.$linkcat.'&editlink='.$linkedit.'&'.api_get_cidreq()
|
||||
);
|
||||
if ($form->validate()) {
|
||||
$values = $form->getSubmitValues();
|
||||
$parent_cat = Category::load($values['select_gradebook']);
|
||||
$final_weight = $values['weight_mask'];
|
||||
$link->set_weight($final_weight);
|
||||
|
||||
if (!empty($values['select_gradebook'])) {
|
||||
$link->set_category_id($values['select_gradebook']);
|
||||
}
|
||||
$link->set_visible(empty($values['visible']) ? 0 : 1);
|
||||
$link->save();
|
||||
|
||||
//Update weight for attendance
|
||||
$sql = 'SELECT ref_id FROM '.$tbl_grade_links.'
|
||||
WHERE id = '.intval($_GET['editlink']).' AND type='.LINK_ATTENDANCE;
|
||||
$rs_attendance = Database::query($sql);
|
||||
if (Database::num_rows($rs_attendance) > 0) {
|
||||
$row_attendance = Database::fetch_array($rs_attendance);
|
||||
$attendance_id = $row_attendance['ref_id'];
|
||||
$sql = 'UPDATE '.$tbl_attendance.' SET
|
||||
attendance_weight ='.api_float_val($final_weight).'
|
||||
WHERE c_id = '.$course_id.' AND id = '.intval($attendance_id);
|
||||
Database::query($sql);
|
||||
}
|
||||
|
||||
//Update weight into forum thread
|
||||
$sql = 'UPDATE '.$tbl_forum_thread.' SET
|
||||
thread_weight = '.api_float_val($final_weight).'
|
||||
WHERE
|
||||
c_id = '.$course_id.' AND
|
||||
thread_id = (
|
||||
SELECT ref_id FROM '.$tbl_grade_links.'
|
||||
WHERE id='.intval($_GET['editlink']).' AND type = 5
|
||||
)';
|
||||
Database::query($sql);
|
||||
|
||||
//Update weight into student publication(work)
|
||||
$em
|
||||
->createQuery('
|
||||
UPDATE ChamiloCourseBundle:CStudentPublication w
|
||||
SET w.weight = :final_weight
|
||||
WHERE w.cId = :course
|
||||
AND w.id = (
|
||||
SELECT l.refId FROM ChamiloCoreBundle:GradebookLink l
|
||||
WHERE l.id = :link AND l.type = :type
|
||||
)
|
||||
')
|
||||
->execute([
|
||||
'final_weight' => $final_weight,
|
||||
'course' => $course_id,
|
||||
'link' => intval($_GET['editlink']),
|
||||
'type' => LINK_STUDENTPUBLICATION,
|
||||
]);
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_GRADEBOOK,
|
||||
'tool_id' => 0,
|
||||
'tool_id_detail' => 0,
|
||||
'action' => 'edit-link',
|
||||
'action_details' => '',
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
header('Location: '.Category::getUrl().'linkedited=&selectcat='.$link->get_category_id());
|
||||
exit;
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$linkcat,
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
$(function() {
|
||||
$("#hide_category_id").change(function() {
|
||||
$("#hide_category_id option:selected").each(function () {
|
||||
var cat_id = $(this).val();
|
||||
$.ajax({
|
||||
url: "'.api_get_path(WEB_AJAX_PATH).'gradebook.ajax.php?a=get_gradebook_weight",
|
||||
data: "cat_id="+cat_id,
|
||||
success: function(return_value) {
|
||||
if (return_value != 0 ) {
|
||||
$("#max_weight").html(return_value);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>';
|
||||
|
||||
Display::display_header(get_lang('EditLink'));
|
||||
$form->display();
|
||||
Display::display_footer();
|
||||
87
main/gradebook/gradebook_edit_result.php
Normal file
87
main/gradebook/gradebook_edit_result.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Script.
|
||||
*
|
||||
* @package chamilo.gradebook
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$select_eval = (int) $_GET['selecteval'];
|
||||
if (empty($select_eval)) {
|
||||
api_not_allowed();
|
||||
}
|
||||
$resultedit = Result::load(null, null, $select_eval);
|
||||
$evaluation = Evaluation::load($select_eval);
|
||||
$evaluation[0]->check_lock_permissions();
|
||||
$courseInfo = api_get_course_info();
|
||||
$sessionId = api_get_session_id();
|
||||
|
||||
$edit_result_form = new EvalForm(
|
||||
EvalForm::TYPE_ALL_RESULTS_EDIT,
|
||||
$evaluation[0],
|
||||
$resultedit,
|
||||
'edit_result_form',
|
||||
null,
|
||||
api_get_self().'?selecteval='.$select_eval.'&'.api_get_cidreq()
|
||||
);
|
||||
if ($edit_result_form->validate()) {
|
||||
$values = $edit_result_form->exportValues();
|
||||
$scores = $values['score'];
|
||||
$bestResult = 0;
|
||||
$scoreFinalList = [];
|
||||
foreach ($scores as $userId => $score) {
|
||||
/** @var array $resultedit */
|
||||
$resultedit = Result::load($userId);
|
||||
/** @var Result $result */
|
||||
$result = $resultedit[0];
|
||||
|
||||
if (empty($score)) {
|
||||
$score = 0;
|
||||
}
|
||||
|
||||
$scoreFinalList[$result->get_user_id()] = $score;
|
||||
|
||||
if ($score > $bestResult) {
|
||||
$bestResult = $score;
|
||||
}
|
||||
$score = api_number_format($score, api_get_setting('gradebook_number_decimals'));
|
||||
$result->set_score($score);
|
||||
$result->save();
|
||||
|
||||
$allowMultipleAttempts = api_get_configuration_value('gradebook_multiple_evaluation_attempts');
|
||||
if ($allowMultipleAttempts) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_ATTEMPT);
|
||||
$now = api_get_utc_datetime();
|
||||
$params = [
|
||||
'result_id' => $result->get_id(),
|
||||
'score' => $score,
|
||||
'comment' => '',
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
Database::insert($table, $params);
|
||||
}
|
||||
}
|
||||
Display::addFlash(Display::return_message(get_lang('AllResultsEdited')));
|
||||
header('Location: gradebook_view_result.php?selecteval='.$select_eval.'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
|
||||
$table = $edit_result_form->toHtml();
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => 'gradebook_view_result.php?selecteval='.$select_eval.'&'.api_get_cidreq(),
|
||||
'name' => get_lang('ViewResult'),
|
||||
];
|
||||
Display::display_header(get_lang('EditResult'));
|
||||
DisplayGradebook::display_header_result($evaluation[0], null, 0, 0);
|
||||
echo $table;
|
||||
Display::display_footer();
|
||||
329
main/gradebook/gradebook_flatview.php
Normal file
329
main/gradebook/gradebook_flatview.php
Normal file
@@ -0,0 +1,329 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/fe/exportgradebook.php';
|
||||
|
||||
$current_course_tool = TOOL_GRADEBOOK;
|
||||
|
||||
api_protect_course_script(true);
|
||||
|
||||
api_block_anonymous_users();
|
||||
$isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
|
||||
api_get_user_id(),
|
||||
api_get_course_info()
|
||||
);
|
||||
|
||||
if (!$isDrhOfCourse) {
|
||||
GradebookUtils::block_students();
|
||||
}
|
||||
|
||||
$categoryId = isset($_REQUEST['selectcat']) ? (int) $_REQUEST['selectcat'] : 0;
|
||||
|
||||
if (isset($_POST['submit']) && isset($_POST['keyword'])) {
|
||||
header('Location: '.api_get_self().'?selectcat='.$categoryId.'&search='.Security::remove_XSS($_POST['keyword']));
|
||||
exit;
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat=1',
|
||||
'name' => get_lang('ToolGradebook'),
|
||||
];
|
||||
|
||||
$showeval = isset($_POST['showeval']) ? '1' : '0';
|
||||
$showlink = isset($_POST['showlink']) ? '1' : '0';
|
||||
if ($showlink == '0' && $showeval == '0') {
|
||||
$showlink = '1';
|
||||
$showeval = '1';
|
||||
}
|
||||
|
||||
$cat = Category::load($categoryId);
|
||||
$userId = isset($_GET['userid']) ? (int) $_GET['userid'] : 0;
|
||||
|
||||
$alleval = null;
|
||||
if ($showeval) {
|
||||
$alleval = $cat[0]->get_evaluations($userId, true);
|
||||
}
|
||||
|
||||
$alllinks = null;
|
||||
if ($showlink) {
|
||||
$alllinks = $cat[0]->get_links($userId, true);
|
||||
}
|
||||
|
||||
if (isset($export_flatview_form) && 'pdf' === !$file_type) {
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
$export_flatview_form->toHtml(),
|
||||
'normal',
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
$category_id = 0;
|
||||
if (isset($_GET['selectcat'])) {
|
||||
$category_id = (int) $_GET['selectcat'];
|
||||
}
|
||||
|
||||
$simple_search_form = new UserForm(
|
||||
UserForm::TYPE_SIMPLE_SEARCH,
|
||||
null,
|
||||
'simple_search_form',
|
||||
null,
|
||||
api_get_self().'?selectcat='.$category_id.'&'.api_get_cidreq()
|
||||
);
|
||||
$values = $simple_search_form->exportValues();
|
||||
|
||||
$keyword = '';
|
||||
if (isset($_GET['search']) && !empty($_GET['search'])) {
|
||||
$keyword = Security::remove_XSS($_GET['search']);
|
||||
}
|
||||
if ($simple_search_form->validate() && empty($keyword)) {
|
||||
$keyword = $values['keyword'];
|
||||
}
|
||||
|
||||
if (!empty($keyword)) {
|
||||
$users = GradebookUtils::find_students($keyword);
|
||||
} else {
|
||||
$users = null;
|
||||
if (isset($alleval) && isset($alllinks)) {
|
||||
$users = GradebookUtils::get_all_users($alleval, $alllinks);
|
||||
}
|
||||
}
|
||||
$offset = isset($_GET['offset']) ? $_GET['offset'] : '0';
|
||||
|
||||
$addparams = ['selectcat' => $cat[0]->get_id()];
|
||||
if (isset($_GET['search'])) {
|
||||
$addparams['search'] = $keyword;
|
||||
}
|
||||
|
||||
// Main course category
|
||||
$mainCourseCategory = Category::load(
|
||||
null,
|
||||
null,
|
||||
api_get_course_id(),
|
||||
null,
|
||||
null,
|
||||
api_get_session_id()
|
||||
);
|
||||
|
||||
$flatViewTable = new FlatViewTable(
|
||||
$cat[0],
|
||||
$users,
|
||||
$alleval,
|
||||
$alllinks,
|
||||
true,
|
||||
$offset,
|
||||
$addparams,
|
||||
$mainCourseCategory[0]
|
||||
);
|
||||
|
||||
$flatViewTable->setAutoFill(false);
|
||||
$parameters = ['selectcat' => $categoryId];
|
||||
$flatViewTable->set_additional_parameters($parameters);
|
||||
|
||||
$params = [];
|
||||
if (isset($_GET['export_pdf']) && 'category' === $_GET['export_pdf']) {
|
||||
$params['only_total_category'] = true;
|
||||
$params['join_firstname_lastname'] = true;
|
||||
$params['show_official_code'] = true;
|
||||
$params['export_pdf'] = true;
|
||||
if ($cat[0]->is_locked() == true || api_is_platform_admin()) {
|
||||
Display::set_header(null, false, false);
|
||||
GradebookUtils::export_pdf_flatview(
|
||||
$flatViewTable,
|
||||
$cat,
|
||||
$users,
|
||||
$alleval,
|
||||
$alllinks,
|
||||
$params,
|
||||
$mainCourseCategory[0]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['exportpdf'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => api_get_self().'?selectcat='.$categoryId.'&'.api_get_cidreq(),
|
||||
'name' => get_lang('FlatView'),
|
||||
];
|
||||
|
||||
$pageNum = isset($_GET['flatviewlist_page_nr']) ? intval($_GET['flatviewlist_page_nr']) : null;
|
||||
$perPage = isset($_GET['flatviewlist_per_page']) ? intval($_GET['flatviewlist_per_page']) : null;
|
||||
$url = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
|
||||
'exportpdf' => '',
|
||||
'offset' => $offset,
|
||||
'selectcat' => $categoryId,
|
||||
'flatviewlist_page_nr' => $pageNum,
|
||||
'flatviewlist_per_page' => $perPage,
|
||||
]);
|
||||
|
||||
$export_pdf_form = new DataForm(
|
||||
DataForm::TYPE_EXPORT_PDF,
|
||||
'export_pdf_form',
|
||||
null,
|
||||
$url,
|
||||
'_blank',
|
||||
''
|
||||
);
|
||||
|
||||
if ($export_pdf_form->validate()) {
|
||||
$params = $export_pdf_form->exportValues();
|
||||
Display::set_header();
|
||||
$params['join_firstname_lastname'] = true;
|
||||
$params['show_official_code'] = true;
|
||||
$params['export_pdf'] = true;
|
||||
$params['only_total_category'] = false;
|
||||
GradebookUtils::export_pdf_flatview(
|
||||
$flatViewTable,
|
||||
$cat,
|
||||
$users,
|
||||
$alleval,
|
||||
$alllinks,
|
||||
$params,
|
||||
$mainCourseCategory[0]
|
||||
);
|
||||
} else {
|
||||
Display::display_header(get_lang('ExportPDF'));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['print'])) {
|
||||
$printable_data = GradebookUtils::get_printable_data(
|
||||
$cat[0],
|
||||
$users,
|
||||
$alleval,
|
||||
$alllinks,
|
||||
$params,
|
||||
$mainCourseCategory[0]
|
||||
);
|
||||
echo print_table(
|
||||
$printable_data[1],
|
||||
$printable_data[0],
|
||||
get_lang('FlatView'),
|
||||
$cat[0]->get_name()
|
||||
);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!empty($_GET['export_report']) &&
|
||||
'export_report' === $_GET['export_report']
|
||||
) {
|
||||
if (api_is_platform_admin() || api_is_course_admin() || api_is_session_general_coach() || $isDrhOfCourse) {
|
||||
$user_id = null;
|
||||
if (empty($_SESSION['export_user_fields'])) {
|
||||
$_SESSION['export_user_fields'] = false;
|
||||
}
|
||||
if (!api_is_allowed_to_edit() && !api_is_course_tutor()) {
|
||||
$user_id = api_get_user_id();
|
||||
}
|
||||
|
||||
$params['show_official_code'] = true;
|
||||
$onlyScore = isset($_GET['only_score']) && 1 === (int) $_GET['only_score'];
|
||||
|
||||
$printableData = GradebookUtils::get_printable_data(
|
||||
$cat[0],
|
||||
$users,
|
||||
$alleval,
|
||||
$alllinks,
|
||||
$params,
|
||||
$mainCourseCategory[0],
|
||||
$onlyScore
|
||||
);
|
||||
|
||||
switch ($_GET['export_format']) {
|
||||
case 'xls':
|
||||
ob_start();
|
||||
$export = new GradeBookResult();
|
||||
$export->exportCompleteReportXLS($printableData);
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo $content;
|
||||
break;
|
||||
case 'doc':
|
||||
ob_start();
|
||||
$export = new GradeBookResult();
|
||||
$export->exportCompleteReportDOC($printableData);
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo $content;
|
||||
break;
|
||||
case 'csv':
|
||||
default:
|
||||
ob_start();
|
||||
$export = new GradeBookResult();
|
||||
$export->exportCompleteReportCSV($printableData);
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
echo $content;
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
}
|
||||
|
||||
$this_section = SECTION_COURSES;
|
||||
if (isset($_GET['selectcat']) && ($_SESSION['studentview'] === 'teacherview')) {
|
||||
$htmlHeadXtra[] = '<script>
|
||||
$(function() {
|
||||
$("#dialog:ui-dialog").dialog("destroy");
|
||||
$("#dialog-confirm").dialog({
|
||||
autoOpen: false,
|
||||
show: "blind",
|
||||
resizable: false,
|
||||
height:300,
|
||||
modal: true
|
||||
});
|
||||
|
||||
$(".export_opener").click(function() {
|
||||
var targetUrl = $(this).attr("href");
|
||||
$("#dialog-confirm").dialog({
|
||||
width:400,
|
||||
height:300,
|
||||
buttons: {
|
||||
"'.addslashes(get_lang('Download')).'": function() {
|
||||
let onlyScore = $("input[name=only_score]").prop("checked") ? 1 : 0;
|
||||
location.href = targetUrl+"&only_score="+onlyScore;
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
$("#dialog-confirm").dialog("open");
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>';
|
||||
}
|
||||
|
||||
if (isset($_GET['exportpdf'])) {
|
||||
$export_pdf_form->display();
|
||||
} else {
|
||||
Display::display_header(get_lang('FlatView'));
|
||||
}
|
||||
if (isset($_GET['isStudentView']) && 'false' === $_GET['isStudentView']) {
|
||||
DisplayGradebook::display_header_reduce_flatview(
|
||||
$cat[0],
|
||||
$showeval,
|
||||
$showlink,
|
||||
$simple_search_form
|
||||
);
|
||||
$flatViewTable->display();
|
||||
} elseif (isset($_GET['selectcat']) && ($_SESSION['studentview'] === 'teacherview')) {
|
||||
DisplayGradebook::display_header_reduce_flatview(
|
||||
$cat[0],
|
||||
$showeval,
|
||||
$showlink,
|
||||
$simple_search_form
|
||||
);
|
||||
|
||||
// Table
|
||||
$flatViewTable->display();
|
||||
//@todo load images with jquery
|
||||
echo '<div id="contentArea" style="text-align: center;" >';
|
||||
$flatViewTable->display_graph_by_resource();
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
Display::display_footer();
|
||||
114
main/gradebook/gradebook_scoring_system.php
Normal file
114
main/gradebook/gradebook_scoring_system.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
if (api_get_setting('teachers_can_change_score_settings') !== 'true') {
|
||||
api_not_allowed();
|
||||
}
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
function plusItem(item) {
|
||||
document.getElementById(item).style.display = "inline";
|
||||
document.getElementById("plus-"+item).style.display = "none";
|
||||
document.getElementById("min-"+(item-1)).style.display = "none";
|
||||
document.getElementById("min-"+(item)).style.display = "inline";
|
||||
document.getElementById("plus-"+(item+1)).style.display = "inline";
|
||||
}
|
||||
|
||||
function minItem(item) {
|
||||
if (item != 1) {
|
||||
document.getElementById(item).style.display = "none";
|
||||
document.getElementById("txta-"+item).value = "";
|
||||
document.getElementById("txtb-"+item).value = "";
|
||||
document.getElementById("plus-"+item).style.display = "inline";
|
||||
document.getElementById("min-"+(item-1)).style.display = "inline";
|
||||
document.getElementById("txta-"+(item-1)).value = "100";
|
||||
}
|
||||
if (item = 1) {
|
||||
document.getElementById("min-"+(item)).style.display = "none";
|
||||
}
|
||||
}
|
||||
</script>';
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat=1',
|
||||
'name' => get_lang('ToolGradebook'),
|
||||
];
|
||||
|
||||
$categoryId = (int) $_GET['selectcat'];
|
||||
if (empty($categoryId)) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$displayScore = ScoreDisplay::instance($categoryId);
|
||||
$customdisplays = $displayScore->get_custom_score_display_settings();
|
||||
|
||||
$nr_items = count($customdisplays) != '0' ? count($customdisplays) : '1';
|
||||
$scoreform = new ScoreDisplayForm(
|
||||
'scoring_system_form',
|
||||
api_get_self().'?selectcat='.$categoryId.'&'.api_get_cidreq()
|
||||
);
|
||||
|
||||
if ($scoreform->validate()) {
|
||||
$value_export = $scoreform->exportValues();
|
||||
$value_export = isset($value_export) ? $scoreform->exportValues() : '';
|
||||
$values = $value_export;
|
||||
|
||||
// create new array of custom display settings
|
||||
// this loop also checks if all score ranges are unique
|
||||
$scoringDisplay = [];
|
||||
$ranges_ok = true;
|
||||
$endscore = isset($values['endscore']) ? $values['endscore'] : null;
|
||||
$displaytext = isset($values['displaytext']) ? $values['displaytext'] : null;
|
||||
for ($counter = 1; $ranges_ok && $counter <= 20; $counter++) {
|
||||
$setting = [];
|
||||
$setting['score'] = $endscore[$counter];
|
||||
$setting['display'] = $displaytext[$counter];
|
||||
if (!empty($setting['score'])) {
|
||||
foreach ($scoringDisplay as $passed_entry) {
|
||||
if ($passed_entry['score'] == $setting['score']) {
|
||||
$ranges_ok = false;
|
||||
}
|
||||
}
|
||||
$scoringDisplay[] = $setting;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ranges_ok) {
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
get_lang('NoUniqueScoreRanges'),
|
||||
'error',
|
||||
false
|
||||
)
|
||||
);
|
||||
header('Location: '.api_get_self().'?selectcat='.$categoryId.'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
|
||||
$scorecolpercent = 0;
|
||||
if ($displayScore->is_coloring_enabled()) {
|
||||
$scorecolpercent = $values['scorecolpercent'];
|
||||
}
|
||||
|
||||
if ($displayScore->is_custom() && !empty($scoringDisplay)) {
|
||||
$displayScore->updateCustomScoreDisplaySettings($scoringDisplay, $scorecolpercent);
|
||||
}
|
||||
|
||||
Display::addFlash(
|
||||
Display::return_message(get_lang('ScoringUpdated'), 'confirm', false)
|
||||
);
|
||||
|
||||
header('Location:'.api_get_self().'?selectcat='.$categoryId.'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
|
||||
$this_section = SECTION_COURSES;
|
||||
Display::display_header(get_lang('ScoreEdit'));
|
||||
$scoreform->display();
|
||||
Display::display_footer();
|
||||
76
main/gradebook/gradebook_showlog_eval.php
Normal file
76
main/gradebook/gradebook_showlog_eval.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
/**
|
||||
* Script.
|
||||
*
|
||||
* @package chamilo.gradebook
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$selectCat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$selectCat,
|
||||
'name' => get_lang('Details'),
|
||||
];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => 'gradebook_showlog_eval.php?visiblelog='.Security::remove_XSS($_GET['visiblelog']).'&selectcat='.$selectCat,
|
||||
'name' => get_lang('GradebookQualifyLog'),
|
||||
];
|
||||
$this_section = SECTION_COURSES;
|
||||
Display::display_header('');
|
||||
echo Display::page_header(get_lang('GradebookQualifyLog'));
|
||||
|
||||
$t_linkeval_log = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
|
||||
$t_user = Database::get_main_table(TABLE_MAIN_USER);
|
||||
$visible_log = Security::remove_XSS($_GET['visiblelog']);
|
||||
|
||||
$evaledit = Evaluation::load($visible_log);
|
||||
$sql = "SELECT le.name,le.description,le.weight,le.visible,le.type,le.created_at, us.user_id
|
||||
FROM $t_linkeval_log le
|
||||
INNER JOIN $t_user us
|
||||
ON le.user_id_log = us.user_id
|
||||
WHERE
|
||||
id_linkeval_log=".$evaledit[0]->get_id()." AND
|
||||
type = 'evaluation'
|
||||
";
|
||||
$result = Database::query($sql);
|
||||
$list_info = [];
|
||||
while ($row = Database::fetch_row($result)) {
|
||||
$list_info[] = $row;
|
||||
}
|
||||
|
||||
foreach ($list_info as $key => $info_log) {
|
||||
$list_info[$key][5] = $info_log[5] ? api_convert_and_format_date($info_log[5]) : 'N/A';
|
||||
$list_info[$key][3] = $info_log[3] == 1 ? get_lang('GradebookVisible') : get_lang('GradebookInvisible');
|
||||
$userInfo = api_get_user_info($info_log[6]);
|
||||
if ($userInfo) {
|
||||
$list_info[$key][6] = $userInfo['complete_name_with_message_link'];
|
||||
} else {
|
||||
$list_info[$key][6] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$parameters = [
|
||||
'visiblelog' => $visible_log,
|
||||
'selectcat' => intval($_GET['selectcat']),
|
||||
];
|
||||
$table = new SortableTableFromArrayConfig($list_info, 1, 20, 'gradebookeval');
|
||||
$table->set_additional_parameters($parameters);
|
||||
|
||||
$table->set_header(0, get_lang('GradebookNameLog'));
|
||||
$table->set_header(1, get_lang('GradebookDescriptionLog'));
|
||||
$table->set_header(2, get_lang('GradebookPreviousWeight'));
|
||||
$table->set_header(3, get_lang('GradebookVisibilityLog'));
|
||||
$table->set_header(4, get_lang('ResourceType'));
|
||||
$table->set_header(5, get_lang('Date'));
|
||||
$table->set_header(6, get_lang('GradebookWhoChangedItLog'));
|
||||
|
||||
$table->display();
|
||||
Display::display_footer();
|
||||
69
main/gradebook/gradebook_showlog_link.php
Normal file
69
main/gradebook/gradebook_showlog_link.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Script.
|
||||
*
|
||||
* @package chamilo.gradebook
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
GradebookUtils::block_students();
|
||||
|
||||
$selectCat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$selectCat,
|
||||
'name' => get_lang('Details'),
|
||||
];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => 'gradebook_showlog_link.php?visiblelink='.Security::remove_XSS($_GET['visiblelink']).'&selectcat='.$selectCat,
|
||||
'name' => get_lang('GradebookQualifyLog'),
|
||||
];
|
||||
$this_section = SECTION_COURSES;
|
||||
Display::display_header('');
|
||||
echo '<div class="actions">';
|
||||
api_display_tool_title(get_lang('GradebookQualifyLog'));
|
||||
echo '</div>';
|
||||
|
||||
$t_user = Database::get_main_table(TABLE_MAIN_USER);
|
||||
$t_link_log = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
|
||||
$visible_link = Security::remove_XSS($_GET['visiblelink']);
|
||||
$evaledit = EvalLink::load($visible_link);
|
||||
$sql = "SELECT lk.name,lk.description,lk.weight,lk.visible,lk.type,lk.created_at,us.username
|
||||
FROM ".$t_link_log." lk inner join ".$t_user." us
|
||||
ON lk.user_id_log=us.user_id
|
||||
WHERE lk.id_linkeval_log=".$evaledit[0]->get_id()." AND lk.type='link';";
|
||||
$result = Database::query($sql);
|
||||
$list_info = [];
|
||||
while ($row = Database::fetch_row($result)) {
|
||||
$list_info[] = $row;
|
||||
}
|
||||
|
||||
foreach ($list_info as $key => $info_log) {
|
||||
$list_info[$key][5] = ($info_log[5]) ? api_convert_and_format_date($info_log[5]) : 'N/A';
|
||||
$list_info[$key][3] = ($info_log[3] == 1) ? get_lang('GradebookVisible') : get_lang('GradebookInvisible');
|
||||
}
|
||||
|
||||
$parameters = [
|
||||
'visiblelink' => Security::remove_XSS($_GET['visiblelink']),
|
||||
'selectcat' => $selectCat,
|
||||
];
|
||||
|
||||
$table = new SortableTableFromArrayConfig($list_info, 1, 20, 'gradebooklink');
|
||||
$table->set_additional_parameters($parameters);
|
||||
$table->set_header(0, get_lang('GradebookNameLog'));
|
||||
$table->set_header(1, get_lang('GradebookDescriptionLog'));
|
||||
$table->set_header(2, get_lang('GradebookPreviousWeight'));
|
||||
$table->set_header(3, get_lang('GradebookVisibilityLog'));
|
||||
$table->set_header(4, get_lang('ResourceType'));
|
||||
$table->set_header(5, get_lang('Date'));
|
||||
$table->set_header(6, get_lang('GradebookWhoChangedItLog'));
|
||||
$table->display();
|
||||
|
||||
Display::display_footer();
|
||||
109
main/gradebook/gradebook_statistics.php
Normal file
109
main/gradebook/gradebook_statistics.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
|
||||
$categoryId = (int) $_GET['selecteval'];
|
||||
$eval = Evaluation::load($categoryId);
|
||||
if (!isset($eval[0])) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
/** @var Evaluation $eval */
|
||||
$eval = $eval[0];
|
||||
|
||||
if ($eval->get_category_id() < 0) {
|
||||
// if category id is negative, then the evaluation's origin is a link
|
||||
$link = LinkFactory::get_evaluation_link($eval->get_id());
|
||||
$currentcat = Category::load($link->get_category_id());
|
||||
} else {
|
||||
$currentcat = Category::load($eval->get_category_id());
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$currentcat[0]->get_id(),
|
||||
'name' => get_lang('ToolGradebook'),
|
||||
];
|
||||
|
||||
if (api_is_allowed_to_edit()) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => 'gradebook_view_result.php?selecteval='.$categoryId.'&'.api_get_cidreq(),
|
||||
'name' => get_lang('ViewResult'),
|
||||
];
|
||||
}
|
||||
$displayScore = ScoreDisplay::instance();
|
||||
|
||||
Display::display_header(get_lang('EvaluationStatistics'));
|
||||
DisplayGradebook::display_header_result(
|
||||
$eval,
|
||||
$currentcat[0]->get_id(),
|
||||
0,
|
||||
'statistics'
|
||||
);
|
||||
|
||||
// Bad, Regular, Good - User definitions
|
||||
$displays = $displayScore->get_custom_score_display_settings();
|
||||
|
||||
if (!$displayScore->is_custom() || empty($displays)) {
|
||||
if (api_is_platform_admin() || api_is_course_admin()) {
|
||||
echo Display::return_message(get_lang('PleaseEnableScoringSystem'), 'error', false);
|
||||
}
|
||||
} else {
|
||||
$allresults = Result::load(null, null, $eval->get_id());
|
||||
$nr_items = [];
|
||||
foreach ($displays as $itemsdisplay) {
|
||||
$nr_items[$itemsdisplay['display']] = 0;
|
||||
}
|
||||
|
||||
$resultcount = 0;
|
||||
foreach ($allresults as $result) {
|
||||
$score = $result->get_score();
|
||||
if (isset($score)) {
|
||||
$display = $displayScore->display_score(
|
||||
[$score, $eval->get_max()],
|
||||
SCORE_CUSTOM,
|
||||
SCORE_ONLY_CUSTOM,
|
||||
true
|
||||
);
|
||||
$nr_items[$display]++;
|
||||
$resultcount++;
|
||||
}
|
||||
}
|
||||
|
||||
$keys = array_keys($nr_items);
|
||||
// find the region with the most scores, this is 100% of the bar
|
||||
$highest_ratio = 0;
|
||||
foreach ($keys as $key) {
|
||||
if ($nr_items[$key] > $highest_ratio) {
|
||||
$highest_ratio = $nr_items[$key];
|
||||
}
|
||||
}
|
||||
|
||||
// Generate table
|
||||
$html = '<table class="table table-hover table-striped data_table" cellspacing="0" cellpadding="3">';
|
||||
$html .= '<tr><th>'.get_lang('ScoringSystem').'</th>';
|
||||
$html .= '<th>'.get_lang('Percentage').'</th>';
|
||||
$html .= '<th>'.get_lang('CountUsers').'</th></tr>';
|
||||
$counter = 0;
|
||||
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
foreach ($keys as $key) {
|
||||
$bar = ($highest_ratio > 0 ? ($nr_items[$key] / $highest_ratio) * 100 : 0);
|
||||
$html .= '<tr class="row_'.($counter % 2 == 0 ? 'odd' : 'even').'">';
|
||||
$html .= '<td width="150">'.$key.'</td>';
|
||||
if (empty($model)) {
|
||||
$html .= '<td width="550">'.Display::bar_progress($bar).'</td>';
|
||||
} else {
|
||||
$html .= '<td width="550">'.ExerciseLib::convertScoreToModel($bar).'</td>';
|
||||
}
|
||||
|
||||
$html .= '<td align="right">'.$nr_items[$key].'</td>';
|
||||
$html .= '</tr>';
|
||||
$counter++;
|
||||
}
|
||||
$html .= '</table>';
|
||||
echo $html;
|
||||
}
|
||||
Display::display_footer();
|
||||
689
main/gradebook/gradebook_view_result.php
Normal file
689
main/gradebook/gradebook_view_result.php
Normal file
@@ -0,0 +1,689 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/fe/exportgradebook.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
$isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
|
||||
api_get_user_id(),
|
||||
api_get_course_info()
|
||||
);
|
||||
|
||||
if (!$isDrhOfCourse) {
|
||||
GradebookUtils::block_students();
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
|
||||
//load the evaluation & category
|
||||
$select_eval = (int) $_GET['selecteval'];
|
||||
if (empty($select_eval)) {
|
||||
api_not_allowed();
|
||||
}
|
||||
|
||||
$displayscore = ScoreDisplay::instance();
|
||||
$eval = Evaluation::load($select_eval);
|
||||
$overwritescore = 0;
|
||||
if ($eval[0]->get_category_id() < 0) {
|
||||
// if category id is negative, then the evaluation's origin is a link
|
||||
$link = LinkFactory::get_evaluation_link($eval[0]->get_id());
|
||||
$currentcat = Category::load($link->get_category_id());
|
||||
} else {
|
||||
$currentcat = Category::load($eval[0]->get_category_id());
|
||||
}
|
||||
|
||||
//load the result with the evaluation id
|
||||
if (isset($_GET['delete_mark'])) {
|
||||
$result = Result::load($_GET['delete_mark']);
|
||||
if (!empty($result[0])) {
|
||||
$result[0]->delete();
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['selecteval'])) {
|
||||
$allresults = Result::load(null, null, $select_eval);
|
||||
$iscourse = !empty(api_get_course_id());
|
||||
}
|
||||
|
||||
$allowMultipleAttempts = api_get_configuration_value('gradebook_multiple_evaluation_attempts');
|
||||
|
||||
if (isset($_GET['action'])) {
|
||||
switch ($_GET['action']) {
|
||||
case 'delete_attempt':
|
||||
$result = Result::load($_GET['editres']);
|
||||
if ($allowMultipleAttempts && !empty($result) && isset($result[0]) && api_is_allowed_to_edit()) {
|
||||
/** @var Result $result */
|
||||
$result = $result[0];
|
||||
$url = api_get_self().'?selecteval='.$select_eval.'&'.api_get_cidreq().'&editres='.$result->get_id();
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_ATTEMPT);
|
||||
if (isset($_GET['result_attempt_id'])) {
|
||||
$attemptId = (int) $_GET['result_attempt_id'];
|
||||
$sql = "DELETE FROM $table WHERE result_id = ".$result->get_id()." AND id = $attemptId";
|
||||
Database::query($sql);
|
||||
Display::addFlash(Display::return_message(get_lang('Deleted')));
|
||||
}
|
||||
|
||||
header('Location: '.$url.'&action=add_attempt');
|
||||
exit;
|
||||
}
|
||||
break;
|
||||
case 'add_attempt':
|
||||
$result = Result::load($_GET['editres']);
|
||||
if ($allowMultipleAttempts && !empty($result) && isset($result[0]) && api_is_allowed_to_edit()) {
|
||||
/** @var Result $result */
|
||||
$result = $result[0];
|
||||
$backUrl = api_get_self().'?selecteval='.$select_eval.'&'.api_get_cidreq();
|
||||
$interbreadcrumb[] = [
|
||||
'url' => $backUrl,
|
||||
'name' => get_lang('Details'),
|
||||
];
|
||||
|
||||
/** @var Evaluation $evaluation */
|
||||
$evaluation = $eval[0];
|
||||
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_ATTEMPT);
|
||||
$now = api_get_utc_datetime();
|
||||
|
||||
$url = api_get_self().'?selecteval='.$select_eval.'&'.api_get_cidreq().'&editres='.$result->get_id();
|
||||
$form = new FormValidator('attempt', 'post', $url.'&action=add_attempt');
|
||||
$form->addHeader(get_lang('AddResult'));
|
||||
$form->addLabel(get_lang('CurrentScore'), $result->get_score());
|
||||
|
||||
$form->addFloat(
|
||||
'score',
|
||||
[
|
||||
get_lang('Score'),
|
||||
null,
|
||||
'/ '.$evaluation->get_max(),
|
||||
],
|
||||
true,
|
||||
[
|
||||
'size' => '4',
|
||||
'maxlength' => '5',
|
||||
],
|
||||
false,
|
||||
0,
|
||||
$evaluation->get_max()
|
||||
);
|
||||
|
||||
$form->addTextarea('comment', get_lang('Comment'));
|
||||
$form->addButtonSave(get_lang('Save'));
|
||||
$attemptList = ResultTable::getResultAttemptTable($result, $url);
|
||||
$form->addLabel(get_lang('Attempts'), $attemptList);
|
||||
|
||||
if ($form->validate()) {
|
||||
$values = $form->getSubmitValues();
|
||||
$newScore = $values['score'];
|
||||
$newScore = api_number_format(
|
||||
$newScore,
|
||||
api_get_setting('gradebook_number_decimals')
|
||||
);
|
||||
|
||||
$params = [
|
||||
'result_id' => $result->get_id(),
|
||||
'score' => $newScore,
|
||||
'comment' => $values['comment'],
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
Database::insert($table, $params);
|
||||
if ($newScore > $result->get_score()) {
|
||||
$result->set_score($newScore);
|
||||
$result->save();
|
||||
}
|
||||
Display::addFlash(Display::return_message(get_lang('Saved')));
|
||||
header('Location: '.api_get_self().'?selecteval='.$select_eval.'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
|
||||
Display::display_header();
|
||||
$items[] = [
|
||||
'url' => $backUrl,
|
||||
'content' => Display::return_icon(
|
||||
'back.png',
|
||||
get_lang('Back'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
),
|
||||
];
|
||||
echo Display::actions($items);
|
||||
$form->display();
|
||||
Display::display_footer();
|
||||
exit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['editres'])) {
|
||||
$resultedit = Result::load($_GET['editres']);
|
||||
$edit_res_form = new EvalForm(
|
||||
EvalForm::TYPE_RESULT_EDIT,
|
||||
$eval[0],
|
||||
$resultedit[0],
|
||||
'edit_result_form',
|
||||
null,
|
||||
api_get_self().'?editres='.$resultedit[0]->get_id().'&selecteval='.$select_eval.'&'.api_get_cidreq()
|
||||
);
|
||||
|
||||
if ($edit_res_form->validate()) {
|
||||
$values = $edit_res_form->exportValues();
|
||||
$result = new Result();
|
||||
$resultlog = new Result();
|
||||
$resultlog->addResultLog($values['hid_user_id'], $select_eval);
|
||||
$result->set_id($_GET['editres']);
|
||||
$result->set_user_id($values['hid_user_id']);
|
||||
$result->set_evaluation_id($select_eval);
|
||||
$row_value = isset($values['score']) ? $values['score'] : 0;
|
||||
if (!empty($row_value) || $row_value == 0) {
|
||||
$row_value = api_number_format(
|
||||
$row_value,
|
||||
api_get_setting('gradebook_number_decimals')
|
||||
);
|
||||
$result->set_score($row_value);
|
||||
}
|
||||
$result->save();
|
||||
if ($allowMultipleAttempts && !empty($result->get_id())) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_ATTEMPT);
|
||||
$now = api_get_utc_datetime();
|
||||
$params = [
|
||||
'result_id' => $result->get_id(),
|
||||
'score' => $row_value,
|
||||
'comment' => $values['comment'],
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
Database::insert($table, $params);
|
||||
}
|
||||
|
||||
Display::addFlash(Display::return_message(get_lang('ResultEdited'), 'normal', false));
|
||||
header('Location: gradebook_view_result.php?selecteval='.$select_eval.'&editresmessage=&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
}
|
||||
$file_type = null;
|
||||
if (isset($_GET['import'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => api_get_path(WEB_CODE_PATH).'gradebook/gradebook_view_result.php?selecteval='.$select_eval.'&'.api_get_cidreq(),
|
||||
'name' => get_lang('ViewResult'),
|
||||
];
|
||||
$import_result_form = new DataForm(
|
||||
DataForm::TYPE_IMPORT,
|
||||
'import_result_form',
|
||||
null,
|
||||
api_get_self().'?import=&selecteval='.$select_eval,
|
||||
'_blank',
|
||||
''
|
||||
);
|
||||
if (!$import_result_form->validate()) {
|
||||
Display::display_header(get_lang('Import'));
|
||||
}
|
||||
$eval[0]->check_lock_permissions();
|
||||
if (isset($_POST['formSent']) && $_POST['formSent']) {
|
||||
if (!empty($_FILES['import_file']['name'])) {
|
||||
$values = $import_result_form->exportValues();
|
||||
$file_type = $_POST['file_type'];
|
||||
$file_name = $_FILES['import_file']['tmp_name'];
|
||||
$results = Import::csvToArray($file_name);
|
||||
$nr_results_added = 0;
|
||||
foreach ($results as $index => $importedresult) {
|
||||
//check username & score
|
||||
$importedresult['user_id'] = UserManager::get_user_id_from_username($importedresult['username']);
|
||||
$added = '0';
|
||||
foreach ($allresults as $allresult) {
|
||||
if (($importedresult['user_id'] == $allresult->get_user_id())) {
|
||||
if ($importedresult['score'] != $allresult->get_score()) {
|
||||
if (!isset($values['overwrite'])) {
|
||||
header('Location: '.api_get_path(WEB_CODE_PATH).'gradebook/gradebook_view_result.php?selecteval='.$select_eval.'&import_score_error='.$importedresult['user_id']);
|
||||
exit;
|
||||
break;
|
||||
} else {
|
||||
GradebookUtils::overwritescore(
|
||||
$allresult->get_id(),
|
||||
$importedresult['score'],
|
||||
$eval[0]->get_max()
|
||||
);
|
||||
$overwritescore++;
|
||||
$added = '1';
|
||||
}
|
||||
} else {
|
||||
$added = '1';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($importedresult['user_id'] == null) {
|
||||
header('Location: gradebook_view_result.php?selecteval='.$select_eval.'&incorrectdata=');
|
||||
exit;
|
||||
}
|
||||
$userinfo = api_get_user_info($importedresult['user_id']);
|
||||
if ($userinfo['lastname'] != $importedresult['lastname'] ||
|
||||
$userinfo['firstname'] != $importedresult['firstname'] ||
|
||||
$userinfo['official_code'] != $importedresult['official_code']
|
||||
) {
|
||||
if (!isset($values['ignoreerrors'])) {
|
||||
header('Location: gradebook_view_result.php?selecteval='.$select_eval.'&import_user_error='.$importedresult['user_id']);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
if ($added != '1') {
|
||||
if ($importedresult['score'] > $eval[0]->get_max()) {
|
||||
header('Location: gradebook_view_result.php?selecteval='.$select_eval.'&overwritemax=');
|
||||
exit;
|
||||
}
|
||||
$result = new Result();
|
||||
$result->set_user_id($importedresult['user_id']);
|
||||
if (!empty($importedresult['score'])) {
|
||||
$result->set_score(
|
||||
api_number_format($importedresult['score'], api_get_setting('gradebook_number_decimals'))
|
||||
);
|
||||
}
|
||||
if (!empty($importedresult['date'])) {
|
||||
$result->set_date(api_get_utc_datetime($importedresult['date']));
|
||||
} else {
|
||||
$result->set_date(api_get_utc_datetime());
|
||||
}
|
||||
$result->set_evaluation_id($select_eval);
|
||||
$result->add();
|
||||
$nr_results_added++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
get_lang('ImportNoFile'),
|
||||
'warning',
|
||||
false
|
||||
)
|
||||
);
|
||||
header('Location: '.api_get_self().'?import=&selecteval='.$select_eval.'&importnofile=');
|
||||
exit;
|
||||
}
|
||||
if ($overwritescore != 0) {
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
get_lang('ImportOverWriteScore').' '.$overwritescore
|
||||
)
|
||||
);
|
||||
header('Location: '.api_get_self().'?selecteval='.$select_eval.'&importoverwritescore='.$overwritescore);
|
||||
exit;
|
||||
}
|
||||
if ($nr_results_added == 0) {
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
get_lang('ProblemUploadingFile'),
|
||||
'warning',
|
||||
false
|
||||
)
|
||||
);
|
||||
header('Location: '.api_get_self().'?selecteval='.$select_eval.'¬hingadded=');
|
||||
exit;
|
||||
}
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
get_lang('FileUploadComplete'),
|
||||
'success',
|
||||
false
|
||||
)
|
||||
);
|
||||
header('Location: '.api_get_self().'?selecteval='.$select_eval.'&importok=');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['export'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => 'gradebook_view_result.php?selecteval='.$select_eval.'&'.api_get_cidreq(),
|
||||
'name' => get_lang('ViewResult'),
|
||||
];
|
||||
$locked_status = $eval[0]->get_locked();
|
||||
$export_result_form = new DataForm(
|
||||
DataForm::TYPE_EXPORT,
|
||||
'export_result_form',
|
||||
null,
|
||||
api_get_self().'?export=&selecteval='.$select_eval.'&'.api_get_cidreq(),
|
||||
'_blank',
|
||||
$locked_status
|
||||
);
|
||||
if (!$export_result_form->validate()) {
|
||||
Display::display_header(get_lang('Export'));
|
||||
}
|
||||
|
||||
if ($export_result_form->validate()) {
|
||||
$export = $export_result_form->exportValues();
|
||||
$file_type = $export['file_type'];
|
||||
$filename = 'export_results_'.gmdate('Y-m-d_H-i-s');
|
||||
$results = Result::load(null, null, $select_eval);
|
||||
$data = []; //when file type is csv, add a header to the output file
|
||||
if ($file_type == 'csv') {
|
||||
$alldata[] = [
|
||||
'username',
|
||||
'official_code',
|
||||
'lastname',
|
||||
'firstname',
|
||||
'score',
|
||||
'date',
|
||||
];
|
||||
}
|
||||
|
||||
// export results to pdf file
|
||||
if ($file_type == 'pdf') {
|
||||
$number_decimals = api_get_setting('gradebook_number_decimals');
|
||||
$datagen = new ResultsDataGenerator($eval[0], $allresults);
|
||||
|
||||
// set headers pdf
|
||||
!empty($_user['official_code']) ? $officialcode = $_user['official_code'].' - ' : '';
|
||||
|
||||
$h1 = [get_lang('Teacher'), $officialcode.$_user['firstName'].', '.$_user['lastName']];
|
||||
$h2 = [get_lang('Score'), $eval[0]->get_max()];
|
||||
$h3 = [get_lang('Course'), $_course['name']];
|
||||
$h4 = [get_lang('Weight'), $eval[0]->get_weight()];
|
||||
$h5 = [get_lang('Session'), api_get_session_name(api_get_session_id())];
|
||||
$date = date('d-m-Y H:i:s', time());
|
||||
$h6 = [get_lang('DateTime'), api_convert_and_format_date($date, "%d/%m/%Y %H:%M")];
|
||||
$header_pdf = [$h1, $h2, $h3, $h4, $h5, $h6];
|
||||
|
||||
// set footer pdf
|
||||
$f1 = '<hr />'.get_lang('Drh');
|
||||
$f2 = '<hr />'.get_lang('Teacher');
|
||||
$f3 = '<hr />'.get_lang('Date');
|
||||
$footer_pdf = [$f1, $f2, $f3];
|
||||
|
||||
// set title pdf
|
||||
$title_pdf = $eval[0]->get_name();
|
||||
|
||||
// set headers data table
|
||||
$head_ape_name = '';
|
||||
if (api_is_western_name_order()) {
|
||||
$head_ape_name = get_lang('FirstName').', '.get_lang('LastName');
|
||||
} else {
|
||||
$head_ape_name = get_lang('LastName').', '.get_lang('FirstName');
|
||||
}
|
||||
|
||||
$head_table = [
|
||||
['#', 3],
|
||||
[get_lang('Code'), 12],
|
||||
[$head_ape_name, 40],
|
||||
[get_lang('Score'), 12],
|
||||
];
|
||||
if ($number_decimals == null) {
|
||||
$head_table[] = [get_lang('Letters'), 15];
|
||||
}
|
||||
$head_display_score = '';
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$customdisplays = $scoredisplay->get_custom_score_display_settings();
|
||||
|
||||
if (!empty($customdisplays) && $scoredisplay->is_custom()) {
|
||||
$head_display_score = get_lang('Display');
|
||||
$head_table[] = [$head_display_score, 15];
|
||||
}
|
||||
|
||||
// get data table
|
||||
if (api_sort_by_first_name()) {
|
||||
$data_array = $datagen->get_data(
|
||||
ResultsDataGenerator::RDG_SORT_FIRSTNAME,
|
||||
0,
|
||||
null,
|
||||
false,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
$data_array = $datagen->get_data(
|
||||
ResultsDataGenerator::RDG_SORT_LASTNAME,
|
||||
0,
|
||||
null,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
$data_table = [];
|
||||
foreach ($data_array as $data) {
|
||||
$result = [];
|
||||
$user_info = api_get_user_info($data['id']);
|
||||
$result[] = $user_info['username'];
|
||||
|
||||
if (api_is_western_name_order()) {
|
||||
$result[] = $user_info['firstname'].', '.$user_info['lastname'];
|
||||
} else {
|
||||
$result[] = $user_info['lastname'].', '.$user_info['firstname'];
|
||||
}
|
||||
if ($number_decimals == null) {
|
||||
if (empty($data['scoreletter']) && !is_numeric($data['score'])) {
|
||||
$result[] = get_lang('DidNotTakeTheExam');
|
||||
} else {
|
||||
$result[] = api_strtoupper(get_lang('Literal'.$data['scoreletter']));
|
||||
}
|
||||
} else {
|
||||
if (empty($data['score']) && !is_numeric($data['score'])) {
|
||||
$result[] = get_lang('DidNotTakeTheExamAcronym');
|
||||
} else {
|
||||
$result[] = $data['score'];
|
||||
}
|
||||
}
|
||||
if ($scoredisplay->is_custom()) {
|
||||
$result[] = $data['display'];
|
||||
}
|
||||
$data_table[] = $result;
|
||||
}
|
||||
|
||||
export_pdf_with_html(
|
||||
$head_table,
|
||||
$data_table,
|
||||
$header_pdf,
|
||||
$footer_pdf,
|
||||
$title_pdf
|
||||
);
|
||||
}
|
||||
|
||||
// export results to xml or csv file
|
||||
foreach ($results as $result) {
|
||||
$userinfo = api_get_user_info($result->get_user_id());
|
||||
$data['username'] = $userinfo['username']; //$result->get_user_id();
|
||||
$data['official_code'] = $userinfo['official_code'];
|
||||
$data['lastname'] = $userinfo['lastname'];
|
||||
$data['firstname'] = $userinfo['firstname'];
|
||||
$data['score'] = $result->get_score();
|
||||
$data['date'] = api_format_date($result->get_date(), "%d/%m/%Y %R");
|
||||
$alldata[] = $data;
|
||||
}
|
||||
|
||||
switch ($file_type) {
|
||||
case 'xml':
|
||||
Export::arrayToXml(
|
||||
$alldata,
|
||||
$filename,
|
||||
'Result',
|
||||
'XMLResults'
|
||||
);
|
||||
exit;
|
||||
break;
|
||||
case 'csv':
|
||||
Export::arrayToCsv($alldata, $filename);
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['resultdelete'])) {
|
||||
$result = Result::load($_GET['resultdelete']);
|
||||
$result[0]->delete();
|
||||
Display::addFlash(Display::return_message(get_lang('ResultDeleted')));
|
||||
header('Location: gradebook_view_result.php?selecteval='.$select_eval.'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_POST['action'])) {
|
||||
$number_of_selected_items = count($_POST['id']);
|
||||
if ($number_of_selected_items == '0') {
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
get_lang('NoItemsSelected'),
|
||||
'warning',
|
||||
false
|
||||
)
|
||||
);
|
||||
} else {
|
||||
switch ($_POST['action']) {
|
||||
case 'delete':
|
||||
$number_of_deleted_results = 0;
|
||||
foreach ($_POST['id'] as $indexstr) {
|
||||
$result = Result::load($indexstr);
|
||||
$result[0]->delete();
|
||||
$number_of_deleted_results++;
|
||||
}
|
||||
Display::addFlash(Display::return_message(get_lang('ResultsDeleted'), 'confirmation', false));
|
||||
header('Location: gradebook_view_result.php?massdelete=&selecteval='.$select_eval.'&'.api_get_cidreq());
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // TODO - what if selecteval not set ?
|
||||
|
||||
$addparams = ['selecteval' => $eval[0]->get_id()];
|
||||
if (isset($_GET['print'])) {
|
||||
$datagen = new ResultsDataGenerator($eval[0], $allresults);
|
||||
if (api_sort_by_first_name()) {
|
||||
$data_array = $datagen->get_data(
|
||||
ResultsDataGenerator::RDG_SORT_FIRSTNAME,
|
||||
0,
|
||||
null,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
$data_array = $datagen->get_data(
|
||||
ResultsDataGenerator::RDG_SORT_LASTNAME,
|
||||
0,
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
if ($displayscore->is_custom()) {
|
||||
if (api_is_western_name_order()) {
|
||||
$header_names = [
|
||||
get_lang('FirstName'),
|
||||
get_lang('LastName'),
|
||||
get_lang('Score'),
|
||||
get_lang('Display'),
|
||||
];
|
||||
} else {
|
||||
$header_names = [
|
||||
get_lang('LastName'),
|
||||
get_lang('FirstName'),
|
||||
get_lang('Score'),
|
||||
get_lang('Display'),
|
||||
];
|
||||
}
|
||||
} else {
|
||||
if (api_is_western_name_order()) {
|
||||
$header_names = [get_lang('FirstName'), get_lang('LastName'), get_lang('Score')];
|
||||
} else {
|
||||
$header_names = [get_lang('LastName'), get_lang('FirstName'), get_lang('Score')];
|
||||
}
|
||||
}
|
||||
$newarray = [];
|
||||
foreach ($data_array as $data) {
|
||||
$newarray[] = array_slice($data, 3);
|
||||
}
|
||||
|
||||
echo print_table(
|
||||
$newarray,
|
||||
$header_names,
|
||||
get_lang('ViewResult'),
|
||||
$eval[0]->get_name()
|
||||
);
|
||||
exit;
|
||||
} else {
|
||||
$resultTable = new ResultTable($eval[0], $allresults, $iscourse, $addparams);
|
||||
}
|
||||
|
||||
$htmlHeadXtra[] = '<script>
|
||||
function confirmationuser() {
|
||||
if (confirm("'.get_lang('DeleteUser').'?"))
|
||||
{return true;}
|
||||
else
|
||||
{return false;}
|
||||
}
|
||||
|
||||
function confirmationall () {
|
||||
if (confirm("'.get_lang('DeleteAll').'?"))
|
||||
{return true;}
|
||||
else
|
||||
{return false;}
|
||||
}
|
||||
</script>';
|
||||
if (isset($_GET['deleteall'])) {
|
||||
$eval[0]->delete_results();
|
||||
Display::addFlash(Display::return_message(get_lang('AllResultDeleted')));
|
||||
header('Location: '.api_get_path(WEB_CODE_PATH).'gradebook/gradebook_view_result.php?allresdeleted=&selecteval='.$select_eval.'&'.api_get_cidreq());
|
||||
exit;
|
||||
}
|
||||
if (!isset($_GET['export']) && (!isset($_GET['import']))) {
|
||||
if (!isset($_GET['selectcat'])) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl().'selectcat='.$currentcat[0]->get_id(),
|
||||
'name' => get_lang('Details'),
|
||||
];
|
||||
}
|
||||
$interbreadcrumb[] = [
|
||||
'url' => api_get_path(WEB_CODE_PATH).'gradebook/gradebook_view_result.php?selecteval='.$select_eval.'&'.api_get_cidreq(),
|
||||
'name' => get_lang('ViewResult'),
|
||||
];
|
||||
Display::display_header();
|
||||
}
|
||||
|
||||
if (isset($_GET['adduser'])) {
|
||||
echo Display::return_message(get_lang('UserAdded'), 'confirmation', false);
|
||||
}
|
||||
|
||||
if (isset($_GET['incorrectdata'])) {
|
||||
echo Display::return_message(get_lang('IncorrectData'), 'warning', false);
|
||||
}
|
||||
|
||||
if (isset($_GET['nouser'])) {
|
||||
echo Display::return_message(get_lang('NoUser'), 'warning', false);
|
||||
}
|
||||
if (isset($_GET['overwritemax'])) {
|
||||
echo Display::return_message(get_lang('OverWriteMax'), 'warning', false);
|
||||
}
|
||||
|
||||
if (isset($_GET['import_user_error'])) {
|
||||
$userinfo = api_get_user_info($_GET['import_user_error']);
|
||||
echo Display::return_message(
|
||||
get_lang('UserInfoDoesNotMatch').' '.
|
||||
api_get_person_name($userinfo['firstname'], $userinfo['lastname']),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
if (isset($_GET['import_score_error'])) {
|
||||
$userinfo = api_get_user_info($_GET['import_score_error']);
|
||||
echo Display::return_message(
|
||||
get_lang('ScoreDoesNotMatch').' '.
|
||||
api_get_person_name($userinfo['firstname'], $userinfo['lastname']),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
|
||||
if ($file_type == null) {
|
||||
//show the result header
|
||||
if (isset($export_result_form) && !(isset($edit_res_form))) {
|
||||
echo $export_result_form->display();
|
||||
DisplayGradebook::display_header_result($eval[0], $currentcat[0]->get_id(), 1);
|
||||
} else {
|
||||
if (isset($import_result_form)) {
|
||||
echo $import_result_form->display();
|
||||
}
|
||||
if (isset($edit_res_form)) {
|
||||
echo $edit_res_form->toHtml();
|
||||
}
|
||||
DisplayGradebook::display_header_result($eval[0], $currentcat[0]->get_id(), 1);
|
||||
}
|
||||
// Letter-based scores are built from lib/results_data_generator.class.php::get_score_display()
|
||||
$resultTable->display();
|
||||
Display::display_footer();
|
||||
}
|
||||
1065
main/gradebook/index.php
Normal file
1065
main/gradebook/index.php
Normal file
File diff suppressed because it is too large
Load Diff
1755
main/gradebook/lib/GradebookUtils.php
Normal file
1755
main/gradebook/lib/GradebookUtils.php
Normal file
File diff suppressed because it is too large
Load Diff
38
main/gradebook/lib/be/PortfolioLink.php
Normal file
38
main/gradebook/lib/be/PortfolioLink.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class PortfolioLink.
|
||||
*/
|
||||
class PortfolioLink extends EvalLink
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->set_type(LINK_PORTFOLIO);
|
||||
}
|
||||
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('Portfolio');
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'portfolio';
|
||||
}
|
||||
|
||||
protected function get_evaluation()
|
||||
{
|
||||
$this->evaluation = parent::get_evaluation();
|
||||
$this->evaluation->set_type('portfolio');
|
||||
|
||||
return $this->evaluation;
|
||||
}
|
||||
}
|
||||
803
main/gradebook/lib/be/abstractlink.class.php
Normal file
803
main/gradebook/lib/be/abstractlink.class.php
Normal file
@@ -0,0 +1,803 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\GradebookLink;
|
||||
|
||||
/**
|
||||
* Class AbstractLink
|
||||
* Defines a gradebook AbstractLink object.
|
||||
* To implement specific links,
|
||||
* extend this class and define a type in LinkFactory.
|
||||
* Use the methods in LinkFactory to create link objects.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
* @author Julio Montoya <gugli100@gmail.com> security improvements
|
||||
*/
|
||||
abstract class AbstractLink implements GradebookItem
|
||||
{
|
||||
public $course_id;
|
||||
public $studentList;
|
||||
/** @var GradebookLink */
|
||||
public $entity;
|
||||
protected $id;
|
||||
protected $type;
|
||||
protected $ref_id;
|
||||
protected $user_id;
|
||||
protected $course_code;
|
||||
/** @var Category */
|
||||
protected $category;
|
||||
protected $created_at;
|
||||
protected $weight;
|
||||
protected $visible;
|
||||
protected $session_id;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->course_id = api_get_course_int_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function has_results();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function get_link();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function is_valid_link();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function get_type_name();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function needs_name_and_description();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function needs_max();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function needs_results();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function is_allowed_to_change_name();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_id()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_ref_id()
|
||||
{
|
||||
return (int) $this->ref_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_session_id()
|
||||
{
|
||||
return (int) $this->session_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_user_id()
|
||||
{
|
||||
return $this->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_course_code()
|
||||
{
|
||||
return $this->course_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Category
|
||||
*/
|
||||
public function getCategory()
|
||||
{
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*/
|
||||
public function setCategory($category)
|
||||
{
|
||||
$this->category = $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_category_id()
|
||||
{
|
||||
return $this->category->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $category_id
|
||||
*/
|
||||
public function set_category_id($category_id)
|
||||
{
|
||||
$categories = Category::load($category_id);
|
||||
if (isset($categories[0])) {
|
||||
$this->setCategory($categories[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public function get_date()
|
||||
{
|
||||
return $this->created_at;
|
||||
}
|
||||
|
||||
public function get_weight()
|
||||
{
|
||||
return $this->weight;
|
||||
}
|
||||
|
||||
public function is_locked()
|
||||
{
|
||||
return isset($this->locked) && 1 == $this->locked ? true : false;
|
||||
}
|
||||
|
||||
public function is_visible()
|
||||
{
|
||||
return $this->visible;
|
||||
}
|
||||
|
||||
public function set_id($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function set_type($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function set_ref_id($ref_id)
|
||||
{
|
||||
$this->ref_id = $ref_id;
|
||||
}
|
||||
|
||||
public function set_user_id($user_id)
|
||||
{
|
||||
$this->user_id = $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $course_code
|
||||
*/
|
||||
public function set_course_code($course_code)
|
||||
{
|
||||
$courseInfo = api_get_course_info($course_code);
|
||||
if ($courseInfo) {
|
||||
$this->course_code = $course_code;
|
||||
$this->course_id = $courseInfo['real_id'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getStudentList()
|
||||
{
|
||||
if (empty($this->studentList)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->studentList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $list
|
||||
*/
|
||||
public function setStudentList($list)
|
||||
{
|
||||
$this->studentList = $list;
|
||||
}
|
||||
|
||||
public function set_date($date)
|
||||
{
|
||||
$this->created_at = $date;
|
||||
}
|
||||
|
||||
public function set_weight($weight)
|
||||
{
|
||||
$this->weight = $weight;
|
||||
}
|
||||
|
||||
public function set_visible($visible)
|
||||
{
|
||||
$this->visible = $visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*/
|
||||
public function set_session_id($id)
|
||||
{
|
||||
$this->session_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $locked
|
||||
*/
|
||||
public function set_locked($locked)
|
||||
{
|
||||
$this->locked = $locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCourseId()
|
||||
{
|
||||
return (int) $this->course_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve links and return them as an array of extensions of AbstractLink.
|
||||
* To keep consistency, do not call this method but LinkFactory::load instead.
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $type
|
||||
* @param int $ref_id
|
||||
* @param int $user_id
|
||||
* @param string $course_code
|
||||
* @param int $category_id
|
||||
* @param int $visible
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function load(
|
||||
$id = null,
|
||||
$type = null,
|
||||
$ref_id = null,
|
||||
$user_id = null,
|
||||
$course_code = null,
|
||||
$category_id = null,
|
||||
$visible = null
|
||||
) {
|
||||
$tbl_grade_links = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$sql = 'SELECT * FROM '.$tbl_grade_links;
|
||||
$paramcount = 0;
|
||||
if (isset($id)) {
|
||||
$sql .= ' WHERE id = '.intval($id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($type)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' type = '.intval($type);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($ref_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' ref_id = '.intval($ref_id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($user_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' user_id = '.intval($user_id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($course_code)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= " course_code = '".Database::escape_string($course_code)."'";
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($category_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' category_id = '.intval($category_id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (isset($visible)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' visible = '.intval($visible);
|
||||
}
|
||||
|
||||
$result = Database::query($sql);
|
||||
$links = self::create_objects_from_sql_result($result);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert this link into the database.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->add_linked_data();
|
||||
if (isset($this->type) &&
|
||||
isset($this->ref_id) &&
|
||||
isset($this->user_id) &&
|
||||
isset($this->course_code) &&
|
||||
isset($this->category) &&
|
||||
isset($this->weight) &&
|
||||
isset($this->visible)
|
||||
) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$sql = "SELECT count(*) count FROM $table
|
||||
WHERE
|
||||
ref_id = ".$this->get_ref_id()." AND
|
||||
category_id = ".$this->category->get_id()." AND
|
||||
course_code = '".$this->course_code."' AND
|
||||
type = ".$this->type;
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
|
||||
if ($row['count'] == 0) {
|
||||
$params = [
|
||||
'type' => $this->get_type(),
|
||||
'ref_id' => $this->get_ref_id(),
|
||||
'user_id' => $this->get_user_id(),
|
||||
'course_code' => $this->get_course_code(),
|
||||
'category_id' => $this->get_category_id(),
|
||||
'weight' => $this->get_weight(),
|
||||
'visible' => $this->is_visible(),
|
||||
'created_at' => api_get_utc_datetime(),
|
||||
'locked' => 0,
|
||||
];
|
||||
$id = Database::insert($table, $params);
|
||||
$this->set_id($id);
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the properties of this link in the database.
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$em = Database::getManager();
|
||||
|
||||
$link = $em->find('ChamiloCoreBundle:GradebookLink', $this->id);
|
||||
|
||||
if (!$link) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::add_link_log($this->id);
|
||||
|
||||
$this->save_linked_data();
|
||||
|
||||
$link
|
||||
->setType($this->get_type())
|
||||
->setRefId($this->get_ref_id())
|
||||
->setUserId($this->get_user_id())
|
||||
->setCourseCode($this->get_course_code())
|
||||
->setCategoryId($this->get_category_id())
|
||||
->setWeight($this->get_weight())
|
||||
->setVisible($this->is_visible());
|
||||
|
||||
$em->merge($link);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $evaluationId
|
||||
*/
|
||||
public static function add_link_log($evaluationId, $nameLog = null)
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
|
||||
$dateobject = self::load($evaluationId, null, null, null, null);
|
||||
$now = api_get_utc_datetime();
|
||||
$arreval = get_object_vars($dateobject[0]);
|
||||
$description_log = isset($arreval['description']) ? $arreval['description'] : '';
|
||||
if (empty($nameLog)) {
|
||||
if (isset($_POST['name_link'])) {
|
||||
$name_log = isset($_POST['name_link']) ? $_POST['name_link'] : $arreval['course_code'];
|
||||
} elseif (isset($_POST['link_'.$evaluationId]) && $_POST['link_'.$evaluationId]) {
|
||||
$name_log = $_POST['link_'.$evaluationId];
|
||||
} else {
|
||||
$name_log = $arreval['course_code'];
|
||||
}
|
||||
} else {
|
||||
$name_log = $nameLog;
|
||||
}
|
||||
|
||||
$params = [
|
||||
'id_linkeval_log' => $arreval['id'],
|
||||
'name' => $name_log,
|
||||
'description' => $description_log,
|
||||
'created_at' => $now,
|
||||
'weight' => $arreval['weight'],
|
||||
'visible' => $arreval['visible'],
|
||||
'type' => 'Link',
|
||||
'user_id_log' => api_get_user_id(),
|
||||
];
|
||||
Database::insert($table, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this link from the database.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->delete_linked_data();
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$sql = 'DELETE FROM '.$table.'
|
||||
WHERE id = '.intval($this->id);
|
||||
Database::query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of possible categories where this link can be moved to.
|
||||
* Notice: its own parent will be included in the list: it's up to the frontend
|
||||
* to disable this element.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 3 subelements (id, name, level)
|
||||
*/
|
||||
public function get_target_categories()
|
||||
{
|
||||
// links can only be moved to categories inside this course
|
||||
$targets = [];
|
||||
$level = 0;
|
||||
$categories = Category::load(null, null, $this->get_course_code(), 0);
|
||||
foreach ($categories as $cat) {
|
||||
$targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
|
||||
$targets = $this->addTargetSubcategories(
|
||||
$targets,
|
||||
$level + 1,
|
||||
$cat->get_id()
|
||||
);
|
||||
}
|
||||
|
||||
return $targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this link to the given category.
|
||||
* If this link moves to outside a course, delete it.
|
||||
*/
|
||||
public function move_to_cat($cat)
|
||||
{
|
||||
if ($this->get_course_code() != $cat->get_course_code()) {
|
||||
$this->delete();
|
||||
} else {
|
||||
$this->set_category_id($cat->get_id());
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find links by name
|
||||
* To keep consistency, do not call this method but LinkFactory::find_links instead.
|
||||
*
|
||||
* @todo can be written more efficiently using a new (but very complex) sql query
|
||||
*
|
||||
* @param string $name_mask
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function find_links($name_mask, $selectcat)
|
||||
{
|
||||
$rootcat = Category::load($selectcat);
|
||||
$links = $rootcat[0]->get_links((api_is_allowed_to_edit() ? null : api_get_user_id()), true);
|
||||
$foundlinks = [];
|
||||
foreach ($links as $link) {
|
||||
if (!(api_strpos(api_strtolower($link->get_name()), api_strtolower($name_mask)) === false)) {
|
||||
$foundlinks[] = $link;
|
||||
}
|
||||
}
|
||||
|
||||
return $foundlinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_item_type()
|
||||
{
|
||||
return 'L';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'link';
|
||||
}
|
||||
|
||||
public function get_all_links()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function add_linked_data()
|
||||
{
|
||||
}
|
||||
|
||||
public function save_linked_data()
|
||||
{
|
||||
}
|
||||
|
||||
public function delete_linked_data()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function set_name($name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*/
|
||||
public function set_description($description)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $max
|
||||
*/
|
||||
public function set_max($max)
|
||||
{
|
||||
}
|
||||
|
||||
public function get_view_url($stud_id)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks a link.
|
||||
*
|
||||
* @param int $locked 1 or unlocked 0
|
||||
*
|
||||
* */
|
||||
public function lock($locked)
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$sql = "UPDATE $table SET locked = '".intval($locked)."'
|
||||
WHERE id='".$this->id."'";
|
||||
Database::query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current user ranking.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param array $studentList Array with user id and scores
|
||||
* Example: [1 => 5.00, 2 => 8.00]
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCurrentUserRanking($userId, $studentList)
|
||||
{
|
||||
$ranking = null;
|
||||
$currentUserId = $userId;
|
||||
if (!empty($studentList) && !empty($currentUserId)) {
|
||||
$studentList = array_map('floatval', $studentList);
|
||||
asort($studentList);
|
||||
$ranking = $count = count($studentList);
|
||||
|
||||
foreach ($studentList as $userId => $position) {
|
||||
if ($currentUserId == $userId) {
|
||||
break;
|
||||
}
|
||||
$ranking--;
|
||||
}
|
||||
|
||||
// If no ranking was detected.
|
||||
if ($ranking == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [$ranking, $count];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSkillsFromItem()
|
||||
{
|
||||
$toolType = '';
|
||||
switch ($this->type) {
|
||||
case LINK_ATTENDANCE:
|
||||
$toolType = ITEM_TYPE_ATTENDANCE;
|
||||
break;
|
||||
case LINK_EXERCISE:
|
||||
$toolType = ITEM_TYPE_EXERCISE;
|
||||
break;
|
||||
case LINK_FORUM_THREAD:
|
||||
$toolType = ITEM_TYPE_FORUM_THREAD;
|
||||
break;
|
||||
case LINK_LEARNPATH:
|
||||
$toolType = ITEM_TYPE_LEARNPATH;
|
||||
break;
|
||||
case LINK_HOTPOTATOES:
|
||||
$toolType = ITEM_TYPE_HOTPOTATOES;
|
||||
break;
|
||||
case LINK_STUDENTPUBLICATION:
|
||||
$toolType = ITEM_TYPE_STUDENT_PUBLICATION;
|
||||
break;
|
||||
case LINK_SURVEY:
|
||||
$toolType = ITEM_TYPE_SURVEY;
|
||||
break;
|
||||
case LINK_PORTFOLIO:
|
||||
$toolType = ITEM_TYPE_PORTFOLIO;
|
||||
break;
|
||||
}
|
||||
|
||||
$skillToString = Skill::getSkillRelItemsToString($toolType, $this->get_ref_id());
|
||||
|
||||
return $skillToString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $itemId
|
||||
* @param int $linkType
|
||||
* @param string $courseCode
|
||||
* @param int $sessionId
|
||||
*
|
||||
* @return array|bool|\Doctrine\DBAL\Driver\Statement
|
||||
*/
|
||||
public static function getGradebookLinksFromItem($itemId, $linkType, $courseCode, $sessionId = 0)
|
||||
{
|
||||
if (empty($courseCode) || empty($itemId) || empty($linkType)) {
|
||||
return false;
|
||||
}
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
|
||||
$tableCategory = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
|
||||
$itemId = (int) $itemId;
|
||||
$linkType = (int) $linkType;
|
||||
$sessionId = (int) $sessionId;
|
||||
|
||||
$sessionCondition = api_get_session_condition($sessionId, true, false, 'c.session_id');
|
||||
$courseCode = Database::escape_string($courseCode);
|
||||
|
||||
$sql = "SELECT DISTINCT l.*
|
||||
FROM $table l INNER JOIN $tableCategory c
|
||||
ON (c.course_code = l.course_code AND c.id = l.category_id)
|
||||
WHERE
|
||||
ref_id = $itemId AND
|
||||
type = $linkType AND
|
||||
l.course_code = '$courseCode'
|
||||
$sessionCondition ";
|
||||
|
||||
$result = Database::query($sql);
|
||||
if (Database::num_rows($result)) {
|
||||
$result = Database::store_result($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Doctrine\DBAL\Driver\Statement|null $result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function create_objects_from_sql_result($result)
|
||||
{
|
||||
$links = [];
|
||||
$allow = api_get_configuration_value('allow_gradebook_stats');
|
||||
if ($allow) {
|
||||
$em = Database::getManager();
|
||||
$repo = $em->getRepository('ChamiloCoreBundle:GradebookLink');
|
||||
}
|
||||
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$link = LinkFactory::create($data['type']);
|
||||
$link->set_id($data['id']);
|
||||
$link->set_type($data['type']);
|
||||
$link->set_ref_id($data['ref_id']);
|
||||
$link->set_user_id($data['user_id']);
|
||||
$link->set_course_code($data['course_code']);
|
||||
$link->set_category_id($data['category_id']);
|
||||
$link->set_date($data['created_at']);
|
||||
$link->set_weight($data['weight']);
|
||||
$link->set_visible($data['visible']);
|
||||
$link->set_locked($data['locked']);
|
||||
|
||||
//session id should depend of the category --> $data['category_id']
|
||||
$session_id = api_get_session_id();
|
||||
$link->set_session_id($session_id);
|
||||
|
||||
if ($allow) {
|
||||
$link->entity = $repo->find($data['id']);
|
||||
}
|
||||
$links[] = $link;
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function used by get_target_categories().
|
||||
*
|
||||
* @param array $targets
|
||||
* @param int $level
|
||||
* @param int $catid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function addTargetSubcategories($targets, $level, $catid)
|
||||
{
|
||||
$subcats = Category::load(null, null, null, $catid);
|
||||
foreach ($subcats as $cat) {
|
||||
$targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
|
||||
$targets = $this->addTargetSubcategories(
|
||||
$targets,
|
||||
$level + 1,
|
||||
$cat->get_id()
|
||||
);
|
||||
}
|
||||
|
||||
return $targets;
|
||||
}
|
||||
}
|
||||
276
main/gradebook/lib/be/attendancelink.class.php
Normal file
276
main/gradebook/lib/be/attendancelink.class.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook link to attendance item.
|
||||
*
|
||||
* @author Christian Fasanando (christian1827@gmail.com)
|
||||
*/
|
||||
class AttendanceLink extends AbstractLink
|
||||
{
|
||||
private $attendance_table = null;
|
||||
private $itemprop_table = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_ATTENDANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('Attendance');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all attendances available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
$tbl_attendance = $this->get_attendance_table();
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
$sql = 'SELECT att.id, att.name, att.attendance_qualify_title
|
||||
FROM '.$tbl_attendance.' att
|
||||
WHERE
|
||||
att.c_id = '.$this->course_id.' AND
|
||||
att.active = 1 AND
|
||||
att.session_id = '.$sessionId;
|
||||
|
||||
$result = Database::query($sql);
|
||||
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
if (isset($data['attendance_qualify_title']) && '' != $data['attendance_qualify_title']) {
|
||||
$cats[] = [$data['id'], $data['attendance_qualify_title']];
|
||||
} else {
|
||||
$cats[] = [$data['id'], $data['name']];
|
||||
}
|
||||
}
|
||||
$my_cats = isset($cats) ? $cats : [];
|
||||
|
||||
return $my_cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this exercise yet ?
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT);
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
$sql = 'SELECT count(*) AS number FROM '.$tbl_attendance_result."
|
||||
WHERE
|
||||
session_id = $sessionId AND
|
||||
c_id = '.$this->course_id.' AND
|
||||
attendance_id = '".$this->get_ref_id()."'";
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $stud_id
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
$tbl_attendance_result = Database::get_course_table(TABLE_ATTENDANCE_RESULT);
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
// get attendance qualify max
|
||||
$sql = 'SELECT att.attendance_qualify_max
|
||||
FROM '.$this->get_attendance_table().' att
|
||||
WHERE
|
||||
att.c_id = '.$this->course_id.' AND
|
||||
att.id = '.$this->get_ref_id().' AND
|
||||
att.session_id = '.$sessionId;
|
||||
$query = Database::query($sql);
|
||||
$attendance = Database::fetch_array($query, 'ASSOC');
|
||||
|
||||
// Get results
|
||||
$sql = 'SELECT *
|
||||
FROM '.$tbl_attendance_result.'
|
||||
WHERE c_id = '.$this->course_id.' AND attendance_id = '.$this->get_ref_id();
|
||||
if (isset($stud_id)) {
|
||||
$sql .= ' AND user_id = '.intval($stud_id);
|
||||
}
|
||||
$scores = Database::query($sql);
|
||||
// for 1 student
|
||||
if (isset($stud_id)) {
|
||||
if ($data = Database::fetch_array($scores, 'ASSOC')) {
|
||||
return [
|
||||
$data['score'],
|
||||
$attendance['attendance_qualify_max'],
|
||||
];
|
||||
} else {
|
||||
//We sent the 0/attendance_qualify_max instead of null for correct calculations
|
||||
return [0, $attendance['attendance_qualify_max']];
|
||||
}
|
||||
} else {
|
||||
// all students -> get average
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$rescount = 0;
|
||||
$sum = 0;
|
||||
$sumResult = 0;
|
||||
$bestResult = 0;
|
||||
|
||||
while ($data = Database::fetch_array($scores)) {
|
||||
if (!(array_key_exists($data['user_id'], $students))) {
|
||||
if (0 != $attendance['attendance_qualify_max']) {
|
||||
$students[$data['user_id']] = $data['score'];
|
||||
$rescount++;
|
||||
$sum += $data['score'] / $attendance['attendance_qualify_max'];
|
||||
$sumResult += $data['score'];
|
||||
if ($data['score'] > $bestResult) {
|
||||
$bestResult = $data['score'];
|
||||
}
|
||||
$weight = $attendance['attendance_qualify_max'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == $rescount) {
|
||||
return [null, null];
|
||||
} else {
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, $weight];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sumResult / $rescount, $weight];
|
||||
break;
|
||||
case 'ranking':
|
||||
return AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
break;
|
||||
default:
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$this->get_attendance_data();
|
||||
$attendance_title = isset($this->attendance_data['name']) ? $this->attendance_data['name'] : '';
|
||||
$attendance_qualify_title = isset($this->attendance_data['attendance_qualify_title']) ? $this->attendance_data['attendance_qualify_title'] : '';
|
||||
if (isset($attendance_qualify_title) && '' != $attendance_qualify_title) {
|
||||
return $this->attendance_data['attendance_qualify_title'];
|
||||
} else {
|
||||
return $attendance_title;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to an exercise.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$sql = 'SELECT count(att.id) FROM '.$this->get_attendance_table().' att
|
||||
WHERE att.c_id = '.$this->course_id.' AND att.id = '.$this->get_ref_id();
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
// it was extracts the attendance id
|
||||
$sessionId = $this->get_session_id();
|
||||
$sql = 'SELECT * FROM '.$this->get_attendance_table().' att
|
||||
WHERE att.c_id = '.$this->course_id.' AND att.id = '.$this->get_ref_id();
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
$attendance_id = $row['id'];
|
||||
$url = api_get_path(WEB_PATH).'main/attendance/index.php?action=attendance_sheet_list&gradebook=view&attendance_id='.$attendance_id.'&'.api_get_cidreq_params($this->get_course_code(), $sessionId);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'attendance';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the student publications.
|
||||
*/
|
||||
private function get_attendance_table()
|
||||
{
|
||||
$this->attendance_table = Database::get_course_table(TABLE_ATTENDANCE);
|
||||
|
||||
return $this->attendance_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|bool
|
||||
*/
|
||||
private function get_attendance_data()
|
||||
{
|
||||
$tbl_name = $this->get_attendance_table();
|
||||
if ('' == $tbl_name) {
|
||||
return false;
|
||||
} elseif (!isset($this->attendance_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_attendance_table().' att
|
||||
WHERE att.c_id = '.$this->course_id.' AND att.id = '.$this->get_ref_id();
|
||||
$query = Database::query($sql);
|
||||
$this->attendance_data = Database::fetch_array($query);
|
||||
}
|
||||
|
||||
return $this->attendance_data;
|
||||
}
|
||||
}
|
||||
2889
main/gradebook/lib/be/category.class.php
Normal file
2889
main/gradebook/lib/be/category.class.php
Normal file
File diff suppressed because it is too large
Load Diff
70
main/gradebook/lib/be/dropboxlink.class.php
Normal file
70
main/gradebook/lib/be/dropboxlink.class.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook link to dropbox item.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class DropboxLink extends EvalLink
|
||||
{
|
||||
private $dropbox_table = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_DROPBOX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of a document
|
||||
* This function is loaded when using a gradebook as a tab (gradebook = -1) see issue #2705.
|
||||
*/
|
||||
public function get_view_url($stud_id)
|
||||
{
|
||||
// find a file uploaded by the given student,
|
||||
// with the same title as the evaluation name
|
||||
|
||||
$eval = $this->get_evaluation();
|
||||
$sql = 'SELECT filename FROM '.$this->get_dropbox_table().'
|
||||
WHERE
|
||||
c_id = '.$this->course_id.' AND
|
||||
uploader_id = '.intval($stud_id)." AND
|
||||
title = '".Database::escape_string($eval->get_name())."'";
|
||||
|
||||
$result = Database::query($sql);
|
||||
if ($fileurl = Database::fetch_row($result)) {
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('LMSDropbox');
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'dropbox';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the dropbox database table.
|
||||
*/
|
||||
private function get_dropbox_table()
|
||||
{
|
||||
$this->dropbox_table = Database::get_course_table(TABLE_DROPBOX_FILE);
|
||||
|
||||
return $this->dropbox_table;
|
||||
}
|
||||
}
|
||||
187
main/gradebook/lib/be/evallink.class.php
Normal file
187
main/gradebook/lib/be/evallink.class.php
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class to be used as basis for links referring to Evaluation objects.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
abstract class EvalLink extends AbstractLink
|
||||
{
|
||||
protected $evaluation;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->has_results();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param string $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function calc_score($userId = null, $type = null)
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->calc_score($userId, $type);
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
// course/platform admin can go to the view_results page
|
||||
if (api_is_allowed_to_edit()) {
|
||||
return 'gradebook_view_result.php?'.api_get_cidreq().'&selecteval='.$eval->get_id();
|
||||
} elseif (ScoreDisplay::instance()->is_custom()) {
|
||||
// students can go to the statistics page (if custom display enabled)
|
||||
|
||||
return 'gradebook_statistics.php?'.api_get_cidreq().'&selecteval='.$eval->get_id();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->get_name();
|
||||
}
|
||||
|
||||
public function get_description()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->get_description();
|
||||
}
|
||||
|
||||
public function get_max()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return $eval->get_max();
|
||||
}
|
||||
|
||||
public function is_valid_link()
|
||||
{
|
||||
$eval = $this->get_evaluation();
|
||||
|
||||
return isset($eval);
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function add_linked_data()
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->add();
|
||||
$this->set_ref_id($this->evaluation->get_id());
|
||||
}
|
||||
}
|
||||
|
||||
public function save_linked_data()
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function delete_linked_data()
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->delete_with_results();
|
||||
}
|
||||
}
|
||||
|
||||
public function set_name($name)
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_name($name);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_description($description)
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_description($description);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_max($max)
|
||||
{
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_max($max);
|
||||
}
|
||||
}
|
||||
|
||||
// Functions overriding non-trivial implementations from AbstractLink
|
||||
public function set_date($date)
|
||||
{
|
||||
$this->created_at = $date;
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_date($date);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_weight($weight)
|
||||
{
|
||||
$this->weight = $weight;
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_weight($weight);
|
||||
}
|
||||
}
|
||||
|
||||
public function set_visible($visible)
|
||||
{
|
||||
$this->visible = $visible;
|
||||
if ($this->is_valid_link()) {
|
||||
$this->evaluation->set_visible($visible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the linked evaluation.
|
||||
*/
|
||||
protected function get_evaluation()
|
||||
{
|
||||
if (!isset($this->evaluation)) {
|
||||
if (isset($this->ref_id)) {
|
||||
$evalarray = Evaluation::load($this->get_ref_id());
|
||||
$this->evaluation = $evalarray[0];
|
||||
} else {
|
||||
$eval = new Evaluation();
|
||||
$eval->set_category_id(-1);
|
||||
$eval->set_date(api_get_utc_datetime()); // these values will be changed
|
||||
$eval->set_weight(0); // when the link setter
|
||||
$eval->set_visible(0); // is called
|
||||
$eval->set_id(-1); // a 'real' id will be set when eval is added to db
|
||||
$eval->set_user_id($this->get_user_id());
|
||||
$eval->set_course_code($this->get_course_code());
|
||||
$this->evaluation = $eval;
|
||||
$this->set_ref_id($eval->get_id());
|
||||
}
|
||||
}
|
||||
|
||||
return $this->evaluation;
|
||||
}
|
||||
}
|
||||
1000
main/gradebook/lib/be/evaluation.class.php
Normal file
1000
main/gradebook/lib/be/evaluation.class.php
Normal file
File diff suppressed because it is too large
Load Diff
676
main/gradebook/lib/be/exerciselink.class.php
Normal file
676
main/gradebook/lib/be/exerciselink.class.php
Normal file
@@ -0,0 +1,676 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class ExerciseLink
|
||||
* Defines a gradebook ExerciseLink object.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class ExerciseLink extends AbstractLink
|
||||
{
|
||||
// This variable is used in the WSGetGradebookUserItemScore service, to check base course tests.
|
||||
public $checkBaseExercises = false;
|
||||
private $course_info;
|
||||
private $exercise_table;
|
||||
private $exercise_data = [];
|
||||
private $is_hp;
|
||||
|
||||
/**
|
||||
* @param int $hp
|
||||
*/
|
||||
public function __construct($hp = 0)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_EXERCISE);
|
||||
$this->is_hp = $hp;
|
||||
if (1 == $this->is_hp) {
|
||||
$this->set_type(LINK_HOTPOTATOES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all exercises available.
|
||||
*
|
||||
* @param bool $getOnlyHotPotatoes
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links($getOnlyHotPotatoes = false)
|
||||
{
|
||||
$TBL_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
|
||||
$tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
$exerciseTable = $this->get_exercise_table();
|
||||
$lpItemTable = Database::get_course_table(TABLE_LP_ITEM);
|
||||
$lpTable = Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
$documentPath = api_get_path(SYS_COURSE_PATH).$this->course_code.'/document';
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
$sessionId = $this->get_session_id();
|
||||
if (empty($sessionId)) {
|
||||
$session_condition = api_get_session_condition(0, true, false, 'e.session_id');
|
||||
} else {
|
||||
$session_condition = api_get_session_condition($sessionId, true, true, 'e.session_id');
|
||||
}
|
||||
|
||||
// @todo
|
||||
$uploadPath = null;
|
||||
$courseId = $this->course_id;
|
||||
|
||||
$sql = "SELECT iid, title FROM $exerciseTable e
|
||||
WHERE
|
||||
c_id = $courseId AND
|
||||
active = 1
|
||||
$session_condition ";
|
||||
|
||||
$sqlLp = "SELECT e.iid, e.title, lp.name lp_name
|
||||
FROM $exerciseTable e
|
||||
INNER JOIN $lpItemTable i
|
||||
ON (e.c_id = i.c_id AND e.iid = i.path)
|
||||
INNER JOIN $lpTable lp
|
||||
ON (lp.c_id = e.c_id AND lp.id = i.lp_id)
|
||||
WHERE
|
||||
e.c_id = $courseId AND
|
||||
active = 0 AND
|
||||
item_type = 'quiz'
|
||||
$session_condition";
|
||||
|
||||
$sql2 = "SELECT d.path as path, d.comment as comment, ip.visibility as visibility, d.id
|
||||
FROM $TBL_DOCUMENT d
|
||||
INNER JOIN $tableItemProperty ip
|
||||
ON (d.id = ip.ref AND d.c_id = ip.c_id)
|
||||
WHERE
|
||||
d.c_id = $courseId AND
|
||||
ip.c_id = $courseId AND
|
||||
ip.tool = '".TOOL_DOCUMENT."' AND
|
||||
(d.path LIKE '%htm%') AND
|
||||
(d.path LIKE '%HotPotatoes_files%') AND
|
||||
d.path LIKE '".Database::escape_string($uploadPath.'/%/%')."' AND
|
||||
ip.visibility = '1'
|
||||
";
|
||||
|
||||
require_once api_get_path(SYS_CODE_PATH).'exercise/hotpotatoes.lib.php';
|
||||
|
||||
$exerciseInLP = [];
|
||||
if (!$this->is_hp) {
|
||||
$result = Database::query($sql);
|
||||
$resultLp = Database::query($sqlLp);
|
||||
$exerciseInLP = Database::store_result($resultLp);
|
||||
} else {
|
||||
$result2 = Database::query($sql2);
|
||||
}
|
||||
|
||||
$cats = [];
|
||||
$exerciseList = [];
|
||||
if (isset($result)) {
|
||||
if (Database::num_rows($result) > 0) {
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$cats[] = [$data['iid'], $data['title']];
|
||||
$exerciseList[] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
$hotPotatoes = [];
|
||||
if (isset($result2)) {
|
||||
if (Database::num_rows($result2) > 0) {
|
||||
while ($row = Database::fetch_array($result2)) {
|
||||
$attribute['path'][] = $row['path'];
|
||||
$attribute['visibility'][] = $row['visibility'];
|
||||
$attribute['comment'][] = $row['comment'];
|
||||
$attribute['id'] = $row['id'];
|
||||
|
||||
if (isset($attribute['path']) && is_array($attribute['path'])) {
|
||||
foreach ($attribute['path'] as $path) {
|
||||
$title = GetQuizName($path, $documentPath);
|
||||
if ($title == '') {
|
||||
$title = basename($path);
|
||||
}
|
||||
$element = [$attribute['id'], $title.'(HP)'];
|
||||
$cats[] = $element;
|
||||
$hotPotatoes[] = $element;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($getOnlyHotPotatoes) {
|
||||
return $hotPotatoes;
|
||||
}
|
||||
|
||||
if (!empty($exerciseInLP)) {
|
||||
$allExercises = array_column($exerciseList, 'iid');
|
||||
|
||||
foreach ($exerciseInLP as $exercise) {
|
||||
if (in_array($exercise['iid'], $allExercises)) {
|
||||
continue;
|
||||
}
|
||||
$allExercises[] = $exercise['iid'];
|
||||
//$lpName = strip_tags($exercise['lp_name']);
|
||||
/*$cats[] = [
|
||||
$exercise['iid'],
|
||||
strip_tags(Exercise::get_formated_title_variable($exercise['title'])).
|
||||
' ('.get_lang('ToolLearnpath').' - '.$lpName.')',
|
||||
];*/
|
||||
$cats[] = [
|
||||
$exercise['iid'],
|
||||
strip_tags(Exercise::get_formated_title_variable($exercise['title'])),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this exercise yet ?
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$tbl_stats = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
|
||||
$sessionId = $this->get_session_id();
|
||||
$course_id = api_get_course_int_id($this->get_course_code());
|
||||
$sql = "SELECT count(exe_id) AS number
|
||||
FROM $tbl_stats
|
||||
WHERE
|
||||
session_id = $sessionId AND
|
||||
c_id = $course_id AND
|
||||
exe_exo_id = ".$this->get_ref_id();
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return $number[0] != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the score of this exercise. Only the first attempts are taken into account.
|
||||
*
|
||||
* @param int $stud_id student id (default: all students who have results -
|
||||
* then the average is returned)
|
||||
* @param string $type
|
||||
*
|
||||
* @return array (score, max) if student is given
|
||||
* array (sum of scores, number of scores) otherwise
|
||||
* or null if no scores available
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
$allowStats = api_get_configuration_value('allow_gradebook_stats');
|
||||
if ($allowStats) {
|
||||
$link = $this->entity;
|
||||
if (!empty($link)) {
|
||||
$weight = $link->getScoreWeight();
|
||||
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
$bestResult = $link->getBestScore();
|
||||
|
||||
return [$bestResult, $weight];
|
||||
|
||||
break;
|
||||
case 'average':
|
||||
$count = count($link->getUserScoreList());
|
||||
//$count = count($this->getStudentList());
|
||||
if (empty($count)) {
|
||||
return [0, $weight];
|
||||
}
|
||||
$sumResult = array_sum($link->getUserScoreList());
|
||||
|
||||
return [$sumResult / $count, $weight];
|
||||
|
||||
break;
|
||||
case 'ranking':
|
||||
return [null, null];
|
||||
break;
|
||||
default:
|
||||
if (!empty($stud_id)) {
|
||||
$scoreList = $link->getUserScoreList();
|
||||
$result = [0, $weight];
|
||||
if (isset($scoreList[$stud_id])) {
|
||||
$result = [$scoreList[$stud_id], $weight];
|
||||
}
|
||||
|
||||
return $result;
|
||||
} else {
|
||||
$studentCount = count($this->getStudentList());
|
||||
$sumResult = array_sum($link->getUserScoreList());
|
||||
$result = [$sumResult, $studentCount];
|
||||
}
|
||||
|
||||
return $result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tblStats = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
|
||||
$tblHp = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES);
|
||||
$tblDoc = Database::get_course_table(TABLE_DOCUMENT);
|
||||
|
||||
/* the following query should be similar (in conditions) to the one used
|
||||
in exercise/exercise.php, look for note-query-exe-results marker*/
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
$exerciseData = $this->get_exercise_data();
|
||||
$exerciseId = isset($exerciseData['iid']) ? (int) $exerciseData['iid'] : 0;
|
||||
$stud_id = (int) $stud_id;
|
||||
|
||||
if (empty($exerciseId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$key = 'exercise_link_id:'.
|
||||
$this->get_id().
|
||||
'exerciseId:'.$exerciseId.'student:'.$stud_id.'session:'.$sessionId.'courseId:'.$courseId.'type:'.$type;
|
||||
|
||||
$useCache = api_get_configuration_value('gradebook_use_apcu_cache');
|
||||
$cacheAvailable = api_get_configuration_value('apc') && $useCache;
|
||||
$cacheDriver = null;
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver = new \Doctrine\Common\Cache\ApcuCache();
|
||||
if ($cacheDriver->contains($key)) {
|
||||
return $cacheDriver->fetch($key);
|
||||
}
|
||||
}
|
||||
|
||||
$exercise = new Exercise($courseId);
|
||||
$exercise->read($exerciseId);
|
||||
|
||||
if (!$this->is_hp) {
|
||||
if (false == $exercise->exercise_was_added_in_lp) {
|
||||
$sql = "SELECT * FROM $tblStats
|
||||
WHERE
|
||||
exe_exo_id = $exerciseId AND
|
||||
orig_lp_id = 0 AND
|
||||
orig_lp_item_id = 0 AND
|
||||
status <> 'incomplete' AND
|
||||
session_id = $sessionId AND
|
||||
c_id = $courseId
|
||||
";
|
||||
} else {
|
||||
$lpCondition = null;
|
||||
if (!empty($exercise->lpList)) {
|
||||
//$lpId = $exercise->getLpBySession($sessionId);
|
||||
$lpList = [];
|
||||
foreach ($exercise->lpList as $lpData) {
|
||||
if ($this->checkBaseExercises) {
|
||||
if ((int) $lpData['session_id'] == 0) {
|
||||
$lpList[] = $lpData['lp_id'];
|
||||
}
|
||||
} else {
|
||||
if ((int) $lpData['session_id'] == $sessionId) {
|
||||
$lpList[] = $lpData['lp_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($lpList) && !empty($sessionId)) {
|
||||
// Check also if an LP was added in the base course.
|
||||
foreach ($exercise->lpList as $lpData) {
|
||||
if ((int) $lpData['session_id'] == 0) {
|
||||
$lpList[] = $lpData['lp_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$lpCondition = ' (orig_lp_id = 0 OR (orig_lp_id IN ("'.implode('", "', $lpList).'"))) AND ';
|
||||
}
|
||||
|
||||
$sql = "SELECT *
|
||||
FROM $tblStats
|
||||
WHERE
|
||||
exe_exo_id = $exerciseId AND
|
||||
$lpCondition
|
||||
status <> 'incomplete' AND
|
||||
session_id = $sessionId AND
|
||||
c_id = $courseId ";
|
||||
}
|
||||
|
||||
if (!empty($stud_id) && 'ranking' !== $type) {
|
||||
$sql .= " AND exe_user_id = $stud_id ";
|
||||
}
|
||||
$sql .= ' ORDER BY exe_id DESC ';
|
||||
} else {
|
||||
$sql = "SELECT * FROM $tblHp hp
|
||||
INNER JOIN $tblDoc doc
|
||||
ON (hp.exe_name = doc.path AND doc.c_id = hp.c_id)
|
||||
WHERE
|
||||
hp.c_id = $courseId AND
|
||||
doc.id = $exerciseId";
|
||||
|
||||
if (!empty($stud_id)) {
|
||||
$sql .= " AND hp.exe_user_id = $stud_id ";
|
||||
}
|
||||
}
|
||||
|
||||
$scores = Database::query($sql);
|
||||
|
||||
if (isset($stud_id) && empty($type)) {
|
||||
// for 1 student
|
||||
if ($data = Database::fetch_array($scores, 'ASSOC')) {
|
||||
$attempts = Database::query($sql);
|
||||
$counter = 0;
|
||||
while ($attempt = Database::fetch_array($attempts)) {
|
||||
$counter++;
|
||||
}
|
||||
$result = [$data['exe_result'], $data['exe_weighting'], $data['exe_date'], $counter];
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
} else {
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// all students -> get average
|
||||
// normal way of getting the info
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$student_count = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
$weight = 0;
|
||||
$sumResult = 0;
|
||||
$studentList = $this->getStudentList();
|
||||
$studentIdList = [];
|
||||
if (!empty($studentList)) {
|
||||
$studentIdList = array_column($studentList, 'user_id');
|
||||
}
|
||||
|
||||
while ($data = Database::fetch_array($scores, 'ASSOC')) {
|
||||
// Only take into account users in the current student list.
|
||||
if (!empty($studentIdList)) {
|
||||
if (!in_array($data['exe_user_id'], $studentIdList)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($students[$data['exe_user_id']])) {
|
||||
if ($data['exe_weighting'] != 0) {
|
||||
$students[$data['exe_user_id']] = $data['exe_result'];
|
||||
$student_count++;
|
||||
if ($data['exe_result'] > $bestResult) {
|
||||
$bestResult = $data['exe_result'];
|
||||
}
|
||||
$sum += $data['exe_result'] / $data['exe_weighting'];
|
||||
$sumResult += $data['exe_result'];
|
||||
$weight = $data['exe_weighting'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($student_count == 0) {
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
} else {
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
$result = [$bestResult, $weight];
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
break;
|
||||
case 'average':
|
||||
$count = count($this->getStudentList());
|
||||
if (empty($count)) {
|
||||
$result = [0, $weight];
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = [$sumResult / $count, $weight];
|
||||
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
break;
|
||||
case 'ranking':
|
||||
$ranking = AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $ranking);
|
||||
}
|
||||
|
||||
return $ranking;
|
||||
break;
|
||||
default:
|
||||
$result = [$sum, $student_count];
|
||||
if ($cacheAvailable) {
|
||||
$cacheDriver->save($key, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL where to go to if the user clicks on the link.
|
||||
* First we go to exercise_jump.php and then to the result page.
|
||||
* Check this php file for more info.
|
||||
*/
|
||||
public function get_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
$data = $this->get_exercise_data();
|
||||
$exerciseId = $data['iid'];
|
||||
$path = isset($data['path']) ? $data['path'] : '';
|
||||
|
||||
return api_get_path(WEB_CODE_PATH).'gradebook/exercise_jump.php?'
|
||||
.http_build_query(
|
||||
[
|
||||
'path' => $path,
|
||||
'session_id' => $sessionId,
|
||||
'cidReq' => $this->get_course_code(),
|
||||
'gradebook' => 'view',
|
||||
'exerciseId' => $exerciseId,
|
||||
'type' => $this->get_type(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name to display: same as exercise title.
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$documentPath = api_get_path(SYS_COURSE_PATH).$this->course_code.'/document';
|
||||
require_once api_get_path(SYS_CODE_PATH).'exercise/hotpotatoes.lib.php';
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if ($this->is_hp == 1) {
|
||||
if (isset($data['path'])) {
|
||||
$title = GetQuizName($data['path'], $documentPath);
|
||||
if ($title == '') {
|
||||
$title = basename($data['path']);
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
}
|
||||
|
||||
return strip_tags(Exercise::get_formated_title_variable($data['title']));
|
||||
}
|
||||
|
||||
public function getLpListToString()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
$lpList = Exercise::getLpListFromExercise($data['iid'], $this->getCourseId());
|
||||
$lpListToString = '';
|
||||
if (!empty($lpList)) {
|
||||
foreach ($lpList as &$list) {
|
||||
$list['name'] = Display::label($list['name'], 'warning');
|
||||
}
|
||||
$lpListToString = implode(' ', array_column($lpList, 'name'));
|
||||
}
|
||||
|
||||
return $lpListToString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description to display: same as exercise description.
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
return isset($data['description']) ? $data['description'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to an exercise.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$exerciseData = $this->get_exercise_data();
|
||||
|
||||
return !empty($exerciseData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
if ($this->is_hp == 1) {
|
||||
return 'HotPotatoes';
|
||||
}
|
||||
|
||||
return get_lang('Quiz');
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'exercise';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hp
|
||||
*/
|
||||
public function setHp($hp)
|
||||
{
|
||||
$this->hp = $hp;
|
||||
}
|
||||
|
||||
public function getBestScore()
|
||||
{
|
||||
return $this->getStats('best');
|
||||
}
|
||||
|
||||
public function getStats($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database contents of this exercise.
|
||||
*/
|
||||
public function get_exercise_data()
|
||||
{
|
||||
$tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
if ($this->is_hp == 1) {
|
||||
$table = Database::get_course_table(TABLE_DOCUMENT);
|
||||
} else {
|
||||
$table = Database::get_course_table(TABLE_QUIZ_TEST);
|
||||
}
|
||||
|
||||
$exerciseId = $this->get_ref_id();
|
||||
|
||||
if (empty($this->exercise_data)) {
|
||||
if ($this->is_hp == 1) {
|
||||
$sql = "SELECT * FROM $table ex
|
||||
INNER JOIN $tableItemProperty ip
|
||||
ON (ip.ref = ex.id AND ip.c_id = ex.c_id)
|
||||
WHERE
|
||||
ip.c_id = $this->course_id AND
|
||||
ex.c_id = $this->course_id AND
|
||||
ip.ref = $exerciseId AND
|
||||
ip.tool = '".TOOL_DOCUMENT."' AND
|
||||
ex.path LIKE '%htm%' AND
|
||||
ex.path LIKE '%HotPotatoes_files%' AND
|
||||
ip.visibility = 1";
|
||||
$result = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($result);
|
||||
} else {
|
||||
// Try with iid
|
||||
$sql = "SELECT * FROM $table
|
||||
WHERE
|
||||
iid = $exerciseId";
|
||||
$result = Database::query($sql);
|
||||
$rows = Database::num_rows($result);
|
||||
|
||||
if (!empty($rows)) {
|
||||
$this->exercise_data = Database::fetch_array($result);
|
||||
} else {
|
||||
// Try wit id
|
||||
$sql = "SELECT * FROM $table
|
||||
WHERE
|
||||
iid = $exerciseId";
|
||||
$result = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->exercise_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->exercise_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the exercise.
|
||||
*/
|
||||
private function get_exercise_table()
|
||||
{
|
||||
$this->exercise_table = Database::get_course_table(TABLE_QUIZ_TEST);
|
||||
|
||||
return $this->exercise_table;
|
||||
}
|
||||
}
|
||||
357
main/gradebook/lib/be/forumthreadlink.class.php
Normal file
357
main/gradebook/lib/be/forumthreadlink.class.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class ForumThreadLink.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class ForumThreadLink extends AbstractLink
|
||||
{
|
||||
private $forum_thread_table;
|
||||
private $itemprop_table;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_FORUM_THREAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('ForumThreads');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all exercises available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$tbl_grade_links = Database::get_course_table(TABLE_FORUM_THREAD);
|
||||
$tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
if ($sessionId) {
|
||||
$session_condition = 'tl.session_id='.$sessionId;
|
||||
} else {
|
||||
$session_condition = '(tl.session_id = 0 OR tl.session_id IS NULL)';
|
||||
}
|
||||
|
||||
$sql = 'SELECT tl.thread_id, tl.thread_title, tl.thread_title_qualify
|
||||
FROM '.$tbl_grade_links.' tl INNER JOIN '.$tbl_item_property.' ip
|
||||
ON (tl.thread_id = ip.ref AND tl.c_id = ip.c_id)
|
||||
WHERE
|
||||
tl.c_id = '.$this->course_id.' AND
|
||||
ip.c_id = '.$this->course_id.' AND
|
||||
ip.tool = "forum_thread" AND
|
||||
ip.visibility <> 2 AND
|
||||
'.$session_condition.'
|
||||
';
|
||||
|
||||
$result = Database::query($sql);
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
if (isset($data['thread_title_qualify']) && '' != $data['thread_title_qualify']) {
|
||||
$cats[] = [$data['thread_id'], $data['thread_title_qualify']];
|
||||
} else {
|
||||
$cats[] = [$data['thread_id'], $data['thread_title']];
|
||||
}
|
||||
}
|
||||
$my_cats = isset($cats) ? $cats : [];
|
||||
|
||||
return $my_cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this exercise yet ?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$table = Database::get_course_table(TABLE_FORUM_POST);
|
||||
|
||||
$sql = "SELECT count(*) AS number FROM $table
|
||||
WHERE
|
||||
c_id = ".$this->course_id." AND
|
||||
thread_id = '".$this->get_ref_id()."'
|
||||
";
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $stud_id
|
||||
* @param string $type
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
|
||||
$threadInfo = get_thread_information('', $this->get_ref_id());
|
||||
$thread_qualify = Database::get_course_table(TABLE_FORUM_THREAD_QUALIFY);
|
||||
$sessionId = $this->get_session_id();
|
||||
$sessionCondition = api_get_session_condition(
|
||||
$sessionId,
|
||||
true,
|
||||
false,
|
||||
'session_id'
|
||||
);
|
||||
|
||||
$sql = 'SELECT thread_qualify_max
|
||||
FROM '.Database::get_course_table(TABLE_FORUM_THREAD)."
|
||||
WHERE
|
||||
c_id = ".$this->course_id." AND
|
||||
thread_id = '".$this->get_ref_id()."'
|
||||
$sessionCondition
|
||||
";
|
||||
$query = Database::query($sql);
|
||||
$assignment = Database::fetch_array($query);
|
||||
|
||||
$sql = "SELECT * FROM $thread_qualify
|
||||
WHERE
|
||||
c_id = ".$this->course_id." AND
|
||||
thread_id = ".$this->get_ref_id()."
|
||||
$sessionCondition
|
||||
";
|
||||
if (isset($stud_id)) {
|
||||
$sql .= ' AND user_id = '.intval($stud_id);
|
||||
}
|
||||
|
||||
// order by id, that way the student's first attempt is accessed first
|
||||
$sql .= ' ORDER BY qualify_time DESC';
|
||||
$scores = Database::query($sql);
|
||||
|
||||
// for 1 student
|
||||
if (isset($stud_id)) {
|
||||
if (0 == $threadInfo['thread_peer_qualify']) {
|
||||
// Classic way of calculate score
|
||||
if ($data = Database::fetch_array($scores)) {
|
||||
return [
|
||||
$data['qualify'],
|
||||
$assignment['thread_qualify_max'],
|
||||
];
|
||||
} else {
|
||||
// We sent the 0/thread_qualify_max instead of null for correct calculations
|
||||
return [0, $assignment['thread_qualify_max']];
|
||||
}
|
||||
} else {
|
||||
// Take average
|
||||
$score = 0;
|
||||
$counter = 0;
|
||||
if (Database::num_rows($scores)) {
|
||||
while ($data = Database::fetch_array($scores, 'ASSOC')) {
|
||||
$score += $data['qualify'];
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
// If no result
|
||||
if (empty($counter) || $counter <= 2) {
|
||||
return [0, $assignment['thread_qualify_max']];
|
||||
}
|
||||
|
||||
return [$score / $counter, $assignment['thread_qualify_max']];
|
||||
}
|
||||
} else {
|
||||
// All students -> get average
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$counter = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
$weight = 0;
|
||||
$sumResult = 0;
|
||||
|
||||
while ($data = Database::fetch_array($scores)) {
|
||||
if (!(array_key_exists($data['user_id'], $students))) {
|
||||
if (0 != $assignment['thread_qualify_max']) {
|
||||
$students[$data['user_id']] = $data['qualify'];
|
||||
$counter++;
|
||||
$sum += $data['qualify'] / $assignment['thread_qualify_max'];
|
||||
$sumResult += $data['qualify'];
|
||||
if ($data['qualify'] > $bestResult) {
|
||||
$bestResult = $data['qualify'];
|
||||
}
|
||||
$weight = $assignment['thread_qualify_max'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == $counter) {
|
||||
return [null, null];
|
||||
} else {
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, $weight];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sumResult / $counter, $weight];
|
||||
break;
|
||||
case 'ranking':
|
||||
return AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
break;
|
||||
default:
|
||||
return [$sum, $counter];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$this->get_exercise_data();
|
||||
$thread_title = isset($this->exercise_data['thread_title']) ? $this->exercise_data['thread_title'] : '';
|
||||
$thread_title_qualify = isset($this->exercise_data['thread_title_qualify']) ? $this->exercise_data['thread_title_qualify'] : '';
|
||||
if (isset($thread_title_qualify) && '' != $thread_title_qualify) {
|
||||
return $this->exercise_data['thread_title_qualify'];
|
||||
}
|
||||
|
||||
return $thread_title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
return ''; //$this->exercise_data['description'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to an exercise.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
$sql = 'SELECT count(id) from '.$this->get_forum_thread_table().'
|
||||
WHERE
|
||||
c_id = '.$this->course_id.' AND
|
||||
thread_id = '.$this->get_ref_id().' AND
|
||||
session_id='.$sessionId;
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
//it was extracts the forum id
|
||||
$sql = 'SELECT * FROM '.$this->get_forum_thread_table()."
|
||||
WHERE
|
||||
c_id = '.$this->course_id.' AND
|
||||
thread_id = '".$this->get_ref_id()."' AND
|
||||
session_id = $sessionId ";
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
$forum_id = $row['forum_id'];
|
||||
|
||||
$url = api_get_path(WEB_PATH).'main/forum/viewthread.php?'.api_get_cidreq_params($this->get_course_code(), $sessionId).'&thread='.$this->get_ref_id().'&gradebook=view&forum='.$forum_id;
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'forum';
|
||||
}
|
||||
|
||||
public function save_linked_data()
|
||||
{
|
||||
$weight = $this->get_weight();
|
||||
$ref_id = $this->get_ref_id();
|
||||
|
||||
if (!empty($ref_id)) {
|
||||
$sql = 'UPDATE '.$this->get_forum_thread_table().' SET
|
||||
thread_weight='.api_float_val($weight).'
|
||||
WHERE c_id = '.$this->course_id.' AND thread_id= '.$ref_id;
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
public function delete_linked_data()
|
||||
{
|
||||
$ref_id = $this->get_ref_id();
|
||||
if (!empty($ref_id)) {
|
||||
// Cleans forum
|
||||
$sql = 'UPDATE '.$this->get_forum_thread_table().' SET
|
||||
thread_qualify_max = 0,
|
||||
thread_weight = 0,
|
||||
thread_title_qualify = ""
|
||||
WHERE c_id = '.$this->course_id.' AND thread_id= '.$ref_id;
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the student publications.
|
||||
*/
|
||||
private function get_forum_thread_table()
|
||||
{
|
||||
return $this->forum_thread_table = Database::get_course_table(TABLE_FORUM_THREAD);
|
||||
}
|
||||
|
||||
private function get_exercise_data()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
if ($sessionId) {
|
||||
$session_condition = 'session_id = '.$sessionId;
|
||||
} else {
|
||||
$session_condition = '(session_id = 0 OR session_id IS NULL)';
|
||||
}
|
||||
|
||||
if (!isset($this->exercise_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_forum_thread_table().'
|
||||
WHERE
|
||||
c_id = '.$this->course_id.' AND
|
||||
thread_id = '.$this->get_ref_id().' AND
|
||||
'.$session_condition;
|
||||
$query = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($query);
|
||||
}
|
||||
|
||||
return $this->exercise_data;
|
||||
}
|
||||
}
|
||||
34
main/gradebook/lib/be/gradebookitem.class.php
Normal file
34
main/gradebook/lib/be/gradebookitem.class.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Interface for all displayable items in the gradebook.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
interface GradebookItem
|
||||
{
|
||||
public function get_item_type();
|
||||
|
||||
public function get_id();
|
||||
|
||||
public function get_name();
|
||||
|
||||
public function get_description();
|
||||
|
||||
public function get_course_code();
|
||||
|
||||
public function get_weight();
|
||||
|
||||
public function get_date();
|
||||
|
||||
public function is_visible();
|
||||
|
||||
public function get_icon_name();
|
||||
|
||||
public function getStudentList();
|
||||
|
||||
public function setStudentList($list);
|
||||
|
||||
public function calc_score($stud_id = null, $type = null);
|
||||
}
|
||||
7
main/gradebook/lib/be/index.html
Normal file
7
main/gradebook/lib/be/index.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; url=../../gradebook.php">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
257
main/gradebook/lib/be/learnpathlink.class.php
Normal file
257
main/gradebook/lib/be/learnpathlink.class.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Defines a gradebook LearnpathLink object.
|
||||
*
|
||||
* @author Yannick Warnier <yannick.warnier@beeznest.com>
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class LearnpathLink extends AbstractLink
|
||||
{
|
||||
private $course_info;
|
||||
private $learnpath_table;
|
||||
private $learnpath_data;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_LEARNPATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all learnpaths available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$session_id = $this->get_session_id();
|
||||
if (empty($session_id)) {
|
||||
$session_condition = api_get_session_condition(0, true);
|
||||
} else {
|
||||
$session_condition = api_get_session_condition($session_id, true, true);
|
||||
}
|
||||
|
||||
$sql = 'SELECT id, name FROM '.$this->get_learnpath_table().'
|
||||
WHERE c_id = '.$this->course_id.' '.$session_condition.' ';
|
||||
$result = Database::query($sql);
|
||||
|
||||
$cats = [];
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$cats[] = [$data['id'], $data['name']];
|
||||
}
|
||||
|
||||
return $cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone used this learnpath yet ?
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$tbl_stats = Database::get_course_table(TABLE_LP_VIEW);
|
||||
$sql = "SELECT count(id) AS number FROM $tbl_stats
|
||||
WHERE c_id = ".$this->course_id." AND lp_id = ".$this->get_ref_id();
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_array($result, 'NUM');
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the progress of this learnpath. Only the last attempt are taken into account.
|
||||
*
|
||||
* @param $stud_id student id (default: all students who have results - then the average is returned)
|
||||
* @param $type The type of score we want to get: best|average|ranking
|
||||
*
|
||||
* @return array (score, max) if student is given
|
||||
* array (sum of scores, number of scores) otherwise
|
||||
* or null if no scores available
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
$tbl_stats = Database::get_course_table(TABLE_LP_VIEW);
|
||||
$session_id = $this->get_session_id();
|
||||
if (empty($session_id)) {
|
||||
$session_id = api_get_session_id();
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM $tbl_stats
|
||||
WHERE
|
||||
c_id = ".$this->course_id." AND
|
||||
lp_id = ".$this->get_ref_id()." AND
|
||||
session_id = $session_id ";
|
||||
|
||||
if (isset($stud_id)) {
|
||||
$sql .= ' AND user_id = '.intval($stud_id);
|
||||
}
|
||||
|
||||
// order by id, that way the student's first attempt is accessed first
|
||||
$sql .= ' ORDER BY view_count DESC';
|
||||
|
||||
$scores = Database::query($sql);
|
||||
// for 1 student
|
||||
if (isset($stud_id)) {
|
||||
if ($data = Database::fetch_assoc($scores)) {
|
||||
return [$data['progress'], 100];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// all students -> get average
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$rescount = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
$sumResult = 0;
|
||||
while ($data = Database::fetch_array($scores)) {
|
||||
if (!(array_key_exists($data['user_id'], $students))) {
|
||||
$students[$data['user_id']] = $data['progress'];
|
||||
$rescount++;
|
||||
$sum += $data['progress'] / 100;
|
||||
$sumResult += $data['progress'];
|
||||
|
||||
if ($data['progress'] > $bestResult) {
|
||||
$bestResult = $data['progress'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == $rescount) {
|
||||
return [null, null];
|
||||
} else {
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, 100];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sumResult / $rescount, 100];
|
||||
break;
|
||||
case 'ranking':
|
||||
return AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
break;
|
||||
default:
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL where to go to if the user clicks on the link.
|
||||
*/
|
||||
public function get_link()
|
||||
{
|
||||
$session_id = $this->get_session_id();
|
||||
$url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.api_get_cidreq_params(
|
||||
$this->get_course_code(),
|
||||
$session_id
|
||||
).'&gradebook=view';
|
||||
|
||||
if (!api_is_allowed_to_edit() || null == $this->calc_score(api_get_user_id())) {
|
||||
$url .= '&action=view&lp_id='.$this->get_ref_id();
|
||||
} else {
|
||||
$url .= '&action=build&lp_id='.$this->get_ref_id();
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name to display: same as learnpath title.
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$data = $this->get_learnpath_data();
|
||||
|
||||
return $data['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description to display: same as learnpath description.
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
$data = $this->get_learnpath_data();
|
||||
|
||||
return $data['description'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to a learnpath.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$sql = 'SELECT count(id) FROM '.$this->get_learnpath_table().'
|
||||
WHERE c_id = '.$this->course_id.' AND id = '.$this->get_ref_id().' ';
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result, 'NUM');
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('LearningPaths');
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'learnpath';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the learnpath.
|
||||
*/
|
||||
private function get_learnpath_table()
|
||||
{
|
||||
$this->learnpath_table = Database::get_course_table(TABLE_LP_MAIN);
|
||||
|
||||
return $this->learnpath_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database contents of this learnpath.
|
||||
*/
|
||||
private function get_learnpath_data()
|
||||
{
|
||||
if (!isset($this->learnpath_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_learnpath_table().'
|
||||
WHERE c_id = '.$this->course_id.' AND id = '.$this->get_ref_id().' ';
|
||||
$result = Database::query($sql);
|
||||
$this->learnpath_data = Database::fetch_array($result);
|
||||
}
|
||||
|
||||
return $this->learnpath_data;
|
||||
}
|
||||
}
|
||||
132
main/gradebook/lib/be/linkfactory.class.php
Normal file
132
main/gradebook/lib/be/linkfactory.class.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class LinkFactory
|
||||
* Factory for link objects.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class LinkFactory
|
||||
{
|
||||
/**
|
||||
* Retrieve links and return them as an array of extensions of AbstractLink.
|
||||
*
|
||||
* @param int $id link id
|
||||
* @param int $type link type
|
||||
* @param int $ref_id reference id
|
||||
* @param int $user_id user id (link owner)
|
||||
* @param string $course_code course code
|
||||
* @param int $category_id parent category
|
||||
* @param int $visible visible
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function load(
|
||||
$id = null,
|
||||
$type = null,
|
||||
$ref_id = null,
|
||||
$user_id = null,
|
||||
$course_code = null,
|
||||
$category_id = null,
|
||||
$visible = null
|
||||
) {
|
||||
return AbstractLink::load(
|
||||
$id,
|
||||
$type,
|
||||
$ref_id,
|
||||
$user_id,
|
||||
$course_code,
|
||||
$category_id,
|
||||
$visible
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link object referring to an evaluation.
|
||||
*/
|
||||
public function get_evaluation_link($eval_id)
|
||||
{
|
||||
$links = AbstractLink::load(null, null, $eval_id);
|
||||
foreach ($links as $link) {
|
||||
if (is_a($link, 'EvalLink')) {
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find links by name.
|
||||
*
|
||||
* @param string $name_mask search string
|
||||
*
|
||||
* @return array link objects matching the search criterium
|
||||
*/
|
||||
public function find_links($name_mask, $selectcat)
|
||||
{
|
||||
return AbstractLink::find_links($name_mask, $selectcat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to create specific link objects.
|
||||
*
|
||||
* @param int $type link type
|
||||
*/
|
||||
public static function create($type)
|
||||
{
|
||||
$type = (int) $type;
|
||||
switch ($type) {
|
||||
case LINK_EXERCISE:
|
||||
return new ExerciseLink();
|
||||
case LINK_HOTPOTATOES:
|
||||
return new ExerciseLink(1);
|
||||
case LINK_DROPBOX:
|
||||
return new DropboxLink();
|
||||
case LINK_STUDENTPUBLICATION:
|
||||
return new StudentPublicationLink();
|
||||
case LINK_LEARNPATH:
|
||||
return new LearnpathLink();
|
||||
case LINK_FORUM_THREAD:
|
||||
return new ForumThreadLink();
|
||||
case LINK_ATTENDANCE:
|
||||
return new AttendanceLink();
|
||||
case LINK_SURVEY:
|
||||
return new SurveyLink();
|
||||
case LINK_PORTFOLIO:
|
||||
return new PortfolioLink();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of all known link types.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_all_types()
|
||||
{
|
||||
$types = [
|
||||
LINK_EXERCISE,
|
||||
//LINK_DROPBOX,
|
||||
LINK_HOTPOTATOES,
|
||||
LINK_STUDENTPUBLICATION,
|
||||
LINK_LEARNPATH,
|
||||
LINK_FORUM_THREAD,
|
||||
LINK_ATTENDANCE,
|
||||
LINK_SURVEY,
|
||||
];
|
||||
|
||||
if (api_get_configuration_value('allow_portfolio_tool')) {
|
||||
$types[] = LINK_PORTFOLIO;
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
}
|
||||
}
|
||||
323
main/gradebook/lib/be/result.class.php
Normal file
323
main/gradebook/lib/be/result.class.php
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Defines a gradebook Result object.
|
||||
*
|
||||
* @author Bert Steppé, Stijn Konings
|
||||
*/
|
||||
class Result
|
||||
{
|
||||
private $id;
|
||||
private $user_id;
|
||||
private $evaluation;
|
||||
private $created_at;
|
||||
private $score;
|
||||
|
||||
/**
|
||||
* Result constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->created_at = api_get_utc_datetime();
|
||||
}
|
||||
|
||||
public function get_id()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_user_id()
|
||||
{
|
||||
return $this->user_id;
|
||||
}
|
||||
|
||||
public function get_evaluation_id()
|
||||
{
|
||||
return $this->evaluation;
|
||||
}
|
||||
|
||||
public function get_date()
|
||||
{
|
||||
return $this->created_at;
|
||||
}
|
||||
|
||||
public function get_score()
|
||||
{
|
||||
return $this->score;
|
||||
}
|
||||
|
||||
public function set_id($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function set_user_id($user_id)
|
||||
{
|
||||
$this->user_id = $user_id;
|
||||
}
|
||||
|
||||
public function set_evaluation_id($evaluation_id)
|
||||
{
|
||||
$this->evaluation = $evaluation_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $creation_date
|
||||
*/
|
||||
public function set_date($creation_date)
|
||||
{
|
||||
$this->created_at = $creation_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $score
|
||||
*/
|
||||
public function set_score($score)
|
||||
{
|
||||
$this->score = $score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve results and return them as an array of Result objects.
|
||||
*
|
||||
* @param $id result id
|
||||
* @param $user_id user id (student)
|
||||
* @param $evaluation_id evaluation where this is a result for
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function load($id = null, $user_id = null, $evaluation_id = null)
|
||||
{
|
||||
$tbl_user = Database::get_main_table(TABLE_MAIN_USER);
|
||||
$tbl_grade_results = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$tbl_course_rel_course = Database::get_main_table(TABLE_MAIN_COURSE_USER);
|
||||
$tbl_session_rel_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
|
||||
$sessionId = api_get_session_id();
|
||||
$list_user_course_list = [];
|
||||
|
||||
if (is_null($id) && is_null($user_id) && !is_null($evaluation_id)) {
|
||||
// Verified_if_exist_evaluation
|
||||
$sql = 'SELECT COUNT(*) AS count
|
||||
FROM '.$tbl_grade_results.'
|
||||
WHERE evaluation_id="'.Database::escape_string($evaluation_id).'"';
|
||||
|
||||
$result = Database::query($sql);
|
||||
$existEvaluation = Database::result($result, 0, 0);
|
||||
|
||||
if (0 != $existEvaluation) {
|
||||
if ($sessionId) {
|
||||
$sql = 'SELECT c_id, user_id as user_id, status
|
||||
FROM '.$tbl_session_rel_course_user.'
|
||||
WHERE
|
||||
status= 0 AND
|
||||
c_id = "'.api_get_course_int_id().'" AND
|
||||
session_id = '.$sessionId;
|
||||
} else {
|
||||
$sql = 'SELECT c_id, user_id, status
|
||||
FROM '.$tbl_course_rel_course.'
|
||||
WHERE status ="'.STUDENT.'" AND c_id = "'.api_get_course_int_id().'" ';
|
||||
}
|
||||
|
||||
$res_course_rel_user = Database::query($sql);
|
||||
while ($row_course_rel_user = Database::fetch_array($res_course_rel_user, 'ASSOC')) {
|
||||
$list_user_course_list[] = $row_course_rel_user;
|
||||
}
|
||||
$current_date = api_get_utc_datetime();
|
||||
for ($i = 0; $i < count($list_user_course_list); $i++) {
|
||||
$sql_verified = 'SELECT COUNT(*) AS count
|
||||
FROM '.$tbl_grade_results.'
|
||||
WHERE
|
||||
user_id="'.intval($list_user_course_list[$i]['user_id']).'" AND
|
||||
evaluation_id="'.intval($evaluation_id).'";';
|
||||
$res_verified = Database::query($sql_verified);
|
||||
$info_verified = Database::result($res_verified, 0, 0);
|
||||
if (0 == $info_verified) {
|
||||
$sql_insert = 'INSERT INTO '.$tbl_grade_results.'(user_id,evaluation_id,created_at,score)
|
||||
VALUES ("'.intval($list_user_course_list[$i]['user_id']).'","'.intval($evaluation_id).'","'.$current_date.'",0);';
|
||||
Database::query($sql_insert);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$userIdList = [];
|
||||
foreach ($list_user_course_list as $data) {
|
||||
$userIdList[] = $data['user_id'];
|
||||
}
|
||||
$userIdListToString = implode("', '", $userIdList);
|
||||
|
||||
$sql = "SELECT lastname, gr.id, gr.user_id, gr.evaluation_id, gr.created_at, gr.score
|
||||
FROM $tbl_grade_results gr
|
||||
INNER JOIN $tbl_user u
|
||||
ON gr.user_id = u.user_id ";
|
||||
|
||||
if (!empty($userIdList)) {
|
||||
$sql .= " AND u.user_id IN ('$userIdListToString')";
|
||||
}
|
||||
|
||||
$paramcount = 0;
|
||||
if (!empty($id)) {
|
||||
$sql .= ' WHERE gr.id = '.intval($id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (!empty($user_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' gr.user_id = '.intval($user_id);
|
||||
$paramcount++;
|
||||
}
|
||||
if (!empty($evaluation_id)) {
|
||||
if (0 != $paramcount) {
|
||||
$sql .= ' AND';
|
||||
} else {
|
||||
$sql .= ' WHERE';
|
||||
}
|
||||
$sql .= ' gr.evaluation_id = '.intval($evaluation_id);
|
||||
}
|
||||
$sql .= ' ORDER BY u.lastname, u.firstname';
|
||||
|
||||
$result = Database::query($sql);
|
||||
$allres = [];
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$res = new Result();
|
||||
$res->set_id($data['id']);
|
||||
$res->set_user_id($data['user_id']);
|
||||
$res->set_evaluation_id($data['evaluation_id']);
|
||||
$res->set_date(api_get_local_time($data['created_at']));
|
||||
$res->set_score($data['score']);
|
||||
$allres[] = $res;
|
||||
}
|
||||
|
||||
return $allres;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert this result into the database.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (isset($this->user_id) && isset($this->evaluation)) {
|
||||
$tbl_grade_results = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$sql = "INSERT INTO ".$tbl_grade_results
|
||||
." (user_id, evaluation_id,
|
||||
created_at";
|
||||
if (isset($this->score)) {
|
||||
$sql .= ",score";
|
||||
}
|
||||
$sql .= ") VALUES
|
||||
(".(int) $this->get_user_id().", ".(int) $this->get_evaluation_id()
|
||||
.", '".$this->get_date()."' ";
|
||||
if (isset($this->score)) {
|
||||
$sql .= ", ".$this->get_score();
|
||||
}
|
||||
$sql .= ")";
|
||||
Database::query($sql);
|
||||
} else {
|
||||
exit('Error in Result add: required field empty');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* insert log result.
|
||||
*/
|
||||
public function addResultLog($userid, $evaluationid)
|
||||
{
|
||||
if (isset($userid) && isset($evaluationid)) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG);
|
||||
$result = new Result();
|
||||
|
||||
$arr_result = $result->load(null, $userid, $evaluationid);
|
||||
$arr = get_object_vars($arr_result[0]);
|
||||
|
||||
$sql = 'INSERT INTO '.$table
|
||||
.' (id_result,user_id, evaluation_id,created_at';
|
||||
if (isset($arr['score'])) {
|
||||
$sql .= ',score';
|
||||
}
|
||||
$sql .= ') VALUES
|
||||
('.(int) $arr['id'].','.(int) $arr['user_id'].', '.(int) $arr['evaluation']
|
||||
.", '".api_get_utc_datetime()."'";
|
||||
if (isset($arr['score'])) {
|
||||
$sql .= ', '.$arr['score'];
|
||||
}
|
||||
$sql .= ')';
|
||||
|
||||
Database::query($sql);
|
||||
} else {
|
||||
exit('Error in Result add: required field empty');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the properties of this result in the database.
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$sql = 'UPDATE '.$table.'
|
||||
SET user_id = '.$this->get_user_id()
|
||||
.', evaluation_id = '.$this->get_evaluation_id()
|
||||
.', score = ';
|
||||
if (isset($this->score)) {
|
||||
$sql .= $this->get_score();
|
||||
} else {
|
||||
$sql .= 'null';
|
||||
}
|
||||
if (isset($this->id)) {
|
||||
$sql .= " WHERE id = {$this->id}";
|
||||
} else {
|
||||
$sql .= " WHERE evaluation_id = {$this->evaluation}
|
||||
AND user_id = {$this->user_id}
|
||||
";
|
||||
}
|
||||
|
||||
// no need to update creation date
|
||||
Database::query($sql);
|
||||
|
||||
Evaluation::generateStats($this->get_evaluation_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this result from the database.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$sql = 'DELETE FROM '.$table.' WHERE id = '.$this->id;
|
||||
Database::query($sql);
|
||||
$allowMultipleAttempts = api_get_configuration_value('gradebook_multiple_evaluation_attempts');
|
||||
if ($allowMultipleAttempts) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_ATTEMPT);
|
||||
$sql = "DELETE FROM $table WHERE result_id = ".$this->id;
|
||||
Database::query($sql);
|
||||
}
|
||||
|
||||
Evaluation::generateStats($this->get_evaluation_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if exists a result with its user and evaluation.
|
||||
*
|
||||
* @throws \Doctrine\ORM\Query\QueryException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists()
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
|
||||
$sql = "SELECT COUNT(*) AS count
|
||||
FROM $table gr
|
||||
WHERE gr.evaluation_id = {$this->evaluation}
|
||||
AND gr.user_id = {$this->user_id}
|
||||
";
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result);
|
||||
$count = (int) $row['count'];
|
||||
|
||||
return $count > 0;
|
||||
}
|
||||
}
|
||||
427
main/gradebook/lib/be/studentpublicationlink.class.php
Normal file
427
main/gradebook/lib/be/studentpublicationlink.class.php
Normal file
@@ -0,0 +1,427 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook link to student publication item.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class StudentPublicationLink extends AbstractLink
|
||||
{
|
||||
private $studpub_table;
|
||||
private $itemprop_table;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_STUDENTPUBLICATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of a document
|
||||
* This function is loaded when using a gradebook as a tab (gradebook = -1)
|
||||
* see issue #2705.
|
||||
*/
|
||||
public function get_view_url($stud_id)
|
||||
{
|
||||
return null;
|
||||
// find a file uploaded by the given student,
|
||||
// with the same title as the evaluation name
|
||||
|
||||
$eval = $this->get_evaluation();
|
||||
$stud_id = (int) $stud_id;
|
||||
$itemProperty = $this->get_itemprop_table();
|
||||
$workTable = $this->get_studpub_table();
|
||||
$courseId = $this->course_id;
|
||||
|
||||
$sql = "SELECT pub.url
|
||||
FROM $itemProperty prop
|
||||
INNER JOIN $workTable pub
|
||||
ON (prop.c_id = pub.c_id AND prop.ref = pub.id)
|
||||
WHERE
|
||||
prop.c_id = $courseId AND
|
||||
pub.c_id = $courseId AND
|
||||
prop.tool = 'work' AND
|
||||
prop.insert_user_id = $stud_id AND
|
||||
pub.title = '".Database::escape_string($eval->get_name())."' AND
|
||||
pub.session_id=".api_get_session_id();
|
||||
|
||||
$result = Database::query($sql);
|
||||
if ($fileurl = Database::fetch_row($result)) {
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('Works');
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of all exercises available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
return [];
|
||||
}
|
||||
$em = Database::getManager();
|
||||
$sessionId = $this->get_session_id();
|
||||
$session = $em->find('ChamiloCoreBundle:Session', $sessionId);
|
||||
/*
|
||||
if (empty($session_id)) {
|
||||
$session_condition = api_get_session_condition(0, true);
|
||||
} else {
|
||||
$session_condition = api_get_session_condition($session_id, true, true);
|
||||
}
|
||||
$sql = "SELECT id, url, title FROM $tbl_grade_links
|
||||
WHERE c_id = {$this->course_id} AND filetype='folder' AND active = 1 $session_condition ";*/
|
||||
|
||||
//Only show works from the session
|
||||
//AND has_properties != ''
|
||||
$links = $em
|
||||
->getRepository('ChamiloCourseBundle:CStudentPublication')
|
||||
->findBy([
|
||||
'cId' => $this->course_id,
|
||||
'active' => true,
|
||||
'filetype' => 'folder',
|
||||
'session' => $session,
|
||||
]);
|
||||
|
||||
foreach ($links as $data) {
|
||||
$work_name = $data->getTitle();
|
||||
if (empty($work_name)) {
|
||||
$work_name = basename($data->getUrl());
|
||||
}
|
||||
$cats[] = [$data->getId(), $work_name];
|
||||
}
|
||||
$cats = isset($cats) ? $cats : [];
|
||||
|
||||
return $cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this exercise yet ?
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
$id = $data['id'];
|
||||
|
||||
$em = Database::getManager();
|
||||
$session = $em->find('ChamiloCoreBundle:Session', $this->get_session_id());
|
||||
$results = $em
|
||||
->getRepository('ChamiloCourseBundle:CStudentPublication')
|
||||
->findBy([
|
||||
'cId' => $this->course_id,
|
||||
'parentId' => $id,
|
||||
'session' => $session,
|
||||
]);
|
||||
|
||||
return 0 != count($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $stud_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
$stud_id = (int) $stud_id;
|
||||
$em = Database::getManager();
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if (empty($data)) {
|
||||
return [];
|
||||
}
|
||||
$id = $data['id'];
|
||||
$session = api_get_session_entity($this->get_session_id());
|
||||
|
||||
$assignment = $em
|
||||
->getRepository('ChamiloCourseBundle:CStudentPublication')
|
||||
->findOneBy([
|
||||
'cId' => $this->course_id,
|
||||
'id' => $id,
|
||||
'session' => $session,
|
||||
])
|
||||
;
|
||||
|
||||
$parentId = !$assignment ? 0 : $assignment->getId();
|
||||
|
||||
if (empty($session)) {
|
||||
$dql = 'SELECT a FROM ChamiloCourseBundle:CStudentPublication a
|
||||
WHERE
|
||||
a.cId = :course AND
|
||||
a.active = :active AND
|
||||
a.parentId = :parent AND
|
||||
a.session is null AND
|
||||
a.qualificatorId <> 0
|
||||
';
|
||||
|
||||
$params = [
|
||||
'course' => $this->course_id,
|
||||
'parent' => $parentId,
|
||||
'active' => true,
|
||||
];
|
||||
} else {
|
||||
$dql = 'SELECT a FROM ChamiloCourseBundle:CStudentPublication a
|
||||
WHERE
|
||||
a.cId = :course AND
|
||||
a.active = :active AND
|
||||
a.parentId = :parent AND
|
||||
a.session = :session AND
|
||||
a.qualificatorId <> 0
|
||||
';
|
||||
|
||||
$params = [
|
||||
'course' => $this->course_id,
|
||||
'parent' => $parentId,
|
||||
'session' => $session,
|
||||
'active' => true,
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($stud_id)) {
|
||||
$dql .= ' AND a.userId = :student ';
|
||||
$params['student'] = $stud_id;
|
||||
}
|
||||
|
||||
$order = api_get_setting('student_publication_to_take_in_gradebook');
|
||||
|
||||
switch ($order) {
|
||||
case 'last':
|
||||
// latest attempt
|
||||
$dql .= ' ORDER BY a.sentDate DESC';
|
||||
break;
|
||||
case 'first':
|
||||
default:
|
||||
// first attempt
|
||||
$dql .= ' ORDER BY a.id';
|
||||
break;
|
||||
}
|
||||
|
||||
$scores = $em->createQuery($dql)->execute($params);
|
||||
|
||||
// for 1 student
|
||||
if (!empty($stud_id)) {
|
||||
if (!count($scores)) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
$data = $scores[0];
|
||||
|
||||
return [
|
||||
$data->getQualification(),
|
||||
$assignment->getQualification(),
|
||||
api_get_local_time($assignment->getDateOfQualification()),
|
||||
1,
|
||||
];
|
||||
}
|
||||
|
||||
$students = []; // user list, needed to make sure we only
|
||||
// take first attempts into account
|
||||
$rescount = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
$weight = 0;
|
||||
$sumResult = 0;
|
||||
|
||||
foreach ($scores as $data) {
|
||||
if (!(array_key_exists($data->getUserId(), $students))) {
|
||||
if (0 != $assignment->getQualification()) {
|
||||
$students[$data->getUserId()] = $data->getQualification();
|
||||
$rescount++;
|
||||
$sum += $data->getQualification() / $assignment->getQualification();
|
||||
$sumResult += $data->getQualification();
|
||||
|
||||
if ($data->getQualification() > $bestResult) {
|
||||
$bestResult = $data->getQualification();
|
||||
}
|
||||
$weight = $assignment->getQualification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == $rescount) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, $weight];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sumResult / $rescount, $weight];
|
||||
break;
|
||||
case 'ranking':
|
||||
return AbstractLink::getCurrentUserRanking($stud_id, $students);
|
||||
break;
|
||||
default:
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
$this->get_exercise_data();
|
||||
$name = isset($this->exercise_data['title']) && !empty($this->exercise_data['title']) ? $this->exercise_data['title'] : get_lang('Untitled');
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
public function get_description()
|
||||
{
|
||||
$this->get_exercise_data();
|
||||
|
||||
return isset($this->exercise_data['description']) ? $this->exercise_data['description'] : null;
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
$url = api_get_path(WEB_PATH).'main/work/work.php?'.api_get_cidreq_params($this->get_course_code(), $sessionId).'&id='.$this->exercise_data['id'].'&gradebook=view';
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_valid_link()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
$id = $data['id'];
|
||||
$sql = 'SELECT count(id) FROM '.$this->get_studpub_table().'
|
||||
WHERE
|
||||
c_id = "'.$this->course_id.'" AND
|
||||
id = '.$id;
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'studentpublication';
|
||||
}
|
||||
|
||||
public function save_linked_data()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
$id = $data['id'];
|
||||
|
||||
$weight = api_float_val($this->get_weight());
|
||||
if (!empty($id)) {
|
||||
//Cleans works
|
||||
$sql = 'UPDATE '.$this->get_studpub_table().'
|
||||
SET weight= '.$weight.'
|
||||
WHERE c_id = '.$this->course_id.' AND id ='.$id;
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function delete_linked_data()
|
||||
{
|
||||
$data = $this->get_exercise_data();
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
//Cleans works
|
||||
$sql = 'UPDATE '.$this->get_studpub_table().'
|
||||
SET weight = 0
|
||||
WHERE c_id = '.$this->course_id.' AND id ='.$id;
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the student publications.
|
||||
*/
|
||||
private function get_studpub_table()
|
||||
{
|
||||
return $this->studpub_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the item properties.
|
||||
*/
|
||||
private function get_itemprop_table()
|
||||
{
|
||||
return $this->itemprop_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_exercise_data()
|
||||
{
|
||||
$course_info = api_get_course_info($this->get_course_code());
|
||||
if (!isset($this->exercise_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_studpub_table()."
|
||||
WHERE
|
||||
c_id ='".$course_info['real_id']."' AND
|
||||
id = '".$this->get_ref_id()."' ";
|
||||
$query = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($query);
|
||||
|
||||
// Try with iid
|
||||
if (empty($this->exercise_data)) {
|
||||
$sql = 'SELECT * FROM '.$this->get_studpub_table()."
|
||||
WHERE
|
||||
c_id ='".$course_info['real_id']."' AND
|
||||
iid = '".$this->get_ref_id()."' ";
|
||||
$query = Database::query($sql);
|
||||
$this->exercise_data = Database::fetch_array($query);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->exercise_data;
|
||||
}
|
||||
}
|
||||
313
main/gradebook/lib/be/surveylink.class.php
Normal file
313
main/gradebook/lib/be/surveylink.class.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook link to a survey item.
|
||||
*
|
||||
* @author Ivan Tcholakov <ivantcholakov@gmail.com>, 2010
|
||||
*/
|
||||
class SurveyLink extends AbstractLink
|
||||
{
|
||||
private $survey_table;
|
||||
private $survey_data = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->set_type(LINK_SURVEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$this->get_survey_data();
|
||||
|
||||
return $this->survey_data['code'].': '.self::html_to_text($this->survey_data['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_description()
|
||||
{
|
||||
$this->get_survey_data();
|
||||
|
||||
return $this->survey_data['subtitle'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_type_name()
|
||||
{
|
||||
return get_lang('Survey');
|
||||
}
|
||||
|
||||
public function is_allowed_to_change_name()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_name_and_description()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_max()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function needs_results()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of all surveys available.
|
||||
*
|
||||
* @return array 2-dimensional array - every element contains 2 subelements (id, name)
|
||||
*/
|
||||
public function get_all_links()
|
||||
{
|
||||
if (empty($this->course_code)) {
|
||||
exit('Error in get_all_links() : course code not set');
|
||||
}
|
||||
$tbl_survey = $this->get_survey_table();
|
||||
$sessionId = $this->get_session_id();
|
||||
$course_id = $this->getCourseId();
|
||||
|
||||
$sql = 'SELECT survey_id, title, code FROM '.$tbl_survey.'
|
||||
WHERE c_id = '.$course_id.' AND session_id = '.$sessionId;
|
||||
$result = Database::query($sql);
|
||||
while ($data = Database::fetch_array($result)) {
|
||||
$links[] = [
|
||||
$data['survey_id'],
|
||||
api_trunc_str(
|
||||
$data['code'].': '.self::html_to_text($data['title']),
|
||||
80
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return isset($links) ? $links : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Has anyone done this survey yet?
|
||||
* Implementation of the AbstractLink class, mainly used dynamically in gradebook/lib/fe.
|
||||
*/
|
||||
public function has_results()
|
||||
{
|
||||
$ref_id = $this->get_ref_id();
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
|
||||
$tbl_survey = Database::get_course_table(TABLE_SURVEY);
|
||||
$tbl_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
|
||||
$sql = "SELECT
|
||||
COUNT(i.answered)
|
||||
FROM $tbl_survey AS s
|
||||
JOIN $tbl_survey_invitation AS i ON s.code = i.survey_code
|
||||
WHERE
|
||||
s.c_id = $courseId AND
|
||||
i.c_id = $courseId AND
|
||||
s.survey_id = $ref_id AND
|
||||
i.session_id = $sessionId";
|
||||
|
||||
$sql_result = Database::query($sql);
|
||||
$data = Database::fetch_array($sql_result);
|
||||
|
||||
return 0 != $data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate score for a student (to show in the gradebook).
|
||||
*
|
||||
* @param int $stud_id
|
||||
* @param string $type Type of result we want (best|average|ranking)
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function calc_score($stud_id = null, $type = null)
|
||||
{
|
||||
// Note: Max score is assumed to be always 1 for surveys,
|
||||
// only student's participation is to be taken into account.
|
||||
$max_score = 1;
|
||||
$ref_id = $this->get_ref_id();
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
$tbl_survey = Database::get_course_table(TABLE_SURVEY);
|
||||
$tbl_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
|
||||
$get_individual_score = !is_null($stud_id);
|
||||
|
||||
$sql = "SELECT i.answered
|
||||
FROM $tbl_survey AS s
|
||||
JOIN $tbl_survey_invitation AS i
|
||||
ON s.code = i.survey_code
|
||||
WHERE
|
||||
s.c_id = $courseId AND
|
||||
i.c_id = $courseId AND
|
||||
s.survey_id = $ref_id AND
|
||||
i.session_id = $sessionId
|
||||
";
|
||||
|
||||
if ($get_individual_score) {
|
||||
$sql .= ' AND i.user = '.intval($stud_id);
|
||||
}
|
||||
|
||||
$sql_result = Database::query($sql);
|
||||
|
||||
if ($get_individual_score) {
|
||||
// for 1 student
|
||||
if ($data = Database::fetch_array($sql_result)) {
|
||||
return [$data['answered'] ? $max_score : 0, $max_score];
|
||||
}
|
||||
|
||||
return [0, $max_score];
|
||||
} else {
|
||||
// for all the students -> get average
|
||||
$rescount = 0;
|
||||
$sum = 0;
|
||||
$bestResult = 0;
|
||||
while ($data = Database::fetch_array($sql_result)) {
|
||||
$sum += $data['answered'] ? $max_score : 0;
|
||||
$rescount++;
|
||||
if ($data['answered'] > $bestResult) {
|
||||
$bestResult = $data['answered'];
|
||||
}
|
||||
}
|
||||
$sum = $sum / $max_score;
|
||||
|
||||
if (0 == $rescount) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'best':
|
||||
return [$bestResult, $rescount];
|
||||
break;
|
||||
case 'average':
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
case 'ranking':
|
||||
return null;
|
||||
break;
|
||||
default:
|
||||
return [$sum, $rescount];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this still links to a survey.
|
||||
*/
|
||||
public function is_valid_link()
|
||||
{
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
|
||||
$sql = 'SELECT count(survey_id) FROM '.$this->get_survey_table().'
|
||||
WHERE
|
||||
c_id = '.$courseId.' AND
|
||||
survey_id = '.$this->get_ref_id().' AND
|
||||
session_id = '.$sessionId;
|
||||
$result = Database::query($sql);
|
||||
$number = Database::fetch_row($result);
|
||||
|
||||
return 0 != $number[0];
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
if (api_get_configuration_value('hide_survey_reporting_button')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (api_is_allowed_to_edit()) {
|
||||
// Let students make access only through "Surveys" tool.
|
||||
$tbl_name = $this->get_survey_table();
|
||||
$sessionId = $this->get_session_id();
|
||||
$courseId = $this->getCourseId();
|
||||
|
||||
if ('' != $tbl_name) {
|
||||
$sql = 'SELECT survey_id
|
||||
FROM '.$this->get_survey_table().'
|
||||
WHERE
|
||||
c_id = '.$courseId.' AND
|
||||
survey_id = '.$this->get_ref_id().' AND
|
||||
session_id = '.$sessionId;
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
$survey_id = $row['survey_id'];
|
||||
|
||||
return api_get_path(WEB_PATH).'main/survey/reporting.php?'.api_get_cidreq_params($this->get_course_code(), $sessionId).'&survey_id='.$survey_id;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the icon for this tool.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon_name()
|
||||
{
|
||||
return 'survey';
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to get the database table of the surveys.
|
||||
*/
|
||||
private function get_survey_table()
|
||||
{
|
||||
$this->survey_table = Database::get_course_table(TABLE_SURVEY);
|
||||
|
||||
return $this->survey_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the survey data from the c_survey table with the current object id.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function get_survey_data()
|
||||
{
|
||||
$tbl_name = $this->get_survey_table();
|
||||
|
||||
if ('' == $tbl_name) {
|
||||
return false;
|
||||
} elseif (empty($this->survey_data)) {
|
||||
$courseId = $this->getCourseId();
|
||||
$sessionId = $this->get_session_id();
|
||||
|
||||
$sql = 'SELECT * FROM '.$tbl_name.'
|
||||
WHERE
|
||||
c_id = '.$courseId.' AND
|
||||
survey_id = '.$this->get_ref_id().' AND
|
||||
session_id = '.$sessionId;
|
||||
$query = Database::query($sql);
|
||||
$this->survey_data = Database::fetch_array($query);
|
||||
}
|
||||
|
||||
return $this->survey_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function html_to_text($string)
|
||||
{
|
||||
return strip_tags($string);
|
||||
}
|
||||
}
|
||||
478
main/gradebook/lib/fe/catform.class.php
Normal file
478
main/gradebook/lib/fe/catform.class.php
Normal file
@@ -0,0 +1,478 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class CatForm.
|
||||
*
|
||||
* @author Stijn Konings
|
||||
*/
|
||||
class CatForm extends FormValidator
|
||||
{
|
||||
public const TYPE_ADD = 1;
|
||||
public const TYPE_EDIT = 2;
|
||||
public const TYPE_MOVE = 3;
|
||||
public const TYPE_SELECT_COURSE = 4;
|
||||
/** @var Category */
|
||||
private $category_object;
|
||||
|
||||
/**
|
||||
* CatForm constructor.
|
||||
* Builds a form containing form items based on a given parameter.
|
||||
*
|
||||
* @param string $form_type 1=add, 2=edit,3=move,4=browse
|
||||
* @param string $category_object
|
||||
* @param string $form_name
|
||||
* @param string $method
|
||||
* @param null $action
|
||||
*/
|
||||
public function __construct(
|
||||
$form_type,
|
||||
$category_object,
|
||||
$form_name,
|
||||
$method = 'post',
|
||||
$action = null
|
||||
) {
|
||||
parent::__construct($form_name, $method, $action);
|
||||
$this->form_type = $form_type;
|
||||
if (isset($category_object)) {
|
||||
$this->category_object = $category_object;
|
||||
}
|
||||
|
||||
switch ($this->form_type) {
|
||||
case self::TYPE_EDIT:
|
||||
$this->build_editing_form();
|
||||
break;
|
||||
case self::TYPE_ADD:
|
||||
$this->build_add_form();
|
||||
break;
|
||||
case self::TYPE_MOVE:
|
||||
$this->build_move_form();
|
||||
break;
|
||||
case self::TYPE_SELECT_COURSE:
|
||||
$this->build_select_course_form();
|
||||
break;
|
||||
}
|
||||
|
||||
$this->setDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will build a move form that will allow the user to move a category to
|
||||
* a another.
|
||||
*/
|
||||
protected function build_move_form()
|
||||
{
|
||||
$renderer = &$this->defaultRenderer();
|
||||
$renderer->setCustomElementTemplate('<span>{element}</span> ');
|
||||
$this->addElement(
|
||||
'static',
|
||||
null,
|
||||
null,
|
||||
'"'.$this->category_object->get_name().'" '
|
||||
);
|
||||
$this->addElement('static', null, null, get_lang('MoveTo').' : ');
|
||||
$select = $this->addElement('select', 'move_cat', null, null);
|
||||
$line = null;
|
||||
foreach ($this->category_object->get_target_categories() as $cat) {
|
||||
for ($i = 0; $i < $cat[2]; $i++) {
|
||||
$line .= '--';
|
||||
}
|
||||
if ($cat[0] != $this->category_object->get_parent_id()) {
|
||||
$select->addOption($line.' '.$cat[1], $cat[0]);
|
||||
} else {
|
||||
$select->addOption($line.' '.$cat[1], $cat[0], 'disabled');
|
||||
}
|
||||
$line = '';
|
||||
}
|
||||
$this->addElement('submit', null, get_lang('Ok'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function builds an 'add category form, if parent id is 0, it will only
|
||||
* show courses.
|
||||
*/
|
||||
protected function build_add_form()
|
||||
{
|
||||
// check if we are a root category
|
||||
// if so, you can only choose between courses
|
||||
if ('0' == $this->category_object->get_parent_id()) {
|
||||
$this->setDefaults(
|
||||
[
|
||||
'select_course' => $this->category_object->get_course_code(),
|
||||
'hid_user_id' => $this->category_object->get_user_id(),
|
||||
'hid_parent_id' => $this->category_object->get_parent_id(),
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$this->setDefaults(
|
||||
[
|
||||
'hid_user_id' => $this->category_object->get_user_id(),
|
||||
'hid_parent_id' => $this->category_object->get_parent_id(),
|
||||
]
|
||||
);
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
'course_code',
|
||||
$this->category_object->get_course_code()
|
||||
);
|
||||
}
|
||||
$this->build_basic_form();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an form to edit a category.
|
||||
*/
|
||||
protected function build_editing_form()
|
||||
{
|
||||
$skills = $this->category_object->getSkillsForSelect();
|
||||
|
||||
$course_code = api_get_course_id();
|
||||
$session_id = api_get_session_id();
|
||||
|
||||
$test_cats = Category::load(
|
||||
null,
|
||||
null,
|
||||
$course_code,
|
||||
null,
|
||||
null,
|
||||
$session_id,
|
||||
false
|
||||
);
|
||||
|
||||
$links = null;
|
||||
if (isset($test_cats[0])) {
|
||||
$links = $test_cats[0]->get_links();
|
||||
}
|
||||
$grade_model_id = $this->category_object->get_grade_model_id();
|
||||
|
||||
if (empty($links)) {
|
||||
$grade_model_id = 0;
|
||||
}
|
||||
|
||||
$category_name = $this->category_object->get_name();
|
||||
|
||||
// The main course category:
|
||||
if (isset($this->category_object) && 0 == $this->category_object->get_parent_id()) {
|
||||
if (empty($category_name)) {
|
||||
$category_name = $course_code;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setDefaults(
|
||||
[
|
||||
'name' => $category_name,
|
||||
'description' => $this->category_object->get_description(),
|
||||
'hid_user_id' => $this->category_object->get_user_id(),
|
||||
'hid_parent_id' => $this->category_object->get_parent_id(),
|
||||
'grade_model_id' => $grade_model_id,
|
||||
'skills' => $skills,
|
||||
'weight' => $this->category_object->get_weight(),
|
||||
'visible' => $this->category_object->is_visible(),
|
||||
'certif_min_score' => $this->category_object->getCertificateMinScore(),
|
||||
'generate_certificates' => $this->category_object->getGenerateCertificates(),
|
||||
'is_requirement' => $this->category_object->getIsRequirement(),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addElement('hidden', 'hid_id', $this->category_object->get_id());
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
'course_code',
|
||||
$this->category_object->get_course_code()
|
||||
);
|
||||
$this->build_basic_form();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function builds an 'select course' form in the add category process,
|
||||
* if parent id is 0, it will only show courses.
|
||||
*/
|
||||
protected function build_select_course_form()
|
||||
{
|
||||
$select = $this->addElement(
|
||||
'select',
|
||||
'select_course',
|
||||
[get_lang('PickACourse'), 'test'],
|
||||
null
|
||||
);
|
||||
$courses = Category::get_all_courses(api_get_user_id());
|
||||
//only return courses that are not yet created by the teacher
|
||||
foreach ($courses as $row) {
|
||||
$select->addOption($row[1], $row[0]);
|
||||
}
|
||||
$this->setDefaults([
|
||||
'hid_user_id' => $this->category_object->get_user_id(),
|
||||
'hid_parent_id' => $this->category_object->get_parent_id(),
|
||||
]);
|
||||
$this->addElement('hidden', 'hid_user_id');
|
||||
$this->addElement('hidden', 'hid_parent_id');
|
||||
$this->addElement('submit', null, get_lang('Ok'));
|
||||
}
|
||||
|
||||
private function build_basic_form()
|
||||
{
|
||||
$this->addText(
|
||||
'name',
|
||||
get_lang('CategoryName'),
|
||||
true,
|
||||
['maxlength' => '50']
|
||||
);
|
||||
$this->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
|
||||
|
||||
if (isset($this->category_object) &&
|
||||
$this->category_object->get_parent_id() == 0
|
||||
) {
|
||||
// we can't change the root category
|
||||
$this->freeze('name');
|
||||
}
|
||||
|
||||
$global_weight = api_get_setting('gradebook_default_weight');
|
||||
|
||||
$value = 100;
|
||||
if (isset($global_weight)) {
|
||||
$value = $global_weight;
|
||||
}
|
||||
|
||||
$this->addFloat(
|
||||
'weight',
|
||||
[
|
||||
get_lang('TotalWeight'),
|
||||
get_lang('TotalSumOfWeights'),
|
||||
],
|
||||
true,
|
||||
['value' => $value, 'maxlength' => '5']
|
||||
);
|
||||
|
||||
$skillsDefaults = [];
|
||||
|
||||
$allowSkillEdit = api_is_platform_admin() || api_is_drh();
|
||||
if (api_get_configuration_value('skills_teachers_can_assign_skills')) {
|
||||
$allowSkillEdit = $allowSkillEdit || api_is_allowed_to_edit();
|
||||
}
|
||||
|
||||
if ($allowSkillEdit) {
|
||||
if (Skill::isToolAvailable()) {
|
||||
$skillSelect = $this->addElement(
|
||||
'select_ajax',
|
||||
'skills',
|
||||
[
|
||||
get_lang('Skills'),
|
||||
get_lang('SkillsAchievedWhenAchievingThisGradebook'),
|
||||
],
|
||||
null,
|
||||
[
|
||||
'id' => 'skills',
|
||||
'multiple' => 'multiple',
|
||||
'url' => api_get_path(WEB_AJAX_PATH).'skill.ajax.php?a=search_skills',
|
||||
]
|
||||
);
|
||||
|
||||
// The magic should be here
|
||||
$skills = $this->category_object->get_skills();
|
||||
foreach ($skills as $skill) {
|
||||
$skillsDefaults[] = $skill['id'];
|
||||
$skillSelect->addOption($skill['name'], $skill['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$defaultCertification = 0;
|
||||
if (!empty($this->category_object)) {
|
||||
$defaultCertification = $this->category_object->getCertificateMinScore();
|
||||
}
|
||||
|
||||
if (isset($this->category_object) &&
|
||||
0 == $this->category_object->get_parent_id()
|
||||
) {
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
if (empty($model)) {
|
||||
$this->addText(
|
||||
'certif_min_score',
|
||||
get_lang('CertificateMinScore'),
|
||||
true,
|
||||
['maxlength' => '5']
|
||||
);
|
||||
|
||||
if (true === api_get_configuration_value('gradebook_enable_subcategory_skills_independant_assignement')) {
|
||||
// It allows the acquisition of competencies independently in the subcategories
|
||||
$allowSkillsBySubCategory = $this->addCheckBox(
|
||||
'allow_skills_by_subcategory',
|
||||
[
|
||||
null,
|
||||
get_lang('ItAllowsTheAcquisitionOfSkillsBySubCategories'),
|
||||
],
|
||||
get_lang('AllowsSkillsBySubCategories')
|
||||
);
|
||||
$allowSkillsBySubCategory->setChecked($this->category_object->getAllowSkillBySubCategory());
|
||||
}
|
||||
} else {
|
||||
$questionWeighting = $value;
|
||||
$defaultCertification = api_number_format($this->category_object->getCertificateMinScore(), 2);
|
||||
$select = $this->addSelect(
|
||||
'certif_min_score',
|
||||
get_lang('CertificateMinScore'),
|
||||
[],
|
||||
['disable_js' => true]
|
||||
);
|
||||
|
||||
foreach ($model['score_list'] as $item) {
|
||||
$i = api_number_format($item['score_to_qualify'] / 100 * $questionWeighting, 2);
|
||||
$model = ExerciseLib::getModelStyle($item, $i);
|
||||
$attributes = ['class' => $item['css_class']];
|
||||
if ($defaultCertification == $i) {
|
||||
$attributes['selected'] = 'selected';
|
||||
}
|
||||
$select->addOption($model, $i, $attributes);
|
||||
}
|
||||
$select->updateSelectWithSelectedOption($this);
|
||||
}
|
||||
|
||||
$this->addRule(
|
||||
'certif_min_score',
|
||||
get_lang('OnlyNumbers'),
|
||||
'numeric'
|
||||
);
|
||||
$this->addRule(
|
||||
'certif_min_score',
|
||||
get_lang('NegativeValue'),
|
||||
'compare',
|
||||
'>=',
|
||||
'server',
|
||||
false,
|
||||
false,
|
||||
0
|
||||
);
|
||||
} else {
|
||||
// It enables minimun score to get the skills independant assigment
|
||||
if (true === api_get_configuration_value('gradebook_enable_subcategory_skills_independant_assignement')) {
|
||||
$allowSkillsBySubCategory = $this->category_object->getAllowSkillBySubCategory($this->category_object->get_parent_id());
|
||||
if ($allowSkillsBySubCategory) {
|
||||
$this->addText(
|
||||
'certif_min_score',
|
||||
get_lang('SkillMinScore'),
|
||||
true,
|
||||
['maxlength' => '5']
|
||||
);
|
||||
$this->addRule(
|
||||
'certif_min_score',
|
||||
get_lang('OnlyNumbers'),
|
||||
'numeric'
|
||||
);
|
||||
$this->addRule(
|
||||
'certif_min_score',
|
||||
get_lang('NegativeValue'),
|
||||
'compare',
|
||||
'>=',
|
||||
'server',
|
||||
false,
|
||||
false,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->addElement('checkbox', 'visible', null, get_lang('Visible'));
|
||||
}
|
||||
|
||||
$this->addElement('hidden', 'hid_user_id');
|
||||
$this->addElement('hidden', 'hid_parent_id');
|
||||
$this->addElement(
|
||||
'textarea',
|
||||
'description',
|
||||
get_lang('Description')
|
||||
);
|
||||
|
||||
if (isset($this->category_object) &&
|
||||
$this->category_object->get_parent_id() == 0 &&
|
||||
(api_is_platform_admin() || api_get_setting('teachers_can_change_grade_model_settings') == 'true')
|
||||
) {
|
||||
// Getting grade models
|
||||
$obj = new GradeModel();
|
||||
$obj->fill_grade_model_select_in_form(
|
||||
$this,
|
||||
'grade_model_id',
|
||||
$this->category_object->get_grade_model_id()
|
||||
);
|
||||
|
||||
// Freeze or not
|
||||
$course_code = api_get_course_id();
|
||||
$session_id = api_get_session_id();
|
||||
$test_cats = Category::load(
|
||||
null,
|
||||
null,
|
||||
$course_code,
|
||||
null,
|
||||
null,
|
||||
$session_id,
|
||||
false
|
||||
);
|
||||
$links = null;
|
||||
if (!empty($test_cats[0])) {
|
||||
$links = $test_cats[0]->get_links();
|
||||
}
|
||||
|
||||
if (count($test_cats) > 1 || !empty($links)) {
|
||||
if ('true' == api_get_setting('gradebook_enable_grade_model')) {
|
||||
$this->freeze('grade_model_id');
|
||||
}
|
||||
}
|
||||
|
||||
$generateCertificatesParams = [];
|
||||
if ($this->category_object->getGenerateCertificates()) {
|
||||
$generateCertificatesParams['checked'] = 'checked';
|
||||
}
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'generate_certificates',
|
||||
null,
|
||||
get_lang('GenerateCertificates'),
|
||||
$generateCertificatesParams
|
||||
);
|
||||
}
|
||||
|
||||
//if (!empty($session_id)) {
|
||||
$isRequirementCheckbox = $this->addCheckBox(
|
||||
'is_requirement',
|
||||
[
|
||||
null,
|
||||
get_lang('ConsiderThisGradebookAsRequirementForASessionSequence'),
|
||||
],
|
||||
get_lang('IsRequirement')
|
||||
);
|
||||
//}
|
||||
|
||||
if ($this->category_object->getIsRequirement()) {
|
||||
$isRequirementCheckbox->setChecked(true);
|
||||
}
|
||||
|
||||
$documentId = $this->category_object->getDocumentId();
|
||||
if (!empty($documentId)) {
|
||||
$documentData = DocumentManager::get_document_data_by_id($documentId, api_get_course_id());
|
||||
|
||||
if (!empty($documentData)) {
|
||||
$this->addLabel(get_lang('Certificate'), $documentData['title']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->form_type == self::TYPE_ADD) {
|
||||
$this->addButtonCreate(get_lang('AddCategory'));
|
||||
} else {
|
||||
$this->addElement('hidden', 'editcat', intval($_GET['editcat']));
|
||||
$this->addButtonUpdate(get_lang('EditCategory'));
|
||||
}
|
||||
|
||||
$setting = api_get_setting('tool_visible_by_default_at_creation');
|
||||
$visibility_default = 1;
|
||||
if (isset($setting['gradebook']) && $setting['gradebook'] == 'false') {
|
||||
$visibility_default = 0;
|
||||
}
|
||||
|
||||
$this->setDefaults(
|
||||
[
|
||||
'visible' => $visibility_default,
|
||||
'skills' => $skillsDefaults,
|
||||
'certif_min_score' => (string) $defaultCertification,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
126
main/gradebook/lib/fe/dataform.class.php
Normal file
126
main/gradebook/lib/fe/dataform.class.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Extends FormValidator with import and export forms.
|
||||
*
|
||||
* @author Stijn Konings
|
||||
*/
|
||||
class DataForm extends FormValidator
|
||||
{
|
||||
public const TYPE_IMPORT = 1;
|
||||
public const TYPE_EXPORT = 2;
|
||||
public const TYPE_EXPORT_PDF = 3;
|
||||
|
||||
/**
|
||||
* Builds a form containing form items based on a given parameter.
|
||||
*
|
||||
* @param int form_type 1=import, 2=export
|
||||
* @param obj cat_obj the category object
|
||||
* @param obj res_obj the result object
|
||||
* @param string form name
|
||||
* @param method
|
||||
* @param action
|
||||
*/
|
||||
public function __construct(
|
||||
$form_type,
|
||||
$form_name,
|
||||
$method = 'post',
|
||||
$action = null,
|
||||
$target = '',
|
||||
$locked_status
|
||||
) {
|
||||
parent::__construct($form_name, $method, $action, $target);
|
||||
$this->form_type = $form_type;
|
||||
if ($this->form_type == self::TYPE_IMPORT) {
|
||||
$this->build_import_form();
|
||||
} elseif ($this->form_type == self::TYPE_EXPORT) {
|
||||
if ($locked_status == 0) {
|
||||
$this->build_export_form_option(false);
|
||||
} else {
|
||||
$this->build_export_form();
|
||||
}
|
||||
} elseif ($this->form_type == self::TYPE_EXPORT_PDF) {
|
||||
$this->build_pdf_export_form();
|
||||
}
|
||||
$this->setDefaults();
|
||||
}
|
||||
|
||||
public function display()
|
||||
{
|
||||
parent::display();
|
||||
}
|
||||
|
||||
public function setDefaults($defaults = [], $filter = null)
|
||||
{
|
||||
parent::setDefaults($defaults, $filter);
|
||||
}
|
||||
|
||||
protected function build_pdf_export_form()
|
||||
{
|
||||
$renderer = &$this->defaultRenderer();
|
||||
$renderer->setCustomElementTemplate('<span>{element}</span>');
|
||||
$this->addElement('header', get_lang('ChooseOrientation'));
|
||||
$this->addElement('radio', 'orientation', null, get_lang('Portrait'), 'portrait');
|
||||
$this->addElement('radio', 'orientation', null, get_lang('Landscape'), 'landscape');
|
||||
$this->addButtonExport(get_lang('Export'));
|
||||
$this->setDefaults([
|
||||
'orientation' => 'portrait',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function build_export_form()
|
||||
{
|
||||
$this->addElement('header', get_lang('ChooseFormat'));
|
||||
$this->addElement('radio', 'file_type', get_lang('OutputFileType'), 'CSV (Comma-Separated Values)', 'csv');
|
||||
$this->addElement('radio', 'file_type', null, 'XML (Extensible Markup Language)', 'xml');
|
||||
$this->addElement('radio', 'file_type', null, 'PDF (Portable Document Format)', 'pdf');
|
||||
$this->addButtonExport(get_lang('Export'));
|
||||
$this->setDefaults([
|
||||
'file_type' => 'csv',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function build_export_form_option($show_pdf = true)
|
||||
{
|
||||
$this->addElement('header', get_lang('ChooseFormat'));
|
||||
$this->addElement('radio', 'file_type', get_lang('OutputFileType'), 'CSV (Comma-Separated Values)', 'csv');
|
||||
$this->addElement('radio', 'file_type', null, 'XML (Extensible Markup Language)', 'xml');
|
||||
$this->addElement(
|
||||
'radio',
|
||||
'file_type',
|
||||
Display::return_icon('info3.gif', get_lang('ToExportMustLockEvaluation')),
|
||||
'PDF (Portable Document Format)',
|
||||
'pdf',
|
||||
['disabled']
|
||||
);
|
||||
$this->addButtonExport(get_lang('Export'));
|
||||
$this->setDefaults([
|
||||
'file_type' => 'csv',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function build_import_form()
|
||||
{
|
||||
$this->addElement('hidden', 'formSent');
|
||||
$this->addElement('header', get_lang('ImportFileLocation'));
|
||||
$this->addElement('file', 'import_file', get_lang('Location'));
|
||||
$this->addElement(
|
||||
'radio',
|
||||
'file_type',
|
||||
get_lang('FileType'),
|
||||
'CSV (<a href="docs/example_csv.html" target="_blank" download>'
|
||||
.get_lang('ExampleCSVFile')
|
||||
.'</a>)',
|
||||
'csv'
|
||||
);
|
||||
//$this->addElement('radio', 'file_type', null, 'XML (<a href="docs/example_xml.html" target="_blank" download>'.get_lang('ExampleXMLFile').'</a>)', 'xml');
|
||||
$this->addElement('checkbox', 'overwrite', null, get_lang('OverwriteScores'));
|
||||
$this->addElement('checkbox', 'ignoreerrors', null, get_lang('IgnoreErrors'));
|
||||
$this->addButtonImport(get_lang('Ok'));
|
||||
$this->setDefaults([
|
||||
'formSent' => '1',
|
||||
'file_type' => 'csv',
|
||||
]);
|
||||
}
|
||||
}
|
||||
734
main/gradebook/lib/fe/displaygradebook.php
Normal file
734
main/gradebook/lib/fe/displaygradebook.php
Normal file
@@ -0,0 +1,734 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class DisplayGradebook.
|
||||
*/
|
||||
class DisplayGradebook
|
||||
{
|
||||
/**
|
||||
* Displays the header for the result page containing the navigation tree and links.
|
||||
*
|
||||
* @param Evaluation $evalobj
|
||||
* @param int $selectcat
|
||||
* @param string $page
|
||||
*/
|
||||
public static function display_header_result($evalobj, $selectcat, $page)
|
||||
{
|
||||
$header = null;
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
$header = '<div class="actions">';
|
||||
if ('statistics' !== $page) {
|
||||
$header .= '<a href="'.Category::getUrl().'selectcat='.$selectcat.'">'
|
||||
.Display::return_icon('back.png', get_lang('FolderView'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
if (($evalobj->get_course_code() != null) && !$evalobj->has_results()) {
|
||||
$header .= '<a href="gradebook_add_result.php?'.api_get_cidreq().'&selectcat='.$selectcat.'&selecteval='.$evalobj->get_id().'">'
|
||||
.Display::return_icon('evaluation_rate.png', get_lang('AddResult'), '', ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
}
|
||||
|
||||
if (api_is_platform_admin() || $evalobj->is_locked() == false) {
|
||||
$header .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&selecteval='.$evalobj->get_id().'&import=">'
|
||||
.Display::return_icon('import_evaluation.png', get_lang('ImportResult'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
}
|
||||
|
||||
if ($evalobj->has_results()) {
|
||||
$header .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&selecteval='.$evalobj->get_id().'&export=">'
|
||||
.Display::return_icon('export_evaluation.png', get_lang('ExportResult'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
|
||||
if (api_is_platform_admin() || !$evalobj->is_locked()) {
|
||||
$header .= '<a href="gradebook_edit_result.php?'.api_get_cidreq().'&selecteval='.$evalobj->get_id().'">'
|
||||
.Display::return_icon('edit.png', get_lang('EditResult'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
$header .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&selecteval='.$evalobj->get_id().'&deleteall=" onclick="return confirmationall();">'
|
||||
.Display::return_icon('delete.png', get_lang('DeleteResult'), [], ICON_SIZE_MEDIUM).'</a>';
|
||||
}
|
||||
}
|
||||
$header .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&print=&selecteval='.$evalobj->get_id().'" target="_blank">'
|
||||
.Display::return_icon('printer.png', get_lang('Print'), [], ICON_SIZE_MEDIUM).'</a>';
|
||||
} else {
|
||||
$header .= '<a href="gradebook_view_result.php?'.api_get_cidreq().'&selecteval='.Security::remove_XSS($_GET['selecteval']).'"> '
|
||||
.Display::return_icon('back.png', get_lang('FolderView'), [], ICON_SIZE_MEDIUM).'</a>';
|
||||
}
|
||||
$header .= '</div>';
|
||||
}
|
||||
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$student_score = '';
|
||||
$average = '';
|
||||
if ($evalobj->has_results()) {
|
||||
// TODO this check needed ?
|
||||
$score = $evalobj->calc_score();
|
||||
if (null != $score) {
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
if (empty($model)) {
|
||||
$average = get_lang('Average').' :<b> '.$scoredisplay->display_score($score, SCORE_AVERAGE).'</b>';
|
||||
$student_score = $evalobj->calc_score(api_get_user_id());
|
||||
$student_score = Display::tag(
|
||||
'h3',
|
||||
get_lang('Score').': '.$scoredisplay->display_score($student_score, SCORE_DIV_PERCENT)
|
||||
);
|
||||
|
||||
$allowMultipleAttempts = api_get_configuration_value('gradebook_multiple_evaluation_attempts');
|
||||
if ($allowMultipleAttempts) {
|
||||
$results = Result::load(null, api_get_user_id(), $evalobj->get_id());
|
||||
if (!empty($results)) {
|
||||
/** @var Result $resultData */
|
||||
foreach ($results as $resultData) {
|
||||
$student_score .= ResultTable::getResultAttemptTable($resultData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$description = '';
|
||||
if ('' == !$evalobj->get_description()) {
|
||||
$description = get_lang('Description').' :<b> '.Security::remove_XSS($evalobj->get_description()).'</b><br>';
|
||||
}
|
||||
|
||||
if ($evalobj->get_course_code() == null) {
|
||||
$course = get_lang('CourseIndependent');
|
||||
} else {
|
||||
$course = CourseManager::getCourseNameFromCode($evalobj->get_course_code());
|
||||
}
|
||||
|
||||
$evalinfo = '<table width="100%" border="0"><tr><td>';
|
||||
$evalinfo .= '<h2>'.Security::remove_XSS($evalobj->get_name()).'</h2><hr>';
|
||||
$evalinfo .= $description;
|
||||
$evalinfo .= get_lang('Course').' :<b> '.$course.'</b><br />';
|
||||
if (empty($model)) {
|
||||
$evalinfo .= get_lang('QualificationNumeric').' :<b> '.$evalobj->get_max().'</b><br>'.$average;
|
||||
}
|
||||
|
||||
if (!api_is_allowed_to_edit()) {
|
||||
$evalinfo .= $student_score;
|
||||
}
|
||||
|
||||
if (!$evalobj->has_results()) {
|
||||
$evalinfo .= '<br /><i>'.get_lang('NoResultsInEvaluation').'</i>';
|
||||
}
|
||||
|
||||
if ($page != 'statistics') {
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
$evalinfo .= '<br /><a href="gradebook_statistics.php?'.api_get_cidreq().'&selecteval='.Security::remove_XSS($_GET['selecteval']).'"> '
|
||||
.Display::return_icon(
|
||||
'statistics.png',
|
||||
get_lang('ViewStatistics'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
).'</a>';
|
||||
}
|
||||
}
|
||||
$evalinfo .= '</td><td>'
|
||||
.Display::return_icon(
|
||||
'tutorial.gif',
|
||||
'',
|
||||
['style' => 'float:right; position:relative;']
|
||||
)
|
||||
.'</td></table>';
|
||||
echo $evalinfo;
|
||||
echo $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the header for the flatview page containing filters.
|
||||
*
|
||||
* @param $catobj
|
||||
* @param $showeval
|
||||
* @param $showlink
|
||||
*/
|
||||
public static function display_header_reduce_flatview($catobj, $showeval, $showlink, $simple_search_form)
|
||||
{
|
||||
$header = '<div class="actions">';
|
||||
if ($catobj->get_parent_id() == 0) {
|
||||
$select_cat = $catobj->get_id();
|
||||
$url = Category::getUrl();
|
||||
} else {
|
||||
$select_cat = $catobj->get_parent_id();
|
||||
$url = 'gradebook_flatview.php';
|
||||
}
|
||||
$header .= '<a href="'.$url.'?'.api_get_cidreq().'&selectcat='.$select_cat.'">'
|
||||
.Display::return_icon('back.png', get_lang('FolderView'), [], ICON_SIZE_MEDIUM).'</a>';
|
||||
|
||||
$pageNum = isset($_GET['flatviewlist_page_nr']) ? (int) $_GET['flatviewlist_page_nr'] : null;
|
||||
$perPage = isset($_GET['flatviewlist_per_page']) ? (int) $_GET['flatviewlist_per_page'] : null;
|
||||
$offset = $_GET['offset'] ?? '0';
|
||||
|
||||
$exportCsvUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
|
||||
'export_format' => 'csv',
|
||||
'export_report' => 'export_report',
|
||||
'selectcat' => $catobj->get_id(),
|
||||
]);
|
||||
|
||||
$scoreRanking = ScoreDisplay::instance()->get_custom_score_display_settings();
|
||||
$attributes = [];
|
||||
if (!empty($scoreRanking)) {
|
||||
$attributes = ['class' => 'export_opener'];
|
||||
}
|
||||
|
||||
$header .= Display::url(
|
||||
Display::return_icon(
|
||||
'export_csv.png',
|
||||
get_lang('ExportAsCSV'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
),
|
||||
$exportCsvUrl,
|
||||
$attributes
|
||||
);
|
||||
|
||||
$exportXlsUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
|
||||
'export_format' => 'xls',
|
||||
'export_report' => 'export_report',
|
||||
'selectcat' => $catobj->get_id(),
|
||||
]);
|
||||
|
||||
$header .= Display::url(
|
||||
Display::return_icon(
|
||||
'export_excel.png',
|
||||
get_lang('ExportAsXLS'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
),
|
||||
$exportXlsUrl,
|
||||
$attributes
|
||||
);
|
||||
|
||||
$exportDocUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
|
||||
'export_format' => 'doc',
|
||||
'export_report' => 'export_report',
|
||||
'selectcat' => $catobj->get_id(),
|
||||
]);
|
||||
|
||||
$header .= Display::url(
|
||||
Display::return_icon(
|
||||
'export_doc.png',
|
||||
get_lang('ExportAsDOC'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
),
|
||||
$exportDocUrl,
|
||||
$attributes
|
||||
);
|
||||
|
||||
$exportPrintUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
|
||||
'print' => '',
|
||||
'selectcat' => $catobj->get_id(),
|
||||
]);
|
||||
|
||||
$header .= Display::url(
|
||||
Display::return_icon(
|
||||
'printer.png',
|
||||
get_lang('Print'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
),
|
||||
$exportPrintUrl,
|
||||
['target' => '_blank']
|
||||
);
|
||||
|
||||
$exportPdfUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
|
||||
'exportpdf' => '',
|
||||
'selectcat' => $catobj->get_id(),
|
||||
'offset' => $offset,
|
||||
'flatviewlist_page_nr' => $pageNum,
|
||||
'flatviewlist_per_page' => $perPage,
|
||||
]);
|
||||
|
||||
$header .= Display::url(
|
||||
Display::return_icon(
|
||||
'pdf.png',
|
||||
get_lang('ExportToPDF'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
),
|
||||
$exportPdfUrl
|
||||
);
|
||||
|
||||
$header .= '</div>';
|
||||
|
||||
$dialog = '';
|
||||
if (!empty($scoreRanking)) {
|
||||
$dialog = '<div id="dialog-confirm" style="display:none" title="'.get_lang('ConfirmYourChoice').'">';
|
||||
$form = new FormValidator(
|
||||
'report',
|
||||
'post',
|
||||
null,
|
||||
null,
|
||||
['class' => 'form-vertical']
|
||||
);
|
||||
$form->addCheckBox(
|
||||
'only_score',
|
||||
null,
|
||||
get_lang('OnlyNumbers')
|
||||
);
|
||||
$dialog .= $form->returnForm();
|
||||
$dialog .= '</div>';
|
||||
}
|
||||
|
||||
echo $header.$dialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the header for the gradebook containing the navigation tree and links.
|
||||
*
|
||||
* @param Category $catobj
|
||||
* @param int $showtree '1' will show the browse tree and naviation buttons
|
||||
* @param $selectcat
|
||||
* @param bool $is_course_admin
|
||||
* @param bool $is_platform_admin
|
||||
* @param bool $simple_search_form
|
||||
* @param bool $show_add_qualification Whether to show or not the link to add a new qualification
|
||||
* (we hide it in case of the course-embedded tool where we have only one
|
||||
* per course or session)
|
||||
* @param bool $show_add_link Whether to show or not the link to add a new item inside
|
||||
* the qualification (we hide it in case of the course-embedded tool
|
||||
* where we have only one qualification per course or session)
|
||||
* @param array $certificateLinkInfo
|
||||
*/
|
||||
public static function header(
|
||||
$catobj,
|
||||
$showtree,
|
||||
$selectcat,
|
||||
$is_course_admin,
|
||||
$is_platform_admin,
|
||||
$simple_search_form,
|
||||
$show_add_qualification = true,
|
||||
$show_add_link = true,
|
||||
$certificateLinkInfo = []
|
||||
) {
|
||||
$userId = api_get_user_id();
|
||||
$courseId = api_get_course_int_id();
|
||||
$sessionId = api_get_session_id();
|
||||
if (!$is_course_admin) {
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
if (!empty($model)) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Student.
|
||||
$status = CourseManager::getUserInCourseStatus($userId, $courseId);
|
||||
$sessionStatus = 0;
|
||||
|
||||
if (!empty($sessionId)) {
|
||||
$sessionStatus = SessionManager::get_user_status_in_course_session(
|
||||
$userId,
|
||||
$courseId,
|
||||
$sessionId
|
||||
);
|
||||
}
|
||||
|
||||
$objcat = new Category();
|
||||
$course_id = CourseManager::get_course_by_category($selectcat);
|
||||
$message_resource = $objcat->show_message_resource_delete($course_id);
|
||||
$grade_model_id = $catobj->get_grade_model_id();
|
||||
$header = null;
|
||||
if (isset($catobj) && !empty($catobj)) {
|
||||
$categories = Category::load(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$catobj->get_id(),
|
||||
null,
|
||||
$sessionId
|
||||
);
|
||||
}
|
||||
|
||||
if (!$is_course_admin && ($status != 1 || $sessionStatus == 0) && $selectcat != 0) {
|
||||
$catcourse = Category::load($catobj->get_id());
|
||||
/** @var Category $category */
|
||||
$category = $catcourse[0];
|
||||
$main_weight = $category->get_weight();
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$allevals = $category->get_evaluations($userId, true);
|
||||
$alllinks = $category->get_links($userId, true);
|
||||
$allEvalsLinks = array_merge($allevals, $alllinks);
|
||||
$item_value_total = 0;
|
||||
$scoreinfo = null;
|
||||
|
||||
for ($count = 0; $count < count($allEvalsLinks); $count++) {
|
||||
$item = $allEvalsLinks[$count];
|
||||
$score = $item->calc_score($userId);
|
||||
if (!empty($score)) {
|
||||
$divide = $score[1] == 0 ? 1 : $score[1];
|
||||
$item_value = $score[0] / $divide * $item->get_weight();
|
||||
$item_value_total += $item_value;
|
||||
}
|
||||
}
|
||||
|
||||
$item_total = $main_weight;
|
||||
$total_score = [$item_value_total, $item_total];
|
||||
$scorecourse_display = $scoredisplay->display_score($total_score, SCORE_DIV_PERCENT);
|
||||
|
||||
if (!$catobj->get_id() == '0' && !isset($_GET['studentoverview']) && !isset($_GET['search'])) {
|
||||
$additionalButtons = null;
|
||||
if (!empty($certificateLinkInfo)) {
|
||||
$additionalButtons .= '<div class="btn-group pull-right">';
|
||||
$additionalButtons .= $certificateLinkInfo['certificate_link'] ?? '';
|
||||
$additionalButtons .= $certificateLinkInfo['badge_link'] ?? '';
|
||||
$additionalButtons .= '</div>';
|
||||
}
|
||||
$scoreinfo .= '<strong>'.sprintf(get_lang('TotalX'), $scorecourse_display.$additionalButtons).'</strong>';
|
||||
}
|
||||
echo Display::return_message($scoreinfo, 'normal', false);
|
||||
}
|
||||
|
||||
// show navigation tree and buttons?
|
||||
if ($showtree == '1' || isset($_GET['studentoverview'])) {
|
||||
$header = '<div class="actions"><table>';
|
||||
$header .= '<tr>';
|
||||
if (!$selectcat == '0') {
|
||||
$header .= '<td><a href="'.api_get_self().'?selectcat='.$catobj->get_parent_id().'">'
|
||||
.Display::return_icon(
|
||||
'back.png',
|
||||
get_lang('BackTo').' '.get_lang('RootCat'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
)
|
||||
.'</a></td>';
|
||||
}
|
||||
$header .= '<td>'.get_lang('CurrentCategory').'</td>'
|
||||
.'<td><form name="selector"><select name="selectcat" onchange="document.selector.submit()">';
|
||||
$cats = Category::load();
|
||||
|
||||
$tree = $cats[0]->get_tree();
|
||||
unset($cats);
|
||||
foreach ($tree as $cat) {
|
||||
$line = str_repeat('—', $cat[2]);
|
||||
if (isset($_GET['selectcat']) && $_GET['selectcat'] == $cat[0]) {
|
||||
$header .= '<option selected value='.$cat[0].'>'.$line.' '.$cat[1].'</option>';
|
||||
} else {
|
||||
$header .= '<option value='.$cat[0].'>'.$line.' '.$cat[1].'</option>';
|
||||
}
|
||||
}
|
||||
$header .= '</select></form></td>';
|
||||
if (!empty($simple_search_form) && $message_resource === false) {
|
||||
$header .= '<td style="vertical-align: top;">'.$simple_search_form->toHtml().'</td>';
|
||||
} else {
|
||||
$header .= '<td></td>';
|
||||
}
|
||||
if (!($is_course_admin &&
|
||||
$message_resource === false &&
|
||||
isset($_GET['selectcat']) && $_GET['selectcat'] != 0) &&
|
||||
isset($_GET['studentoverview'])
|
||||
) {
|
||||
$header .= '<td style="vertical-align: top;">
|
||||
<a href="'.api_get_self().'?'.api_get_cidreq().'&studentoverview=&exportpdf=&selectcat='.$catobj->get_id().'" target="_blank">
|
||||
'.Display::return_icon('pdf.png', get_lang('ExportPDF'), [], ICON_SIZE_MEDIUM).'
|
||||
'.get_lang('ExportPDF').'</a>';
|
||||
}
|
||||
$header .= '</td></tr>';
|
||||
$header .= '</table></div>';
|
||||
}
|
||||
|
||||
// for course admin & platform admin add item buttons are added to the header
|
||||
$actionsLeft = '';
|
||||
$actionsRight = '';
|
||||
$my_api_cidreq = api_get_cidreq();
|
||||
$isCoach = api_is_coach(api_get_session_id(), api_get_course_int_id());
|
||||
$accessToRead = api_is_allowed_to_edit(null, true) || $isCoach;
|
||||
$accessToEdit = api_is_allowed_to_edit(null, true);
|
||||
$courseCode = api_get_course_id();
|
||||
|
||||
if ($accessToRead) {
|
||||
$my_category = $catobj->showAllCategoryInfo($catobj->get_id());
|
||||
if ($selectcat != '0' && $accessToEdit) {
|
||||
if ($my_api_cidreq == '') {
|
||||
$my_api_cidreq = 'cidReq='.$my_category['course_code'];
|
||||
}
|
||||
if ($show_add_link && !$message_resource) {
|
||||
$actionsLeft .= '<a href="gradebook_add_eval.php?'.$my_api_cidreq.'&selectcat='.$catobj->get_id().'" >'
|
||||
.Display::return_icon('new_evaluation.png', get_lang('NewEvaluation'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
$cats = Category::load($selectcat);
|
||||
|
||||
if ($cats[0]->get_course_code() != null && !$message_resource) {
|
||||
$actionsLeft .= '<a href="gradebook_add_link.php?'.$my_api_cidreq.'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon('new_online_evaluation.png', get_lang('MakeLink'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
} else {
|
||||
$actionsLeft .= '<a href="gradebook_add_link_select_course.php?'.$my_api_cidreq.'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon('new_online_evaluation.png', get_lang('MakeLink'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((empty($grade_model_id) || $grade_model_id == -1) && $accessToEdit) {
|
||||
$actionsLeft .= '<a href="gradebook_add_cat.php?'.api_get_cidreq().'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon(
|
||||
'new_folder.png',
|
||||
get_lang('AddGradebook'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
).'</a></td>';
|
||||
}
|
||||
|
||||
if ($selectcat != '0') {
|
||||
if (!$message_resource) {
|
||||
$actionsLeft .= '<a href="gradebook_flatview.php?'.$my_api_cidreq.'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon('statistics.png', get_lang('FlatView'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
|
||||
if ($my_category['generate_certificates'] == 1) {
|
||||
$actionsLeft .= Display::url(
|
||||
Display::return_icon(
|
||||
'certificate_list.png',
|
||||
get_lang('GradebookSeeListOfStudentsCertificates'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
),
|
||||
"gradebook_display_certificate.php?$my_api_cidreq&cat_id=".$selectcat
|
||||
);
|
||||
}
|
||||
|
||||
$actionsLeft .= Display::url(
|
||||
Display::return_icon(
|
||||
'user.png',
|
||||
get_lang('GradebookListOfStudentsReports'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
),
|
||||
"gradebook_display_summary.php?$my_api_cidreq&selectcat=".$selectcat
|
||||
);
|
||||
|
||||
$allow = api_get_configuration_value('gradebook_custom_student_report');
|
||||
if ($allow) {
|
||||
$actionsLeft .= Display::url(
|
||||
get_lang('GenerateCustomReport'),
|
||||
api_get_path(WEB_AJAX_PATH)."gradebook.ajax.php?$my_api_cidreq&a=generate_custom_report",
|
||||
['class' => 'btn btn-default ajax']
|
||||
);
|
||||
}
|
||||
|
||||
// Right icons
|
||||
if ($accessToEdit) {
|
||||
$actionsRight = '<a href="gradebook_edit_cat.php?editcat='.$catobj->get_id(
|
||||
).'&cidReq='.$catobj->get_course_code().'&id_session='.$catobj->get_session_id().'">'
|
||||
.Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
|
||||
if (api_get_plugin_setting('customcertificate', 'enable_plugin_customcertificate') === 'true' &&
|
||||
api_get_course_setting('customcertificate_course_enable') == 1
|
||||
) {
|
||||
$actionsRight .= '<a href="'.api_get_path(WEB_PLUGIN_PATH).'customcertificate/src/index.php?'
|
||||
.$my_api_cidreq.'&origin=gradebook&selectcat='.$catobj->get_id().'">'.
|
||||
Display::return_icon(
|
||||
'certificate.png',
|
||||
get_lang('AttachCertificate'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
).'</a>';
|
||||
} else {
|
||||
$actionsRight .= '<a href="'.api_get_path(WEB_CODE_PATH)
|
||||
.'document/document.php?curdirpath=/certificates&'.$my_api_cidreq
|
||||
.'&origin=gradebook&selectcat='.$catobj->get_id().'">'.
|
||||
Display::return_icon(
|
||||
'certificate.png',
|
||||
get_lang('AttachCertificate'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
).'</a>';
|
||||
}
|
||||
|
||||
if (empty($categories)) {
|
||||
$actionsRight .= '<a href="gradebook_edit_all.php?id_session='.api_get_session_id()
|
||||
.'&'.$my_api_cidreq.'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon(
|
||||
'percentage.png',
|
||||
get_lang('EditAllWeights'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
).'</a>';
|
||||
}
|
||||
$score_display_custom = api_get_setting('gradebook_score_display_custom');
|
||||
if (api_get_setting('teachers_can_change_score_settings') == 'true' &&
|
||||
$score_display_custom['my_display_custom'] == 'true'
|
||||
) {
|
||||
$actionsRight .= '<a href="gradebook_scoring_system.php?'.$my_api_cidreq.'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon('ranking.png', get_lang('ScoreEdit'), [], ICON_SIZE_MEDIUM).'</a>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (isset($_GET['search'])) {
|
||||
echo $header = '<b>'.get_lang('SearchResults').' :</b>';
|
||||
}
|
||||
|
||||
$isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
|
||||
api_get_user_id(),
|
||||
api_get_course_info()
|
||||
);
|
||||
|
||||
if ($isDrhOfCourse) {
|
||||
$actionsLeft .= '<a href="gradebook_flatview.php?'.$my_api_cidreq.'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon(
|
||||
'statistics.png',
|
||||
get_lang('FlatView'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
)
|
||||
.'</a>';
|
||||
}
|
||||
|
||||
if ($isCoach || api_is_allowed_to_edit(null, true)) {
|
||||
echo $toolbar = Display::toolbarAction(
|
||||
'gradebook-actions',
|
||||
[$actionsLeft, $actionsRight]
|
||||
);
|
||||
}
|
||||
|
||||
if ($accessToEdit || api_is_allowed_to_edit(null, true)) {
|
||||
$weight = intval($catobj->get_weight()) > 0 ? $catobj->get_weight() : 0;
|
||||
$weight = '<strong>'.get_lang('TotalWeight').' : </strong>'.$weight;
|
||||
$min_certification = intval($catobj->getCertificateMinScore() > 0) ? $catobj->getCertificateMinScore() : 0;
|
||||
|
||||
if (!empty($min_certification)) {
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
if (!empty($model)) {
|
||||
$defaultCertification = api_number_format($min_certification, 2);
|
||||
$questionWeighting = $catobj->get_weight();
|
||||
foreach ($model['score_list'] as $item) {
|
||||
$i = api_number_format($item['score_to_qualify'] / 100 * $questionWeighting, 2);
|
||||
$model = ExerciseLib::getModelStyle($item, $i);
|
||||
if ($defaultCertification == $i) {
|
||||
$min_certification = $model;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$min_certification = get_lang('CertificateMinScore').' : '.$min_certification;
|
||||
$edit_icon = '<a href="gradebook_edit_cat.php?editcat='.$catobj->get_id().'&cidReq='.$catobj->get_course_code().'&id_session='.$catobj->get_session_id().'">'
|
||||
.Display::return_icon('edit.png', get_lang('Edit')).'</a>';
|
||||
|
||||
$msg = $weight.' - '.$min_certification.$edit_icon;
|
||||
//@todo show description
|
||||
$description = (($catobj->get_description() == '' || is_null($catobj->get_description())) ? '' : '<strong>'.get_lang('GradebookDescriptionLog').'</strong>'.': '.$catobj->get_description());
|
||||
echo Display::return_message($msg, 'normal', false);
|
||||
if (!empty($description)) {
|
||||
echo Display::div($description, []);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $catobj
|
||||
* @param $is_course_admin
|
||||
* @param $is_platform_admin
|
||||
* @param $simple_search_form
|
||||
* @param bool $show_add_qualification
|
||||
* @param bool $show_add_link
|
||||
*/
|
||||
public function display_reduce_header_gradebook(
|
||||
$catobj,
|
||||
$is_course_admin,
|
||||
$is_platform_admin,
|
||||
$simple_search_form,
|
||||
$show_add_qualification = true,
|
||||
$show_add_link = true
|
||||
) {
|
||||
//student
|
||||
if (!$is_course_admin) {
|
||||
$user = api_get_user_info(api_get_user_id());
|
||||
$catcourse = Category::load($catobj->get_id());
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$scorecourse = $catcourse[0]->calc_score(api_get_user_id());
|
||||
$scorecourse_display = isset($scorecourse) ? $scoredisplay->display_score($scorecourse, SCORE_AVERAGE) : get_lang('NoResultsAvailable');
|
||||
$cattotal = Category::load(0);
|
||||
$scoretotal = $cattotal[0]->calc_score(api_get_user_id());
|
||||
$scoretotal_display = isset($scoretotal) ? $scoredisplay->display_score($scoretotal, SCORE_PERCENT) : get_lang('NoResultsAvailable');
|
||||
$scoreinfo = get_lang('StatsStudent').' :<b> '.$user['complete_name'].'</b><br />';
|
||||
if ((!$catobj->get_id() == '0') && (!isset($_GET['studentoverview'])) && (!isset($_GET['search']))) {
|
||||
$scoreinfo .= '<br />'.get_lang('TotalForThisCategory').' : <b>'.$scorecourse_display.'</b>';
|
||||
}
|
||||
$scoreinfo .= '<br />'.get_lang('Total').' : <b>'.$scoretotal_display.'</b>';
|
||||
Display::addFlash(
|
||||
Display::return_message($scoreinfo, 'normal', false)
|
||||
);
|
||||
}
|
||||
// show navigation tree and buttons?
|
||||
$header = '<div class="actions">';
|
||||
|
||||
if ($is_course_admin) {
|
||||
$header .= '<a href="gradebook_flatview.php?'.api_get_cidreq().'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon('statistics.png', get_lang('FlatView'), [], ICON_SIZE_MEDIUM).'</a>';
|
||||
$header .= '<a href="gradebook_scoring_system.php?'.api_get_cidreq().'&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon('settings.png', get_lang('ScoreEdit'), [], ICON_SIZE_MEDIUM).'</a>';
|
||||
} elseif (!(isset($_GET['studentoverview']))) {
|
||||
$header .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&studentoverview=&selectcat='.$catobj->get_id().'">'
|
||||
.Display::return_icon('view_list.gif', get_lang('FlatView')).' '.get_lang('FlatView').'</a>';
|
||||
} else {
|
||||
$header .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&studentoverview=&exportpdf=&selectcat='.$catobj->get_id().'" target="_blank">'
|
||||
.Display::return_icon('pdf.png', get_lang('ExportPDF'), [], ICON_SIZE_MEDIUM).'</a>';
|
||||
}
|
||||
$header .= '</div>';
|
||||
echo $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int $categoryId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function display_header_user($userId, $categoryId)
|
||||
{
|
||||
$user = api_get_user_info($userId);
|
||||
if (empty($user)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$catcourse = Category::load($categoryId);
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
|
||||
// generating the total score for a course
|
||||
$allevals = $catcourse[0]->get_evaluations(
|
||||
$userId,
|
||||
true,
|
||||
api_get_course_id()
|
||||
);
|
||||
$alllinks = $catcourse[0]->get_links(
|
||||
$userId,
|
||||
true,
|
||||
api_get_course_id()
|
||||
);
|
||||
$evals_links = array_merge($allevals, $alllinks);
|
||||
$item_value = 0;
|
||||
$item_total = 0;
|
||||
for ($count = 0; $count < count($evals_links); $count++) {
|
||||
$item = $evals_links[$count];
|
||||
$score = $item->calc_score($userId);
|
||||
if ($score) {
|
||||
$my_score_denom = ($score[1] == 0) ? 1 : $score[1];
|
||||
$item_value += $score[0] / $my_score_denom * $item->get_weight();
|
||||
}
|
||||
$item_total += $item->get_weight();
|
||||
}
|
||||
$item_value = api_number_format($item_value, 2);
|
||||
$total_score = [$item_value, $item_total];
|
||||
$scorecourse_display = $scoredisplay->display_score($total_score, SCORE_DIV_PERCENT);
|
||||
|
||||
$info = '<div class="row"><div class="col-md-3">';
|
||||
$info .= '<div class="thumbnail"><img src="'.$user['avatar'].'" /></div>';
|
||||
$info .= '</div>';
|
||||
$info .= '<div class="col-md-6">';
|
||||
$info .= get_lang('Name').' : '.$user['complete_name_with_message_link'].'<br />';
|
||||
|
||||
if (api_get_setting('show_email_addresses') === 'true') {
|
||||
$info .= get_lang('Email').' : <a href="mailto:'.$user['email'].'">'.$user['email'].'</a><br />';
|
||||
}
|
||||
|
||||
$info .= get_lang('TotalUser').' : <b>'.$scorecourse_display.'</b>';
|
||||
$info .= '</div>';
|
||||
$info .= '</div>';
|
||||
echo $info;
|
||||
}
|
||||
}
|
||||
768
main/gradebook/lib/fe/evalform.class.php
Normal file
768
main/gradebook/lib/fe/evalform.class.php
Normal file
@@ -0,0 +1,768 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class EvalForm.
|
||||
*
|
||||
* Extends FormValidator with add&edit forms for evaluations
|
||||
*
|
||||
* @author Stijn Konings
|
||||
*/
|
||||
class EvalForm extends FormValidator
|
||||
{
|
||||
public const TYPE_ADD = 1;
|
||||
public const TYPE_EDIT = 2;
|
||||
public const TYPE_MOVE = 3;
|
||||
public const TYPE_RESULT_ADD = 4;
|
||||
public const TYPE_RESULT_EDIT = 5;
|
||||
public const TYPE_ALL_RESULTS_EDIT = 6;
|
||||
public const TYPE_ADD_USERS_TO_EVAL = 7;
|
||||
|
||||
protected $evaluation_object;
|
||||
private $result_object;
|
||||
private $extra;
|
||||
|
||||
/**
|
||||
* Builds a form containing form items based on a given parameter.
|
||||
*
|
||||
* @param int $form_type 1=add, 2=edit,3=move,4=result_add
|
||||
* @param Evaluation $evaluation_object the category object
|
||||
* @param obj $result_object the result object
|
||||
* @param string $form_name
|
||||
* @param string $method
|
||||
* @param string $action
|
||||
*/
|
||||
public function __construct(
|
||||
$form_type,
|
||||
$evaluation_object,
|
||||
$result_object,
|
||||
$form_name,
|
||||
$method = 'post',
|
||||
$action = null,
|
||||
$extra1 = null,
|
||||
$extra2 = null
|
||||
) {
|
||||
parent::__construct($form_name, $method, $action);
|
||||
|
||||
if (isset($evaluation_object)) {
|
||||
$this->evaluation_object = $evaluation_object;
|
||||
}
|
||||
if (isset($result_object)) {
|
||||
$this->result_object = $result_object;
|
||||
}
|
||||
if (isset($extra1)) {
|
||||
$this->extra = $extra1;
|
||||
}
|
||||
|
||||
switch ($form_type) {
|
||||
case self::TYPE_EDIT:
|
||||
$this->build_editing_form();
|
||||
break;
|
||||
case self::TYPE_ADD:
|
||||
$this->build_add_form();
|
||||
break;
|
||||
case self::TYPE_MOVE:
|
||||
$this->build_editing_form();
|
||||
break;
|
||||
case self::TYPE_RESULT_ADD:
|
||||
$this->build_result_add_form();
|
||||
break;
|
||||
case self::TYPE_RESULT_EDIT:
|
||||
$this->build_result_edit_form();
|
||||
break;
|
||||
case self::TYPE_ALL_RESULTS_EDIT:
|
||||
$this->build_all_results_edit_form();
|
||||
break;
|
||||
case self::TYPE_ADD_USERS_TO_EVAL:
|
||||
$this->build_add_user_to_eval();
|
||||
break;
|
||||
}
|
||||
$this->protect();
|
||||
$this->setDefaults();
|
||||
}
|
||||
|
||||
public function display()
|
||||
{
|
||||
parent::display();
|
||||
}
|
||||
|
||||
public function setDefaults($defaults = [], $filter = null)
|
||||
{
|
||||
parent::setDefaults($defaults, $filter);
|
||||
}
|
||||
|
||||
public function sort_by_user($item1, $item2)
|
||||
{
|
||||
$user1 = $item1['user'];
|
||||
$user2 = $item2['user'];
|
||||
if (api_sort_by_first_name()) {
|
||||
$result = api_strcmp($user1['firstname'], $user2['firstname']);
|
||||
if (0 == $result) {
|
||||
return api_strcmp($user1['lastname'], $user2['lastname']);
|
||||
}
|
||||
} else {
|
||||
$result = api_strcmp($user1['lastname'], $user2['lastname']);
|
||||
if (0 == $result) {
|
||||
return api_strcmp($user1['firstname'], $user2['firstname']);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This form will build a form to add users to an evaluation.
|
||||
*/
|
||||
protected function build_add_user_to_eval()
|
||||
{
|
||||
$this->addElement('header', get_lang('ChooseUser'));
|
||||
$select = $this->addElement(
|
||||
'select',
|
||||
'firstLetterUser',
|
||||
get_lang('FirstLetter'),
|
||||
null,
|
||||
[
|
||||
'onchange' => 'document.add_users_to_evaluation.submit()',
|
||||
]
|
||||
);
|
||||
$select->addOption('', '');
|
||||
for ($i = 65; $i <= 90; $i++) {
|
||||
$letter = chr($i);
|
||||
if (isset($this->extra) && $this->extra == $letter) {
|
||||
$select->addOption($letter, $letter, 'selected');
|
||||
} else {
|
||||
$select->addOption($letter, $letter);
|
||||
}
|
||||
}
|
||||
$select = $this->addElement(
|
||||
'select',
|
||||
'add_users',
|
||||
null,
|
||||
null,
|
||||
[
|
||||
'multiple' => 'multiple',
|
||||
'size' => '15',
|
||||
'style' => 'width:250px',
|
||||
]
|
||||
);
|
||||
foreach ($this->evaluation_object->get_not_subscribed_students() as $user) {
|
||||
if ((!isset($this->extra)) || empty($this->extra) || api_strtoupper(api_substr($user[1], 0, 1)) == $this->extra
|
||||
) {
|
||||
$select->addOption($user[1].' '.$user[2].' ('.$user[3].')', $user[0]);
|
||||
}
|
||||
}
|
||||
$this->addButtonCreate(get_lang('AddUserToEval'), 'submit_button');
|
||||
}
|
||||
|
||||
/**
|
||||
* This function builds a form to edit all results in an evaluation.
|
||||
*/
|
||||
protected function build_all_results_edit_form()
|
||||
{
|
||||
//extra field for check on maxvalue
|
||||
$this->addElement('header', get_lang('EditResult'));
|
||||
$renderer = &$this->defaultRenderer();
|
||||
// set new form template
|
||||
$form_template = '<form{attributes}>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-striped data_table" border="0" cellpadding="5" cellspacing="5">{content}</table>
|
||||
</div>
|
||||
</form>';
|
||||
$renderer->setFormTemplate($form_template);
|
||||
|
||||
$skillRelItemsEnabled = api_get_configuration_value('allow_skill_rel_items');
|
||||
$columnSkill = '';
|
||||
if ($skillRelItemsEnabled) {
|
||||
$columnSkill = '<th>'.get_lang('Skills').'</th>';
|
||||
}
|
||||
|
||||
if (api_is_western_name_order()) {
|
||||
$renderer->setHeaderTemplate(
|
||||
'<tr>
|
||||
<th>'.get_lang('OfficialCode').'</th>
|
||||
<th>'.get_lang('UserName').'</th>
|
||||
<th>'.get_lang('FirstName').'</th>
|
||||
<th>'.get_lang('LastName').'</th>
|
||||
<th>'.get_lang('Qualify').'</th>
|
||||
'.$columnSkill.'
|
||||
</tr>'
|
||||
);
|
||||
} else {
|
||||
$renderer->setHeaderTemplate(
|
||||
'<tr>
|
||||
<th>'.get_lang('OfficialCode').'</th>
|
||||
<th>'.get_lang('UserName').'</th>
|
||||
<th>'.get_lang('LastName').'</th>
|
||||
<th>'.get_lang('FirstName').'</th>
|
||||
<th>'.get_lang('Qualify').'</th>
|
||||
'.$columnSkill.'
|
||||
</tr>'
|
||||
);
|
||||
}
|
||||
$template_submit = '<tr>
|
||||
<td colspan="4" ></td>
|
||||
<td>
|
||||
{element}
|
||||
<!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
|
||||
</td>
|
||||
'.($skillRelItemsEnabled ? '<td></td>' : '').'
|
||||
</tr>';
|
||||
|
||||
$results_and_users = [];
|
||||
foreach ($this->result_object as $result) {
|
||||
$user = api_get_user_info($result->get_user_id());
|
||||
$results_and_users[] = ['result' => $result, 'user' => $user];
|
||||
}
|
||||
usort($results_and_users, ['EvalForm', 'sort_by_user']);
|
||||
$defaults = [];
|
||||
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
|
||||
foreach ($results_and_users as $result_and_user) {
|
||||
$user = $result_and_user['user'];
|
||||
/** @var \Result $result */
|
||||
$result = $result_and_user['result'];
|
||||
$renderer = &$this->defaultRenderer();
|
||||
|
||||
$columnSkillResult = '';
|
||||
if ($skillRelItemsEnabled) {
|
||||
$columnSkillResult = '<td>'.Skill::getAddSkillsToUserBlock(ITEM_TYPE_GRADEBOOK_EVALUATION, $result->get_evaluation_id(), $result->get_user_id(), $result->get_id()).'</td>';
|
||||
}
|
||||
|
||||
if (api_is_western_name_order()) {
|
||||
$user_info = '<td align="left" >'.$user['firstname'].'</td>';
|
||||
$user_info .= '<td align="left" >'.$user['lastname'].'</td>';
|
||||
} else {
|
||||
$user_info = '<td align="left" >'.$user['lastname'].'</td>';
|
||||
$user_info .= '<td align="left" >'.$user['firstname'].'</td>';
|
||||
}
|
||||
|
||||
$template = '<tr>
|
||||
<td align="left" >'.$user['official_code'].'</td>
|
||||
<td align="left" >'.$user['username'].'</td>
|
||||
'.$user_info.'
|
||||
<td align="left">{element} / '.$this->evaluation_object->get_max().'
|
||||
<!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
|
||||
</td>
|
||||
'.$columnSkillResult.'
|
||||
</tr>';
|
||||
|
||||
if (empty($model)) {
|
||||
$this->addFloat(
|
||||
'score['.$result->get_id().']',
|
||||
$this->build_stud_label($user['user_id'], $user['username'], $user['lastname'], $user['firstname']),
|
||||
false,
|
||||
[
|
||||
'maxlength' => 5,
|
||||
],
|
||||
false,
|
||||
0,
|
||||
$this->evaluation_object->get_max()
|
||||
);
|
||||
$defaults['score['.$result->get_id().']'] = $result->get_score();
|
||||
} else {
|
||||
$questionWeighting = $this->evaluation_object->get_max();
|
||||
$select = $this->addSelect(
|
||||
'score['.$result->get_id().']',
|
||||
get_lang('Score'),
|
||||
[],
|
||||
['disable_js' => true, 'id' => 'score_'.$result->get_id()]
|
||||
);
|
||||
|
||||
foreach ($model['score_list'] as $item) {
|
||||
$i = api_number_format($item['score_to_qualify'] / 100 * $questionWeighting, 2);
|
||||
$modelStyle = ExerciseLib::getModelStyle($item, $i);
|
||||
$attributes = ['class' => $item['css_class']];
|
||||
if ($result->get_score() == $i) {
|
||||
$attributes['selected'] = 'selected';
|
||||
}
|
||||
$select->addOption($modelStyle, $i, $attributes);
|
||||
}
|
||||
$select->updateSelectWithSelectedOption($this);
|
||||
|
||||
$template = '<tr>
|
||||
<td align="left" >'.$user['official_code'].'</td>
|
||||
<td align="left" >'.$user['username'].'</td>
|
||||
'.$user_info.'
|
||||
<td align="left">{element} <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
|
||||
</td>
|
||||
'.$columnSkillResult.'
|
||||
</tr>';
|
||||
}
|
||||
$renderer->setElementTemplate($template, 'score['.$result->get_id().']');
|
||||
}
|
||||
|
||||
if (empty($model)) {
|
||||
$this->setDefaults($defaults);
|
||||
}
|
||||
$this->addButtonSave(get_lang('EditResult'));
|
||||
$renderer->setElementTemplate($template_submit, 'submit');
|
||||
}
|
||||
|
||||
/**
|
||||
* This function builds a form to move an item to another category.
|
||||
*/
|
||||
protected function build_move_form()
|
||||
{
|
||||
$renderer = &$this->defaultRenderer();
|
||||
$renderer->setCustomElementTemplate('<span>{element}</span> ');
|
||||
$this->addElement('static', null, null, '"'.$this->evaluation_object->get_name().'" ');
|
||||
$this->addElement('static', null, null, get_lang('MoveTo').' : ');
|
||||
$select = $this->addElement('select', 'move_cat', null, null);
|
||||
$line = '';
|
||||
foreach ($this->evaluation_object->get_target_categories() as $cat) {
|
||||
for ($i = 0; $i < $cat[2]; $i++) {
|
||||
$line .= '—';
|
||||
}
|
||||
$select->addOption($line.' '.$cat[1], $cat[0]);
|
||||
$line = '';
|
||||
}
|
||||
$this->addButtonSave(get_lang('Ok'), 'submit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a result form containing inputs for all students with a given course_code.
|
||||
*/
|
||||
protected function build_result_add_form()
|
||||
{
|
||||
$renderer = &$this->defaultRenderer();
|
||||
$renderer->setFormTemplate(
|
||||
'<form{attributes}>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-striped data_table">
|
||||
{content}
|
||||
</table>
|
||||
</div>
|
||||
</form>'
|
||||
);
|
||||
|
||||
$users = GradebookUtils::get_users_in_course($this->evaluation_object->get_course_code());
|
||||
$nr_users = 0;
|
||||
//extra field for check on maxvalue
|
||||
$this->addElement('hidden', 'maxvalue', $this->evaluation_object->get_max());
|
||||
$this->addElement('hidden', 'minvalue', 0);
|
||||
$this->addElement('header', get_lang('AddResult'));
|
||||
|
||||
if (api_is_western_name_order()) {
|
||||
$renderer->setHeaderTemplate(
|
||||
'<tr>
|
||||
<th>'.get_lang('OfficialCode').'</th>
|
||||
<th>'.get_lang('UserName').'</th>
|
||||
<th>'.get_lang('FirstName').'</th>
|
||||
<th>'.get_lang('LastName').'</th>
|
||||
<th>'.get_lang('Qualify').'</th>
|
||||
</tr>'
|
||||
);
|
||||
} else {
|
||||
$renderer->setHeaderTemplate(
|
||||
'<tr>
|
||||
<th>'.get_lang('OfficialCode').'</th>
|
||||
<th>'.get_lang('UserName').'</th>
|
||||
<th>'.get_lang('LastName').'</th>
|
||||
<th>'.get_lang('FirstName').'</th>
|
||||
<th>'.get_lang('Qualify').'</th>
|
||||
</tr>'
|
||||
);
|
||||
}
|
||||
|
||||
$firstUser = true;
|
||||
foreach ($users as $user) {
|
||||
$element_name = 'score['.$user[0].']';
|
||||
$scoreColumnProperties = ['maxlength' => 5];
|
||||
if ($firstUser) {
|
||||
$scoreColumnProperties['autofocus'] = '';
|
||||
$firstUser = false;
|
||||
}
|
||||
|
||||
//user_id, user.username, lastname, firstname
|
||||
$this->addFloat(
|
||||
$element_name,
|
||||
$this->build_stud_label($user[0], $user[1], $user[2], $user[3]),
|
||||
false,
|
||||
$scoreColumnProperties,
|
||||
false,
|
||||
0,
|
||||
$this->evaluation_object->get_max()
|
||||
);
|
||||
|
||||
if (api_is_western_name_order()) {
|
||||
$user_info = '<td align="left" >'.$user[3].'</td>';
|
||||
$user_info .= '<td align="left" >'.$user[2].'</td>';
|
||||
} else {
|
||||
$user_info = '<td align="left" >'.$user[2].'</td>';
|
||||
$user_info .= '<td align="left" >'.$user[3].'</td>';
|
||||
}
|
||||
$nr_users++;
|
||||
|
||||
$template = '<tr>
|
||||
<td align="left" >'.$user[4].'</td>
|
||||
<td align="left" >'.$user[1].'</td>
|
||||
'.$user_info.'
|
||||
<td align="left">{element} / '.$this->evaluation_object->get_max().'
|
||||
<!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
|
||||
</td>
|
||||
</tr>';
|
||||
$renderer->setElementTemplate($template, $element_name);
|
||||
}
|
||||
$this->addElement('hidden', 'nr_users', $nr_users);
|
||||
$this->addElement('hidden', 'evaluation_id', $this->result_object->get_evaluation_id());
|
||||
$this->addButtonSave(get_lang('AddResult'), 'submit');
|
||||
|
||||
$template_submit = '<tr>
|
||||
<td colspan="4" ></td>
|
||||
<td >
|
||||
{element}
|
||||
<!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
|
||||
</td>
|
||||
</tr>';
|
||||
$renderer->setElementTemplate($template_submit, 'submit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a form to edit a result.
|
||||
*/
|
||||
protected function build_result_edit_form()
|
||||
{
|
||||
$userInfo = api_get_user_info($this->result_object->get_user_id());
|
||||
$this->addHeader(get_lang('User').': '.$userInfo['complete_name']);
|
||||
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
|
||||
if (empty($model)) {
|
||||
$this->addFloat(
|
||||
'score',
|
||||
[
|
||||
get_lang('Score'),
|
||||
null,
|
||||
'/ '.$this->evaluation_object->get_max(),
|
||||
],
|
||||
false,
|
||||
[
|
||||
'size' => '4',
|
||||
'maxlength' => '5',
|
||||
],
|
||||
false,
|
||||
0,
|
||||
$this->evaluation_object->get_max()
|
||||
);
|
||||
$this->setDefaults(
|
||||
[
|
||||
'score' => $this->result_object->get_score(),
|
||||
'maximum' => $this->evaluation_object->get_max(),
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$questionWeighting = $this->evaluation_object->get_max();
|
||||
$select = $this->addSelect('score', get_lang('Score'), [], ['disable_js' => true]);
|
||||
|
||||
foreach ($model['score_list'] as $item) {
|
||||
$i = api_number_format($item['score_to_qualify'] / 100 * $questionWeighting, 2);
|
||||
$model = ExerciseLib::getModelStyle($item, $i);
|
||||
$attributes = ['class' => $item['css_class']];
|
||||
if ($this->result_object->get_score() == $i) {
|
||||
$attributes['selected'] = 'selected';
|
||||
}
|
||||
$select->addOption($model, $i, $attributes);
|
||||
}
|
||||
$select->updateSelectWithSelectedOption($this);
|
||||
}
|
||||
|
||||
$allowMultipleAttempts = api_get_configuration_value('gradebook_multiple_evaluation_attempts');
|
||||
if ($allowMultipleAttempts) {
|
||||
$this->addTextarea('comment', get_lang('Comment'));
|
||||
}
|
||||
|
||||
$this->addButtonSave(get_lang('Edit'));
|
||||
$this->addElement('hidden', 'hid_user_id', $this->result_object->get_user_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a form to add an evaluation.
|
||||
*/
|
||||
protected function build_add_form()
|
||||
{
|
||||
$this->setDefaults([
|
||||
'hid_user_id' => $this->evaluation_object->get_user_id(),
|
||||
'hid_category_id' => $this->evaluation_object->get_category_id(),
|
||||
'hid_course_code' => $this->evaluation_object->get_course_code(),
|
||||
'created_at' => api_get_utc_datetime(),
|
||||
]);
|
||||
$this->build_basic_form();
|
||||
if ($this->evaluation_object->get_course_code() == null) {
|
||||
$this->addElement('checkbox', 'adduser', null, get_lang('AddUserToEval'));
|
||||
} else {
|
||||
$this->addElement('checkbox', 'addresult', null, get_lang('AddResult'));
|
||||
}
|
||||
|
||||
Skill::addSkillsToForm(
|
||||
$this,
|
||||
api_get_course_int_id(),
|
||||
api_get_session_id(),
|
||||
ITEM_TYPE_GRADEBOOK_EVALUATION
|
||||
);
|
||||
|
||||
$this->addButtonCreate(get_lang('AddAssessment'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a form to edit an evaluation.
|
||||
*/
|
||||
protected function build_editing_form()
|
||||
{
|
||||
$parent_cat = Category::load($this->evaluation_object->get_category_id());
|
||||
//@TODO $weight_mask is replaced?
|
||||
if ($parent_cat[0]->get_parent_id() == 0) {
|
||||
$weight_mask = $this->evaluation_object->get_weight();
|
||||
} else {
|
||||
$cat = Category::load($parent_cat[0]->get_parent_id());
|
||||
$global_weight = $cat[0]->get_weight();
|
||||
$weight_mask = $global_weight * $this->evaluation_object->get_weight() / $parent_cat[0]->get_weight();
|
||||
}
|
||||
$weight = $weight_mask = $this->evaluation_object->get_weight();
|
||||
|
||||
$evaluationId = $this->evaluation_object->get_id();
|
||||
$this->addHidden('hid_id', $evaluationId);
|
||||
|
||||
$this->setDefaults([
|
||||
'hid_id' => $evaluationId,
|
||||
'name' => $this->evaluation_object->get_name(),
|
||||
'description' => $this->evaluation_object->get_description(),
|
||||
'hid_user_id' => $this->evaluation_object->get_user_id(),
|
||||
'hid_course_code' => $this->evaluation_object->get_course_code(),
|
||||
'hid_category_id' => $this->evaluation_object->get_category_id(),
|
||||
'created_at' => api_get_utc_datetime($this->evaluation_object->get_date()),
|
||||
'weight' => $weight,
|
||||
'weight_mask' => $weight_mask,
|
||||
'max' => $this->evaluation_object->get_max(),
|
||||
'visible' => $this->evaluation_object->is_visible(),
|
||||
]);
|
||||
|
||||
$this->build_basic_form(1);
|
||||
|
||||
if (!empty($evaluationId)) {
|
||||
Skill::addSkillsToForm(
|
||||
$this,
|
||||
api_get_course_int_id(),
|
||||
api_get_session_id(),
|
||||
ITEM_TYPE_GRADEBOOK_EVALUATION,
|
||||
$evaluationId
|
||||
);
|
||||
}
|
||||
|
||||
$this->addButtonSave(get_lang('ModifyEvaluation'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a basic form that is used in add and edit.
|
||||
*
|
||||
* @param int $edit
|
||||
*/
|
||||
private function build_basic_form($edit = 0)
|
||||
{
|
||||
$form_title = get_lang('NewEvaluation');
|
||||
if (!empty($_GET['editeval'])) {
|
||||
$form_title = get_lang('EditEvaluation');
|
||||
}
|
||||
|
||||
$this->addHeader($form_title);
|
||||
$this->addElement('hidden', 'hid_user_id');
|
||||
$this->addElement('hidden', 'hid_course_code');
|
||||
|
||||
$this->addText(
|
||||
'name',
|
||||
get_lang('EvaluationName'),
|
||||
true,
|
||||
[
|
||||
'maxlength' => '50',
|
||||
'id' => 'evaluation_title',
|
||||
]
|
||||
);
|
||||
|
||||
$cat_id = $this->evaluation_object->get_category_id();
|
||||
|
||||
$session_id = api_get_session_id();
|
||||
$course_code = api_get_course_id();
|
||||
$all_categories = Category::load(
|
||||
null,
|
||||
null,
|
||||
$course_code,
|
||||
null,
|
||||
null,
|
||||
$session_id,
|
||||
false
|
||||
);
|
||||
|
||||
if (1 == count($all_categories)) {
|
||||
$this->addElement('hidden', 'hid_category_id', $cat_id);
|
||||
} else {
|
||||
$select_gradebook = $this->addElement(
|
||||
'select',
|
||||
'hid_category_id',
|
||||
get_lang('SelectGradebook'),
|
||||
[],
|
||||
['id' => 'hid_category_id']
|
||||
);
|
||||
$this->addRule('hid_category_id', get_lang('ThisFieldIsRequired'), 'nonzero');
|
||||
$default_weight = 0;
|
||||
if (!empty($all_categories)) {
|
||||
foreach ($all_categories as $my_cat) {
|
||||
if ($my_cat->get_course_code() == api_get_course_id()) {
|
||||
$grade_model_id = $my_cat->get_grade_model_id();
|
||||
if (empty($grade_model_id)) {
|
||||
if ($my_cat->get_parent_id() == 0) {
|
||||
$default_weight = $my_cat->get_weight();
|
||||
$select_gradebook->addOption(get_lang('Default'), $my_cat->get_id());
|
||||
$cats_added[] = $my_cat->get_id();
|
||||
} else {
|
||||
$select_gradebook->addOption(Security::remove_XSS($my_cat->get_name()), $my_cat->get_id());
|
||||
$cats_added[] = $my_cat->get_id();
|
||||
}
|
||||
} else {
|
||||
$select_gradebook->addOption(get_lang('Select'), 0);
|
||||
}
|
||||
if ($this->evaluation_object->get_category_id() == $my_cat->get_id()) {
|
||||
$default_weight = $my_cat->get_weight();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->addFloat(
|
||||
'weight_mask',
|
||||
[
|
||||
get_lang('Weight'),
|
||||
null,
|
||||
' [0 .. <span id="max_weight">'.$all_categories[0]->get_weight().'</span>] ',
|
||||
],
|
||||
true,
|
||||
[
|
||||
'size' => '4',
|
||||
'maxlength' => '5',
|
||||
]
|
||||
);
|
||||
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
|
||||
if ($edit) {
|
||||
if (empty($model)) {
|
||||
if (!$this->evaluation_object->has_results()) {
|
||||
$this->addText(
|
||||
'max',
|
||||
get_lang('QualificationNumeric'),
|
||||
true,
|
||||
[
|
||||
'maxlength' => '5',
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$this->addText(
|
||||
'max',
|
||||
[get_lang('QualificationNumeric'), get_lang('CannotChangeTheMaxNote')],
|
||||
false,
|
||||
[
|
||||
'maxlength' => '5',
|
||||
'disabled' => 'disabled',
|
||||
]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$class = '';
|
||||
foreach ($model['score_list'] as $item) {
|
||||
$class = $item['css_class'];
|
||||
}
|
||||
$this->addText(
|
||||
'max',
|
||||
get_lang('QualificationNumeric'),
|
||||
false,
|
||||
[
|
||||
'maxlength' => '5',
|
||||
'class' => $class,
|
||||
'disabled' => 'disabled',
|
||||
]
|
||||
);
|
||||
|
||||
$defaults['max'] = $item['max'];
|
||||
$this->setDefaults($defaults);
|
||||
}
|
||||
} else {
|
||||
if (empty($model)) {
|
||||
$this->addText(
|
||||
'max',
|
||||
get_lang('QualificationNumeric'),
|
||||
true,
|
||||
[
|
||||
'maxlength' => '5',
|
||||
]
|
||||
);
|
||||
$default_max = api_get_setting('gradebook_default_weight');
|
||||
$defaults['max'] = isset($default_max) ? $default_max : 100;
|
||||
$this->setDefaults($defaults);
|
||||
} else {
|
||||
$class = '';
|
||||
foreach ($model['score_list'] as $item) {
|
||||
$class = $item['css_class'];
|
||||
}
|
||||
$this->addText(
|
||||
'max',
|
||||
get_lang('QualificationNumeric'),
|
||||
false,
|
||||
[
|
||||
'maxlength' => '5',
|
||||
'class' => $class,
|
||||
'disabled' => 'disabled',
|
||||
]
|
||||
);
|
||||
|
||||
$defaults['max'] = $item['max'];
|
||||
$this->setDefaults($defaults);
|
||||
}
|
||||
}
|
||||
|
||||
$this->addElement('textarea', 'description', get_lang('Description'));
|
||||
$this->addRule('hid_category_id', get_lang('ThisFieldIsRequired'), 'required');
|
||||
$this->addElement('checkbox', 'visible', null, get_lang('Visible'));
|
||||
$this->addRule('max', get_lang('OnlyNumbers'), 'numeric');
|
||||
$this->addRule(
|
||||
'max',
|
||||
get_lang('NegativeValue'),
|
||||
'compare',
|
||||
'>=',
|
||||
'server',
|
||||
false,
|
||||
false,
|
||||
0
|
||||
);
|
||||
$setting = api_get_setting('tool_visible_by_default_at_creation');
|
||||
$visibility_default = 1;
|
||||
if (isset($setting['gradebook']) && $setting['gradebook'] == 'false') {
|
||||
$visibility_default = 0;
|
||||
}
|
||||
$this->setDefaults(['visible' => $visibility_default]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param $username
|
||||
* @param $lastname
|
||||
* @param $firstname
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_stud_label($id, $username, $lastname, $firstname)
|
||||
{
|
||||
$opendocurl_start = '';
|
||||
$opendocurl_end = '';
|
||||
// evaluation's origin is a link
|
||||
if ($this->evaluation_object->get_category_id() < 0) {
|
||||
$link = LinkFactory::get_evaluation_link($this->evaluation_object->get_id());
|
||||
$doc_url = $link->get_view_url($id);
|
||||
if (null != $doc_url) {
|
||||
$opendocurl_start .= '<a href="'.$doc_url.'" target="_blank">';
|
||||
$opendocurl_end = '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
return $opendocurl_start.api_get_person_name($firstname, $lastname).' ('.$username.')'.$opendocurl_end;
|
||||
}
|
||||
}
|
||||
168
main/gradebook/lib/fe/exportgradebook.php
Normal file
168
main/gradebook/lib/fe/exportgradebook.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
/**
|
||||
* Script.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints an HTML page with a table containing the gradebook data.
|
||||
*
|
||||
* @param array Array containing the data to be printed in the table
|
||||
* @param array Table headers
|
||||
* @param string View to print as a title for the table
|
||||
* @param string Course name to print as title for the table
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function print_table($data_array, $header_names, $view, $coursename)
|
||||
{
|
||||
$styleWebPath = api_get_path(WEB_PUBLIC_PATH).'assets/bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
$printdata = '<!DOCTYPE html>
|
||||
<html lang="'.api_get_language_isocode().'">
|
||||
<head>
|
||||
<title>'.get_lang('Print').'</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset='.api_get_system_encoding().'" />
|
||||
'.api_get_css(api_get_cdn_path($styleWebPath), 'screen,print').'
|
||||
</head>
|
||||
<body dir="'.api_get_text_direction().'"><div id="main">';
|
||||
|
||||
$printdata .= '<h2>'.$view.' : '.$coursename.'</h2>';
|
||||
|
||||
$table = new HTML_Table(['class' => 'table table-bordered']);
|
||||
$table->setHeaders($header_names);
|
||||
$table->setData($data_array);
|
||||
|
||||
$printdata .= $table->toHtml();
|
||||
$printdata .= '</div></body></html>';
|
||||
|
||||
return $printdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function get a content html for export inside a pdf file.
|
||||
*
|
||||
* @param array table headers
|
||||
* @param array table body
|
||||
* @param array pdf headers
|
||||
* @param array pdf footers
|
||||
*/
|
||||
function export_pdf_with_html($headers_table, $data_table, $headers_pdf, $footers_pdf, $title_pdf)
|
||||
{
|
||||
$headers_in_pdf = '<img src="'.api_get_path(WEB_CSS_PATH).api_get_setting('stylesheets').'/images/header-logo.png">';
|
||||
|
||||
if (is_array($headers_pdf)) {
|
||||
// preparing headers pdf
|
||||
$header = '<br/><br/>
|
||||
<table width="100%" cellspacing="1" cellpadding="5" border="0" class="strong">
|
||||
<tr>
|
||||
<td width="100%" style="text-align: center;" class="title" colspan="4">
|
||||
<h1>'.$title_pdf.'</h1></td></tr>';
|
||||
foreach ($headers_pdf as $header_pdf) {
|
||||
if (!empty($header_pdf[0]) && !empty($header_pdf[1])) {
|
||||
$header .= '<tr><td><strong>'.$header_pdf[0].'</strong> </td><td>'.$header_pdf[1].'</td></tr>';
|
||||
}
|
||||
}
|
||||
$header .= '</table><br />';
|
||||
}
|
||||
|
||||
// preparing footer pdf
|
||||
$footer = '<table width="100%" cellspacing="2" cellpadding="10" border="0">';
|
||||
if (is_array($footers_pdf)) {
|
||||
$footer .= '<tr>';
|
||||
foreach ($footers_pdf as $foot_pdf) {
|
||||
$footer .= '<td width="33%" style="text-align: center;">'.$foot_pdf.'</td>';
|
||||
}
|
||||
$footer .= '</tr>';
|
||||
}
|
||||
$footer .= '</table>';
|
||||
$footer .= '<div align="right" style="font-weight: bold;">{PAGENO}/{nb}</div>';
|
||||
|
||||
// preparing content pdf
|
||||
$css = api_get_print_css();
|
||||
$items_per_page = 30;
|
||||
$count_pages = ceil(count($data_table) / $items_per_page);
|
||||
for ($x = 0; $x < $count_pages; $x++) {
|
||||
$content_table .= '<table width="100%" border="1" style="border-collapse:collapse">';
|
||||
// header table
|
||||
$content_table .= '<tr>';
|
||||
$i = 0;
|
||||
if (is_array($headers_table)) {
|
||||
foreach ($headers_table as $head_table) {
|
||||
if (!empty($head_table[0])) {
|
||||
$width = (!empty($head_table[1]) ? $head_table[1].'%' : '');
|
||||
$content_table .= '<th width="'.$width.'">'.$head_table[0].'</th>';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$content_table .= '</tr>';
|
||||
// body table
|
||||
|
||||
if (is_array($data_table) && count($data_table) > 0) {
|
||||
$offset = $x * $items_per_page;
|
||||
$data_table = array_slice($data_table, $offset, count($data_table));
|
||||
$i = 1;
|
||||
$item = $offset + 1;
|
||||
foreach ($data_table as $data) {
|
||||
$content_table .= '<tr>';
|
||||
$content_table .= '<td>'.($item < 10 ? '0'.$item : $item).'</td>';
|
||||
foreach ($data as $key => $content) {
|
||||
if (isset($content)) {
|
||||
$key == 1 ? $align = 'align="left"' : $align = 'align="center"';
|
||||
$content_table .= '<td '.$align.' style="padding:4px;" >'.$content.'</td>';
|
||||
}
|
||||
}
|
||||
$content_table .= '</tr>';
|
||||
$i++;
|
||||
$item++;
|
||||
if ($i > $items_per_page) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$content_table .= '<tr colspan="'.$i.'"><td>'.get_lang('Empty').'</td></tr>';
|
||||
}
|
||||
$content_table .= '</table>';
|
||||
if ($x < ($count_pages - 1)) {
|
||||
$content_table .= '<pagebreak />';
|
||||
}
|
||||
}
|
||||
$pdf = new PDF();
|
||||
$pdf->set_custom_footer($footer);
|
||||
$pdf->set_custom_header($headers_in_pdf);
|
||||
$pdf->content_to_pdf($header.$content_table, $css, $title_pdf);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the data as a table on a PDF page.
|
||||
*
|
||||
* @param resource The PDF object (ezpdf class) used to generate the file
|
||||
* @param array The data array
|
||||
* @param array Table headers
|
||||
* @param string Format (portrait or landscape)
|
||||
*/
|
||||
function export_pdf($pdf, $newarray, $header_names, $format)
|
||||
{
|
||||
$pdf->selectFont(api_get_path(LIBRARY_PATH).'ezpdf/fonts/Courier.afm');
|
||||
$pdf->ezSetCmMargins(0, 0, 0, 0);
|
||||
$pdf->ezSetY(($format == 'portrait') ? '820' : '570');
|
||||
$pdf->selectFont(api_get_path(LIBRARY_PATH).'ezpdf/fonts/Courier.afm');
|
||||
if ('portrait' == $format) {
|
||||
$pdf->line(40, 790, 540, 790);
|
||||
$pdf->line(40, 40, 540, 40);
|
||||
} else {
|
||||
$pdf->line(40, 540, 790, 540);
|
||||
$pdf->line(40, 40, 790, 40);
|
||||
}
|
||||
$pdf->ezSetY(($format == 'portrait') ? '750' : '520');
|
||||
$pdf->ezTable($newarray, $header_names, '', [
|
||||
'showHeadings' => 1,
|
||||
'shaded' => 1,
|
||||
'showLines' => 1,
|
||||
'rowGap' => 3,
|
||||
'width' => (($format == 'portrait') ? '500' : '750'),
|
||||
]);
|
||||
$pdf->ezStream();
|
||||
}
|
||||
517
main/gradebook/lib/fe/flatviewtable.class.php
Normal file
517
main/gradebook/lib/fe/flatviewtable.class.php
Normal file
@@ -0,0 +1,517 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
use CpChart\Cache as pCache;
|
||||
use CpChart\Data as pData;
|
||||
use CpChart\Image as pImage;
|
||||
|
||||
/**
|
||||
* Class FlatViewTable
|
||||
* Table to display flat view (all evaluations and links for all students).
|
||||
*
|
||||
* @author Stijn Konings
|
||||
* @author Bert Steppé - (refactored, optimised)
|
||||
* @author Julio Montoya Armas - Gradebook Graphics
|
||||
*/
|
||||
class FlatViewTable extends SortableTable
|
||||
{
|
||||
public $datagen;
|
||||
private $selectcat;
|
||||
private $limit_enabled;
|
||||
private $offset;
|
||||
private $mainCourseCategory;
|
||||
|
||||
/**
|
||||
* @param Category $selectcat
|
||||
* @param array $users
|
||||
* @param array $evals
|
||||
* @param array $links
|
||||
* @param bool $limit_enabled
|
||||
* @param int $offset
|
||||
* @param null $addparams
|
||||
* @param Category $mainCourseCategory
|
||||
*/
|
||||
public function __construct(
|
||||
$selectcat,
|
||||
$users = [],
|
||||
$evals = [],
|
||||
$links = [],
|
||||
$limit_enabled = false,
|
||||
$offset = 0,
|
||||
$addparams = null,
|
||||
$mainCourseCategory = null
|
||||
) {
|
||||
parent::__construct(
|
||||
'flatviewlist',
|
||||
null,
|
||||
null,
|
||||
api_is_western_name_order() ? 1 : 0
|
||||
);
|
||||
|
||||
$this->selectcat = $selectcat;
|
||||
$this->datagen = new FlatViewDataGenerator(
|
||||
$users,
|
||||
$evals,
|
||||
$links,
|
||||
['only_subcat' => $this->selectcat->get_id()],
|
||||
$mainCourseCategory
|
||||
);
|
||||
|
||||
$this->limit_enabled = $limit_enabled;
|
||||
$this->offset = $offset;
|
||||
if (isset($addparams)) {
|
||||
$this->set_additional_parameters($addparams ?: []);
|
||||
}
|
||||
|
||||
// step 2: generate rows: students
|
||||
$this->datagen->category = $this->selectcat;
|
||||
$this->mainCourseCategory = $mainCourseCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setLimitEnabled($value)
|
||||
{
|
||||
$this->limit_enabled = (bool) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Category
|
||||
*/
|
||||
public function getMainCourseCategory()
|
||||
{
|
||||
return $this->mainCourseCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display gradebook graphs.
|
||||
*/
|
||||
public function display_graph_by_resource()
|
||||
{
|
||||
$headerName = $this->datagen->get_header_names();
|
||||
$total_users = $this->datagen->get_total_users_count();
|
||||
$customdisplays = ScoreDisplay::instance()->get_custom_score_display_settings();
|
||||
|
||||
if (empty($customdisplays)) {
|
||||
echo get_lang('ToViewGraphScoreRuleMustBeEnabled');
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$user_results = $this->datagen->get_data_to_graph2(false);
|
||||
|
||||
if (empty($user_results) || empty($total_users)) {
|
||||
echo get_lang('NoResults');
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// Removing first name
|
||||
array_shift($headerName);
|
||||
// Removing last name
|
||||
array_shift($headerName);
|
||||
// Removing username
|
||||
array_shift($headerName);
|
||||
|
||||
$pre_result = [];
|
||||
foreach ($user_results as $result) {
|
||||
for ($i = 0; $i < count($headerName); $i++) {
|
||||
if (isset($result[$i + 1])) {
|
||||
$pre_result[$i + 3][] = $result[$i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$resource_list = [];
|
||||
$pre_result2 = [];
|
||||
foreach ($pre_result as $key => $res_array) {
|
||||
rsort($res_array);
|
||||
$pre_result2[] = $res_array;
|
||||
}
|
||||
|
||||
//@todo when a display custom does not exist the order of the color does not match
|
||||
//filling all the answer that are not responded with 0
|
||||
rsort($customdisplays);
|
||||
|
||||
if ($total_users > 0) {
|
||||
foreach ($pre_result2 as $key => $res_array) {
|
||||
$key_list = [];
|
||||
foreach ($res_array as $user_result) {
|
||||
$userResult = isset($user_result[1]) ? $user_result[1] : null;
|
||||
if (!isset($resource_list[$key][$userResult])) {
|
||||
$resource_list[$key][$userResult] = 0;
|
||||
}
|
||||
$resource_list[$key][$userResult]++;
|
||||
$key_list[] = $userResult;
|
||||
}
|
||||
|
||||
foreach ($customdisplays as $display) {
|
||||
if (!in_array($display['display'], $key_list)) {
|
||||
$resource_list[$key][$display['display']] = 0;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
//fixing $resource_list
|
||||
$max = 0;
|
||||
$new_list = [];
|
||||
foreach ($resource_list as $key => $value) {
|
||||
$new_value = [];
|
||||
foreach ($customdisplays as $item) {
|
||||
if ($value[$item['display']] > $max) {
|
||||
$max = $value[$item['display']];
|
||||
}
|
||||
$new_value[$item['display']] = strip_tags($value[$item['display']]);
|
||||
}
|
||||
$new_list[] = $new_value;
|
||||
}
|
||||
$resource_list = $new_list;
|
||||
$i = 1;
|
||||
// Cache definition
|
||||
$cachePath = api_get_path(SYS_ARCHIVE_PATH);
|
||||
foreach ($resource_list as $key => $resource) {
|
||||
// Reverse array, otherwise we get highest values first
|
||||
$resource = array_reverse($resource, true);
|
||||
|
||||
$dataSet = new pData();
|
||||
$dataSet->addPoints($resource, 'Serie');
|
||||
$dataSet->addPoints(array_keys($resource), 'Labels');
|
||||
$header = $headerName[$i - 1];
|
||||
if (is_array($header) && isset($header['header'])) {
|
||||
$header = $header['header'];
|
||||
}
|
||||
$header = strip_tags(api_html_entity_decode($header));
|
||||
$dataSet->setSerieDescription('Labels', $header);
|
||||
$dataSet->setAbscissa('Labels');
|
||||
$dataSet->setAbscissaName(get_lang('GradebookSkillsRanking'));
|
||||
$dataSet->setAxisName(0, get_lang('Students'));
|
||||
$palette = [
|
||||
'0' => ['R' => 186, 'G' => 206, 'B' => 151, 'Alpha' => 100],
|
||||
'1' => ['R' => 210, 'G' => 148, 'B' => 147, 'Alpha' => 100],
|
||||
'2' => ['R' => 148, 'G' => 170, 'B' => 208, 'Alpha' => 100],
|
||||
'3' => ['R' => 221, 'G' => 133, 'B' => 61, 'Alpha' => 100],
|
||||
'4' => ['R' => 65, 'G' => 153, 'B' => 176, 'Alpha' => 100],
|
||||
'5' => ['R' => 114, 'G' => 88, 'B' => 144, 'Alpha' => 100],
|
||||
'6' => ['R' => 138, 'G' => 166, 'B' => 78, 'Alpha' => 100],
|
||||
'7' => ['R' => 171, 'G' => 70, 'B' => 67, 'Alpha' => 100],
|
||||
'8' => ['R' => 69, 'G' => 115, 'B' => 168, 'Alpha' => 100],
|
||||
];
|
||||
$myCache = new pCache(['CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)]);
|
||||
$chartHash = $myCache->getHash($dataSet);
|
||||
if ($myCache->isInCache($chartHash)) {
|
||||
$imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
|
||||
$myCache->saveFromCache($chartHash, $imgPath);
|
||||
$imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
|
||||
} else {
|
||||
/* Create the pChart object */
|
||||
$widthSize = 480;
|
||||
$heightSize = 250;
|
||||
$myPicture = new pImage($widthSize, $heightSize, $dataSet);
|
||||
|
||||
/* Turn of Antialiasing */
|
||||
$myPicture->Antialias = false;
|
||||
|
||||
/* Add a border to the picture */
|
||||
$myPicture->drawRectangle(
|
||||
0,
|
||||
0,
|
||||
$widthSize - 1,
|
||||
$heightSize - 1,
|
||||
[
|
||||
'R' => 0,
|
||||
'G' => 0,
|
||||
'B' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
/* Set the default font */
|
||||
$myPicture->setFontProperties(
|
||||
[
|
||||
'FontName' => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
|
||||
'FontSize' => 10,
|
||||
]
|
||||
);
|
||||
/* Write the chart title */
|
||||
$myPicture->drawText(
|
||||
250,
|
||||
30,
|
||||
$header,
|
||||
[
|
||||
'FontSize' => 12,
|
||||
'Align' => TEXT_ALIGN_BOTTOMMIDDLE,
|
||||
]
|
||||
);
|
||||
|
||||
/* Define the chart area */
|
||||
$myPicture->setGraphArea(50, 40, $widthSize - 20, $heightSize - 50);
|
||||
|
||||
/* Draw the scale */
|
||||
$scaleSettings = [
|
||||
'GridR' => 200,
|
||||
'GridG' => 200,
|
||||
'GridB' => 200,
|
||||
'DrawSubTicks' => true,
|
||||
'CycleBackground' => true,
|
||||
'Mode' => SCALE_MODE_START0,
|
||||
];
|
||||
$myPicture->drawScale($scaleSettings);
|
||||
|
||||
/* Turn on shadow computing */
|
||||
$myPicture->setShadow(
|
||||
true,
|
||||
[
|
||||
'X' => 1,
|
||||
'Y' => 1,
|
||||
'R' => 0,
|
||||
'G' => 0,
|
||||
'B' => 0,
|
||||
'Alpha' => 10,
|
||||
]
|
||||
);
|
||||
|
||||
/* Draw the chart */
|
||||
$myPicture->setShadow(
|
||||
true,
|
||||
[
|
||||
'X' => 1,
|
||||
'Y' => 1,
|
||||
'R' => 0,
|
||||
'G' => 0,
|
||||
'B' => 0,
|
||||
'Alpha' => 10,
|
||||
]
|
||||
);
|
||||
$settings = [
|
||||
'OverrideColors' => $palette,
|
||||
'Gradient' => false,
|
||||
'GradientMode' => GRADIENT_SIMPLE,
|
||||
'DisplayPos' => LABEL_POS_TOP,
|
||||
'DisplayValues' => true,
|
||||
'DisplayR' => 0,
|
||||
'DisplayG' => 0,
|
||||
'DisplayB' => 0,
|
||||
'DisplayShadow' => true,
|
||||
'Surrounding' => 10,
|
||||
];
|
||||
$myPicture->drawBarChart($settings);
|
||||
|
||||
/* Render the picture (choose the best way) */
|
||||
$myCache->writeToCache($chartHash, $myPicture);
|
||||
$imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
|
||||
$myCache->saveFromCache($chartHash, $imgPath);
|
||||
$imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
|
||||
}
|
||||
echo '<img src="'.$imgPath.'" >';
|
||||
if ($i % 2 == 0 && $i != 0) {
|
||||
echo '<br /><br />';
|
||||
} else {
|
||||
echo ' ';
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used by SortableTable to get total number of items in the table.
|
||||
*/
|
||||
public function get_total_number_of_items()
|
||||
{
|
||||
return $this->datagen->get_total_users_count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used by SortableTable to generate the data to display.
|
||||
*/
|
||||
public function get_table_data(
|
||||
$from = 1,
|
||||
$per_page = null,
|
||||
$column = null,
|
||||
$direction = null,
|
||||
$sort = null
|
||||
) {
|
||||
$is_western_name_order = api_is_western_name_order();
|
||||
|
||||
// create page navigation if needed
|
||||
$totalitems = $this->datagen->get_total_items_count();
|
||||
|
||||
if ($this->limit_enabled && $totalitems > GRADEBOOK_ITEM_LIMIT) {
|
||||
$selectlimit = GRADEBOOK_ITEM_LIMIT;
|
||||
} else {
|
||||
$selectlimit = $totalitems;
|
||||
}
|
||||
|
||||
$header = null;
|
||||
if ($this->limit_enabled && $totalitems > GRADEBOOK_ITEM_LIMIT) {
|
||||
$header .= '<table
|
||||
style="width: 100%; text-align: right; margin-left: auto; margin-right: auto;"
|
||||
border="0" cellpadding="2"><tbody>
|
||||
<tr>';
|
||||
// previous X
|
||||
$header .= '<td style="width:100%;">';
|
||||
if ($this->offset >= GRADEBOOK_ITEM_LIMIT) {
|
||||
$header .= '<a
|
||||
href="'.api_get_self().'?selectcat='.(int) $_GET['selectcat'].'&offset='.(($this->offset) - GRADEBOOK_ITEM_LIMIT)
|
||||
.(isset($_GET['search']) ? '&search='.Security::remove_XSS($_GET['search']) : '').'">'
|
||||
.Display::return_icon(
|
||||
'action_prev.png',
|
||||
get_lang('PreviousPage'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
)
|
||||
.'</a>';
|
||||
} else {
|
||||
$header .= Display::return_icon(
|
||||
'action_prev_na.png',
|
||||
get_lang('PreviousPage'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
);
|
||||
}
|
||||
$header .= ' ';
|
||||
// next X
|
||||
$calcnext = (($this->offset + (2 * GRADEBOOK_ITEM_LIMIT)) > $totalitems) ?
|
||||
($totalitems - (GRADEBOOK_ITEM_LIMIT + $this->offset)) : GRADEBOOK_ITEM_LIMIT;
|
||||
|
||||
if ($calcnext > 0) {
|
||||
$header .= '<a href="'.api_get_self()
|
||||
.'?selectcat='.Security::remove_XSS($_GET['selectcat'])
|
||||
.'&offset='.($this->offset + GRADEBOOK_ITEM_LIMIT)
|
||||
.(isset($_GET['search']) ? '&search='.Security::remove_XSS($_GET['search']) : '').'">'
|
||||
.Display::return_icon('action_next.png', get_lang('NextPage'), [], ICON_SIZE_MEDIUM)
|
||||
.'</a>';
|
||||
} else {
|
||||
$header .= Display::return_icon(
|
||||
'action_next_na.png',
|
||||
get_lang('NextPage'),
|
||||
[],
|
||||
ICON_SIZE_MEDIUM
|
||||
);
|
||||
}
|
||||
$header .= '</td>';
|
||||
$header .= '</tbody></table>';
|
||||
echo $header;
|
||||
}
|
||||
|
||||
// retrieve sorting type
|
||||
if ($is_western_name_order) {
|
||||
$users_sorting = ($this->column == 0 ? FlatViewDataGenerator::FVDG_SORT_FIRSTNAME : FlatViewDataGenerator::FVDG_SORT_LASTNAME);
|
||||
} else {
|
||||
$users_sorting = ($this->column == 0 ? FlatViewDataGenerator::FVDG_SORT_LASTNAME : FlatViewDataGenerator::FVDG_SORT_FIRSTNAME);
|
||||
}
|
||||
|
||||
if ('DESC' === $this->direction) {
|
||||
$users_sorting |= FlatViewDataGenerator::FVDG_SORT_DESC;
|
||||
} else {
|
||||
$users_sorting |= FlatViewDataGenerator::FVDG_SORT_ASC;
|
||||
}
|
||||
|
||||
// step 1: generate columns: evaluations and links
|
||||
$header_names = $this->datagen->get_header_names($this->offset, $selectlimit);
|
||||
$userRowSpan = false;
|
||||
foreach ($header_names as $item) {
|
||||
if (is_array($item)) {
|
||||
$userRowSpan = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$thAttributes = '';
|
||||
if ($userRowSpan) {
|
||||
$thAttributes = 'rowspan=2';
|
||||
}
|
||||
|
||||
$this->set_header(0, $header_names[0], true, $thAttributes);
|
||||
$this->set_header(1, $header_names[1], true, $thAttributes);
|
||||
|
||||
$column = 2;
|
||||
$firstHeader = [];
|
||||
while ($column < count($header_names)) {
|
||||
$headerData = $header_names[$column];
|
||||
if (is_array($headerData)) {
|
||||
$countItems = count($headerData['items']);
|
||||
$this->set_header(
|
||||
$column,
|
||||
$headerData['header'],
|
||||
false,
|
||||
'colspan="'.$countItems.'"'
|
||||
);
|
||||
|
||||
if (count($headerData['items']) > 0) {
|
||||
foreach ($headerData['items'] as $item) {
|
||||
$firstHeader[] = '<span class="text-center">'.$item.'</span>';
|
||||
}
|
||||
} else {
|
||||
$firstHeader[] = '—';
|
||||
}
|
||||
} else {
|
||||
$this->set_header($column, $headerData, false, $thAttributes);
|
||||
}
|
||||
$column++;
|
||||
}
|
||||
|
||||
$data_array = $this->datagen->get_data(
|
||||
$users_sorting,
|
||||
$from,
|
||||
$this->per_page,
|
||||
$this->offset,
|
||||
$selectlimit
|
||||
);
|
||||
|
||||
$table_data = [];
|
||||
|
||||
if (!empty($firstHeader)) {
|
||||
$table_data[] = $firstHeader;
|
||||
}
|
||||
|
||||
$columnOffset = empty($this->datagen->params['show_official_code']) ? 0 : 1;
|
||||
|
||||
foreach ($data_array as $user_row) {
|
||||
$user_id = $user_row[0];
|
||||
unset($user_row[0]);
|
||||
$userInfo = api_get_user_info($user_id);
|
||||
if ($is_western_name_order) {
|
||||
$user_row[1 + $columnOffset] = $this->build_name_link(
|
||||
$user_id,
|
||||
$userInfo['firstname']
|
||||
);
|
||||
$user_row[2 + $columnOffset] = $this->build_name_link(
|
||||
$user_id,
|
||||
$userInfo['lastname']
|
||||
);
|
||||
} else {
|
||||
$user_row[1 + $columnOffset] = $this->build_name_link(
|
||||
$user_id,
|
||||
$userInfo['lastname']
|
||||
);
|
||||
$user_row[2 + $columnOffset] = $this->build_name_link(
|
||||
$user_id,
|
||||
$userInfo['firstname']
|
||||
);
|
||||
}
|
||||
$user_row = array_values($user_row);
|
||||
|
||||
$table_data[] = $user_row;
|
||||
}
|
||||
|
||||
return $table_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $userId
|
||||
* @param $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_name_link($userId, $name)
|
||||
{
|
||||
return '<a
|
||||
href="user_stats.php?userid='.$userId.'&selectcat='.$this->selectcat->get_id().'&'.api_get_cidreq().'">'.
|
||||
$name.'</a>';
|
||||
}
|
||||
}
|
||||
1360
main/gradebook/lib/fe/gradebooktable.class.php
Normal file
1360
main/gradebook/lib/fe/gradebooktable.class.php
Normal file
File diff suppressed because it is too large
Load Diff
7
main/gradebook/lib/fe/index.html
Normal file
7
main/gradebook/lib/fe/index.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; url=../../gradebook.php">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
211
main/gradebook/lib/fe/linkaddeditform.class.php
Normal file
211
main/gradebook/lib/fe/linkaddeditform.class.php
Normal file
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Form used to add or edit links.
|
||||
*
|
||||
* @author Stijn Konings
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class LinkAddEditForm extends FormValidator
|
||||
{
|
||||
public const TYPE_ADD = 1;
|
||||
public const TYPE_EDIT = 2;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* To add link, define category_object and link_type
|
||||
* To edit link, define link_object.
|
||||
*/
|
||||
public function __construct(
|
||||
$form_type,
|
||||
$category_object,
|
||||
$link_type,
|
||||
$link_object,
|
||||
$form_name,
|
||||
$action = null
|
||||
) {
|
||||
parent::__construct($form_name, 'post', $action);
|
||||
|
||||
// set or create link object
|
||||
if (isset($link_object)) {
|
||||
$link = $link_object;
|
||||
} elseif (isset($link_type) && isset($category_object)) {
|
||||
$link = LinkFactory::create($link_type);
|
||||
$link->set_course_code(api_get_course_id());
|
||||
$link->set_session_id(api_get_session_id());
|
||||
$link->set_category_id($category_object[0]->get_id());
|
||||
} else {
|
||||
exit('LinkAddEditForm error: define link_type/category_object or link_object');
|
||||
}
|
||||
|
||||
$defaults = [];
|
||||
if (!empty($_GET['editlink'])) {
|
||||
$this->addElement('header', '', get_lang('EditLink'));
|
||||
}
|
||||
|
||||
// ELEMENT: name
|
||||
if ($form_type == self::TYPE_ADD || $link->is_allowed_to_change_name()) {
|
||||
if ($link->needs_name_and_description()) {
|
||||
$this->addText('name', get_lang('Name'), true, ['size' => '40', 'maxlength' => '40']);
|
||||
} else {
|
||||
$select = $this->addElement('select', 'select_link', get_lang('ChooseItem'));
|
||||
foreach ($link->get_all_links() as $newlink) {
|
||||
$name = strip_tags(Exercise::get_formated_title_variable($newlink[1]));
|
||||
$select->addOption($name, $newlink[0]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->addElement(
|
||||
'label',
|
||||
get_lang('Name'),
|
||||
'<span class="freeze">'.$link->get_name().' ['.$link->get_type_name().']</span>'
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
'name_link',
|
||||
$link->get_name(),
|
||||
['id' => 'name_link']
|
||||
);
|
||||
}
|
||||
|
||||
if (1 == count($category_object)) {
|
||||
$this->addElement('hidden', 'select_gradebook', $category_object[0]->get_id());
|
||||
} else {
|
||||
$select_gradebook = $this->addElement(
|
||||
'select',
|
||||
'select_gradebook',
|
||||
get_lang('SelectGradebook'),
|
||||
[],
|
||||
['id' => 'hide_category_id']
|
||||
);
|
||||
$this->addRule('select_gradebook', get_lang('ThisFieldIsRequired'), 'nonzero');
|
||||
$default_weight = 0;
|
||||
if (!empty($category_object)) {
|
||||
foreach ($category_object as $my_cat) {
|
||||
if ($my_cat->get_course_code() == api_get_course_id()) {
|
||||
$grade_model_id = $my_cat->get_grade_model_id();
|
||||
if (empty($grade_model_id)) {
|
||||
if (0 == $my_cat->get_parent_id()) {
|
||||
$default_weight = $my_cat->get_weight();
|
||||
$select_gradebook->addOption(get_lang('Default'), $my_cat->get_id());
|
||||
} else {
|
||||
$select_gradebook->addOption(Security::remove_XSS($my_cat->get_name()), $my_cat->get_id());
|
||||
}
|
||||
} else {
|
||||
$select_gradebook->addOption(get_lang('Select'), 0);
|
||||
}
|
||||
if ($link->get_category_id() == $my_cat->get_id()) {
|
||||
$default_weight = $my_cat->get_weight();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->addFloat(
|
||||
'weight_mask',
|
||||
[
|
||||
get_lang('Weight'),
|
||||
null,
|
||||
' [0 .. <span id="max_weight">'.$category_object[0]->get_weight(
|
||||
).'</span>] ',
|
||||
],
|
||||
true,
|
||||
[
|
||||
'size' => '4',
|
||||
'maxlength' => '5',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addElement('hidden', 'weight');
|
||||
|
||||
if (self::TYPE_EDIT == $form_type) {
|
||||
$parent_cat = Category::load($link->get_category_id());
|
||||
if (0 == $parent_cat[0]->get_parent_id()) {
|
||||
$values['weight'] = $link->get_weight();
|
||||
} else {
|
||||
$cat = Category::load($parent_cat[0]->get_parent_id());
|
||||
$values['weight'] = $link->get_weight();
|
||||
}
|
||||
$defaults['weight_mask'] = $values['weight'];
|
||||
$defaults['select_gradebook'] = $link->get_category_id();
|
||||
}
|
||||
// ELEMENT: max
|
||||
if ($link->needs_max()) {
|
||||
if ($form_type == self::TYPE_EDIT && $link->has_results()) {
|
||||
$this->addText(
|
||||
'max',
|
||||
get_lang('QualificationNumeric'),
|
||||
false,
|
||||
[
|
||||
'size' => '4',
|
||||
'maxlength' => '5',
|
||||
'disabled' => 'disabled',
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$this->addText('max', get_lang('QualificationNumeric'), true, ['size' => '4', 'maxlength' => '5']);
|
||||
$this->addRule('max', get_lang('OnlyNumbers'), 'numeric');
|
||||
$this->addRule(
|
||||
'max',
|
||||
get_lang('NegativeValue'),
|
||||
'compare',
|
||||
'>=',
|
||||
'server',
|
||||
false,
|
||||
false,
|
||||
0
|
||||
);
|
||||
}
|
||||
if ($form_type == self::TYPE_EDIT) {
|
||||
$defaults['max'] = $link->get_max();
|
||||
}
|
||||
}
|
||||
|
||||
// ELEMENT: description
|
||||
if ($link->needs_name_and_description()) {
|
||||
$this->addElement(
|
||||
'textarea',
|
||||
'description',
|
||||
get_lang('Description'),
|
||||
['rows' => '3', 'cols' => '34']
|
||||
);
|
||||
if ($form_type == self::TYPE_EDIT) {
|
||||
$defaults['description'] = $link->get_description();
|
||||
}
|
||||
}
|
||||
|
||||
// ELEMENT: visible
|
||||
$visible = ($form_type == self::TYPE_EDIT && $link->is_visible()) ? '1' : '0';
|
||||
$this->addElement('checkbox', 'visible', null, get_lang('Visible'), $visible);
|
||||
if ($form_type == self::TYPE_EDIT) {
|
||||
$defaults['visible'] = $link->is_visible();
|
||||
}
|
||||
|
||||
// ELEMENT: add results
|
||||
if ($form_type == self::TYPE_ADD && $link->needs_results()) {
|
||||
$this->addElement('checkbox', 'addresult', get_lang('AddResult'));
|
||||
}
|
||||
// submit button
|
||||
if ($form_type == self::TYPE_ADD) {
|
||||
$this->addButtonCreate(get_lang('CreateLink'));
|
||||
} else {
|
||||
$this->addButtonUpdate(get_lang('LinkMod'));
|
||||
}
|
||||
|
||||
if ($form_type == self::TYPE_ADD) {
|
||||
$setting = api_get_setting('tool_visible_by_default_at_creation');
|
||||
$visibility_default = 1;
|
||||
if (isset($setting['gradebook']) && $setting['gradebook'] === 'false') {
|
||||
$visibility_default = 0;
|
||||
}
|
||||
$defaults['visible'] = $visibility_default;
|
||||
}
|
||||
|
||||
// set default values
|
||||
$this->setDefaults($defaults);
|
||||
}
|
||||
}
|
||||
158
main/gradebook/lib/fe/linkform.class.php
Normal file
158
main/gradebook/lib/fe/linkform.class.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class LinkForm
|
||||
* Forms related to links.
|
||||
*
|
||||
* @author Stijn Konings
|
||||
* @author Bert Steppé (made more generic)
|
||||
*/
|
||||
class LinkForm extends FormValidator
|
||||
{
|
||||
public const TYPE_CREATE = 1;
|
||||
public const TYPE_MOVE = 2;
|
||||
/** @var Category */
|
||||
private $category_object;
|
||||
private $link_object;
|
||||
private $extra;
|
||||
|
||||
/**
|
||||
* Builds a form containing form items based on a given parameter.
|
||||
*
|
||||
* @param int $form_type 1=choose link
|
||||
* @param Category $category_object the category object
|
||||
* @param AbstractLink $link_object
|
||||
* @param string $form_name name
|
||||
* @param string $method
|
||||
* @param string $action
|
||||
*/
|
||||
public function __construct(
|
||||
$form_type,
|
||||
$category_object,
|
||||
$link_object,
|
||||
$form_name,
|
||||
$method = 'post',
|
||||
$action = null,
|
||||
$extra = null
|
||||
) {
|
||||
parent::__construct($form_name, $method, $action);
|
||||
|
||||
if (isset($category_object)) {
|
||||
$this->category_object = $category_object;
|
||||
} else {
|
||||
if (isset($link_object)) {
|
||||
$this->link_object = $link_object;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($extra)) {
|
||||
$this->extra = $extra;
|
||||
}
|
||||
if (self::TYPE_CREATE == $form_type) {
|
||||
$this->build_create();
|
||||
} elseif (self::TYPE_MOVE == $form_type) {
|
||||
$this->build_move();
|
||||
}
|
||||
}
|
||||
|
||||
protected function build_move()
|
||||
{
|
||||
$renderer = &$this->defaultRenderer();
|
||||
$renderer->setCustomElementTemplate('<span>{element}</span> ');
|
||||
$this->addElement(
|
||||
'static',
|
||||
null,
|
||||
null,
|
||||
'"'.$this->link_object->get_name().'" '
|
||||
);
|
||||
$this->addElement('static', null, null, get_lang('MoveTo').' : ');
|
||||
$select = $this->addElement('select', 'move_cat', null, null);
|
||||
$line = '';
|
||||
foreach ($this->link_object->get_target_categories() as $cat) {
|
||||
for ($i = 0; $i < $cat[2]; $i++) {
|
||||
$line .= '—';
|
||||
}
|
||||
$select->addOption($line.' '.$cat[1], $cat[0]);
|
||||
$line = '';
|
||||
}
|
||||
$this->addElement('submit', null, get_lang('Ok'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the form.
|
||||
*/
|
||||
protected function build_create()
|
||||
{
|
||||
$this->addHeader(get_lang('MakeLink'));
|
||||
$select = $this->addElement(
|
||||
'select',
|
||||
'select_link',
|
||||
get_lang('ChooseLink'),
|
||||
null,
|
||||
['onchange' => 'document.create_link.submit()']
|
||||
);
|
||||
|
||||
$select->addOption('['.get_lang('ChooseLink').']', 0);
|
||||
$courseCode = $this->category_object->get_course_code();
|
||||
|
||||
$linkTypes = LinkFactory::get_all_types();
|
||||
foreach ($linkTypes as $linkType) {
|
||||
// The hot potatoe link will be added "inside" the exercise option.
|
||||
if ($linkType == LINK_HOTPOTATOES) {
|
||||
continue;
|
||||
}
|
||||
$link = $this->createLink($linkType, $courseCode);
|
||||
/* configure the session id within the gradebook evaluation*/
|
||||
$link->set_session_id(api_get_session_id());
|
||||
// disable this element if the link works with a dropdownlist
|
||||
// and if there are no links left
|
||||
if (!$link->needs_name_and_description() && count($link->get_all_links()) == '0') {
|
||||
$select->addOption($link->get_type_name(), $linkType, 'disabled');
|
||||
} else {
|
||||
$select->addOption($link->get_type_name(), $linkType);
|
||||
}
|
||||
|
||||
if ($link->get_type() == LINK_EXERCISE) {
|
||||
// Adding hot potatoes
|
||||
$linkHot = $this->createLink(LINK_HOTPOTATOES, $courseCode);
|
||||
$linkHot->setHp(true);
|
||||
if ($linkHot->get_all_links(true)) {
|
||||
$select->addOption(
|
||||
' '.$linkHot->get_type_name(),
|
||||
LINK_HOTPOTATOES
|
||||
);
|
||||
} else {
|
||||
$select->addOption(
|
||||
' '.$linkHot->get_type_name(),
|
||||
LINK_HOTPOTATOES,
|
||||
'disabled'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->extra)) {
|
||||
$this->setDefaults(['select_link' => $this->extra]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $link
|
||||
* @param string|null $courseCode
|
||||
*
|
||||
* @return AttendanceLink|DropboxLink|ExerciseLink|ForumThreadLink|LearnpathLink|StudentPublicationLink|SurveyLink|null
|
||||
*/
|
||||
private function createLink($link, $courseCode)
|
||||
{
|
||||
$link = LinkFactory::create($link);
|
||||
if (!empty($courseCode)) {
|
||||
$link->set_course_code($courseCode);
|
||||
} elseif (!empty($_GET['course_code'])) {
|
||||
$link->set_course_code(Database::escape_string($_GET['course_code'], null, false));
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
275
main/gradebook/lib/fe/resulttable.class.php
Normal file
275
main/gradebook/lib/fe/resulttable.class.php
Normal file
@@ -0,0 +1,275 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class ResultTable
|
||||
* Table to display results for an evaluation.
|
||||
*
|
||||
* @author Stijn Konings
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class ResultTable extends SortableTable
|
||||
{
|
||||
private $datagen;
|
||||
private $evaluation;
|
||||
private $allresults;
|
||||
private $iscourse;
|
||||
|
||||
/**
|
||||
* ResultTable constructor.
|
||||
*
|
||||
* @param string $evaluation
|
||||
* @param array $results
|
||||
* @param string|null $iscourse
|
||||
* @param array $addparams
|
||||
* @param bool $forprint
|
||||
*/
|
||||
public function __construct(
|
||||
$evaluation,
|
||||
$results,
|
||||
$iscourse,
|
||||
$addparams = [],
|
||||
$forprint = false
|
||||
) {
|
||||
parent::__construct(
|
||||
'resultlist',
|
||||
null,
|
||||
null,
|
||||
api_is_western_name_order() ? 1 : 2
|
||||
);
|
||||
|
||||
$this->datagen = new ResultsDataGenerator($evaluation, $results, true);
|
||||
|
||||
$this->evaluation = $evaluation;
|
||||
$this->iscourse = $iscourse;
|
||||
$this->forprint = $forprint;
|
||||
|
||||
if (isset($addparams)) {
|
||||
$this->set_additional_parameters($addparams);
|
||||
}
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$column = 0;
|
||||
if ('1' == $this->iscourse) {
|
||||
$this->set_header($column++, '', false);
|
||||
$this->set_form_actions([
|
||||
'delete' => get_lang('Delete'),
|
||||
]);
|
||||
}
|
||||
if (api_is_western_name_order()) {
|
||||
$this->set_header($column++, get_lang('FirstName'));
|
||||
$this->set_header($column++, get_lang('LastName'));
|
||||
} else {
|
||||
$this->set_header($column++, get_lang('LastName'));
|
||||
$this->set_header($column++, get_lang('FirstName'));
|
||||
}
|
||||
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
if (empty($model)) {
|
||||
$this->set_header($column++, get_lang('Score'));
|
||||
}
|
||||
|
||||
if ($scoredisplay->is_custom()) {
|
||||
$this->set_header($column++, get_lang('Display'));
|
||||
}
|
||||
if (!$this->forprint) {
|
||||
$this->set_header($column++, get_lang('Modify'), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used by SortableTable to get total number of items in the table.
|
||||
*/
|
||||
public function get_total_number_of_items()
|
||||
{
|
||||
return $this->datagen->get_total_results_count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used by SortableTable to generate the data to display.
|
||||
*/
|
||||
public function get_table_data(
|
||||
$from = 1,
|
||||
$per_page = null,
|
||||
$column = null,
|
||||
$direction = null,
|
||||
$sort = null
|
||||
) {
|
||||
$isWesternNameOrder = api_is_western_name_order();
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
|
||||
// determine sorting type
|
||||
$col_adjust = $this->iscourse == '1' ? 1 : 0;
|
||||
|
||||
switch ($this->column) {
|
||||
// first name or last name
|
||||
case 0 + $col_adjust:
|
||||
if ($isWesternNameOrder) {
|
||||
$sorting = ResultsDataGenerator::RDG_SORT_FIRSTNAME;
|
||||
} else {
|
||||
$sorting = ResultsDataGenerator::RDG_SORT_LASTNAME;
|
||||
}
|
||||
break;
|
||||
// first name or last name
|
||||
case 1 + $col_adjust:
|
||||
if ($isWesternNameOrder) {
|
||||
$sorting = ResultsDataGenerator::RDG_SORT_LASTNAME;
|
||||
} else {
|
||||
$sorting = ResultsDataGenerator::RDG_SORT_FIRSTNAME;
|
||||
}
|
||||
break;
|
||||
// Score
|
||||
case 2 + $col_adjust:
|
||||
$sorting = ResultsDataGenerator::RDG_SORT_SCORE;
|
||||
break;
|
||||
case 3 + $col_adjust:
|
||||
$sorting = ResultsDataGenerator::RDG_SORT_MASK;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->direction === 'DESC') {
|
||||
$sorting |= ResultsDataGenerator::RDG_SORT_DESC;
|
||||
} else {
|
||||
$sorting |= ResultsDataGenerator::RDG_SORT_ASC;
|
||||
}
|
||||
|
||||
$data_array = $this->datagen->get_data($sorting, $from, $this->per_page);
|
||||
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
|
||||
// generate the data to display
|
||||
$sortable_data = [];
|
||||
foreach ($data_array as $item) {
|
||||
$row = [];
|
||||
if ('1' == $this->iscourse) {
|
||||
$row[] = $item['result_id'];
|
||||
}
|
||||
if ($isWesternNameOrder) {
|
||||
$row[] = $item['firstname'];
|
||||
$row[] = $item['lastname'];
|
||||
} else {
|
||||
$row[] = $item['lastname'];
|
||||
$row[] = $item['firstname'];
|
||||
}
|
||||
|
||||
if (empty($model)) {
|
||||
$row[] = Display::bar_progress(
|
||||
$item['percentage_score'],
|
||||
false,
|
||||
$item['score']
|
||||
);
|
||||
}
|
||||
|
||||
if ($scoredisplay->is_custom()) {
|
||||
$row[] = $item['display'];
|
||||
}
|
||||
if (!$this->forprint) {
|
||||
$row[] = $this->build_edit_column($item);
|
||||
}
|
||||
$sortable_data[] = $row;
|
||||
}
|
||||
|
||||
return $sortable_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Result $result
|
||||
* @param string $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getResultAttemptTable($result, $url = '')
|
||||
{
|
||||
if (empty($result)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_ATTEMPT);
|
||||
|
||||
$sql = "SELECT * FROM $table WHERE result_id = ".$result->get_id().' ORDER BY created_at DESC';
|
||||
$resultQuery = Database::query($sql);
|
||||
$list = Database::store_result($resultQuery);
|
||||
|
||||
$htmlTable = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
|
||||
$htmlTable->setHeaderContents(0, 0, get_lang('Score'));
|
||||
$htmlTable->setHeaderContents(0, 1, get_lang('Comment'));
|
||||
$htmlTable->setHeaderContents(0, 2, get_lang('CreatedAt'));
|
||||
|
||||
if (!empty($url)) {
|
||||
$htmlTable->setHeaderContents(0, 3, get_lang('Actions'));
|
||||
}
|
||||
|
||||
$row = 1;
|
||||
foreach ($list as $data) {
|
||||
$htmlTable->setCellContents($row, 0, $data['score']);
|
||||
$htmlTable->setCellContents($row, 1, $data['comment']);
|
||||
$htmlTable->setCellContents($row, 2, Display::dateToStringAgoAndLongDate($data['created_at']));
|
||||
if (!empty($url)) {
|
||||
$htmlTable->setCellContents(
|
||||
$row,
|
||||
3,
|
||||
Display::url(
|
||||
Display::return_icon('delete.png', get_lang('Delete')),
|
||||
$url.'&action=delete_attempt&result_attempt_id='.$data['id']
|
||||
)
|
||||
);
|
||||
}
|
||||
$row++;
|
||||
}
|
||||
|
||||
return $htmlTable->toHtml();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $item
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_edit_column($item)
|
||||
{
|
||||
$locked_status = $this->evaluation->get_locked();
|
||||
$allowMultipleAttempts = api_get_configuration_value('gradebook_multiple_evaluation_attempts');
|
||||
$baseUrl = api_get_self().'?selecteval='.$this->evaluation->get_id().'&'.api_get_cidreq();
|
||||
$editColumn = '';
|
||||
if (api_is_allowed_to_edit(null, true) && $locked_status == 0) {
|
||||
if ($allowMultipleAttempts) {
|
||||
if (!empty($item['percentage_score'])) {
|
||||
$editColumn .=
|
||||
Display::url(
|
||||
Display::return_icon('add.png', get_lang('AddAttempt'), '', '22'),
|
||||
$baseUrl.'&action=add_attempt&editres='.$item['result_id']
|
||||
);
|
||||
} else {
|
||||
$editColumn .= '<a href="'.api_get_self().'?editres='.$item['result_id'].'&selecteval='.$this->evaluation->get_id().'&'.api_get_cidreq().'">'.
|
||||
Display::return_icon('edit.png', get_lang('Modify'), '', '22').'</a>';
|
||||
}
|
||||
} else {
|
||||
$editColumn .= '<a href="'.api_get_self().'?editres='.$item['result_id'].'&selecteval='.$this->evaluation->get_id().'&'.api_get_cidreq().'">'.
|
||||
Display::return_icon('edit.png', get_lang('Modify'), '', '22').'</a>';
|
||||
}
|
||||
$editColumn .= ' <a href="'.api_get_self().'?delete_mark='.$item['result_id'].'&selecteval='.$this->evaluation->get_id().'&'.api_get_cidreq().'">'.
|
||||
Display::return_icon('delete.png', get_lang('Delete'), '', '22').'</a>';
|
||||
}
|
||||
|
||||
if ($this->evaluation->get_course_code() == null) {
|
||||
$editColumn .= ' <a href="'.api_get_self().'?resultdelete='.$item['result_id'].'&selecteval='.$this->evaluation->get_id().'" onclick="return confirmationuser();">';
|
||||
$editColumn .= Display::return_icon('delete.png', get_lang('Delete'));
|
||||
$editColumn .= '</a>';
|
||||
$editColumn .= ' <a href="user_stats.php?userid='.$item['id'].'&selecteval='.$this->evaluation->get_id().'&'.api_get_cidreq().'">';
|
||||
$editColumn .= Display::return_icon('statistics.gif', get_lang('Statistics'));
|
||||
$editColumn .= '</a>';
|
||||
}
|
||||
|
||||
// Evaluation's origin is a link
|
||||
if ($this->evaluation->get_category_id() < 0) {
|
||||
$link = LinkFactory::get_evaluation_link($this->evaluation->get_id());
|
||||
$doc_url = $link->get_view_url($item['id']);
|
||||
|
||||
if ($doc_url != null) {
|
||||
$editColumn .= ' <a href="'.$doc_url.'" target="_blank">';
|
||||
$editColumn .= Display::return_icon('link.gif', get_lang('OpenDocument')).'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
return $editColumn;
|
||||
}
|
||||
}
|
||||
160
main/gradebook/lib/fe/scoredisplayform.class.php
Normal file
160
main/gradebook/lib/fe/scoredisplayform.class.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class ScoreDisplayForm
|
||||
* Form for the score display dialog.
|
||||
*
|
||||
* @author Stijn Konings
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class ScoreDisplayForm extends FormValidator
|
||||
{
|
||||
/**
|
||||
* @param $form_name
|
||||
* @param null $action
|
||||
*/
|
||||
public function __construct($form_name, $action = null)
|
||||
{
|
||||
parent::__construct($form_name, 'post', $action);
|
||||
$displayscore = ScoreDisplay::instance();
|
||||
$customdisplays = $displayscore->get_custom_score_display_settings();
|
||||
|
||||
$nr_items = ('0' != count($customdisplays)) ? count($customdisplays) : '1';
|
||||
$this->setDefaults(
|
||||
[
|
||||
'scorecolpercent' => $displayscore->get_color_split_value(),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addElement('hidden', 'maxvalue', '100');
|
||||
$this->addElement('hidden', 'minvalue', '0');
|
||||
$counter = 1;
|
||||
|
||||
// Setting the default values
|
||||
if (is_array($customdisplays)) {
|
||||
foreach ($customdisplays as $customdisplay) {
|
||||
$this->setDefaults(
|
||||
[
|
||||
'endscore['.$counter.']' => $customdisplay['score'],
|
||||
'displaytext['.$counter.']' => $customdisplay['display'],
|
||||
]
|
||||
);
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
// Settings for the colored score
|
||||
$this->addElement('header', get_lang('ScoreEdit'));
|
||||
|
||||
if ($displayscore->is_coloring_enabled()) {
|
||||
$this->addElement('html', '<b>'.get_lang('ScoreColor').'</b>');
|
||||
$this->addElement(
|
||||
'text',
|
||||
'scorecolpercent',
|
||||
[get_lang('Below'), get_lang('WillColorRed'), '%'],
|
||||
[
|
||||
'size' => 5,
|
||||
'maxlength' => 5,
|
||||
'input-size' => 2,
|
||||
]
|
||||
);
|
||||
|
||||
if (api_get_setting('teachers_can_change_score_settings') != 'true') {
|
||||
$this->freeze('scorecolpercent');
|
||||
}
|
||||
|
||||
$this->addRule('scorecolpercent', get_lang('OnlyNumbers'), 'numeric');
|
||||
$this->addRule(['scorecolpercent', 'maxvalue'], get_lang('Over100'), 'compare', '<=');
|
||||
$this->addRule(['scorecolpercent', 'minvalue'], get_lang('UnderMin'), 'compare', '>');
|
||||
}
|
||||
|
||||
// Settings for the scoring system
|
||||
if ($displayscore->is_custom()) {
|
||||
$this->addElement('html', '<br /><b>'.get_lang('ScoringSystem').'</b>');
|
||||
$this->addElement('static', null, null, get_lang('ScoreInfo'));
|
||||
$this->setDefaults([
|
||||
'beginscore' => '0',
|
||||
]);
|
||||
$this->addElement('text', 'beginscore', [get_lang('Between'), null, '%'], [
|
||||
'size' => 5,
|
||||
'maxlength' => 5,
|
||||
'disabled' => 'disabled',
|
||||
'input-size' => 2,
|
||||
]);
|
||||
|
||||
for ($counter = 1; $counter <= 20; $counter++) {
|
||||
$renderer = &$this->defaultRenderer();
|
||||
$elementTemplateTwoLabel =
|
||||
'<div id='.$counter.' style="display: '.(($counter <= $nr_items) ? 'inline' : 'none').';">
|
||||
<!-- BEGIN required --><span class="form_required">*</span> <!-- END required -->
|
||||
<label class="control-label">{label}</label>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">
|
||||
</label>
|
||||
<div class="col-sm-1">
|
||||
<!-- BEGIN error --><span class="form_error">{error}</span><br />
|
||||
<!-- END error --> <b>'.get_lang('And').'</b>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
{element}
|
||||
</div>
|
||||
<div class="col-sm-1">
|
||||
=
|
||||
</div>';
|
||||
|
||||
$elementTemplateTwoLabel2 = '
|
||||
<div class="col-sm-2">
|
||||
<!-- BEGIN error --><span class="form_error">{error}</span>
|
||||
<!-- END error -->
|
||||
{element}
|
||||
</div>
|
||||
<div class="col-sm-1">
|
||||
<a href="javascript:plusItem('.($counter + 1).')">
|
||||
<img style="display: '.(($counter >= $nr_items) ? 'inline' : 'none').';" id="plus-'.($counter + 1).'" src="'.Display::returnIconPath('add.png').'" alt="'.get_lang('Add').'" title="'.get_lang('Add').'"></a>
|
||||
<a href="javascript:minItem('.($counter).')">
|
||||
<img style="display: '.(($counter >= $nr_items && $counter != 1) ? 'inline' : 'none').';" id="min-'.$counter.'" src="'.Display::returnIconPath('delete.png').'" alt="'.get_lang('Delete').'" title="'.get_lang('Delete').'"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'endscore['.$counter.']',
|
||||
null,
|
||||
[
|
||||
'size' => 5,
|
||||
'maxlength' => 5,
|
||||
'id' => 'txta-'.$counter,
|
||||
'input-size' => 2,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'displaytext['.$counter.']',
|
||||
null,
|
||||
[
|
||||
'size' => 40,
|
||||
'maxlength' => 40,
|
||||
'id' => 'txtb-'.$counter,
|
||||
]
|
||||
);
|
||||
$renderer->setElementTemplate($elementTemplateTwoLabel, 'endscore['.$counter.']');
|
||||
$renderer->setElementTemplate($elementTemplateTwoLabel2, 'displaytext['.$counter.']');
|
||||
$this->addRule('endscore['.$counter.']', get_lang('OnlyNumbers'), 'numeric');
|
||||
$this->addRule(['endscore['.$counter.']', 'maxvalue'], get_lang('Over100'), 'compare', '<=');
|
||||
$this->addRule(['endscore['.$counter.']', 'minvalue'], get_lang('UnderMin'), 'compare', '>');
|
||||
}
|
||||
}
|
||||
|
||||
if ($displayscore->is_custom()) {
|
||||
$this->addButtonSave(get_lang('Ok'));
|
||||
}
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
return parent::validate();
|
||||
}
|
||||
}
|
||||
85
main/gradebook/lib/fe/userform.class.php
Normal file
85
main/gradebook/lib/fe/userform.class.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class UserForm
|
||||
* Extends formvalidator with import and export forms.
|
||||
*
|
||||
* @author Stijn Konings
|
||||
*/
|
||||
class UserForm extends FormValidator
|
||||
{
|
||||
public const TYPE_USER_INFO = 1;
|
||||
public const TYPE_SIMPLE_SEARCH = 3;
|
||||
|
||||
/**
|
||||
* Builds a form containing form items based on a given parameter.
|
||||
*
|
||||
* @param int form_type 1 = user_info
|
||||
* @param user array
|
||||
* @param string form name
|
||||
* @param string $method
|
||||
* @param string $action
|
||||
*/
|
||||
public function __construct($form_type, $user, $form_name, $method = 'post', $action = null)
|
||||
{
|
||||
parent::__construct($form_name, $method, $action);
|
||||
$this->form_type = $form_type;
|
||||
if (isset($user)) {
|
||||
$this->user_info = $user;
|
||||
}
|
||||
if (isset($result_object)) {
|
||||
$this->result_object = $result_object;
|
||||
}
|
||||
if (self::TYPE_USER_INFO == $this->form_type) {
|
||||
$this->build_user_info_form();
|
||||
} elseif (self::TYPE_SIMPLE_SEARCH == $this->form_type) {
|
||||
$this->build_simple_search();
|
||||
}
|
||||
$this->setDefaults();
|
||||
}
|
||||
|
||||
public function display()
|
||||
{
|
||||
parent::display();
|
||||
}
|
||||
|
||||
public function setDefaults($defaults = [], $filter = null)
|
||||
{
|
||||
parent::setDefaults($defaults, $filter);
|
||||
}
|
||||
|
||||
protected function build_simple_search()
|
||||
{
|
||||
if (isset($_GET['search']) && (!empty($_GET['search']))) {
|
||||
$this->setDefaults([
|
||||
'keyword' => Security::remove_XSS($_GET['search']),
|
||||
]);
|
||||
}
|
||||
$renderer = &$this->defaultRenderer();
|
||||
$renderer->setCustomElementTemplate('<span>{element}</span> ');
|
||||
$this->addElement('text', 'keyword', '');
|
||||
$this->addButtonSearch(get_lang('Search'), 'submit');
|
||||
}
|
||||
|
||||
protected function build_user_info_form()
|
||||
{
|
||||
if (api_is_western_name_order()) {
|
||||
$this->addElement('static', 'fname', get_lang('FirstName'), $this->user_info['firstname']);
|
||||
$this->addElement('static', 'lname', get_lang('LastName'), $this->user_info['lastname']);
|
||||
} else {
|
||||
$this->addElement('static', 'lname', get_lang('LastName'), $this->user_info['lastname']);
|
||||
$this->addElement('static', 'fname', get_lang('FirstName'), $this->user_info['firstname']);
|
||||
}
|
||||
$this->addElement('static', 'uname', get_lang('UserName'), $this->user_info['username']);
|
||||
$this->addElement(
|
||||
'static',
|
||||
'email',
|
||||
get_lang('Email'),
|
||||
'<a href="mailto:'.$this->user_info['email'].'">'.$this->user_info['email'].'</a>'
|
||||
);
|
||||
$this->addElement('static', 'ofcode', get_lang('OfficialCode'), $this->user_info['official_code']);
|
||||
$this->addElement('static', 'phone', get_lang('Phone'), $this->user_info['phone']);
|
||||
$this->addButtonSave(get_lang('Back'), 'submit');
|
||||
}
|
||||
}
|
||||
141
main/gradebook/lib/fe/usertable.class.php
Normal file
141
main/gradebook/lib/fe/usertable.class.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class UserTable
|
||||
* Table to display flat view of a student's evaluations and links.
|
||||
*
|
||||
* @author Stijn Konings
|
||||
* @author Bert Steppé (refactored, optimised, use of caching, datagenerator class)
|
||||
*/
|
||||
class UserTable extends SortableTable
|
||||
{
|
||||
private $userid;
|
||||
private $datagen;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($userid, $evals = [], $links = [], $addparams = null)
|
||||
{
|
||||
parent::__construct('userlist', null, null, 0);
|
||||
$this->userid = $userid;
|
||||
$this->datagen = new UserDataGenerator($userid, $evals, $links);
|
||||
if (isset($addparams)) {
|
||||
$this->set_additional_parameters($addparams ?: []);
|
||||
}
|
||||
$column = 0;
|
||||
$this->set_header($column++, get_lang('Type'));
|
||||
$this->set_header($column++, get_lang('Evaluation'));
|
||||
$this->set_header($column++, get_lang('Course'));
|
||||
$this->set_header($column++, get_lang('Category'));
|
||||
$this->set_header($column++, get_lang('EvaluationAverage'));
|
||||
$this->set_header($column++, get_lang('Result'));
|
||||
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
if ($scoredisplay->is_custom()) {
|
||||
$this->set_header($column++, get_lang('Display'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used by SortableTable to get total number of items in the table.
|
||||
*/
|
||||
public function get_total_number_of_items()
|
||||
{
|
||||
return $this->datagen->get_total_items_count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used by SortableTable to generate the data to display.
|
||||
*/
|
||||
public function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = null)
|
||||
{
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
|
||||
// determine sorting type
|
||||
switch ($this->column) {
|
||||
// Type
|
||||
case 0:
|
||||
$sorting = UserDataGenerator::UDG_SORT_TYPE;
|
||||
break;
|
||||
case 1:
|
||||
$sorting = UserDataGenerator::UDG_SORT_NAME;
|
||||
break;
|
||||
case 2:
|
||||
$sorting = UserDataGenerator::UDG_SORT_COURSE;
|
||||
break;
|
||||
case 3:
|
||||
$sorting = UserDataGenerator::UDG_SORT_CATEGORY;
|
||||
break;
|
||||
case 4:
|
||||
$sorting = UserDataGenerator::UDG_SORT_AVERAGE;
|
||||
break;
|
||||
case 5:
|
||||
$sorting = UserDataGenerator::UDG_SORT_SCORE;
|
||||
break;
|
||||
case 6:
|
||||
$sorting = UserDataGenerator::UDG_SORT_MASK;
|
||||
break;
|
||||
}
|
||||
if ('DESC' === $this->direction) {
|
||||
$sorting |= UserDataGenerator::UDG_SORT_DESC;
|
||||
} else {
|
||||
$sorting |= UserDataGenerator::UDG_SORT_ASC;
|
||||
}
|
||||
$data_array = $this->datagen->get_data($sorting, $from, $this->per_page);
|
||||
// generate the data to display
|
||||
$sortable_data = [];
|
||||
foreach ($data_array as $data) {
|
||||
if ('' != $data[2]) {
|
||||
// filter by course removed
|
||||
$row = [];
|
||||
$row[] = $this->build_type_column($data[0]);
|
||||
$row[] = $this->build_name_link($data[0]);
|
||||
$row[] = $data[2];
|
||||
$row[] = $data[3];
|
||||
$row[] = $data[4];
|
||||
$row[] = $data[5];
|
||||
if ($scoredisplay->is_custom()) {
|
||||
$row[] = $data[6];
|
||||
}
|
||||
$sortable_data[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $sortable_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_type_column($item)
|
||||
{
|
||||
return GradebookUtils::build_type_icon_tag($item->get_icon_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_name_link($item)
|
||||
{
|
||||
switch ($item->get_item_type()) {
|
||||
// evaluation
|
||||
case 'E':
|
||||
return ' '
|
||||
.'<a href="gradebook_view_result.php?selecteval='.$item->get_id().'&'.api_get_cidreq().'">'
|
||||
.$item->get_name()
|
||||
.'</a>';
|
||||
// link
|
||||
case 'L':
|
||||
return ' <a href="'.$item->get_link().'">'
|
||||
.$item->get_name()
|
||||
.'</a>'
|
||||
.' ['.$item->get_type_name().']';
|
||||
}
|
||||
}
|
||||
}
|
||||
1140
main/gradebook/lib/flatview_data_generator.class.php
Normal file
1140
main/gradebook/lib/flatview_data_generator.class.php
Normal file
File diff suppressed because it is too large
Load Diff
843
main/gradebook/lib/gradebook_data_generator.class.php
Normal file
843
main/gradebook/lib/gradebook_data_generator.class.php
Normal file
@@ -0,0 +1,843 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
/**
|
||||
* Class GradebookDataGenerator
|
||||
* Class to select, sort and transform object data into array data,
|
||||
* used for the general gradebook view.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class GradebookDataGenerator
|
||||
{
|
||||
// Sorting types constants
|
||||
public const GDG_SORT_TYPE = 1;
|
||||
public const GDG_SORT_NAME = 2;
|
||||
public const GDG_SORT_DESCRIPTION = 4;
|
||||
public const GDG_SORT_WEIGHT = 8;
|
||||
public const GDG_SORT_DATE = 16;
|
||||
public const GDG_SORT_ASC = 32;
|
||||
public const GDG_SORT_DESC = 64;
|
||||
public const GDG_SORT_ID = 128;
|
||||
public $userId;
|
||||
public $hidePercentage = false;
|
||||
|
||||
public $items;
|
||||
public $preLoadDataKey;
|
||||
public $exportToPdf;
|
||||
private $evals_links;
|
||||
|
||||
/**
|
||||
* @param array $cats
|
||||
* @param array $evals
|
||||
* @param array $links
|
||||
*/
|
||||
public function __construct($cats = [], $evals = [], $links = [])
|
||||
{
|
||||
$allcats = isset($cats) ? $cats : [];
|
||||
$allevals = isset($evals) ? $evals : [];
|
||||
$alllinks = isset($links) ? $links : [];
|
||||
$this->exportToPdf = false;
|
||||
|
||||
// if we are in the root category and if there are sub categories
|
||||
// display only links depending of the root category and not link that belongs
|
||||
// to a sub category https://support.chamilo.org/issues/6602
|
||||
$tabLinkToDisplay = $alllinks;
|
||||
if (count($allcats) > 0) {
|
||||
// get sub categories id
|
||||
$tabCategories = [];
|
||||
for ($i = 0; $i < count($allcats); $i++) {
|
||||
$tabCategories[] = $allcats[$i]->get_id();
|
||||
}
|
||||
// dont display links that belongs to a sub category
|
||||
$tabLinkToDisplay = [];
|
||||
for ($i = 0; $i < count($alllinks); $i++) {
|
||||
if (!in_array($alllinks[$i]->get_category_id(), $tabCategories)) {
|
||||
$tabLinkToDisplay[] = $alllinks[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// merge categories, evaluations and links
|
||||
$this->items = array_merge($allcats, $allevals, $tabLinkToDisplay);
|
||||
$this->evals_links = array_merge($allevals, $tabLinkToDisplay);
|
||||
$this->userId = api_get_user_id();
|
||||
$this->hidePercentage = api_get_configuration_value('hide_gradebook_percentage_user_result');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total number of items (rows).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_total_items_count()
|
||||
{
|
||||
return count($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get actual array data.
|
||||
*
|
||||
* @param int $count
|
||||
*
|
||||
* @return array 2-dimensional array - each array contains the elements:
|
||||
* 0: cat/eval/link object
|
||||
* 1: item name
|
||||
* 2: description
|
||||
* 3: weight
|
||||
* 4: date
|
||||
* 5: student's score (if student logged in)
|
||||
*/
|
||||
public function get_data(
|
||||
$sorting = 0,
|
||||
$start = 0,
|
||||
$count = null,
|
||||
$ignore_score_color = false,
|
||||
$studentList = [],
|
||||
$loadStats = true
|
||||
) {
|
||||
// do some checks on count, redefine if invalid value
|
||||
if (!isset($count)) {
|
||||
$count = count($this->items) - $start;
|
||||
}
|
||||
if ($count < 0) {
|
||||
$count = 0;
|
||||
}
|
||||
|
||||
$allitems = $this->items;
|
||||
usort($allitems, ['GradebookDataGenerator', 'sort_by_name']);
|
||||
$userId = $this->userId;
|
||||
$visibleItems = array_slice($allitems, $start, $count);
|
||||
$userCount = !empty($studentList) ? count($studentList) : 0;
|
||||
// Generate the data to display
|
||||
$data = [];
|
||||
$allowStats = api_get_configuration_value('allow_gradebook_stats');
|
||||
$scoreDisplay = ScoreDisplay::instance();
|
||||
$defaultData = Session::read($this->preLoadDataKey);
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
$useExerciseScoreInTotal = api_get_configuration_value('gradebook_use_exercise_score_settings_in_total');
|
||||
|
||||
/** @var GradebookItem $item */
|
||||
foreach ($visibleItems as $item) {
|
||||
$row = [];
|
||||
$row[] = $item;
|
||||
$row[] = Security::remove_XSS($item->get_name());
|
||||
// display the 2 first line of description and all description
|
||||
// on mouseover (https://support.chamilo.org/issues/6588)
|
||||
$row[] = '<span title="'.api_remove_tags_with_space($item->get_description()).'">'.
|
||||
api_get_short_text_from_html($item->get_description(), 160).'</span>';
|
||||
$row[] = $item->get_weight();
|
||||
$item->setStudentList($studentList);
|
||||
$itemType = get_class($item);
|
||||
|
||||
switch ($itemType) {
|
||||
case 'Evaluation':
|
||||
// Items inside a category.
|
||||
$resultColumn = $this->build_result_column(
|
||||
$userId,
|
||||
$item,
|
||||
$ignore_score_color,
|
||||
false,
|
||||
$useExerciseScoreInTotal
|
||||
);
|
||||
$row[] = $resultColumn['display'];
|
||||
$row['result_score'] = $resultColumn['score'];
|
||||
$row['result_score_weight'] = $resultColumn['score_weight'];
|
||||
|
||||
// Best
|
||||
if (isset($defaultData[$item->get_id()]) && isset($defaultData[$item->get_id()]['best'])) {
|
||||
$best = $defaultData[$item->get_id()]['best'];
|
||||
} else {
|
||||
$best = $this->buildBestResultColumn($item, $useExerciseScoreInTotal);
|
||||
}
|
||||
|
||||
if (empty($model)) {
|
||||
$row['best'] = $best['display'];
|
||||
$row['best_score'] = $best['score'];
|
||||
// Average
|
||||
if (isset($defaultData[$item->get_id()]) && isset($defaultData[$item->get_id()]['average'])) {
|
||||
$average = $defaultData[$item->get_id()]['average'];
|
||||
} else {
|
||||
$average = $this->buildBestResultColumn($item, $useExerciseScoreInTotal);
|
||||
}
|
||||
|
||||
$row['average'] = $average['display'];
|
||||
$row['average_score'] = $average['score'];
|
||||
|
||||
// Ranking
|
||||
$ranking = $this->buildRankingColumn($item, $userId, $userCount);
|
||||
$row['ranking'] = $ranking['display'];
|
||||
$row['ranking_score'] = $ranking['score'];
|
||||
}
|
||||
$row[] = $item;
|
||||
break;
|
||||
case 'ExerciseLink':
|
||||
/** @var ExerciseLink $item */
|
||||
// Category.
|
||||
$result = $this->build_result_column(
|
||||
$userId,
|
||||
$item,
|
||||
$ignore_score_color,
|
||||
true,
|
||||
$useExerciseScoreInTotal
|
||||
);
|
||||
$row[] = $result['display'];
|
||||
$row['result_score'] = $result['score'];
|
||||
$row['result_score_weight'] = $result['score'];
|
||||
|
||||
if (empty($model)) {
|
||||
// Best
|
||||
if (isset($defaultData[$item->get_id()]) && isset($defaultData[$item->get_id()]['best'])) {
|
||||
$best = $defaultData[$item->get_id()]['best'];
|
||||
} else {
|
||||
$best = $this->buildBestResultColumn($item);
|
||||
}
|
||||
|
||||
$row['best'] = $best['display'];
|
||||
$row['best_score'] = $best['score'];
|
||||
|
||||
$rankingStudentList = [];
|
||||
$invalidateResults = false;
|
||||
// Average
|
||||
if (isset($defaultData[$item->get_id()]) && isset($defaultData[$item->get_id()]['average'])) {
|
||||
$average = $defaultData[$item->get_id()]['average'];
|
||||
} else {
|
||||
$average = $this->buildAverageResultColumn($item);
|
||||
}
|
||||
|
||||
$row['average'] = $average['display'];
|
||||
$row['average_score'] = $average['score'];
|
||||
|
||||
// Ranking.
|
||||
if ($allowStats) {
|
||||
// Ranking
|
||||
if (isset($defaultData[$item->get_id()]) &&
|
||||
isset($defaultData[$item->get_id()]['ranking'])
|
||||
) {
|
||||
$rankingStudentList = $defaultData[$item->get_id()]['ranking'];
|
||||
$invalidateResults = $defaultData[$item->get_id()]['ranking_invalidate'];
|
||||
$score = AbstractLink::getCurrentUserRanking($userId, $rankingStudentList);
|
||||
} else {
|
||||
if (!empty($studentList)) {
|
||||
foreach ($studentList as $user) {
|
||||
$score = $this->build_result_column(
|
||||
$user['user_id'],
|
||||
$item,
|
||||
$ignore_score_color,
|
||||
true
|
||||
);
|
||||
if (!empty($score['score'][0])) {
|
||||
$invalidateResults = false;
|
||||
}
|
||||
$rankingStudentList[$user['user_id']] = $score['score'][0];
|
||||
}
|
||||
$defaultData[$item->get_id()]['ranking'] = $rankingStudentList;
|
||||
$defaultData[$item->get_id()]['ranking_invalidate'] = $invalidateResults;
|
||||
Session::write($this->preLoadDataKey, $defaultData);
|
||||
}
|
||||
$score = AbstractLink::getCurrentUserRanking($userId, $rankingStudentList);
|
||||
}
|
||||
} else {
|
||||
if (!empty($studentList)) {
|
||||
$session_id = api_get_session_id();
|
||||
$evals = [];
|
||||
$links = [];
|
||||
if ('C' === $item->get_item_type()) {
|
||||
$evals = $item->get_evaluations(null);
|
||||
$links = $item->get_links(null);
|
||||
|
||||
foreach ($studentList as $user) {
|
||||
$ressum = 0;
|
||||
$weightsum = 0;
|
||||
$bestResult = 0;
|
||||
if (!empty($evals)) {
|
||||
foreach ($evals as $eval) {
|
||||
$evalres = $eval->calc_score($user['user_id'], null);
|
||||
$eval->setStudentList($studentList);
|
||||
|
||||
if (isset($evalres) && 0 != $eval->get_weight()) {
|
||||
$evalweight = $eval->get_weight();
|
||||
$weightsum += $evalweight;
|
||||
if (!empty($evalres[1])) {
|
||||
$ressum += $evalres[0] / $evalres[1] * $evalweight;
|
||||
}
|
||||
|
||||
if ($ressum > $bestResult) {
|
||||
$bestResult = $ressum;
|
||||
}
|
||||
} else {
|
||||
if (0 != $eval->get_weight()) {
|
||||
$evalweight = $eval->get_weight();
|
||||
$weightsum += $evalweight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($links)) {
|
||||
foreach ($links as $link) {
|
||||
$link->setStudentList($studentList);
|
||||
if ($session_id) {
|
||||
$link->set_session_id($session_id);
|
||||
}
|
||||
$linkres = $link->calc_score($user['user_id'], null);
|
||||
if (!empty($linkres) && 0 != $link->get_weight()) {
|
||||
$linkweight = $link->get_weight();
|
||||
$link_res_denom = 0 == $linkres[1] ? 1 : $linkres[1];
|
||||
|
||||
$weightsum += $linkweight;
|
||||
$ressum += $linkres[0] / $link_res_denom * $linkweight;
|
||||
if ($ressum > $bestResult) {
|
||||
$bestResult = $ressum;
|
||||
}
|
||||
} else {
|
||||
// Adding if result does not exists
|
||||
if (0 != $link->get_weight()) {
|
||||
$linkweight = $link->get_weight();
|
||||
$weightsum += $linkweight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($ressum)) {
|
||||
$invalidateResults = false;
|
||||
}
|
||||
$rankingStudentList[$user['user_id']] = $ressum;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($rankingStudentList)) {
|
||||
foreach ($studentList as $user) {
|
||||
$score = $this->build_result_column(
|
||||
$user['user_id'],
|
||||
$item,
|
||||
$ignore_score_color,
|
||||
true
|
||||
);
|
||||
if (!empty($score['score'][0])) {
|
||||
$invalidateResults = false;
|
||||
}
|
||||
|
||||
$rankingStudentList[$user['user_id']] = 0;
|
||||
if ($score['score']) {
|
||||
$rankingStudentList[$user['user_id']] = $score['score'][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$score = AbstractLink::getCurrentUserRanking($userId, $rankingStudentList);
|
||||
}
|
||||
|
||||
$row['ranking'] = $scoreDisplay->display_score(
|
||||
$score,
|
||||
SCORE_DIV,
|
||||
SCORE_BOTH,
|
||||
true,
|
||||
true
|
||||
);
|
||||
if ($invalidateResults) {
|
||||
$row['ranking'] = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Category.
|
||||
$result = $this->build_result_column(
|
||||
$userId,
|
||||
$item,
|
||||
$ignore_score_color,
|
||||
true,
|
||||
$useExerciseScoreInTotal
|
||||
);
|
||||
$row[] = $result['display'];
|
||||
$row['result_score'] = $result['score'];
|
||||
$row['result_score_weight'] = $result['score'];
|
||||
$showPercentage = true;
|
||||
if ($this->hidePercentage) {
|
||||
$showPercentage = false;
|
||||
}
|
||||
|
||||
if (empty($model)) {
|
||||
// Best
|
||||
if (isset($defaultData[$item->get_id()]) && isset($defaultData[$item->get_id()]['best'])) {
|
||||
$best = $defaultData[$item->get_id()]['best'];
|
||||
if ($useExerciseScoreInTotal) {
|
||||
$bestScore = $best['score'];
|
||||
$best['display'] = ExerciseLib::show_score($bestScore[0], $bestScore[1], $showPercentage);
|
||||
} else {
|
||||
$best = $defaultData[$item->get_id()]['best'];
|
||||
}
|
||||
} else {
|
||||
$best = $this->buildBestResultColumn($item, $useExerciseScoreInTotal);
|
||||
}
|
||||
|
||||
$row['best'] = $best['display'];
|
||||
$row['best_score'] = $best['score'];
|
||||
$rankingStudentList = [];
|
||||
$invalidateResults = true;
|
||||
// Average
|
||||
if (isset($defaultData[$item->get_id()]) && isset($defaultData[$item->get_id()]['average'])) {
|
||||
$average = $defaultData[$item->get_id()]['average'];
|
||||
if ($useExerciseScoreInTotal) {
|
||||
$averageScore = $average['score'];
|
||||
$average['display'] = ExerciseLib::show_score($averageScore[0], $averageScore[1], $showPercentage);
|
||||
}
|
||||
} else {
|
||||
$average = $this->buildAverageResultColumn($item, $useExerciseScoreInTotal);
|
||||
}
|
||||
$row['average'] = $average['display'];
|
||||
$row['average_score'] = $average['score'];
|
||||
|
||||
// Ranking
|
||||
if (isset($defaultData[$item->get_id()]) && isset($defaultData[$item->get_id()]['ranking'])) {
|
||||
$rankingStudentList = $defaultData[$item->get_id()]['ranking'];
|
||||
$invalidateResults = $defaultData[$item->get_id()]['ranking_invalidate'];
|
||||
$invalidateResults = false;
|
||||
$score = AbstractLink::getCurrentUserRanking($userId, $rankingStudentList);
|
||||
} else {
|
||||
if (!empty($studentList)) {
|
||||
foreach ($studentList as $user) {
|
||||
$score = $this->build_result_column(
|
||||
$user['user_id'],
|
||||
$item,
|
||||
$ignore_score_color,
|
||||
true
|
||||
);
|
||||
if (!empty($score['score'][0])) {
|
||||
$invalidateResults = false;
|
||||
}
|
||||
$rankingStudentList[$user['user_id']] = $score['score'][0];
|
||||
}
|
||||
}
|
||||
$score = AbstractLink::getCurrentUserRanking($userId, $rankingStudentList);
|
||||
}
|
||||
|
||||
$row['ranking'] = $scoreDisplay->display_score(
|
||||
$score,
|
||||
SCORE_DIV,
|
||||
SCORE_BOTH,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
if ($invalidateResults) {
|
||||
$row['ranking'] = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
$data[] = $row;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the link to the certificate generation, if the score is enough, otherwise
|
||||
* returns an empty string. This only works with categories.
|
||||
*
|
||||
* @param object Item
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_certificate_link($item)
|
||||
{
|
||||
if (is_a($item, 'Category')) {
|
||||
if ($item->is_certificate_available(api_get_user_id())) {
|
||||
$link = '<a
|
||||
href="'.Category::getUrl().'export_certificate=1&cat='.$item->get_id().'&user='.api_get_user_id().'">'.
|
||||
get_lang('Certificate').'</a>';
|
||||
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GradebookItem $item1
|
||||
* @param GradebookItem $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function sort_by_name($item1, $item2)
|
||||
{
|
||||
return api_strnatcmp($item1->get_name(), $item2->get_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GradebookItem $item1
|
||||
* @param GradebookItem $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_id($item1, $item2)
|
||||
{
|
||||
return api_strnatcmp($item1->get_id(), $item2->get_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GradebookItem $item1
|
||||
* @param GradebookItem $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_type($item1, $item2)
|
||||
{
|
||||
if ($item1->get_item_type() == $item2->get_item_type()) {
|
||||
return $this->sort_by_name($item1, $item2);
|
||||
}
|
||||
|
||||
return $item1->get_item_type() < $item2->get_item_type() ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GradebookItem $item1
|
||||
* @param GradebookItem $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_description($item1, $item2)
|
||||
{
|
||||
$result = api_strcmp($item1->get_description(), $item2->get_description());
|
||||
if (0 == $result) {
|
||||
return $this->sort_by_name($item1, $item2);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GradebookItem $item1
|
||||
* @param GradebookItem $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_weight($item1, $item2)
|
||||
{
|
||||
if ($item1->get_weight() == $item2->get_weight()) {
|
||||
return $this->sort_by_name($item1, $item2);
|
||||
}
|
||||
|
||||
return $item1->get_weight() < $item2->get_weight() ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GradebookItem $item1
|
||||
* @param GradebookItem $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_date($item1, $item2)
|
||||
{
|
||||
if (is_int($item1->get_date())) {
|
||||
$timestamp1 = $item1->get_date();
|
||||
} else {
|
||||
$date = $item1->get_date();
|
||||
if (!empty($date)) {
|
||||
$timestamp1 = api_strtotime($date, 'UTC');
|
||||
} else {
|
||||
$timestamp1 = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_int($item2->get_date())) {
|
||||
$timestamp2 = $item2->get_date();
|
||||
} else {
|
||||
$timestamp2 = api_strtotime($item2->get_date(), 'UTC');
|
||||
}
|
||||
|
||||
if ($timestamp1 == $timestamp2) {
|
||||
return $this->sort_by_name($item1, $item2);
|
||||
}
|
||||
|
||||
return $timestamp1 < $timestamp2 ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get best result of an item.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildBestResultColumn(GradebookItem $item, $userExerciseSettings = false)
|
||||
{
|
||||
$score = $item->calc_score(
|
||||
null,
|
||||
'best',
|
||||
api_get_course_id(),
|
||||
api_get_session_id()
|
||||
);
|
||||
|
||||
if (empty($score)) {
|
||||
return [
|
||||
'display' => '',
|
||||
'score' => '',
|
||||
];
|
||||
}
|
||||
|
||||
$scoreMode = SCORE_DIV_PERCENT_WITH_CUSTOM;
|
||||
$showPercentage = true;
|
||||
if ($this->hidePercentage) {
|
||||
$scoreMode = SCORE_DIV;
|
||||
$showPercentage = false;
|
||||
}
|
||||
$scoreDisplay = ScoreDisplay::instance();
|
||||
$display = $scoreDisplay->display_score(
|
||||
$score,
|
||||
$scoreMode,
|
||||
SCORE_BOTH,
|
||||
true,
|
||||
false,
|
||||
true
|
||||
);
|
||||
$type = $item->get_item_type();
|
||||
if ('L' === $type && 'ExerciseLink' === get_class($item)) {
|
||||
$display = ExerciseLib::show_score(
|
||||
$score[0],
|
||||
$score[1],
|
||||
$showPercentage
|
||||
);
|
||||
}
|
||||
|
||||
if ($userExerciseSettings) {
|
||||
$display = ExerciseLib::show_score(
|
||||
$score[0],
|
||||
$score[1],
|
||||
$showPercentage
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
'display' => $display,
|
||||
'score' => $score,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function buildAverageResultColumn(GradebookItem $item, $userExerciseSettings = false)
|
||||
{
|
||||
$score = $item->calc_score(null, 'average');
|
||||
|
||||
if (empty($score)) {
|
||||
return [
|
||||
'display' => '',
|
||||
'score' => '',
|
||||
];
|
||||
}
|
||||
|
||||
$scoreDisplay = ScoreDisplay::instance();
|
||||
|
||||
$scoreMode = SCORE_DIV_PERCENT_WITH_CUSTOM;
|
||||
$showPercentage = true;
|
||||
if ($this->hidePercentage) {
|
||||
$scoreMode = SCORE_DIV;
|
||||
$showPercentage = false;
|
||||
}
|
||||
|
||||
$display = $scoreDisplay->display_score(
|
||||
$score,
|
||||
$scoreMode,
|
||||
SCORE_BOTH,
|
||||
true,
|
||||
false,
|
||||
true
|
||||
);
|
||||
$type = $item->get_item_type();
|
||||
|
||||
if ('L' === $type && 'ExerciseLink' === get_class($item)) {
|
||||
$display = ExerciseLib::show_score($score[0], $score[1], $showPercentage);
|
||||
$result = ExerciseLib::convertScoreToPlatformSetting($score[0], $score[1]);
|
||||
$score[0] = $result['score'];
|
||||
$score[1] = $result['weight'];
|
||||
} else {
|
||||
if ($userExerciseSettings) {
|
||||
$display = ExerciseLib::show_score(
|
||||
$score[0],
|
||||
$score[1],
|
||||
$showPercentage
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'display' => $display,
|
||||
'score' => $score,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int $userCount
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildRankingColumn(GradebookItem $item, $userId = null, $userCount = 0)
|
||||
{
|
||||
$score = $item->calc_score($userId, 'ranking');
|
||||
$score[1] = $userCount;
|
||||
$scoreDisplay = null;
|
||||
if (isset($score[0])) {
|
||||
$scoreDisplay = ScoreDisplay::instance();
|
||||
$scoreDisplay = $scoreDisplay->display_score(
|
||||
$score,
|
||||
SCORE_DIV,
|
||||
SCORE_BOTH,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
'display' => $scoreDisplay,
|
||||
'score' => $score,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param GradebookItem $item
|
||||
* @param bool $ignore_score_color
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function build_result_column(
|
||||
$userId,
|
||||
$item,
|
||||
$ignore_score_color,
|
||||
$forceSimpleResult = false,
|
||||
$useExerciseScoreInTotal = false
|
||||
) {
|
||||
$scoreDisplay = ScoreDisplay::instance();
|
||||
$score = $item->calc_score($userId);
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
if (!empty($score)) {
|
||||
switch ($item->get_item_type()) {
|
||||
// category
|
||||
case 'C':
|
||||
if (null != $score) {
|
||||
if (empty($model)) {
|
||||
if ($useExerciseScoreInTotal) {
|
||||
$display = ExerciseLib::show_score($score[0], $score[1], false);
|
||||
} else {
|
||||
$display = $scoreDisplay->display_score(
|
||||
$score,
|
||||
SCORE_DIV,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
'display' => $display,
|
||||
'score' => $score,
|
||||
'score_weight' => $score,
|
||||
];
|
||||
} else {
|
||||
$display = ExerciseLib::show_score(
|
||||
$score[0],
|
||||
$score[1],
|
||||
false
|
||||
);
|
||||
|
||||
return [
|
||||
'display' => $display,
|
||||
'score' => $score,
|
||||
'score_weight' => $score,
|
||||
];
|
||||
}
|
||||
} else {
|
||||
return [
|
||||
'display' => null,
|
||||
'score' => $score,
|
||||
'score_weight' => $score,
|
||||
];
|
||||
}
|
||||
break;
|
||||
case 'E':
|
||||
case 'L':
|
||||
$scoreWeight = [
|
||||
($score[1] > 0) ? $score[0] / $score[1] * $item->get_weight() : 0,
|
||||
$item->get_weight(),
|
||||
];
|
||||
|
||||
if (empty($model)) {
|
||||
if ($useExerciseScoreInTotal) {
|
||||
$display = ExerciseLib::show_score($score[0], $score[1], false);
|
||||
} else {
|
||||
$display = $scoreDisplay->display_score(
|
||||
$score,
|
||||
SCORE_DIV_PERCENT_WITH_CUSTOM,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
/*$type = $item->get_item_type();
|
||||
if ('L' === $type && 'ExerciseLink' === get_class($item)) {
|
||||
$display = ExerciseLib::show_score(
|
||||
$score[0],
|
||||
$score[1],
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}*/
|
||||
} else {
|
||||
$display = ExerciseLib::show_score(
|
||||
$score[0],
|
||||
$score[1],
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
'display' => $display,
|
||||
'score' => $score,
|
||||
'score_weight' => $scoreWeight,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'display' => null,
|
||||
'score' => null,
|
||||
'score_weight' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GradebookItem $item
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_date_column($item)
|
||||
{
|
||||
$date = $item->get_date();
|
||||
if (!isset($date) || empty($date)) {
|
||||
return '';
|
||||
} else {
|
||||
if (is_int($date)) {
|
||||
return api_convert_and_format_date($date);
|
||||
}
|
||||
|
||||
return api_format_date($date);
|
||||
}
|
||||
}
|
||||
}
|
||||
171
main/gradebook/lib/gradebook_result.class.php
Normal file
171
main/gradebook/lib/gradebook_result.class.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Gradebook results class.
|
||||
*
|
||||
* @author Yannick Warnier
|
||||
*/
|
||||
class GradeBookResult
|
||||
{
|
||||
private $gradebook_list = []; //stores the list of exercises
|
||||
private $results = []; //stores the results
|
||||
|
||||
/**
|
||||
* constructor of the class.
|
||||
*/
|
||||
public function __construct($get_questions = false, $get_answers = false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the complete report as a CSV file.
|
||||
*
|
||||
* @param string $dato Document path inside the document tool
|
||||
*
|
||||
* @return bool False on error
|
||||
*/
|
||||
public function exportCompleteReportCSV($dato)
|
||||
{
|
||||
$filename = 'gradebook_results_'.gmdate('YmdGis').'.csv';
|
||||
$data = '';
|
||||
foreach ($dato[0] as $header_col) {
|
||||
if (!empty($header_col)) {
|
||||
if (is_array($header_col)) {
|
||||
if (isset($header_col['header'])) {
|
||||
$data .= str_replace(
|
||||
"\r\n",
|
||||
' ',
|
||||
api_html_entity_decode(strip_tags($header_col['header']))
|
||||
).';';
|
||||
}
|
||||
} else {
|
||||
$data .= str_replace("\r\n", ' ', api_html_entity_decode(strip_tags($header_col))).';';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$data .= "\r\n";
|
||||
$cant_students = count($dato[1]);
|
||||
for ($i = 0; $i < $cant_students; $i++) {
|
||||
foreach ($dato[1][$i] as $col_name) {
|
||||
$data .= str_replace("\r\n", ' ', api_html_entity_decode(strip_tags($col_name))).';';
|
||||
}
|
||||
$data .= "\r\n";
|
||||
}
|
||||
|
||||
// output the results
|
||||
$len = strlen($data);
|
||||
header('Content-type: application/octet-stream');
|
||||
header('Content-Type: application/force-download');
|
||||
header('Content-length: '.$len);
|
||||
if (preg_match("/MSIE 5.5/", $_SERVER['HTTP_USER_AGENT'])) {
|
||||
header('Content-Disposition: filename= '.$filename);
|
||||
} else {
|
||||
header('Content-Disposition: attachment; filename= '.$filename);
|
||||
}
|
||||
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
|
||||
header('Pragma: ');
|
||||
header('Cache-Control: ');
|
||||
header('Cache-Control: public'); // IE cannot download from sessions without a cache
|
||||
}
|
||||
header('Content-Description: '.$filename);
|
||||
header('Content-transfer-encoding: binary');
|
||||
echo $data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the complete report as an XLS file.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @throws PHPExcel_Exception
|
||||
* @throws PHPExcel_Writer_Exception
|
||||
*/
|
||||
public function exportCompleteReportXLS($data)
|
||||
{
|
||||
$filename = 'gradebook-results-'.api_get_local_time().'.xlsx';
|
||||
|
||||
$spreadsheet = new PHPExcel();
|
||||
$spreadsheet->setActiveSheetIndex(0);
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$line = 1;
|
||||
$column = 0;
|
||||
// headers.
|
||||
foreach ($data[0] as $headerData) {
|
||||
$title = $headerData;
|
||||
if (isset($headerData['header'])) {
|
||||
$title = $headerData['header'];
|
||||
}
|
||||
$title = html_entity_decode(strip_tags($title));
|
||||
$worksheet->SetCellValueByColumnAndRow(
|
||||
$column,
|
||||
$line,
|
||||
$title
|
||||
);
|
||||
$column++;
|
||||
}
|
||||
$line++;
|
||||
$cant_students = count($data[1]);
|
||||
for ($i = 0; $i < $cant_students; $i++) {
|
||||
$column = 0;
|
||||
foreach ($data[1][$i] as $col_name) {
|
||||
$worksheet->SetCellValueByColumnAndRow(
|
||||
$column,
|
||||
$line,
|
||||
html_entity_decode(strip_tags($col_name))
|
||||
);
|
||||
$column++;
|
||||
}
|
||||
$line++;
|
||||
}
|
||||
|
||||
$file = api_get_path(SYS_ARCHIVE_PATH).api_replace_dangerous_char($filename);
|
||||
$writer = new PHPExcel_Writer_Excel2007($spreadsheet);
|
||||
$writer->save($file);
|
||||
DocumentManager::file_send_for_download($file, true, $filename);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the complete report as a DOCX file.
|
||||
*
|
||||
* @param array $data The table data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exportCompleteReportDOC($data)
|
||||
{
|
||||
$filename = 'gradebook_results_'.api_get_local_time().'.docx';
|
||||
|
||||
$doc = new \PhpOffice\PhpWord\PhpWord();
|
||||
$section = $doc->addSection(['orientation' => 'landscape']);
|
||||
$table = $section->addTable();
|
||||
$table->addRow();
|
||||
|
||||
for ($i = 0; $i < count($data[0]); $i++) {
|
||||
$title = $data[0][$i];
|
||||
if (isset($data[0][$i]['header'])) {
|
||||
$title = $data[0][$i]['header'];
|
||||
}
|
||||
$title = strip_tags($title);
|
||||
$table->addCell(1750)->addText($title);
|
||||
}
|
||||
|
||||
foreach ($data[1] as $dataLine) {
|
||||
$table->addRow();
|
||||
for ($i = 0; $i < count($dataLine); $i++) {
|
||||
$table->addCell(1750)->addText(strip_tags($dataLine[$i]));
|
||||
}
|
||||
}
|
||||
|
||||
$file = api_get_path(SYS_ARCHIVE_PATH).api_replace_dangerous_char($filename);
|
||||
$doc->save($file, 'Word2007');
|
||||
|
||||
DocumentManager::file_send_for_download($file, true, $filename);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
7
main/gradebook/lib/index.html
Normal file
7
main/gradebook/lib/index.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; url=../gradebook.php">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
231
main/gradebook/lib/results_data_generator.class.php
Normal file
231
main/gradebook/lib/results_data_generator.class.php
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* ResultsDataGenerator Class
|
||||
* Class to select, sort and transform object data into array data,
|
||||
* used for the teacher's evaluation results view.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class ResultsDataGenerator
|
||||
{
|
||||
// Sorting types constants
|
||||
public const RDG_SORT_LASTNAME = 1;
|
||||
public const RDG_SORT_FIRSTNAME = 2;
|
||||
public const RDG_SORT_SCORE = 4;
|
||||
public const RDG_SORT_MASK = 8;
|
||||
|
||||
public const RDG_SORT_ASC = 16;
|
||||
public const RDG_SORT_DESC = 32;
|
||||
private $evaluation;
|
||||
private $results;
|
||||
private $is_course_ind;
|
||||
private $include_edit;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
$evaluation,
|
||||
$results = [],
|
||||
$include_edit = false
|
||||
) {
|
||||
$this->evaluation = $evaluation;
|
||||
$this->results = isset($results) ? $results : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total number of results (rows).
|
||||
*/
|
||||
public function get_total_results_count()
|
||||
{
|
||||
return count($this->results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get actual array data.
|
||||
*
|
||||
* @param int $count
|
||||
*
|
||||
* @return array 2-dimensional array - each array contains the elements:
|
||||
* 0 ['id'] : user id
|
||||
* 1 ['result_id'] : result id
|
||||
* 2 ['lastname'] : user lastname
|
||||
* 3 ['firstname'] : user firstname
|
||||
* 4 ['score'] : student's score
|
||||
* 5 ['display'] : custom score display (only if custom scoring enabled)
|
||||
*/
|
||||
public function get_data(
|
||||
$sorting = 0,
|
||||
$start = 0,
|
||||
$count = null,
|
||||
$ignore_score_color = false,
|
||||
$pdf = false
|
||||
) {
|
||||
// do some checks on count, redefine if invalid value
|
||||
$number_decimals = api_get_setting('gradebook_number_decimals');
|
||||
if (!isset($count)) {
|
||||
$count = count($this->results) - $start;
|
||||
}
|
||||
if ($count < 0) {
|
||||
$count = 0;
|
||||
}
|
||||
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
|
||||
$scoreDisplay = ScoreDisplay::instance();
|
||||
// generate actual data array
|
||||
$table = [];
|
||||
foreach ($this->results as $result) {
|
||||
$user = [];
|
||||
$info = api_get_user_info($result->get_user_id());
|
||||
$user['id'] = $result->get_user_id();
|
||||
if ($pdf) {
|
||||
$user['username'] = $info['username'];
|
||||
}
|
||||
$user['result_id'] = $result->get_id();
|
||||
$user['lastname'] = $info['lastname'];
|
||||
$user['firstname'] = $info['firstname'];
|
||||
if ($pdf) {
|
||||
$user['score'] = $result->get_score();
|
||||
} else {
|
||||
$user['score'] = $this->get_score_display(
|
||||
$result->get_score(),
|
||||
true,
|
||||
$ignore_score_color
|
||||
);
|
||||
}
|
||||
|
||||
$user['percentage_score'] = (int) $scoreDisplay->display_score(
|
||||
[$result->get_score(), $this->evaluation->get_max()],
|
||||
SCORE_PERCENT,
|
||||
SCORE_BOTH,
|
||||
true
|
||||
);
|
||||
|
||||
if ($pdf && null == $number_decimals) {
|
||||
$user['scoreletter'] = $result->get_score();
|
||||
}
|
||||
if ($scoreDisplay->is_custom()) {
|
||||
$user['display'] = $this->get_score_display(
|
||||
$result->get_score(),
|
||||
false,
|
||||
$ignore_score_color
|
||||
);
|
||||
if (!empty($model)) {
|
||||
$user['display'] .= ' '.
|
||||
ExerciseLib::show_score(
|
||||
$result->get_score(),
|
||||
$this->evaluation->get_max()
|
||||
)
|
||||
;
|
||||
}
|
||||
}
|
||||
$table[] = $user;
|
||||
}
|
||||
|
||||
// sort array
|
||||
if ($sorting & self::RDG_SORT_LASTNAME) {
|
||||
usort($table, ['ResultsDataGenerator', 'sort_by_last_name']);
|
||||
} elseif ($sorting & self::RDG_SORT_FIRSTNAME) {
|
||||
usort($table, ['ResultsDataGenerator', 'sort_by_first_name']);
|
||||
} elseif ($sorting & self::RDG_SORT_SCORE) {
|
||||
usort($table, ['ResultsDataGenerator', 'sort_by_score']);
|
||||
} elseif ($sorting & self::RDG_SORT_MASK) {
|
||||
usort($table, ['ResultsDataGenerator', 'sort_by_mask']);
|
||||
}
|
||||
if ($sorting & self::RDG_SORT_DESC) {
|
||||
$table = array_reverse($table);
|
||||
}
|
||||
$return = array_slice($table, $start, $count);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
// Sort functions - used internally
|
||||
|
||||
/**
|
||||
* @param array $item1
|
||||
* @param array $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_last_name($item1, $item2)
|
||||
{
|
||||
return api_strcmp($item1['lastname'], $item2['lastname']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $item1
|
||||
* @param array $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_first_name($item1, $item2)
|
||||
{
|
||||
return api_strcmp($item1['firstname'], $item2['firstname']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $item1
|
||||
* @param array $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_score($item1, $item2)
|
||||
{
|
||||
if ($item1['percentage_score'] == $item2['percentage_score']) {
|
||||
return 0;
|
||||
} else {
|
||||
return $item1['percentage_score'] < $item2['percentage_score'] ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $item1
|
||||
* @param array $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_mask($item1, $item2)
|
||||
{
|
||||
$score1 = (isset($item1['score']) ? [$item1['score'], $this->evaluation->get_max()] : null);
|
||||
$score2 = (isset($item2['score']) ? [$item2['score'], $this->evaluation->get_max()] : null);
|
||||
|
||||
return ScoreDisplay::compare_scores_by_custom_display($score1, $score2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-formats the score to show percentage ("2/4 (50 %)") or letters ("A").
|
||||
*
|
||||
* @param float Current absolute score (max score is taken from $this->evaluation->get_max()
|
||||
* @param bool Whether we want the real score (2/4 (50 %)) or the transformation (A, B, C, etc)
|
||||
* @param bool Whether we want to ignore the score color
|
||||
* @param bool $realscore
|
||||
*
|
||||
* @return string The score as we want to show it
|
||||
*/
|
||||
private function get_score_display(
|
||||
$score,
|
||||
$realscore,
|
||||
$ignore_score_color = false
|
||||
) {
|
||||
if (null != $score) {
|
||||
$scoreDisplay = ScoreDisplay::instance();
|
||||
$type = SCORE_CUSTOM;
|
||||
if (true === $realscore) {
|
||||
$type = SCORE_DIV_PERCENT;
|
||||
}
|
||||
|
||||
return $scoreDisplay->display_score(
|
||||
[$score, $this->evaluation->get_max()],
|
||||
$type,
|
||||
SCORE_BOTH,
|
||||
$ignore_score_color
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
679
main/gradebook/lib/scoredisplay.class.php
Normal file
679
main/gradebook/lib/scoredisplay.class.php
Normal file
@@ -0,0 +1,679 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class ScoreDisplay
|
||||
* Display scores according to the settings made by the platform admin.
|
||||
* This class works as a singleton: call instance() to retrieve an object.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class ScoreDisplay
|
||||
{
|
||||
private $coloring_enabled;
|
||||
private $color_split_value;
|
||||
private $custom_enabled;
|
||||
private $upperlimit_included;
|
||||
private $custom_display;
|
||||
private $custom_display_conv;
|
||||
|
||||
/**
|
||||
* Protected constructor - call instance() to instantiate.
|
||||
*
|
||||
* @param int $category_id
|
||||
*/
|
||||
public function __construct($category_id = 0)
|
||||
{
|
||||
if (!empty($category_id)) {
|
||||
$this->category_id = $category_id;
|
||||
}
|
||||
|
||||
// Loading portal settings + using standard functions.
|
||||
$value = api_get_setting('gradebook_score_display_coloring');
|
||||
$value = $value['my_display_coloring'];
|
||||
|
||||
// Setting coloring.
|
||||
$this->coloring_enabled = $value === 'true' ? true : false;
|
||||
|
||||
if ($this->coloring_enabled) {
|
||||
$value = api_get_setting('gradebook_score_display_colorsplit');
|
||||
if (isset($value)) {
|
||||
$this->color_split_value = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting custom enabled
|
||||
$value = api_get_setting('gradebook_score_display_custom');
|
||||
$value = $value['my_display_custom'];
|
||||
$this->custom_enabled = $value === 'true' ? true : false;
|
||||
|
||||
if ($this->custom_enabled) {
|
||||
$params = ['category = ?' => ['Gradebook']];
|
||||
$displays = api_get_settings_params($params);
|
||||
$portal_displays = [];
|
||||
if (!empty($displays)) {
|
||||
foreach ($displays as $display) {
|
||||
$data = explode('::', $display['selected_value']);
|
||||
if (empty($data[1])) {
|
||||
$data[1] = '';
|
||||
}
|
||||
$portal_displays[$data[0]] = [
|
||||
'score' => $data[0],
|
||||
'display' => $data[1],
|
||||
];
|
||||
}
|
||||
sort($portal_displays);
|
||||
}
|
||||
$this->custom_display = $portal_displays;
|
||||
if (count($this->custom_display) > 0) {
|
||||
$value = api_get_setting('gradebook_score_display_upperlimit');
|
||||
$value = $value['my_display_upperlimit'];
|
||||
$this->upperlimit_included = $value === 'true' ? true : false;
|
||||
$this->custom_display_conv = $this->convert_displays($this->custom_display);
|
||||
}
|
||||
}
|
||||
|
||||
// If teachers can override the portal parameters
|
||||
if (api_get_setting('teachers_can_change_score_settings') === 'true') {
|
||||
//Load course settings
|
||||
if ($this->custom_enabled) {
|
||||
$this->custom_display = $this->get_custom_displays();
|
||||
if (count($this->custom_display) > 0) {
|
||||
$this->custom_display_conv = $this->convert_displays($this->custom_display);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->coloring_enabled) {
|
||||
$this->color_split_value = $this->get_score_color_percent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of this class.
|
||||
*
|
||||
* @param int $categoryId
|
||||
*
|
||||
* @return ScoreDisplay
|
||||
*/
|
||||
public static function instance($categoryId = 0)
|
||||
{
|
||||
static $instance;
|
||||
if (!isset($instance)) {
|
||||
$instance = new ScoreDisplay($categoryId);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the custom display of 2 scores, can be useful in sorting.
|
||||
*/
|
||||
public static function compare_scores_by_custom_display($score1, $score2)
|
||||
{
|
||||
if (!isset($score1)) {
|
||||
return isset($score2) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (!isset($score2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$scoreDisplay = self::instance();
|
||||
$custom1 = $scoreDisplay->display_custom($score1);
|
||||
$custom2 = $scoreDisplay->display_custom($score2);
|
||||
if ($custom1 == $custom2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($score1[0] / $score1[1]) < ($score2[0] / $score2[1]) ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is coloring enabled ?
|
||||
*/
|
||||
public function is_coloring_enabled()
|
||||
{
|
||||
return $this->coloring_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is custom score display enabled ?
|
||||
*/
|
||||
public function is_custom()
|
||||
{
|
||||
return $this->custom_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is upperlimit included ?
|
||||
*/
|
||||
public function is_upperlimit_included()
|
||||
{
|
||||
return $this->upperlimit_included;
|
||||
}
|
||||
|
||||
/**
|
||||
* If custom score display is enabled, this will return the current settings.
|
||||
* See also updateCustomScoreDisplaySettings.
|
||||
*
|
||||
* @return array current settings (or null if feature not enabled)
|
||||
*/
|
||||
public function get_custom_score_display_settings()
|
||||
{
|
||||
return $this->custom_display;
|
||||
}
|
||||
|
||||
/**
|
||||
* If coloring is enabled, scores below this value will be displayed in red.
|
||||
*
|
||||
* @return int color split value, in percent (or null if feature not enabled)
|
||||
*/
|
||||
public function get_color_split_value()
|
||||
{
|
||||
return $this->color_split_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update custom score display settings.
|
||||
*
|
||||
* @param array $displays 2-dimensional array - every sub array must have keys (score, display)
|
||||
* @param int score color percent (optional)
|
||||
* @param int gradebook category id (optional)
|
||||
*/
|
||||
public function updateCustomScoreDisplaySettings(
|
||||
$displays,
|
||||
$scorecolpercent = 0,
|
||||
$category_id = null
|
||||
) {
|
||||
$this->custom_display = $displays;
|
||||
$this->custom_display_conv = $this->convert_displays($this->custom_display);
|
||||
if (isset($category_id)) {
|
||||
$category_id = (int) $category_id;
|
||||
} else {
|
||||
$category_id = $this->get_current_gradebook_category_id();
|
||||
}
|
||||
|
||||
// remove previous settings
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY);
|
||||
$sql = 'DELETE FROM '.$table.' WHERE category_id = '.$category_id;
|
||||
Database::query($sql);
|
||||
|
||||
// add new settings
|
||||
foreach ($displays as $display) {
|
||||
$params = [
|
||||
'score' => $display['score'],
|
||||
'display' => $display['display'],
|
||||
'category_id' => $category_id,
|
||||
'score_color_percent' => $scorecolpercent,
|
||||
];
|
||||
Database::insert($table, $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $category_id
|
||||
*
|
||||
* @return false|null
|
||||
*/
|
||||
public function insert_defaults($category_id)
|
||||
{
|
||||
if (empty($category_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Get this from DB settings
|
||||
$display = [
|
||||
50 => get_lang('GradebookFailed'),
|
||||
60 => get_lang('GradebookPoor'),
|
||||
70 => get_lang('GradebookFair'),
|
||||
80 => get_lang('GradebookGood'),
|
||||
90 => get_lang('GradebookOutstanding'),
|
||||
100 => get_lang('GradebookExcellent'),
|
||||
];
|
||||
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY);
|
||||
foreach ($display as $value => $text) {
|
||||
$params = [
|
||||
'score' => $value,
|
||||
'display' => $text,
|
||||
'category_id' => $category_id,
|
||||
'score_color_percent' => 0,
|
||||
];
|
||||
Database::insert($table, $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_number_decimals()
|
||||
{
|
||||
$number_decimals = api_get_setting('gradebook_number_decimals');
|
||||
if (!isset($number_decimals)) {
|
||||
$number_decimals = 0;
|
||||
}
|
||||
|
||||
return $number_decimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number depending of the number of decimals.
|
||||
*
|
||||
* @param float $score
|
||||
* @param bool $ignoreDecimals
|
||||
* @param string $decimalSeparator
|
||||
* @param string $thousandSeparator
|
||||
* @param bool $removeEmptyDecimals Converts 100.00 to 100, 53.00 to 53
|
||||
*
|
||||
* @return float the score formatted
|
||||
*/
|
||||
public function format_score(
|
||||
$score,
|
||||
$ignoreDecimals = false,
|
||||
$decimalSeparator = '.',
|
||||
$thousandSeparator = ',',
|
||||
$removeEmptyDecimals = false
|
||||
) {
|
||||
$decimals = $this->get_number_decimals();
|
||||
if ($ignoreDecimals) {
|
||||
$decimals = 0;
|
||||
}
|
||||
|
||||
if ($removeEmptyDecimals) {
|
||||
if ($score && self::hasEmptyDecimals($score)) {
|
||||
$score = round($score);
|
||||
$decimals = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return api_number_format($score, $decimals, $decimalSeparator, $thousandSeparator);
|
||||
}
|
||||
|
||||
public static function hasEmptyDecimals($score)
|
||||
{
|
||||
$hasEmptyDecimals = false;
|
||||
if (is_float($score)) {
|
||||
$check = fmod($score, 1);
|
||||
if (0 === bccomp(0, $check)) {
|
||||
$score = round($score);
|
||||
$hasEmptyDecimals = true;
|
||||
}
|
||||
}
|
||||
if (is_int($score) || is_string($score)) {
|
||||
$score = (float) $score;
|
||||
$check = fmod($score, 1);
|
||||
if (0 === bccomp(0, $check)) {
|
||||
$hasEmptyDecimals = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $hasEmptyDecimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a score according to the current settings.
|
||||
*
|
||||
* @param array $score data structure, as returned by the calc_score functions
|
||||
* @param int $type one of the following constants:
|
||||
* SCORE_DIV, SCORE_PERCENT, SCORE_DIV_PERCENT, SCORE_AVERAGE
|
||||
* (ignored for student's view if custom score display is enabled)
|
||||
* @param int $what one of the following constants:
|
||||
* SCORE_BOTH, SCORE_ONLY_DEFAULT, SCORE_ONLY_CUSTOM (default: SCORE_BOTH)
|
||||
* (only taken into account if custom score display is enabled and for course/platform admin)
|
||||
* @param bool $disableColor
|
||||
* @param bool $ignoreDecimals
|
||||
* @param bool $removeEmptyDecimals Replaces 100.00 to 100
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function display_score(
|
||||
$score,
|
||||
$type = SCORE_DIV_PERCENT,
|
||||
$what = SCORE_BOTH,
|
||||
$disableColor = false,
|
||||
$ignoreDecimals = false,
|
||||
$removeEmptyDecimals = false
|
||||
) {
|
||||
// No score available.
|
||||
if (!is_array($score)) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
$my_score = $score == 0 ? [] : $score;
|
||||
switch ($type) {
|
||||
case SCORE_BAR:
|
||||
$percentage = $my_score[0] / $my_score[1] * 100;
|
||||
|
||||
return Display::bar_progress($percentage);
|
||||
break;
|
||||
case SCORE_NUMERIC:
|
||||
$percentage = $my_score[0] / $my_score[1] * 100;
|
||||
|
||||
return round($percentage);
|
||||
break;
|
||||
}
|
||||
|
||||
if (false === $disableColor && $this->custom_enabled && isset($this->custom_display_conv)) {
|
||||
$display = $this->displayDefault($my_score, $type, $ignoreDecimals, $removeEmptyDecimals, true);
|
||||
} else {
|
||||
// if no custom display set, use default display
|
||||
$display = $this->displayDefault($my_score, $type, $ignoreDecimals, $removeEmptyDecimals);
|
||||
}
|
||||
|
||||
if ($this->coloring_enabled && false === $disableColor) {
|
||||
$denom = isset($score[1]) && !empty($score[1]) && $score[1] > 0 ? $score[1] : 1;
|
||||
$scoreCleaned = isset($score[0]) ? $score[0] : 0;
|
||||
if (($scoreCleaned / $denom) < ($this->color_split_value / 100)) {
|
||||
$display = Display::tag(
|
||||
'font',
|
||||
$display,
|
||||
['color' => 'red']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Depends on the teacher's configuration of thresholds. i.e. [0 50] "Bad", [50:100] "Good".
|
||||
*
|
||||
* @param array $score
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function display_custom($score)
|
||||
{
|
||||
if (empty($score)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$denom = $score[1] == 0 ? 1 : $score[1];
|
||||
$scaledscore = $score[0] / $denom;
|
||||
|
||||
if ($this->upperlimit_included) {
|
||||
foreach ($this->custom_display_conv as $displayitem) {
|
||||
if ($scaledscore <= $displayitem['score']) {
|
||||
return $displayitem['display'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!empty($this->custom_display_conv)) {
|
||||
foreach ($this->custom_display_conv as $displayitem) {
|
||||
if ($scaledscore < $displayitem['score'] || $displayitem['score'] == 1) {
|
||||
return $displayitem['display'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current gradebook category id.
|
||||
*
|
||||
* @return int Category id
|
||||
*/
|
||||
private function get_current_gradebook_category_id()
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
|
||||
$courseCode = api_get_course_id();
|
||||
$sessionId = api_get_session_id();
|
||||
$sessionCondition = api_get_session_condition($sessionId, true);
|
||||
|
||||
$sql = "SELECT id FROM $table
|
||||
WHERE course_code = '$courseCode' $sessionCondition";
|
||||
$rs = Database::query($sql);
|
||||
$categoryId = 0;
|
||||
if (Database::num_rows($rs) > 0) {
|
||||
$row = Database::fetch_row($rs);
|
||||
$categoryId = $row[0];
|
||||
}
|
||||
|
||||
return $categoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $score
|
||||
* @param int $type
|
||||
* @param bool $ignoreDecimals
|
||||
* @param bool $removeEmptyDecimals
|
||||
* @param bool $addScoreLabel
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function displayDefault($score, $type, $ignoreDecimals = false, $removeEmptyDecimals = false, $addScoreLabel = false)
|
||||
{
|
||||
$scoreLabel = '';
|
||||
if ($addScoreLabel) {
|
||||
$scoreLabel = $this->display_custom($score);
|
||||
if (!empty($scoreLabel)) {
|
||||
$scoreLabel = ' - '.$scoreLabel;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case SCORE_DIV: // X / Y
|
||||
return $this->display_as_div($score, $ignoreDecimals, $removeEmptyDecimals).$scoreLabel;
|
||||
case SCORE_PERCENT: // XX %
|
||||
return $this->display_as_percent($score).$scoreLabel;
|
||||
case SCORE_DIV_PERCENT: // X / Y (XX %)
|
||||
//return $this->display_as_div($score).' ('.$this->display_as_percent($score).')';
|
||||
// 2020-10 Changed to XX % (X / Y)
|
||||
return $this->display_as_percent($score).' ('.$this->display_as_div($score).')'.$scoreLabel;
|
||||
case SCORE_AVERAGE: // XX %
|
||||
return $this->display_as_percent($score).$scoreLabel;
|
||||
case SCORE_DECIMAL: // 0.50 (X/Y)
|
||||
return $this->display_as_decimal($score).$scoreLabel;
|
||||
case SCORE_DIV_PERCENT_WITH_CUSTOM: // X / Y (XX %) - Good!
|
||||
$div = $this->display_as_div($score, false, $removeEmptyDecimals);
|
||||
|
||||
return
|
||||
$this->display_as_percent($score).PHP_EOL
|
||||
.Display::div("($div)", ['class' => 'small'])
|
||||
.$scoreLabel;
|
||||
case SCORE_DIV_SIMPLE_WITH_CUSTOM: // X - Good!
|
||||
return $this->display_simple_score($score).$scoreLabel;
|
||||
break;
|
||||
case SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS:
|
||||
$score = $this->display_simple_score($score);
|
||||
// Needs sudo apt-get install php5-intl
|
||||
if (class_exists('NumberFormatter')) {
|
||||
$iso = api_get_language_isocode();
|
||||
$f = new NumberFormatter($iso, NumberFormatter::SPELLOUT);
|
||||
$letters = $f->format($score);
|
||||
$letters = api_strtoupper($letters);
|
||||
$letters = " ($letters) ";
|
||||
}
|
||||
|
||||
return $score.$letters.$scoreLabel;
|
||||
case SCORE_CUSTOM: // Good!
|
||||
return $this->display_custom($score);
|
||||
case SCORE_SIMPLE:
|
||||
if (!isset($score[0])) {
|
||||
$score[0] = 0;
|
||||
}
|
||||
|
||||
return $this->format_score($score[0], $ignoreDecimals).$scoreLabel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $score
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
private function display_simple_score($score)
|
||||
{
|
||||
if (isset($score[0])) {
|
||||
return $this->format_score($score[0]);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns "1" for array("100", "100").
|
||||
*
|
||||
* @param array $score
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
private function display_as_decimal($score)
|
||||
{
|
||||
$score_denom = $score[1] == 0 ? 1 : $score[1];
|
||||
|
||||
return $this->format_score($score[0] / $score_denom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns "100 %" for array("100", "100").
|
||||
*/
|
||||
private function display_as_percent($score)
|
||||
{
|
||||
if (empty($score)) {
|
||||
return null;
|
||||
}
|
||||
$scoreDenom = $score[1] == 0 ? 1 : $score[1];
|
||||
|
||||
return $this->format_score($score[0] / $scoreDenom * 100).' %';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 10.00 / 10.00 for array("100", "100").
|
||||
*
|
||||
* @param array $score
|
||||
* @param bool $ignoreDecimals
|
||||
* @param bool $removeEmptyDecimals
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function display_as_div($score, $ignoreDecimals = false, $removeEmptyDecimals = false)
|
||||
{
|
||||
if ($score == 1) {
|
||||
return '0 / 0';
|
||||
}
|
||||
|
||||
if (empty($score)) {
|
||||
return '0 / 0';
|
||||
}
|
||||
|
||||
$score[0] = isset($score[0]) ? $this->format_score($score[0], $ignoreDecimals) : 0;
|
||||
$score[1] = isset($score[1]) ? $this->format_score(
|
||||
$score[1],
|
||||
$ignoreDecimals,
|
||||
'.',
|
||||
',',
|
||||
$removeEmptyDecimals
|
||||
) : 0;
|
||||
|
||||
return $score[0].' / '.$score[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get score color percent by category.
|
||||
*
|
||||
* @param int Gradebook category id
|
||||
*
|
||||
* @return int Score
|
||||
*/
|
||||
private function get_score_color_percent($category_id = null)
|
||||
{
|
||||
$tbl_display = Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY);
|
||||
if (isset($category_id)) {
|
||||
$category_id = (int) $category_id;
|
||||
} else {
|
||||
$category_id = $this->get_current_gradebook_category_id();
|
||||
}
|
||||
|
||||
$sql = 'SELECT score_color_percent FROM '.$tbl_display.'
|
||||
WHERE category_id = '.$category_id.'
|
||||
LIMIT 1';
|
||||
$result = Database::query($sql);
|
||||
$score = 0;
|
||||
if (Database::num_rows($result) > 0) {
|
||||
$row = Database::fetch_row($result);
|
||||
$score = $row[0];
|
||||
}
|
||||
|
||||
return $score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current custom score display settings.
|
||||
*
|
||||
* @param int Gradebook category id
|
||||
*
|
||||
* @return array 2-dimensional array every element contains 3 subelements (id, score, display)
|
||||
*/
|
||||
private function get_custom_displays($category_id = null)
|
||||
{
|
||||
$tbl_display = Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY);
|
||||
if (isset($category_id)) {
|
||||
$category_id = (int) $category_id;
|
||||
} else {
|
||||
$category_id = $this->get_current_gradebook_category_id();
|
||||
}
|
||||
$sql = 'SELECT * FROM '.$tbl_display.'
|
||||
WHERE category_id = '.$category_id.'
|
||||
ORDER BY score';
|
||||
$result = Database::query($sql);
|
||||
|
||||
return Database::store_result($result, 'ASSOC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert display settings to internally used values.
|
||||
*/
|
||||
private function convert_displays($custom_display)
|
||||
{
|
||||
if (isset($custom_display)) {
|
||||
// get highest score entry, and copy each element to a new array
|
||||
$converted = [];
|
||||
$highest = 0;
|
||||
foreach ($custom_display as $element) {
|
||||
if ($element['score'] > $highest) {
|
||||
$highest = (float) $element['score'];
|
||||
}
|
||||
$converted[] = $element;
|
||||
}
|
||||
// sort the new array (ascending)
|
||||
usort($converted, ['ScoreDisplay', 'sort_display']);
|
||||
|
||||
// adjust each score in such a way that
|
||||
// each score is scaled between 0 and 1
|
||||
// the highest score in this array will be equal to 1
|
||||
$converted2 = [];
|
||||
foreach ($converted as $element) {
|
||||
$newelement = [];
|
||||
if (isset($highest) && !empty($highest) && $highest > 0) {
|
||||
$newelement['score'] = (float) $element['score'] / $highest;
|
||||
} else {
|
||||
$newelement['score'] = 0;
|
||||
}
|
||||
$newelement['display'] = $element['display'];
|
||||
$converted2[] = $newelement;
|
||||
}
|
||||
|
||||
return $converted2;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $item1
|
||||
* @param array $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function sort_display($item1, $item2)
|
||||
{
|
||||
if ($item1['score'] === $item2['score']) {
|
||||
return 0;
|
||||
} else {
|
||||
return $item1['score'] < $item2['score'] ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
447
main/gradebook/lib/user_data_generator.class.php
Normal file
447
main/gradebook/lib/user_data_generator.class.php
Normal file
@@ -0,0 +1,447 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class UserDataGenerator
|
||||
* Class to select, sort and transform object data into array data,
|
||||
* used for a student's general view.
|
||||
*
|
||||
* @author Bert Steppé
|
||||
*/
|
||||
class UserDataGenerator
|
||||
{
|
||||
// Sorting types constants
|
||||
public const UDG_SORT_TYPE = 1;
|
||||
public const UDG_SORT_NAME = 2;
|
||||
public const UDG_SORT_COURSE = 4;
|
||||
public const UDG_SORT_CATEGORY = 8;
|
||||
public const UDG_SORT_AVERAGE = 16;
|
||||
public const UDG_SORT_SCORE = 32;
|
||||
public const UDG_SORT_MASK = 64;
|
||||
|
||||
public const UDG_SORT_ASC = 128;
|
||||
public const UDG_SORT_DESC = 256;
|
||||
|
||||
private $items;
|
||||
private $userid;
|
||||
|
||||
private $coursecodecache;
|
||||
private $categorycache;
|
||||
private $scorecache;
|
||||
private $avgcache;
|
||||
|
||||
/**
|
||||
* UserDataGenerator constructor.
|
||||
*
|
||||
* @param int $userid
|
||||
* @param array $evals
|
||||
* @param array $links
|
||||
*/
|
||||
public function __construct($userid, $evals = [], $links = [])
|
||||
{
|
||||
$this->userid = $userid;
|
||||
$result = [];
|
||||
foreach ($evals as $eval) {
|
||||
$toadd = true;
|
||||
$coursecode = $eval->get_course_code();
|
||||
if (isset($coursecode)) {
|
||||
$result = Result::load(null, $userid, $eval->get_id());
|
||||
if (0 == count($result)) {
|
||||
$toadd = false;
|
||||
}
|
||||
}
|
||||
if ($toadd) {
|
||||
$evals_filtered_copy = $evals;
|
||||
}
|
||||
}
|
||||
if (0 == count($result)) {
|
||||
$evals_filtered = $evals;
|
||||
} else {
|
||||
$evals_filtered = $evals_filtered_copy;
|
||||
}
|
||||
$this->items = array_merge($evals_filtered, $links);
|
||||
|
||||
$this->coursecodecache = [];
|
||||
$this->categorycache = [];
|
||||
$this->scorecache = null;
|
||||
$this->avgcache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total number of items (rows).
|
||||
*/
|
||||
public function get_total_items_count()
|
||||
{
|
||||
return count($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get actual array data.
|
||||
*
|
||||
* @return array 2-dimensional array - each array contains the elements:
|
||||
* 0: eval/link object
|
||||
* 1: item name
|
||||
* 2: course name
|
||||
* 3: category name
|
||||
* 4: average score
|
||||
* 5: student's score
|
||||
* 6: student's score as custom display (only if custom scoring enabled)
|
||||
*/
|
||||
public function get_data(
|
||||
$sorting = 0,
|
||||
$start = 0,
|
||||
$count = null,
|
||||
$ignore_score_color = false
|
||||
) {
|
||||
// do some checks on count, redefine if invalid value
|
||||
if (!isset($count)) {
|
||||
$count = count($this->items) - $start;
|
||||
}
|
||||
if ($count < 0) {
|
||||
$count = 0;
|
||||
}
|
||||
$allitems = $this->items;
|
||||
|
||||
// sort users array
|
||||
if ($sorting & self::UDG_SORT_TYPE) {
|
||||
usort($allitems, ['UserDataGenerator', 'sort_by_type']);
|
||||
} elseif ($sorting & self::UDG_SORT_NAME) {
|
||||
usort($allitems, ['UserDataGenerator', 'sort_by_name']);
|
||||
} elseif ($sorting & self::UDG_SORT_COURSE) {
|
||||
usort($allitems, ['UserDataGenerator', 'sort_by_course']);
|
||||
} elseif ($sorting & self::UDG_SORT_CATEGORY) {
|
||||
usort($allitems, ['UserDataGenerator', 'sort_by_category']);
|
||||
} elseif ($sorting & self::UDG_SORT_AVERAGE) {
|
||||
// if user sorts on average scores, first calculate them and cache them
|
||||
foreach ($allitems as $item) {
|
||||
$this->avgcache[$item->get_item_type().$item->get_id()] = $item->calc_score();
|
||||
}
|
||||
usort($allitems, ['UserDataGenerator', 'sort_by_average']);
|
||||
} elseif ($sorting & self::UDG_SORT_SCORE) {
|
||||
// if user sorts on student's scores, first calculate them and cache them
|
||||
foreach ($allitems as $item) {
|
||||
$this->scorecache[$item->get_item_type().$item->get_id()] = $item->calc_score($this->userid);
|
||||
}
|
||||
usort($allitems, ['UserDataGenerator', 'sort_by_score']);
|
||||
} elseif ($sorting & self::UDG_SORT_MASK) {
|
||||
// if user sorts on student's masks, first calculate scores and cache them
|
||||
foreach ($allitems as $item) {
|
||||
$this->scorecache[$item->get_item_type().$item->get_id()] = $item->calc_score($this->userid);
|
||||
}
|
||||
usort($allitems, ['UserDataGenerator', 'sort_by_mask']);
|
||||
}
|
||||
|
||||
if ($sorting & self::UDG_SORT_DESC) {
|
||||
$allitems = array_reverse($allitems);
|
||||
}
|
||||
// select the items we have to display
|
||||
$visibleitems = array_slice($allitems, $start, $count);
|
||||
|
||||
// fill score cache if not done yet
|
||||
if (!isset($this->scorecache)) {
|
||||
foreach ($visibleitems as $item) {
|
||||
$this->scorecache[$item->get_item_type().$item->get_id()] = $item->calc_score($this->userid);
|
||||
}
|
||||
}
|
||||
// generate the data to display
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$data = [];
|
||||
$model = ExerciseLib::getCourseScoreModel();
|
||||
foreach ($visibleitems as $item) {
|
||||
$row = [];
|
||||
$row[] = $item;
|
||||
$row[] = $item->get_name();
|
||||
$row[] = $this->build_course_name($item);
|
||||
$row[] = $this->build_category_name($item);
|
||||
|
||||
if (!empty($model)) {
|
||||
if (isset($this->avgcache)) {
|
||||
$avgscore = $this->avgcache[$item->get_item_type().$item->get_id()];
|
||||
} else {
|
||||
$avgscore = $item->calc_score();
|
||||
}
|
||||
$row[] = ExerciseLib::show_score($avgscore[0], $avgscore[1]);
|
||||
$score = $this->scorecache[$item->get_item_type().$item->get_id()];
|
||||
$displayScore = ExerciseLib::show_score($score[0], $score[1]);
|
||||
$row[] = $displayScore;
|
||||
if ($scoredisplay->is_custom()) {
|
||||
$row[] = $displayScore;
|
||||
}
|
||||
} else {
|
||||
$row[] = $this->build_average_column($item, $ignore_score_color);
|
||||
$row[] = $this->build_result_column($item, $ignore_score_color);
|
||||
if ($scoredisplay->is_custom()) {
|
||||
$row[] = $this->build_mask_column($item, $ignore_score_color);
|
||||
}
|
||||
}
|
||||
|
||||
$data[] = $row;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item1
|
||||
* @param $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_type($item1, $item2)
|
||||
{
|
||||
if ($item1->get_item_type() == $item2->get_item_type()) {
|
||||
return $this->sort_by_name($item1, $item2);
|
||||
} else {
|
||||
return $item1->get_item_type() < $item2->get_item_type() ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item1
|
||||
* @param $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_course($item1, $item2)
|
||||
{
|
||||
$name1 = api_strtolower(
|
||||
$this->get_course_name_from_code_cached($item1->get_course_code())
|
||||
);
|
||||
$name2 = api_strtolower(
|
||||
$this->get_course_name_from_code_cached($item2->get_course_code())
|
||||
);
|
||||
|
||||
return api_strnatcmp($name1, $name2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item1
|
||||
* @param $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_category($item1, $item2)
|
||||
{
|
||||
$cat1 = $this->get_category_cached($item1->get_category_id());
|
||||
$cat2 = $this->get_category_cached($item2->get_category_id());
|
||||
$name1 = api_strtolower($this->get_category_name_to_display($cat1));
|
||||
$name2 = api_strtolower($this->get_category_name_to_display($cat2));
|
||||
|
||||
return api_strnatcmp($name1, $name2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item1
|
||||
* @param $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_name($item1, $item2)
|
||||
{
|
||||
return api_strnatcmp($item1->get_name(), $item2->get_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item1
|
||||
* @param $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_average($item1, $item2)
|
||||
{
|
||||
$score1 = $this->avgcache[$item1->get_item_type().$item1->get_id()];
|
||||
$score2 = $this->avgcache[$item2->get_item_type().$item2->get_id()];
|
||||
|
||||
return $this->compare_scores($score1, $score2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item1
|
||||
* @param $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_score($item1, $item2)
|
||||
{
|
||||
$score1 = $this->scorecache[$item1->get_item_type().$item1->get_id()];
|
||||
$score2 = $this->scorecache[$item2->get_item_type().$item2->get_id()];
|
||||
|
||||
return $this->compare_scores($score1, $score2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item1
|
||||
* @param $item2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_mask($item1, $item2)
|
||||
{
|
||||
$score1 = $this->scorecache[$item1->get_item_type().$item1->get_id()];
|
||||
$score2 = $this->scorecache[$item2->get_item_type().$item2->get_id()];
|
||||
|
||||
return ScoreDisplay::compare_scores_by_custom_display($score1, $score2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $score1
|
||||
* @param $score2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function compare_scores($score1, $score2)
|
||||
{
|
||||
if (!isset($score1)) {
|
||||
return isset($score2) ? 1 : 0;
|
||||
} elseif (!isset($score2)) {
|
||||
return -1;
|
||||
} elseif (($score1[0] / $score1[1]) == ($score2[0] / $score2[1])) {
|
||||
return 0;
|
||||
} else {
|
||||
return ($score1[0] / $score1[1]) < ($score2[0] / $score2[1]) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function build_course_name($item)
|
||||
{
|
||||
return $this->get_course_name_from_code_cached($item->get_course_code());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_category_name($item)
|
||||
{
|
||||
$cat = $this->get_category_cached($item->get_category_id());
|
||||
|
||||
return $this->get_category_name_to_display($cat);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @param $ignore_score_color
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_average_column($item, $ignore_score_color)
|
||||
{
|
||||
if (isset($this->avgcache)) {
|
||||
$avgscore = $this->avgcache[$item->get_item_type().$item->get_id()];
|
||||
} else {
|
||||
$avgscore = $item->calc_score('', 'average');
|
||||
}
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$displaytype = SCORE_AVERAGE;
|
||||
|
||||
return $scoredisplay->display_score($avgscore, $displaytype);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @param $ignore_score_color
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_result_column($item, $ignore_score_color)
|
||||
{
|
||||
$studscore = $this->scorecache[$item->get_item_type().$item->get_id()];
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$displaytype = SCORE_DIV_PERCENT;
|
||||
if ($ignore_score_color) {
|
||||
$displaytype |= SCORE_IGNORE_SPLIT;
|
||||
}
|
||||
|
||||
return $scoredisplay->display_score(
|
||||
$studscore,
|
||||
$displaytype,
|
||||
SCORE_ONLY_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @param $ignore_score_color
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_mask_column($item, $ignore_score_color)
|
||||
{
|
||||
$studscore = $this->scorecache[$item->get_item_type().$item->get_id()];
|
||||
$scoredisplay = ScoreDisplay::instance();
|
||||
$displaytype = SCORE_DIV_PERCENT;
|
||||
if ($ignore_score_color) {
|
||||
$displaytype |= SCORE_IGNORE_SPLIT;
|
||||
}
|
||||
|
||||
return $scoredisplay->display_score(
|
||||
$studscore,
|
||||
$displaytype,
|
||||
SCORE_ONLY_CUSTOM
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $coursecode
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function get_course_name_from_code_cached($coursecode)
|
||||
{
|
||||
if (isset($this->coursecodecache) &&
|
||||
isset($this->coursecodecache[$coursecode])
|
||||
) {
|
||||
return $this->coursecodecache[$coursecode];
|
||||
} else {
|
||||
$name = CourseManager::getCourseNameFromCode($coursecode);
|
||||
$this->coursecodecache[$coursecode] = $name;
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $category_id
|
||||
*/
|
||||
private function get_category_cached($category_id)
|
||||
{
|
||||
if (isset($this->categorycache) &&
|
||||
isset($this->categorycache[$category_id])
|
||||
) {
|
||||
return $this->categorycache[$category_id];
|
||||
} else {
|
||||
$cat = Category::load($category_id);
|
||||
if (isset($cat)) {
|
||||
$this->categorycache[$category_id] = $cat[0];
|
||||
|
||||
return $cat[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $cat
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_category_name_to_display($cat)
|
||||
{
|
||||
if (isset($cat)) {
|
||||
if ('0' == $cat->get_parent_id() || null == $cat->get_parent_id()) {
|
||||
return '';
|
||||
} else {
|
||||
return $cat->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
63
main/gradebook/my_certificates.php
Normal file
63
main/gradebook/my_certificates.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* List of achieved certificates by the current user.
|
||||
*
|
||||
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
|
||||
*/
|
||||
$cidReset = true;
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
api_block_inactive_user();
|
||||
|
||||
$logInfo = [
|
||||
'tool' => 'MyCertificates',
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
if (api_is_anonymous()) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
$userId = api_get_user_id();
|
||||
|
||||
$courseList = GradebookUtils::getUserCertificatesInCourses($userId);
|
||||
$sessionList = GradebookUtils::getUserCertificatesInSessions($userId);
|
||||
|
||||
if (empty($courseList) && empty($sessionList)) {
|
||||
Display::addFlash(
|
||||
Display::return_message(get_lang('YouNotYetAchievedCertificates'), 'warning')
|
||||
);
|
||||
}
|
||||
|
||||
$hideExportLink = api_get_setting('hide_certificate_export_link');
|
||||
$hideExportLinkStudent = api_get_setting('hide_certificate_export_link_students');
|
||||
$allowExport = true;
|
||||
if ($hideExportLink === 'true' ||
|
||||
(api_is_student() && $hideExportLinkStudent === 'true')
|
||||
) {
|
||||
$allowExport = false;
|
||||
}
|
||||
|
||||
$template = new Template(get_lang('MyCertificates'));
|
||||
$template->assign('course_list', $courseList);
|
||||
$template->assign('session_list', $sessionList);
|
||||
$template->assign('allow_export', $allowExport);
|
||||
$templateName = $template->get_template('gradebook/my_certificates.tpl');
|
||||
$content = $template->fetch($templateName);
|
||||
|
||||
if ('true' === api_get_setting('allow_public_certificates')) {
|
||||
$template->assign(
|
||||
'actions',
|
||||
Display::toolbarButton(
|
||||
get_lang('SearchCertificates'),
|
||||
api_get_path(WEB_CODE_PATH).'gradebook/search.php',
|
||||
'search',
|
||||
'info'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$template->assign('content', $content);
|
||||
$template->display_one_col_template();
|
||||
33
main/gradebook/personal_stats.php
Normal file
33
main/gradebook/personal_stats.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/* See license terms in /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
$categoryId = isset($_GET['selectcat']) ? intval($_GET['selectcat']) : false;
|
||||
|
||||
if (empty($categoryId)) {
|
||||
api_not_allowed(false);
|
||||
}
|
||||
$userId = api_get_user_id();
|
||||
|
||||
$cats = Category::load($categoryId);
|
||||
if (isset($cats[0])) {
|
||||
$cat = $cats[0];
|
||||
}
|
||||
|
||||
$allcat = $cats[0]->get_subcategories($userId, api_get_course_id(), api_get_session_id());
|
||||
$alleval = $cats[0]->get_evaluations($userId);
|
||||
$alllink = $cats[0]->get_links($userId);
|
||||
|
||||
$gradebooktable = new GradebookTable(
|
||||
$cat,
|
||||
$allcat,
|
||||
$alleval,
|
||||
$alllink,
|
||||
[],
|
||||
false
|
||||
);
|
||||
$gradebooktable->userId = $userId;
|
||||
$table = $gradebooktable->return_table();
|
||||
|
||||
echo $gradebooktable->getGraph();
|
||||
39
main/gradebook/print.css
Normal file
39
main/gradebook/print.css
Normal file
@@ -0,0 +1,39 @@
|
||||
body {
|
||||
font-family: arial, verdana, helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
margin: 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a:link {text-decoration: none; font-weight : bold; color : black;}
|
||||
a:visited {text-decoration: none; font-weight : bold; color : black;}
|
||||
a:active {text-decoration: none; font-weight : bold; color : black;}
|
||||
|
||||
.data_table{
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
border: 1px;
|
||||
}
|
||||
.data_table th{
|
||||
padding: 5px;
|
||||
vertical-align: top;
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
border-right: 1px solid black;
|
||||
border-left: 1px solid black;
|
||||
}
|
||||
.data_table tr.row_odd{
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.data_table tr.row_even{
|
||||
background-color: #fff;
|
||||
}
|
||||
.data_table td{
|
||||
padding: 5px;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px solid black;
|
||||
border-right: 1px solid black;
|
||||
border-left: 1px solid black;
|
||||
}
|
||||
89
main/gradebook/search.php
Normal file
89
main/gradebook/search.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Search user certificates if them are publics.
|
||||
*
|
||||
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
|
||||
*/
|
||||
$cidReset = true;
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
if (api_get_setting('allow_public_certificates') != 'true') {
|
||||
api_not_allowed(
|
||||
true,
|
||||
Display::return_message(get_lang('CertificatesNotPublic'), 'warning')
|
||||
);
|
||||
}
|
||||
|
||||
$userId = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
|
||||
$userList = $userInfo = $courseList = $sessionList = [];
|
||||
|
||||
$searchForm = new FormValidator('search_form', 'post', null, null);
|
||||
$searchForm->addText('firstname', get_lang('FirstName'));
|
||||
$searchForm->addText('lastname', get_lang('LastName'));
|
||||
$searchForm->addButtonSearch();
|
||||
|
||||
if ($searchForm->validate()) {
|
||||
$firstname = $searchForm->getSubmitValue('firstname');
|
||||
$lastname = $searchForm->getSubmitValue('lastname');
|
||||
$userList = UserManager::getUsersByName($firstname, $lastname);
|
||||
|
||||
if (empty($userList)) {
|
||||
Display::addFlash(
|
||||
Display::return_message(get_lang('NoResults'), 'warning')
|
||||
);
|
||||
|
||||
header('Location: '.api_get_self());
|
||||
exit;
|
||||
}
|
||||
} elseif ($userId > 0) {
|
||||
$userInfo = api_get_user_info($userId);
|
||||
|
||||
if (empty($userInfo)) {
|
||||
Display::addFlash(
|
||||
Display::return_message(get_lang('NoUser'), 'warning')
|
||||
);
|
||||
|
||||
header('Location: '.api_get_self());
|
||||
exit;
|
||||
}
|
||||
|
||||
$courseList = GradebookUtils::getUserCertificatesInCourses($userId, false);
|
||||
$sessionList = GradebookUtils::getUserCertificatesInSessions(
|
||||
$userId,
|
||||
false
|
||||
);
|
||||
|
||||
if (empty($courseList) && empty($sessionList)) {
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
sprintf(
|
||||
get_lang('TheUserXNotYetAchievedCertificates'),
|
||||
$userInfo['complete_name']
|
||||
),
|
||||
'warning'
|
||||
)
|
||||
);
|
||||
|
||||
header('Location: '.api_get_self());
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template(get_lang('SearchCertificates'));
|
||||
|
||||
$template->assign('search_form', $searchForm->returnForm());
|
||||
$template->assign('user_list', $userList);
|
||||
$template->assign('user_info', $userInfo);
|
||||
$template->assign('course_list', $courseList);
|
||||
$template->assign('session_list', $sessionList);
|
||||
$templateName = $template->get_template('gradebook/search.tpl');
|
||||
$content = $template->fetch($templateName);
|
||||
|
||||
$template->assign('header', get_lang('SearchCertificates'));
|
||||
$template->assign('content', $content);
|
||||
|
||||
$template->display_one_col_template();
|
||||
88
main/gradebook/skill_rel_user.php
Normal file
88
main/gradebook/skill_rel_user.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\SkillBundle\Entity\SkillRelItem;
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
if (api_get_configuration_value('allow_skill_rel_items') == false) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
$htmlContentExtraClass[] = 'feature-item-user-skill-on';
|
||||
|
||||
api_protect_course_script();
|
||||
GradebookUtils::block_students();
|
||||
$courseId = api_get_course_int_id();
|
||||
$sessionId = api_get_session_id();
|
||||
|
||||
$userId = isset($_GET['user_id']) ? (int) $_GET['user_id'] : 0;
|
||||
$categoryId = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
$userInfo = api_get_user_info($userId);
|
||||
|
||||
if (empty($userInfo)) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$skills = Skill::getSkillRelItemsPerCourse($courseId, $sessionId);
|
||||
$uniqueSkills = [];
|
||||
$itemsPerSkill = [];
|
||||
$uniqueSkillsConclusion = [];
|
||||
$skillRelUser = new SkillRelUser();
|
||||
$userSkills = $skillRelUser->getUserSkills($userId, api_get_course_int_id(), api_get_session_id());
|
||||
$userSkillsList = [];
|
||||
if (!empty($userSkills)) {
|
||||
foreach ($userSkills as $userSkill) {
|
||||
$userSkillsList[] = $userSkill['skill_id'];
|
||||
}
|
||||
}
|
||||
|
||||
$em = Database::getManager();
|
||||
$codePath = api_get_path(WEB_CODE_PATH);
|
||||
/** @var SkillRelItem $skill */
|
||||
foreach ($skills as $skill) {
|
||||
$skillId = $skill->getSkill()->getId();
|
||||
$uniqueSkills[$skillId] = $skill->getSkill();
|
||||
$itemInfo = Skill::getItemInfo($skill->getItemId(), $skill->getItemType());
|
||||
|
||||
$criteria = [
|
||||
'user' => $userId,
|
||||
'skillRelItem' => $skill,
|
||||
];
|
||||
/** @var \Chamilo\SkillBundle\Entity\SkillRelItemRelUser $skillRelItemRelUser */
|
||||
$skillRelItemRelUser = $em->getRepository('ChamiloSkillBundle:SkillRelItemRelUser')->findOneBy($criteria);
|
||||
$itemInfo['status'] = $skillRelItemRelUser ? true : false;
|
||||
$itemInfo['url_activity'] = $codePath.$skill->getItemResultList(api_get_cidreq());
|
||||
if ($skillRelItemRelUser) {
|
||||
$itemInfo['url_activity'] = $codePath.$skillRelItemRelUser->getUserItemResultUrl(api_get_cidreq());
|
||||
}
|
||||
|
||||
$itemsPerSkill[$skillId][]['info'] = $itemInfo;
|
||||
}
|
||||
foreach ($itemsPerSkill as $skillId => $skillList) {
|
||||
$uniqueSkillsConclusion[$skillId] = in_array($skillId, $userSkillsList);
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
$interbreadcrumb[] = [
|
||||
'url' => api_get_path(WEB_CODE_PATH).'gradebook/gradebook_display_summary.php?'.api_get_cidreq().'&selectcat='.$categoryId,
|
||||
'name' => get_lang('GradebookListOfStudentsReports'),
|
||||
];
|
||||
|
||||
$url = api_get_path(WEB_AJAX_PATH).'skill.ajax.php?a=assign_user_to_skill';
|
||||
|
||||
$template = new Template(get_lang('SkillUserList'));
|
||||
$template->assign('conclusion_list', $uniqueSkillsConclusion);
|
||||
$template->assign('skills', $uniqueSkills);
|
||||
$template->assign('items', $itemsPerSkill);
|
||||
$template->assign('user', $userInfo);
|
||||
$template->assign('course_id', api_get_course_int_id());
|
||||
$template->assign('session_id', api_get_session_id());
|
||||
$template->assign('assign_user_url', $url);
|
||||
|
||||
$templateName = $template->get_template('gradebook/skill_rel_user.tpl');
|
||||
$content = $template->fetch($templateName);
|
||||
$template->assign('content', $content);
|
||||
$template->display_one_col_template();
|
||||
135
main/gradebook/user_stats.php
Normal file
135
main/gradebook/user_stats.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
$isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
|
||||
api_get_user_id(),
|
||||
api_get_course_info()
|
||||
);
|
||||
|
||||
if (!$isDrhOfCourse) {
|
||||
GradebookUtils::block_students();
|
||||
}
|
||||
$interbreadcrumb[] = [
|
||||
'url' => Category::getUrl(),
|
||||
'name' => get_lang('Gradebook'),
|
||||
];
|
||||
|
||||
$categoryId = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
|
||||
$evaluationId = isset($_GET['selecteval']) ? (int) $_GET['selecteval'] : 0;
|
||||
|
||||
$category = Category::load($categoryId);
|
||||
$userId = Security::remove_XSS($_GET['userid']);
|
||||
$allevals = $category[0]->get_evaluations($userId, true);
|
||||
$alllinks = $category[0]->get_links($userId, true);
|
||||
|
||||
if (!empty($categoryId)) {
|
||||
$addparams = [
|
||||
'userid' => $userId,
|
||||
'selectcat' => $categoryId,
|
||||
];
|
||||
} else {
|
||||
$addparams = [
|
||||
'userid' => $userId,
|
||||
'selecteval' => $evaluationId,
|
||||
];
|
||||
}
|
||||
|
||||
$userTable = new UserTable($userId, $allevals, $alllinks, $addparams);
|
||||
|
||||
if (isset($_GET['exportpdf'])) {
|
||||
$datagen = new UserDataGenerator($userId, $allevals, $alllinks);
|
||||
$data_array = $datagen->get_data(
|
||||
UserDataGenerator::UDG_SORT_NAME,
|
||||
0,
|
||||
null,
|
||||
true
|
||||
);
|
||||
$newarray = [];
|
||||
$displayscore = ScoreDisplay::instance();
|
||||
foreach ($data_array as $data) {
|
||||
$newarray[] = array_slice($data, 1);
|
||||
}
|
||||
$userInfo = api_get_user_info($userId);
|
||||
$html = get_lang('Results').' : '.$userInfo['complete_name_with_username'].' ('.api_get_local_time().')';
|
||||
|
||||
if ($displayscore->is_custom()) {
|
||||
$header_names = [
|
||||
get_lang('Evaluation'),
|
||||
get_lang('Course'),
|
||||
get_lang('Category'),
|
||||
get_lang('EvaluationAverage'),
|
||||
get_lang('Result'),
|
||||
get_lang('Display'),
|
||||
];
|
||||
} else {
|
||||
$header_names = [
|
||||
get_lang('Evaluation'),
|
||||
get_lang('Course'),
|
||||
get_lang('Category'),
|
||||
get_lang('EvaluationAverage'),
|
||||
get_lang('Result'),
|
||||
];
|
||||
}
|
||||
|
||||
$table = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
|
||||
$row = 0;
|
||||
$column = 0;
|
||||
foreach ($header_names as $item) {
|
||||
$table->setHeaderContents($row, $column, $item);
|
||||
$column++;
|
||||
}
|
||||
$row = 1;
|
||||
if (!empty($newarray)) {
|
||||
foreach ($newarray as $data) {
|
||||
$column = 0;
|
||||
$table->setCellContents($row, $column, $data);
|
||||
$table->updateCellAttributes($row, $column, 'align="center"');
|
||||
$column++;
|
||||
$row++;
|
||||
}
|
||||
}
|
||||
$html .= $table->toHtml();
|
||||
$pdf = new PDF();
|
||||
$pdf->content_to_pdf($html);
|
||||
exit;
|
||||
}
|
||||
|
||||
$actions = '<div class="actions">';
|
||||
if (!empty($categoryId)) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => 'gradebook_flatview.php?selectcat='.$categoryId.'&'.api_get_cidreq(),
|
||||
'name' => get_lang('FlatView'),
|
||||
];
|
||||
$actions .= '<a href=gradebook_flatview.php?selectcat='.$categoryId.'&'.api_get_cidreq().'>'.
|
||||
Display::return_icon(
|
||||
'back.png',
|
||||
get_lang('BackTo').' '.get_lang('FlatView'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
).
|
||||
'</a>';
|
||||
}
|
||||
|
||||
if (!empty($evaluationId)) {
|
||||
$interbreadcrumb[] = [
|
||||
'url' => 'gradebook_view_result.php?selecteval='.$evaluationId.'&'.api_get_cidreq(),
|
||||
'name' => get_lang('ViewResult'),
|
||||
];
|
||||
$actions .= '<a href="gradebook_view_result.php?selecteval='.$evaluationId.'&'.api_get_cidreq().'">
|
||||
'.Display::return_icon('back.png', get_lang('BackToEvaluation'), '', ICON_SIZE_MEDIUM).'</a>';
|
||||
}
|
||||
|
||||
$actions .= '<a href="'.api_get_self().'?exportpdf=&userid='.$userId.'&selectcat='.$category[0]->get_id().'&'.api_get_cidreq().'" target="_blank">
|
||||
'.Display::return_icon('pdf.png', get_lang('ExportPDF'), '', ICON_SIZE_MEDIUM).'</a>';
|
||||
|
||||
$actions .= '</div>';
|
||||
|
||||
Display::display_header(get_lang('ResultsPerUser'));
|
||||
echo $actions;
|
||||
DisplayGradebook::display_header_user($_GET['userid'], $category[0]->get_id());
|
||||
$userTable->display();
|
||||
Display::display_footer();
|
||||
Reference in New Issue
Block a user